iap 优化,避免 v8 升级失败

Signed-off-by: a1012112796 <1012112796@qq.com>
This commit is contained in:
2023-12-08 08:42:05 +08:00
parent 1830fad2a7
commit 32d8112577
8 changed files with 171 additions and 64 deletions

View File

@@ -395,11 +395,11 @@ static int _iap_entry(rt_bool_t is_boot)
_response_cmd(IAP_V5_CMD_ONE_REPLY); _response_cmd(IAP_V5_CMD_ONE_REPLY);
rt_thread_mdelay(200); rt_thread_mdelay(200);
if (!iap_v5_req_char(console_dev, &_wait, 'c', 1000)) // if (!iap_v5_req_char(console_dev, &_wait, 'c', 1000))
{ // {
err = RT_ENOSYS; // err = RT_ENOSYS;
goto _exit; // goto _exit;
} // }
_response_cmd(IAP_V5_CMD_C_REPLY); _response_cmd(IAP_V5_CMD_C_REPLY);
@@ -410,6 +410,7 @@ static int _iap_entry(rt_bool_t is_boot)
rt_kprintf("rt_malloc failed\n"); rt_kprintf("rt_malloc failed\n");
goto _exit; goto _exit;
} }
ctx->parent.v5_iap_adapt = RT_TRUE;
ctx->flash = fal_partition_find(IapAppAddr? IAP_FLASH_BOOT_SEC: IAP_FLASH_APP_SEC); ctx->flash = fal_partition_find(IapAppAddr? IAP_FLASH_BOOT_SEC: IAP_FLASH_APP_SEC);
if (ctx->flash == RT_NULL) if (ctx->flash == RT_NULL)

View File

@@ -428,7 +428,7 @@
<Group> <Group>
<GroupName>DeviceDrivers</GroupName> <GroupName>DeviceDrivers</GroupName>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
@@ -604,7 +604,7 @@
<Group> <Group>
<GroupName>Drivers</GroupName> <GroupName>Drivers</GroupName>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
@@ -856,7 +856,7 @@
<Group> <Group>
<GroupName>IAP</GroupName> <GroupName>IAP</GroupName>
<tvExp>0</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel> <cbSel>0</cbSel>
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>

View File

@@ -10,14 +10,14 @@
<TargetName>rt-thread</TargetName> <TargetName>rt-thread</TargetName>
<ToolsetNumber>0x4</ToolsetNumber> <ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName> <ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>5060750::V5.06 update 6 (build 750)::ARMCC</pCCUsed> <pCCUsed>5060960::V5.06 update 7 (build 960)::.\ARMCC</pCCUsed>
<uAC6>0</uAC6> <uAC6>0</uAC6>
<TargetOption> <TargetOption>
<TargetCommonOption> <TargetCommonOption>
<Device>STM32F413VGTx</Device> <Device>STM32F413VGTx</Device>
<Vendor>STMicroelectronics</Vendor> <Vendor>STMicroelectronics</Vendor>
<PackID>Keil.STM32F4xx_DFP.2.16.0</PackID> <PackID>Keil.STM32F4xx_DFP.2.17.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL> <PackURL>https://www.keil.com/pack/</PackURL>
<Cpu>IRAM(0x20000000,0x00050000) IROM(0x08000000,0x00100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu> <Cpu>IRAM(0x20000000,0x00050000) IROM(0x08000000,0x00100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec> <FlashUtilSpec></FlashUtilSpec>
<StartupFile></StartupFile> <StartupFile></StartupFile>
@@ -54,7 +54,7 @@
<CreateLib>1</CreateLib> <CreateLib>1</CreateLib>
<CreateHexFile>0</CreateHexFile> <CreateHexFile>0</CreateHexFile>
<DebugInformation>1</DebugInformation> <DebugInformation>1</DebugInformation>
<BrowseInformation>0</BrowseInformation> <BrowseInformation>1</BrowseInformation>
<ListingPath>.\build\keil\List\</ListingPath> <ListingPath>.\build\keil\List\</ListingPath>
<HexFormatSelection>1</HexFormatSelection> <HexFormatSelection>1</HexFormatSelection>
<Merge32K>0</Merge32K> <Merge32K>0</Merge32K>

View File

@@ -30,6 +30,16 @@ struct custom_ctx
char fpath[DFS_PATH_MAX]; char fpath[DFS_PATH_MAX];
}; };
static const char *_get_path_lastname(const char *path)
{
char *ptr;
if ((ptr = (char *)strrchr(path, '/')) == NULL)
return path;
/* skip the '/' then return */
return ++ptr;
}
static enum rym_code _rym_recv_begin( static enum rym_code _rym_recv_begin(
struct rym_ctx *ctx, struct rym_ctx *ctx,
rt_uint8_t *buf, rt_uint8_t *buf,
@@ -125,7 +135,18 @@ static enum rym_code _rym_send_begin(
rt_kprintf("error open file.\n"); rt_kprintf("error open file.\n");
return RYM_ERR_FILE; return RYM_ERR_FILE;
} }
rt_sprintf((char *)buf, "%s%c%d", (char *) & (cctx->fpath[1]), insert_0, file_buf.st_size);
const char *fdst = _get_path_lastname(cctx->fpath);
if(fdst != cctx->fpath)
{
fdst = dfs_normalize_path(RT_NULL, fdst);
if (fdst == RT_NULL)
{
return RYM_ERR_FILE;
}
}
rt_sprintf((char *)buf, "%s%c%d", fdst, insert_0, file_buf.st_size);
return RYM_CODE_SOH; return RYM_CODE_SOH;
} }
@@ -153,6 +174,10 @@ static enum rym_code _rym_send_data(
ctx->stage = RYM_STAGE_FINISHING; ctx->stage = RYM_STAGE_FINISHING;
} }
if (read_size > 128)
{
return RYM_CODE_STX;
}
return RYM_CODE_SOH; return RYM_CODE_SOH;
} }
@@ -174,7 +199,7 @@ static rt_err_t rym_download_file(rt_device_t idev,const char *file_path)
if (!ctx) if (!ctx)
{ {
rt_kprintf("rt_malloc failed\n"); rt_kprintf("rt_malloc failed\n");
return RT_ENOMEM; return -RT_ENOMEM;
} }
ctx->fd = -1; ctx->fd = -1;
rt_strncpy(ctx->fpath, file_path, DFS_PATH_MAX); rt_strncpy(ctx->fpath, file_path, DFS_PATH_MAX);
@@ -194,7 +219,7 @@ static rt_err_t rym_upload_file(rt_device_t idev, const char *file_path)
if (!ctx) if (!ctx)
{ {
rt_kprintf("rt_malloc failed\n"); rt_kprintf("rt_malloc failed\n");
return RT_ENOMEM; return -RT_ENOMEM;
} }
ctx->fd = -1; ctx->fd = -1;
rt_strncpy(ctx->fpath, file_path, DFS_PATH_MAX); rt_strncpy(ctx->fpath, file_path, DFS_PATH_MAX);

