Rec 0002
本帖最后由 jf_1137202360 于 2023-4-15 23:40 编辑
转自公众号,欢迎关注
工程代码见附件
前言 前面我们移植了文件系统littlefs, 有时需求将文件导入导出开发板,通过串口的xmodem协议实现文件传输是一个不错的选择。 这一篇就演示移植xmodem,并进行文件的导入导出测试,为了查看文件实现了ls的shell命令。
过程下载代码git clone https://github.com/kelvinlawson/xmodem-1k.git
将代码添加到工程
添加头文件包含路径
实现接口基于之前的usart_fifo的串口收发接口
- #include
- #include \"SYSTEM/usart/usart_fifo.h\"
- #include \"SYSTEM/delay/delay.h\"
复制代码
_inbyte
- int _inbyte(unsigned short timeout)
- {
- uint8_t ch;
- int res;
- do
- {
- res = uart_read(&ch, 1);
- if(res == 0)
- {
- delay_ms(1);
- }
- }while((res==0) && (timeout-->0));
- if(res == 0)
- {
- return -1;
- }
- else
- {
- return ch;
- }
- }
复制代码
_outbyte
- void _outbyte(int c)
- {
- uint8_t ch = c;
- uart_write(&ch,1);
- }
复制代码
接收处理xmodemReceive函数中 memcpy (&dest[len], &xbuff[3], count);改为写&xbuff[3处长度为count的内容到文件
发送处理xmodemTransmit函数中 memset (&xbuff[3], 0, bufsz); memcpy (&xbuff[3], &src[len], c); 改为读文件长度为c的内容到&xbuff[3]
代码
Shell命令行
添加两个shell命令用于实现rx sx
- void SxFun(void * cmdbuf)
- {
- uint8_t name[64];
- int size;
- unsigned int len = sscanf((char const *)cmdbuf, \"%*s %s %d\", name, &size);
- if (len == 2)
- {
- xmodemTransmit(name, size);
- }
- else
- {
- printf(\"usage:rx file\\r\\n\");
- }
- }
-
-
- void RxFun(void * cmdbuf)
- {
- uint8_t name[64];
- int size;
- unsigned int len = sscanf((char const *)cmdbuf, \"%*s %s %d\", name, &size);
- if (len == 2)
- {
- xmodemReceive(name, size);
- }
- else
- {
- printf(\"usage:rx file\\r\\n\");
- }
- }
复制代码
添加ls命令用于查看文件
- int ls_file(const char* path)
- {
- lfs_dir_t dir;
- lfs_file_t file;
- struct lfs_info info;
- if(lfs_dir_open(&lfs, &dir, \"/\") < 0)
- {
- return -1;
- }
- while(1)
- {
- int res = lfs_dir_read(&lfs, &dir, &info);
- if(res == 1)
- {
- if(info.type == LFS_TYPE_DIR)
- {
- printf(\"D:%s %d\\r\\n\",info.name,info.size);
- }
- else if(info.type == LFS_TYPE_REG)
- {
- printf(\"F:%s %d\\r\\n\",info.name,info.size);
- }
- }
- else
- {
- break;
- }
- }
- lfs_dir_close(&lfs, &dir);
- return 0;
- }
-
-
- void LsFun(void * cmdbuf)
- {
- uint8_t dir[64];
- unsigned int len = sscanf((char const *)cmdbuf, \"%*s %s\", dir);
- if (len == 1)
- {
- ls_file((const char*)dir);
- }
- else
- {
- printf(\"usage:ls dir\\r\\n\");
- }
- }
复制代码
测试
终端中需要配置xmodem的模式为1k模式
因为按照xmodem协议,最后不足1包长度需要补齐到1包长度,所以最后可能会多一些无用信息,所以我们传入文件长度,这样可以只保存实际文件长度的内容,截断最后的补齐内容。
导入文件输入rx rx.txt 3605回车 其中rx.txt是待导入到开发板的文件 3605为长度。 菜单栏 Transfer-> Send Xmodem...
选择文件 send
看到传输完成
Ls查看文件
导出文件输入sx rx.txt 3605回车 其中sx.txt是待导出的文件 3605为长度。
菜单栏 Transfer ->Receive Xmodem...
设置保存路径和文件名
看到传输完成
可以看到导入之前和rx.txt和导出之后的sx.txt是一样的
只是终端在接收时补齐到了1024后面加了一些0,这是终端按照xmodem协议进行的处理,我们不能控制,我们保证开发板接收是保存的实际长度即可。
总结以上基于xmodem和串口实现了文件的传输,方便后面文件的导入导出。依赖于前期的串口驱动。
|