求关于RT-Thread中Ymodem的使用方法

发布于 2018-08-08 11:34:27
有没有大神用过RT-thread中的Ymodem的?
我尝试了论坛早期发的Ymodem使用方法,但是接收不到CCCC,又尝试了ENV中的Ymodem,但是还是不能成功,求指教怎么使用这个功能。。。。。。


查看更多

关注者
0
被浏览
3.1k
17 个回答
armink
armink 2018-08-08
来一段,使用 Ymodem + EasyFlash 完成 IAP 固件下载的代码示例,仅供参考

#include 
#include
#include
#include
#include
#include
#include
#include

static size_t update_file_total_size, update_file_cur_size;
static uint32_t crc32_checksum = 0;
static enum rym_code ymodem_on_begin(struct rym_ctx *ctx, rt_uint8_t *buf, rt_size_t len) {
char *file_name, *file_size;

/* calculate and store file size */
file_name = (char *) &buf[0];
file_size = (char *) &buf[rt_strlen(file_name) + 1];
update_file_total_size = atol(file_size);
/* 4 bytes align */
update_file_total_size = (update_file_total_size + 3) / 4 * 4;
update_file_cur_size = 0;
crc32_checksum = 0;

/* erase backup section */
if (ef_erase_bak_app(update_file_total_size)) {
/* if erase fail then end session */
return RYM_CODE_CAN;
}

return RYM_CODE_ACK;
}

static enum rym_code ymodem_on_data(struct rym_ctx *ctx, rt_uint8_t *buf, rt_size_t len) {
if (update_file_cur_size + len <= update_file_total_size) {
crc32_checksum = ef_calc_crc32(crc32_checksum, buf, len);
} else {
crc32_checksum = ef_calc_crc32(crc32_checksum, buf, update_file_total_size - update_file_cur_size);
}
/* write data of application to backup section */
if (ef_write_data_to_bak(buf, len, &update_file_cur_size, update_file_total_size)) {
/* if write fail then end session */
return RYM_CODE_CAN;
}
return RYM_CODE_ACK;
}

void update(uint8_t argc, char **argv) {
char new_char[2], c_file_size[11] = { 0 }, c_crc32_checksum[11] = { 0 };
struct rym_ctx rctx;

elog_set_output_enabled(false);
rt_kprintf("Waring: This operator will not recovery. If you want, press 'Y'.\n");
new_char[0] = getchar();
rt_kprintf("%c", new_char[0]);
new_char[1] = getchar();
rt_kprintf("%c", new_char[1]);
if ((new_char[0] != 'y') && (new_char[0] != 'Y')) {
goto __exit;
}
rt_kprintf("Please select the application firmware file and use Ymodem to send.\n");

if (!rym_recv_on_device(&rctx, rt_console_get_device(), RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
ymodem_on_begin, ymodem_on_data, NULL, RT_TICK_PER_SECOND)) {
/* wait some time for terminal response finish */
rt_thread_delay(RT_TICK_PER_SECOND);
/* save the downloaded firmware crc32 checksum ENV */
ef_set_env("iap_need_crc32_check", "1");
rt_snprintf(c_crc32_checksum, sizeof(c_crc32_checksum), "%ld", crc32_checksum);
ef_set_env("iap_crc32_checksum", c_crc32_checksum);
/* set need copy application from backup section flag is 1, backup application length */
ef_set_env("iap_need_copy_app", "1");
rt_sprintf(c_file_size, "%ld", update_file_total_size);
ef_set_env("iap_copy_app_size", c_file_size);
ef_save_env();
rt_kprintf("Download firmware to flash OK.\n");
rt_kprintf("System now will restart...\n");
NVIC_SystemReset();
} else {
/* wait some time for terminal response finish */
rt_thread_delay(RT_TICK_PER_SECOND);
rt_kprintf("Update firmware fail.\n");
}

__exit:
elog_set_output_enabled(true);
}
MSH_CMD_EXPORT(update, Update user application firmware);


丿纸飞机巛
丿纸飞机巛 2018-08-08
armink 发表于 2018-8-8 13:58
来一段,使用 Ymodem + EasyFlash 完成 IAP 固件下载的代码示例,仅供参考


谢谢,不过我的应用场景是想通过Ymodem协议发送字库文件到挂载的外部flash上,通过固件库example的tofile.c文件没实现........可能是我使用的方法不对,目前没头绪!
bernard
bernard 2018-08-08
你需要传进去,还是传出去?传进去到板子上,是tofile.c,记得有个命令执行下,然后就可以通过串口工具发送文件了。因为是tofile,所以是写到文件系统上,保存为文件的。
armink
armink 2018-08-08
ymodem_on_data 里 ef_write_data_to_bak 就是拷贝接收到的数据到 flash 上的
丿纸飞机巛
丿纸飞机巛 2018-08-09
bernard 发表于 2018-8-8 19:05
你需要传进去,还是传出去?传进去到板子上,是tofile.c,记得有个命令执行下,然后就可以通过串口工具发送 ...