View File

@@ -0,0 +1,17 @@
#ifndef __RY_SY_H__
#define __RY_SY_H__
#include "dfs.h"
#include "ymodem.h"
struct rym_file_ctx
{
struct rym_ctx parent;
int fd;
int flen;
char fpath[DFS_PATH_MAX];
};
rt_err_t rym_download_file(rt_device_t idev, struct rym_file_ctx *ctx, rt_bool_t v5_adapt);
#endif

View File

@@ -1,5 +1,5 @@
/* /*
* COPYRIGHT (C) 2011-2021, Real-Thread Information Technology Ltd * COPYRIGHT (C) 2011-2023, Real-Thread Information Technology Ltd
* All rights reserved * All rights reserved
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
@@ -121,7 +121,7 @@ static enum rym_code _rym_read_code(
} }
/* the caller should at least alloc _RYM_STX_PKG_SZ buffer */ /* the caller should at least alloc _RYM_STX_PKG_SZ buffer */
static rt_size_t _rym_read_data( static rt_ssize_t _rym_read_data(
struct rym_ctx *ctx, struct rym_ctx *ctx,
rt_size_t len) rt_size_t len)
{ {
@@ -149,31 +149,44 @@ static rt_err_t _rym_send_packet(
rt_uint16_t send_crc; rt_uint16_t send_crc;
rt_uint8_t index_inv = ~index; rt_uint8_t index_inv = ~index;
rt_size_t writelen = 0; rt_size_t writelen = 0;
rt_size_t packetlen = 0;
send_crc = CRC16(ctx->buf + 3, _RYM_SOH_PKG_SZ - 5); switch(code)
{
case RYM_CODE_SOH:
packetlen = _RYM_SOH_PKG_SZ;
break;
case RYM_CODE_STX:
packetlen = _RYM_STX_PKG_SZ;
break;
default:
return -RT_ERROR;
}
send_crc = CRC16(ctx->buf + 3, packetlen - 5);
ctx->buf[0] = code; ctx->buf[0] = code;
ctx->buf[1] = index; ctx->buf[1] = index;
ctx->buf[2] = index_inv; ctx->buf[2] = index_inv;
ctx->buf[131] = (rt_uint8_t)(send_crc >> 8); ctx->buf[packetlen - 2] = (rt_uint8_t)(send_crc >> 8);
ctx->buf[132] = (rt_uint8_t)send_crc & 0xff; ctx->buf[packetlen - 1] = (rt_uint8_t)send_crc & 0xff;
do do
{ {
writelen += rt_device_write(ctx->dev, 0, ctx->buf + writelen, writelen += rt_device_write(ctx->dev, 0, ctx->buf + writelen,
_RYM_SOH_PKG_SZ - writelen); packetlen - writelen);
} }
while (writelen < _RYM_SOH_PKG_SZ); while (writelen < packetlen);
return RT_EOK; return RT_EOK;
} }
static rt_size_t _rym_putchar(struct rym_ctx *ctx, rt_uint8_t code) static rt_ssize_t _rym_putchar(struct rym_ctx *ctx, rt_uint8_t code)
{ {
rt_device_write(ctx->dev, 0, &code, sizeof(code)); rt_device_write(ctx->dev, 0, &code, sizeof(code));
return 1; return 1;
} }
static rt_size_t _rym_getchar(struct rym_ctx *ctx) static rt_ssize_t _rym_getchar(struct rym_ctx *ctx)
{ {
rt_uint8_t getc_ack; rt_uint8_t getc_ack;
@@ -276,7 +289,9 @@ static rt_err_t _rym_do_send_handshake(
/* congratulations, check passed. */ /* congratulations, check passed. */
if (ctx->on_begin && ctx->on_begin(ctx, ctx->buf + 3, data_sz - 5) != RYM_CODE_SOH) if (ctx->on_begin && ctx->on_begin(ctx, ctx->buf + 3, data_sz - 5) != RYM_CODE_SOH)
{
return -RYM_ERR_CODE; return -RYM_ERR_CODE;
}
code = RYM_CODE_SOH; code = RYM_CODE_SOH;
_rym_send_packet(ctx, code, index); _rym_send_packet(ctx, code, index);
@@ -349,6 +364,7 @@ static rt_err_t _rym_do_trans(struct rym_ctx *ctx)
_rym_putchar(ctx, RYM_CODE_ACK); _rym_putchar(ctx, RYM_CODE_ACK);
_rym_putchar(ctx, RYM_CODE_C); _rym_putchar(ctx, RYM_CODE_C);
ctx->stage = RYM_STAGE_ESTABLISHED; ctx->stage = RYM_STAGE_ESTABLISHED;
rt_size_t errors = 0;
while (1) while (1)
{ {
@@ -360,36 +376,61 @@ static rt_err_t _rym_do_trans(struct rym_ctx *ctx)
RYM_WAIT_PKG_TICK); RYM_WAIT_PKG_TICK);
switch (code) switch (code)
{ {
case RYM_CODE_SOH: case RYM_CODE_SOH:
data_sz = 128; data_sz = 128;
break; break;
case RYM_CODE_STX: case RYM_CODE_STX:
data_sz = 1024; data_sz = 1024;
break; break;
case RYM_CODE_EOT: case RYM_CODE_EOT:
return RT_EOK; return RT_EOK;
default: default:
return -RYM_ERR_CODE; errors++;
if(errors > RYM_MAX_ERRORS)
{
return -RYM_ERR_CODE;/* Abort communication */
}
else
{
_rym_putchar(ctx, RYM_CODE_NAK);/* Ask for a packet */
continue;
}
}; };
err = _rym_trans_data(ctx, data_sz, &code); err = _rym_trans_data(ctx, data_sz, &code);
if (err != RT_EOK) if (err != RT_EOK)
return err; {
errors++;
if(errors > RYM_MAX_ERRORS)
{
return err;/* Abort communication */
}
else
{
_rym_putchar(ctx, RYM_CODE_NAK);/* Ask for a packet */
continue;
}
}
else
{
errors = 0;
}
switch (code) switch (code)
{ {
case RYM_CODE_CAN: case RYM_CODE_CAN:
/* the spec require multiple CAN */ /* the spec require multiple CAN */
for (i = 0; i < RYM_END_SESSION_SEND_CAN_NUM; i++) for (i = 0; i < RYM_END_SESSION_SEND_CAN_NUM; i++)
{ {
_rym_putchar(ctx, RYM_CODE_CAN); _rym_putchar(ctx, RYM_CODE_CAN);
} }
return -RYM_ERR_CAN; return -RYM_ERR_CAN;
case RYM_CODE_ACK: case RYM_CODE_ACK:
_rym_putchar(ctx, RYM_CODE_ACK); _rym_putchar(ctx, RYM_CODE_ACK);
break; break;
default: default:
// wrong code // wrong code
break; break;
}; };
} }
} }
@@ -402,21 +443,20 @@ static rt_err_t _rym_do_send_trans(struct rym_ctx *ctx)
rt_uint32_t index = 1; rt_uint32_t index = 1;
rt_uint8_t getc_ack; rt_uint8_t getc_ack;
data_sz = _RYM_SOH_PKG_SZ; data_sz = _RYM_STX_PKG_SZ;
while (1) while (1)
{ {
if (ctx->on_data && ctx->on_data(ctx, ctx->buf + 3, data_sz - 5) != RYM_CODE_SOH) if (!ctx->on_data)
{
return -RYM_ERR_CODE; return -RYM_ERR_CODE;
}
code = RYM_CODE_SOH; code = ctx->on_data(ctx, ctx->buf + 3, data_sz - 5);
_rym_send_packet(ctx, code, index); _rym_send_packet(ctx, code, index);
index++; index++;
rt_device_set_rx_indicate(ctx->dev, _rym_rx_ind); rt_device_set_rx_indicate(ctx->dev, _rym_rx_ind);
getc_ack = _rym_getchar(ctx); getc_ack = _rym_getchar(ctx);
if (getc_ack != RYM_CODE_ACK) if (getc_ack != RYM_CODE_ACK)
{ {
return -RYM_ERR_ACK; return -RYM_ERR_ACK;
@@ -429,6 +469,8 @@ static rt_err_t _rym_do_send_trans(struct rym_ctx *ctx)
return RT_EOK; return RT_EOK;
} }
// 发送EOT飞控回复ACK和'C'然后发送SOH空数据然后回复ACK然后等待飞控下发B5,5B,03,BB表示升级成功
static rt_err_t _rym_do_fin(struct rym_ctx *ctx) static rt_err_t _rym_do_fin(struct rym_ctx *ctx)
{ {
enum rym_code code; enum rym_code code;
@@ -442,10 +484,15 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx)
if (ctx->on_end) if (ctx->on_end)
ctx->on_end(ctx, ctx->buf + 3, 128); ctx->on_end(ctx, ctx->buf + 3, 128);
_rym_putchar(ctx, RYM_CODE_NAK); if (!ctx->v5_iap_adapt)
code = _rym_read_code(ctx, RYM_WAIT_PKG_TICK); {
if (code != RYM_CODE_EOT) _rym_putchar(ctx, RYM_CODE_NAK);
return -RYM_ERR_CODE; code = _rym_read_code(ctx, RYM_WAIT_PKG_TICK);
if (code != RYM_CODE_EOT)
{
return -RYM_ERR_CODE;
}
}
_rym_putchar(ctx, RYM_CODE_ACK); _rym_putchar(ctx, RYM_CODE_ACK);
_rym_putchar(ctx, RYM_CODE_C); _rym_putchar(ctx, RYM_CODE_C);
@@ -460,7 +507,9 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx)
data_sz = _RYM_STX_PKG_SZ; data_sz = _RYM_STX_PKG_SZ;
} }
else else
{
return -RYM_ERR_CODE; return -RYM_ERR_CODE;
}
i = _rym_read_data(ctx, _RYM_SOH_PKG_SZ - 1); i = _rym_read_data(ctx, _RYM_SOH_PKG_SZ - 1);
if (i != (_RYM_SOH_PKG_SZ - 1)) if (i != (_RYM_SOH_PKG_SZ - 1))
@@ -558,11 +607,6 @@ static rt_err_t _rym_do_recv(
while (1) while (1)
{ {
err = _rym_do_trans(ctx); err = _rym_do_trans(ctx);
if (err != RT_EOK)
{
rt_free(ctx->buf);
return err;
}
err = _rym_do_fin(ctx); err = _rym_do_fin(ctx);
if (err != RT_EOK) if (err != RT_EOK)
@@ -669,6 +713,11 @@ __exit:
_rym_the_ctx = RT_NULL; _rym_the_ctx = RT_NULL;
if (res != RT_EOK)
{
rt_kprintf("rym_recv_on_device err: %d\n", res);
}
return res; return res;
} }

View File

@@ -58,6 +58,11 @@ enum rym_code
#define RYM_END_SESSION_SEND_CAN_NUM 0x07 #define RYM_END_SESSION_SEND_CAN_NUM 0x07
#endif #endif
/* how many retries were made when the error occurred */
#ifndef RYM_MAX_ERRORS
#define RYM_MAX_ERRORS ((rt_size_t)20)
#endif
enum rym_stage enum rym_stage
{ {
RYM_STAGE_NONE = 0, RYM_STAGE_NONE = 0,
@@ -105,6 +110,16 @@ struct rym_ctx
struct rt_semaphore sem; struct rt_semaphore sem;
rt_device_t dev; rt_device_t dev;
/**
* @brief 适配 v5 iap 升级逻辑, 流程如下:
*
* 收到 EOT 后返回 ACT 'C';
* 收到一包空数据后返回 ACT, 正常结束 IAP
* 逻辑.
*
*/
rt_bool_t v5_iap_adapt;
}; };
/* recv a file on device dev with ymodem session ctx. /* recv a file on device dev with ymodem session ctx.