From 32d811257732b6849f816f8da6316fe61b305a88 Mon Sep 17 00:00:00 2001 From: a1012112796 <1012112796@qq.com> Date: Fri, 8 Dec 2023 08:42:05 +0800 Subject: [PATCH] =?UTF-8?q?iap=20=E4=BC=98=E5=8C=96=EF=BC=8C=E9=81=BF?= =?UTF-8?q?=E5=85=8D=20v8=20=E5=8D=87=E7=BA=A7=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: a1012112796 <1012112796@qq.com> --- iap/iap.c | 11 +- project.uvoptx | 6 +- project.uvprojx | 8 +- .../components/utilities/ymodem/SConscript | 2 +- rt-thread/components/utilities/ymodem/ry_sy.c | 31 +++- rt-thread/components/utilities/ymodem/ry_sy.h | 17 ++ .../components/utilities/ymodem/ymodem.c | 145 ++++++++++++------ .../components/utilities/ymodem/ymodem.h | 15 ++ 8 files changed, 171 insertions(+), 64 deletions(-) create mode 100644 rt-thread/components/utilities/ymodem/ry_sy.h diff --git a/iap/iap.c b/iap/iap.c index 3a7c144..f97a517 100644 --- a/iap/iap.c +++ b/iap/iap.c @@ -395,11 +395,11 @@ static int _iap_entry(rt_bool_t is_boot) _response_cmd(IAP_V5_CMD_ONE_REPLY); rt_thread_mdelay(200); - if (!iap_v5_req_char(console_dev, &_wait, 'c', 1000)) - { - err = RT_ENOSYS; - goto _exit; - } +// if (!iap_v5_req_char(console_dev, &_wait, 'c', 1000)) +// { +// err = RT_ENOSYS; +// goto _exit; +// } _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"); goto _exit; } + ctx->parent.v5_iap_adapt = RT_TRUE; ctx->flash = fal_partition_find(IapAppAddr? IAP_FLASH_BOOT_SEC: IAP_FLASH_APP_SEC); if (ctx->flash == RT_NULL) diff --git a/project.uvoptx b/project.uvoptx index 1fe999a..17fd503 100644 --- a/project.uvoptx +++ b/project.uvoptx @@ -428,7 +428,7 @@ DeviceDrivers - 1 + 0 0 0 0 @@ -604,7 +604,7 @@ Drivers - 1 + 0 0 0 0 @@ -856,7 +856,7 @@ IAP - 0 + 1 0 0 0 diff --git a/project.uvprojx b/project.uvprojx index f45b8fc..5841c38 100644 --- a/project.uvprojx +++ b/project.uvprojx @@ -10,14 +10,14 @@ rt-thread 0x4 ARM-ADS - 5060750::V5.06 update 6 (build 750)::ARMCC + 5060960::V5.06 update 7 (build 960)::.\ARMCC 0 STM32F413VGTx STMicroelectronics - Keil.STM32F4xx_DFP.2.16.0 - http://www.keil.com/pack/ + Keil.STM32F4xx_DFP.2.17.0 + https://www.keil.com/pack/ IRAM(0x20000000,0x00050000) IROM(0x08000000,0x00100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE @@ -54,7 +54,7 @@ 1 0 1 - 0 + 1 .\build\keil\List\ 1 0 diff --git a/rt-thread/components/utilities/ymodem/SConscript b/rt-thread/components/utilities/ymodem/SConscript index d75539f..2b3f14f 100644 --- a/rt-thread/components/utilities/ymodem/SConscript +++ b/rt-thread/components/utilities/ymodem/SConscript @@ -4,7 +4,7 @@ cwd = GetCurrentDir() src = Split(''' ymodem.c ''') - + CPPPATH = [cwd] if GetDepend('YMODEM_USING_FILE_TRANSFER'): diff --git a/rt-thread/components/utilities/ymodem/ry_sy.c b/rt-thread/components/utilities/ymodem/ry_sy.c index 0d22c48..557d4bc 100644 --- a/rt-thread/components/utilities/ymodem/ry_sy.c +++ b/rt-thread/components/utilities/ymodem/ry_sy.c @@ -30,6 +30,16 @@ struct custom_ctx 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( struct rym_ctx *ctx, rt_uint8_t *buf, @@ -125,7 +135,18 @@ static enum rym_code _rym_send_begin( rt_kprintf("error open file.\n"); 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; } @@ -153,6 +174,10 @@ static enum rym_code _rym_send_data( ctx->stage = RYM_STAGE_FINISHING; } + if (read_size > 128) + { + return RYM_CODE_STX; + } 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) { rt_kprintf("rt_malloc failed\n"); - return RT_ENOMEM; + return -RT_ENOMEM; } ctx->fd = -1; 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) { rt_kprintf("rt_malloc failed\n"); - return RT_ENOMEM; + return -RT_ENOMEM; } ctx->fd = -1; rt_strncpy(ctx->fpath, file_path, DFS_PATH_MAX); diff --git a/rt-thread/components/utilities/ymodem/ry_sy.h b/rt-thread/components/utilities/ymodem/ry_sy.h new file mode 100644 index 0000000..f1150aa --- /dev/null +++ b/rt-thread/components/utilities/ymodem/ry_sy.h @@ -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 diff --git a/rt-thread/components/utilities/ymodem/ymodem.c b/rt-thread/components/utilities/ymodem/ymodem.c index 51b0578..a344a45 100644 --- a/rt-thread/components/utilities/ymodem/ymodem.c +++ b/rt-thread/components/utilities/ymodem/ymodem.c @@ -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 * * 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 */ -static rt_size_t _rym_read_data( +static rt_ssize_t _rym_read_data( struct rym_ctx *ctx, rt_size_t len) { @@ -149,31 +149,44 @@ static rt_err_t _rym_send_packet( rt_uint16_t send_crc; rt_uint8_t index_inv = ~index; 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[1] = index; ctx->buf[2] = index_inv; - ctx->buf[131] = (rt_uint8_t)(send_crc >> 8); - ctx->buf[132] = (rt_uint8_t)send_crc & 0xff; + ctx->buf[packetlen - 2] = (rt_uint8_t)(send_crc >> 8); + ctx->buf[packetlen - 1] = (rt_uint8_t)send_crc & 0xff; do { 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; } -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)); 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; @@ -276,7 +289,9 @@ static rt_err_t _rym_do_send_handshake( /* congratulations, check passed. */ if (ctx->on_begin && ctx->on_begin(ctx, ctx->buf + 3, data_sz - 5) != RYM_CODE_SOH) + { return -RYM_ERR_CODE; + } code = RYM_CODE_SOH; _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_C); ctx->stage = RYM_STAGE_ESTABLISHED; + rt_size_t errors = 0; while (1) { @@ -360,36 +376,61 @@ static rt_err_t _rym_do_trans(struct rym_ctx *ctx) RYM_WAIT_PKG_TICK); switch (code) { - case RYM_CODE_SOH: - data_sz = 128; - break; - case RYM_CODE_STX: - data_sz = 1024; - break; - case RYM_CODE_EOT: - return RT_EOK; - default: - return -RYM_ERR_CODE; + case RYM_CODE_SOH: + data_sz = 128; + break; + case RYM_CODE_STX: + data_sz = 1024; + break; + case RYM_CODE_EOT: + return RT_EOK; + default: + 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); 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) { - case RYM_CODE_CAN: - /* the spec require multiple CAN */ - for (i = 0; i < RYM_END_SESSION_SEND_CAN_NUM; i++) - { - _rym_putchar(ctx, RYM_CODE_CAN); - } - return -RYM_ERR_CAN; - case RYM_CODE_ACK: - _rym_putchar(ctx, RYM_CODE_ACK); - break; - default: - // wrong code - break; + case RYM_CODE_CAN: + /* the spec require multiple CAN */ + for (i = 0; i < RYM_END_SESSION_SEND_CAN_NUM; i++) + { + _rym_putchar(ctx, RYM_CODE_CAN); + } + return -RYM_ERR_CAN; + case RYM_CODE_ACK: + _rym_putchar(ctx, RYM_CODE_ACK); + break; + default: + // wrong code + break; }; } } @@ -402,21 +443,20 @@ static rt_err_t _rym_do_send_trans(struct rym_ctx *ctx) rt_uint32_t index = 1; rt_uint8_t getc_ack; - data_sz = _RYM_SOH_PKG_SZ; - + data_sz = _RYM_STX_PKG_SZ; 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; - - code = RYM_CODE_SOH; + } + code = ctx->on_data(ctx, ctx->buf + 3, data_sz - 5); _rym_send_packet(ctx, code, index); index++; rt_device_set_rx_indicate(ctx->dev, _rym_rx_ind); getc_ack = _rym_getchar(ctx); - if (getc_ack != RYM_CODE_ACK) { return -RYM_ERR_ACK; @@ -429,6 +469,8 @@ static rt_err_t _rym_do_send_trans(struct rym_ctx *ctx) return RT_EOK; } +// 发送EOT,飞控回复ACK和'C',然后发送SOH空数据,然后回复ACK,然后等待飞控下发B5,5B,03,BB表示升级成功 + static rt_err_t _rym_do_fin(struct rym_ctx *ctx) { enum rym_code code; @@ -442,10 +484,15 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx) if (ctx->on_end) ctx->on_end(ctx, ctx->buf + 3, 128); - _rym_putchar(ctx, RYM_CODE_NAK); - code = _rym_read_code(ctx, RYM_WAIT_PKG_TICK); - if (code != RYM_CODE_EOT) - return -RYM_ERR_CODE; + if (!ctx->v5_iap_adapt) + { + _rym_putchar(ctx, RYM_CODE_NAK); + 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_C); @@ -460,7 +507,9 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx) data_sz = _RYM_STX_PKG_SZ; } else + { return -RYM_ERR_CODE; + } i = _rym_read_data(ctx, _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) { err = _rym_do_trans(ctx); - if (err != RT_EOK) - { - rt_free(ctx->buf); - return err; - } err = _rym_do_fin(ctx); if (err != RT_EOK) @@ -669,6 +713,11 @@ __exit: _rym_the_ctx = RT_NULL; + if (res != RT_EOK) + { + rt_kprintf("rym_recv_on_device err: %d\n", res); + } + return res; } diff --git a/rt-thread/components/utilities/ymodem/ymodem.h b/rt-thread/components/utilities/ymodem/ymodem.h index 398e168..163d7d4 100644 --- a/rt-thread/components/utilities/ymodem/ymodem.h +++ b/rt-thread/components/utilities/ymodem/ymodem.h @@ -58,6 +58,11 @@ enum rym_code #define RYM_END_SESSION_SEND_CAN_NUM 0x07 #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 { RYM_STAGE_NONE = 0, @@ -105,6 +110,16 @@ struct rym_ctx struct rt_semaphore sem; 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.