是的,熊老大,就是传文件到文件系统上,但是我执行命令就死机,不知道什么问题


TIM截图20180809184926.png
丿纸飞机巛
丿纸飞机巛 2018-08-09
armink 发表于 2018-8-8 22:17
ymodem_on_data 里 ef_write_data_to_bak 就是拷贝接收到的数据到 flash 上的


嗯,因为有例子,想着实现上传文件就好了,没有注意协议的实现方法,我好好研究一下你这个代码块吧,谢谢!
e_donkey
e_donkey 2019-01-17
有没有办法传文件到上位机?
hnhebing
hnhebing 2019-01-28
rtt+fal+easyflash+ymodem 有完整实例吗?

我用stm32f4 实现rtt+fal+easyflash 可以应用,但是在用到ymodem->rym_recv_on_device()时程序跑飞了!!

环境:env1.10 + rtt4.0
armink
armink 2019-01-28
hnhebing 发表于 2019-1-28 15:20
rtt+fal+easyflash+ymodem 有完整实例吗?

我用stm32f4 实现rtt+fal+easyflash 可以应用,但是在用到ymode ...


有的呀,你可以参考 IoT Board 里的 Ymodem OTA 例程,都是开源的
hnhebing
hnhebing 2019-02-01
在正点原子stm32f407gz ymodem ota已经正常读写,获取收获把bootloader移到flash高端 0x080c0000位置,最也不担心应用程序破坏bootloader了!
海阔天kongcyc
海阔天kongcyc 2019-02-01
hnhebing 发表于 2019-2-1 08:30
在正点原子stm32f407gz ymodem ota已经正常读写,获取收获把bootloader移到flash高端 0x080c0000位置,最也 ...


请教一下哈,ymodem是一个串口文件传输协议,可以通过串口将编译后的固件烧写到flash中?那么为什么要使用这个协议呢?jlink可以下载,stlink可以下载,hex文件,有一个什么hex工具也可以通过串口下载, 这个ymodem的作用或者有点是什么呢?
noerr
noerr 2019-02-01
海阔天kongcyc 发表于 2019-2-1 08:45
请教一下哈,ymodem是一个串口文件传输协议,可以通过串口将编译后的固件烧写到flash中?那么为什么要使 ...


我通过 ymodem 烧录程序,相对于Jlink要方便,不容易出错,给组装机器或者维修人员更容易更新程序,不然还要拆掉机器再烧录比较麻烦
noerr
noerr 2019-02-01
tofile.c文件里面有带的 具体看代码,改起来不难的
海阔天kongcyc
海阔天kongcyc 2019-02-01
noerr 发表于 2019-2-1 09:10
我通过 ymodem 烧录程序,相对于Jlink要方便,不容易出错,给组装机器或者维修人员更容易更新程序,不然 ...


谢谢,不过据我了解,也可以直接通过串口一键下载固件,使用mcuisp软件下载,不过硬件上要预留一键启动电路来控制boot0引脚,你这边使用ymodem下载,其实还有一个原因就是不需要硬件特地留出一键启动电路是么?换句话说,使用ymodem可以更加简单的更新固件
如下截图是我看了原子MINI开发板的《STM32不完全手册》

这个是将使用串口下载程序
666666.png

这个是一键启动电路:
7777777777.png
noerr
noerr 2019-02-01
    本帖最后由 noerr 于 2019-2-1 09:34 编辑


用Ymoden 读取传输的文件 校验OK之后保存到flash ,之后reboot 程序从bootloader 开始 建立文件系统(或者直接读取对应的起始地址也可以,看你怎么保存了,我嫌麻烦就开了文件系统),判断当flash中存在对应的app的bin文件之后 将文件写入到对应的app 地址中, 覆盖之前的app程序,完成app程序的重新烧录, btloader 完成后,程序跳转到app 起始地址中, 机器本来是密封的就留出了接口给上位机和打印串口(用来调试),在这两个端口我都做了程序更新的功能,方便其他人调试或者更新和维护
hnhebing
hnhebing 2019-02-01
用PuTTY工具里YModem协议传输文件,mcuisp需要修改硬件boot0脚不是很方便!
海阔天kongcyc
海阔天kongcyc 2019-02-01
hnhebing 发表于 2019-2-1 10:27
用PuTTY工具里YModem协议传输文件,mcuisp需要修改硬件boot0脚不是很方便!


谢谢你的回复,了解了
fangyongbest
fangyongbest 2020-06-29
海阔天kongcyc 发表于 2019-2-1 08:45
请教一下哈,ymodem是一个串口文件传输协议,可以通过串口将编译后的固件烧写到flash中?那么为什么要使 ...


你想想 你的设备出去了,装到机器上了,上面有屏 或有U盘口 如果 有JLINK 你在设备上面麻烦,也不容易把他取下来,要是能用个U盘 或直接在屏上面上传 操作 是不是简单?也不用带电脑 ?第二想测试个文件 直接远程升级

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友