Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
ymodem 发送代码实现,测试支持securecrt8.1的多文件传输
发布于 2018-11-16 10:25:43 浏览:5725
订阅该版
* 本帖最后由 白霖 于 2018-11-30 09:46 编辑 * 原代码仅支持ymodem文件下载,效果还比较不错,位置在/rt-thread/components/utilities/ymodem目录下 现需要使用到ymodem文件上传功能,因此顺便实现了上传功能, 代码风格继承原有风格,本来打算分成多个文件,不过考虑到原来c文件的命名,还是算了,都放到ymodem.c中得了 希望能给rtt出些绵薄之力。 -------------------------------------分割线2018-11-16 12:06-------------------------------------- 补充说明以下使用方法 传递参数类似rym /** * @brief transmit multi file * @param dev serial port to be used * @param oflag serial port open flag * @param fname_list file's name to be sent * @param file_num file count to be sent * @return if succeed return RT_EOK * @attention the file name in fname_list must be absolute file path * if not, the transmistion will be failed */ rt_err_t tym_recv_on_device( struct tym_ctx *ctx, rt_device_t dev, rt_uint16_t oflag, int handshake_timeout, const char** fname_list, int file_num); 注意区分的是:fname_list 的类型是一个字符串数组,file_num指明待传文件数量 同时,需要提前实现dfs接口。 传输的文件名也必须是绝对地址。 示例函数 ```int sym_test(void) { const char* filenamelist[2]={"/menu.json","coregen.log"}; struct tym_ctx *ctx = rt_malloc(sizeof(struct tym_ctx)); rt_device_t dev = rt_device_find("uart3"); rt_err_t err = tym_recv_on_device(ctx, dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX, 1000, filenamelist, 2); rt_free(ctx); return err; } FINSH_FUNCTION_EXPORT(sym_test, sym function demo);```------------------------------------------分割线------2018-11-30 09:42------------------------------------------ 发现一个使用问题,情景是,当传输的文件大小超过10个数据包时,传输出错, 经过监听端口发现,原本应该为0A的包序号,被flag为STREAM的串口端口强制转换成了0D 0A 进一步查看代码发现,这个转换是在serial驱动模块里实现的。 下载附件 [ymodem.c](https://oss-club.rt-thread.org/uploads/201811/16/102504bm46e8icgat4c8co.attach) 下载附件 [ymodem.h](https://oss-club.rt-thread.org/uploads/201811/16/102505ufretmunegfll9uf.attach)
查看更多
10
个回答
默认排序
按发布时间排序
armink
2018-11-30
这家伙很懒,什么也没写!
>发现一个使用问题,情景是,当传输的文件大小超过10个数据包时,传输出错, >经过监听端口发现,原本应该为0 ... --- 估计你的用法有问题吧,本来 on_device 时就是有做这个处理的,如下图:[attach]6895[/attach] 我们的一般用法如下: ``` #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; ulog_global_filter_lvl_set(LOG_FILTER_LVL_SILENT); 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: ulog_global_filter_lvl_set(LOG_FILTER_LVL_ALL); } MSH_CMD_EXPORT(update, Update user application firmware); ```
yqiu
2018-11-16
这家伙很懒,什么也没写!
赞,建议可以提 PR,直接合并到 RT-Thread github 中。
白霖
2018-11-16
这家伙很懒,什么也没写!
我公司这边有限制,1没法连接外网,2由于某些原因,无法使用git, 所以我把我的代码通过特殊方式传到这里。 如果有谁不介意的话可以劳烦一下,合并到github中
白霖
2018-11-30
这家伙很懒,什么也没写!
发现一个使用问题,情景是,当传输的文件大小超过10个数据包时,传输出错, 经过监听端口发现,原本应该为0A的包序号,被flag为STREAM的串口端口强制转换成了0D 0A 进一步查看代码发现,这个转换是在serial驱动模块里实现的。 有没有比较优雅的管理flag方式?在调用ymodem前取消STREAM标志,调用完成再加上
flyboy
2018-11-30
Do my self();
mark
白霖
2018-12-02
这家伙很懒,什么也没写!
>估计你的用法有问题吧,本来 on_device 时就是有做这个处理的,如下图: --- 谢谢,后面我会根据你的推荐做法,做一个ymodem发送的实例代码 同时,考虑到资源紧张的嵌入式环境, 我考虑,在将ymodem代码升级成不依赖dfs文件系统, 仅使用回调函数的方式,实现ymodem发送文件。 改好后,我尝试贡献到版本库中
youqun
2019-04-03
这家伙很懒,什么也没写!
[i=s] 本帖最后由 youqun 于 2019-4-3 17:39 编辑 [/i] >发现一个使用问题,情景是,当传输的文件大小超过10个数据包时,传输出错, >经过监听端口发现,原本应该为0 ... --- 请问大文件upload时的错误你是如何fix的,我发现好像stream没有问题。 如下为log: msh />upload /ymodem_1.txt [tym_recv_on_device]: started dev->flag:0x153 [tym_recv_on_device]: do dev->flag:0x113 Starting ymodem transfer. Press Ctrl+C to cancel. Transferring ymodem_1.txt... 100% 15 bytes 15 bytes/sec 00:00:01 0 Errors tym_recv_on_device]: end dev->flag:0x153 msh />upload /sweep20_8000_10s.wav [tym_recv_on_device]: started dev->flag:0x153 [tym_recv_on_device]: do dev->flag:0x113 Starting ymodem transfer. Press Ctrl+C to cancel. Transferring sweep20_8000_10s.wav, errors 100...
yangsmithcool
2019-06-02
这家伙很懒,什么也没写!
用xshell试了一下会一直发送NAK,不知道什么原因
yangsmithcool
2019-06-03
这家伙很懒,什么也没写!
发现新的设备驱动里面使用了dev->open_flag作为串口设备打开标志,所以要关闭流模式应该使用dev->open_flag,否则还是会被转换
Dryad
2019-10-17
这家伙很懒,什么也没写!
>用xshell试了一下会一直发送NAK,不知道什么原因 --- 你好,我也遇到了这个问题,请问你解决了吗?
撰写答案
登录
注册新账号
关注者
1
被浏览
5.7k
关于作者
白霖
这家伙很懒,什么也没写!
提问
5
回答
6
被采纳
0
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
GD32F450 片内 flash驱动适配
2
STM32H7R7运行CherryUSB
3
RT-Smart首次线下培训,锁定2024 RT-Thread开发者大会!
4
使用RC522软件包驱动FM1722
5
常量数据类型和表达式陷阱分享
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
freemodbus
PWM
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
中断
编译报错
Debug
SFUD
rt_mq_消息队列_msg_queue
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
a1012112796
10
个答案
1
次被采纳
踩姑娘的小蘑菇
4
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
Ryan_CW
4
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
YZRD
2
篇文章
5
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
Woshizhapuren
1
篇文章
5
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部