IO模拟SPI操作SD卡系列之五.实现Shell和Xmodem文件传输

原创 嵌入式Lee 2024-08-15 08:00

.前言

前面我们移植了FATFS文件系统,此时就可以方便地读取TF卡上的文件了。为了和开发板进行交互,我们继续实现通过xmodem导入导出文件的功能。xmodem的实现和shell的实现参考公众号文章。

https://mp.weixin.qq.com/s/QSYKxND3DTyQZ0JtnSqkzQ XMODEM协议介绍与高效高可移植非阻塞版本实现

https://mp.weixin.qq.com/s/XLmbJn0SKoDT1aLdxHDrbg一个超级精简高可移植的shell命令行C实现

.Xmodem导入文件

shell_func.c

添加fatfs头文件

#include "ff.h"

中申明实现函数

static void rxfilefunc(uint8_t* param);

g_shell_cmd_list_ast中添加一行

{ (uint8_t*)"rxfile",       rxfilefunc,       (uint8_t*)"rxfile name len"},

实现函数rxfilefunc

void rxfilefunc(uint8_t* param){  char name[64];  uint32_t len;  int res = 0;  if(2 == sscanf((const char*)param, "%*s %s %ld", name, &len))  {    xprintf("rxfile %s %ld\r\n",name,len);    if(0 == rx_file_open(name))    {      xmodem_cfg_st cfg=      {          .buffer = rxtx_buf,          .crccheck = 1,          .getms = getms,          .io_read = io_read,          .io_read_flush = io_read_flush,          .io_write = io_write,          .start_timeout = 60,          .packet_timeout = 1000,          .ack_timeout = 1000,          .mem_write = rx_file_write,          .addr = 0,          .totallen = len,      };      xmodem_init_rx(&cfg);      while((res = xmodem_rx()) == 0);      rx_file_close(name);      xprintf("res:%d\r\n",res);    }    else    {      xprintf("open:%s err\r\n",name);    }  }}

需要实现相关的接口

static uint8_t rxtx_buf[1029];
static uint32_t getms(void){  return os_boot_time32();}
static uint32_t io_read(uint8_t* buffer, uint32_t len){  return fifo_cdc_rx_read(buffer, len);}
static void io_read_flush(void){  uint8_t tmp;  while(0 != fifo_cdc_rx_read(&tmp, 1));}
static uint32_t io_write(uint8_t* buffer, uint32_t len){  fifo_cdc_tx_write(buffer, len);  return len;}

文件相关接口

static FIL rx_fil;            /* File object */static int rx_file_open_flag = 0;
static int rx_file_open(char* name){  FRESULT res = f_open(&rx_fil, name, FA_CREATE_NEW | FA_WRITE);  if (FR_OK == 0)  {    rx_file_open_flag = 1;    return 0;  }  else  {    xprintf("open %s err %d\r\n",name,res);    return -1;  }}
static int rx_file_close(char* name){  if(rx_file_open_flag != 0)  {    rx_file_open_flag = 0;    FRESULT res = f_close(&rx_fil);    if(res != FR_OK)    {      xprintf("close err %d\r\n",res);     }    return 0;  }  else  {    return -1;  }}
static uint32_t  rx_file_write(uint32_t addr, uint8_t* buffer, uint32_t len){  if(rx_file_open_flag != 0)  {    UINT bw;    FRESULT res = f_write(&rx_fil, buffer, len, &bw);    if ((bw != len) || (res != FR_OK))    {      xprintf("write err %d %d\r\n",bw,res);    }    return bw;  }  else  {    return 0;  }}

需要初始化时已经挂在文件系统

   static FATFS fs;   /* Filesystem object */
    if(0 == (r = sd_itf_init()))    {        if(FR_OK != (res = f_mount (&fs, "0:", 1)))        {                       printf("mount err %d, mkfs\r\n",res);            res = f_mkfs("0:",0,work,sizeof(work));            if(res == 0)            {                printf("mkfs ok\r\n");                if(FR_OK == f_mount (&fs, "0:", 1))                {                    printf("mount ok\r\n");                }                else                {                    printf("mount err\r\n");                }            }            else            {                printf("mkfs err %d\r\n",res);            }        }          else        {            printf("mount ok\r\n");        }     }    else    {        printf("sd init err:%d\r\n",r);    }

测试输入help查看新添加的命令

输入

rxfile zhcy093.pdf 2573119回车

Crt中菜单栏

Transfer->Send Xmodem...

选择对应的文件,打开开始发送

开始传输

传输完成

用读卡器查看导入的文件

计算校验信息和原始文件一样

三. Xmodem导出文件

shell_func.c

中申明实现函数

static void sxfilefunc(uint8_t* param);

g_shell_cmd_list_ast中添加一行

{ (uint8_t*)"sxfile",       sxfilefunc,       (uint8_t*)"sxfile name len"}, 

实现函数sxfilefunc

void sxfilefunc(uint8_t* param){  char name[64];  uint32_t len;  int res = 0;  if(2 == sscanf((const char*)param, "%*s %s %ld", name, &len))  {    xprintf("sxfile %s %ld\r\n",name,len);    if(0 == tx_file_open(name))    {      xmodem_cfg_st cfg=      {        .buffer = rxtx_buf,        .plen = 1024,        .getms = getms,        .io_read = io_read,        .io_read_flush = io_read_flush,        .io_write = io_write,        .start_timeout = 60,        .packet_timeout = 1000,        .ack_timeout = 5000,        .mem_read = tx_file_read,        .addr = 0,        .totallen = len,      };      xmodem_init_tx(&cfg);      while((res = xmodem_tx()) == 0);      tx_file_close(name);      xprintf("res:%d\r\n",res);    }    else    {      xprintf("open:%s err\r\n",name);    }  }}

文件读接口实现

static FIL tx_fil;            /* File object */static int tx_file_open_flag = 0;
static int tx_file_open(char* name){  FRESULT res = f_open(&tx_fil, name,  FA_READ);  if (FR_OK == 0)  {    tx_file_open_flag = 1;    return 0;  }  else  {    xprintf("open %s err %d\r\n",name,res);    return -1;  }}
static int tx_file_close(char* name){  if(tx_file_open_flag != 0)  {    tx_file_open_flag = 0;    FRESULT res = f_close(&tx_fil);    if(res != FR_OK)    {      xprintf("close err %d\r\n",res);     }    return 0;  }  else  {    return -1;  }}
static uint32_t tx_file_read(uint32_t addr, uint8_t* buffer, uint32_t len){  UINT br;  FRESULT res = f_read(&tx_fil, buffer, len, &br);  if(res != 0)  {    xprintf("read err %d\r\n",res);   }  return br;}

测试输入help查看新添加的命令

输入

sxfile zhcy093.pdf 2573119 回车

Crt中菜单栏

Transfer->Receive Xmodem...

选择保存为文件zhcy093-1.pdf

传输中

传输完成

Xmodem协议最后不足包长需要填充0x1A,所以接收的文件中需要删除这部分,我们实现的xmodem会根据长度信息只保存指定长度没有这个问题。

删除这部分填充

检查校验信息,完全一致

四. 总结

得益于我们前面构造的shellxmodem的轮子,可以很快的就实现文件传输的功能,这也是之前文章分享中要不断积累自己的轮子的原因。平常功能模块注意设计好框架接口,按照面向对象思想设计,考虑可移植性,这样就可以快速的移植使用。











评论
  • 戴上XR眼镜去“追龙”是种什么体验?2024年11月30日,由上海自然博物馆(上海科技馆分馆)与三湘印象联合出品、三湘印象旗下观印象艺术发展有限公司(下简称“观印象”)承制的《又见恐龙》XR嘉年华在上海自然博物馆重磅开幕。该体验项目将于12月1日正式对公众开放,持续至2025年3月30日。双向奔赴,恐龙IP撞上元宇宙不久前,上海市经济和信息化委员会等部门联合印发了《上海市超高清视听产业发展行动方案》,特别提到“支持博物馆、主题乐园等场所推动超高清视听技术应用,丰富线下文旅消费体验”。作为上海自然
    电子与消费 2024-11-30 22:03 68浏览
  • 光伏逆变器是一种高效的能量转换设备,它能够将光伏太阳能板(PV)产生的不稳定的直流电压转换成与市电频率同步的交流电。这种转换后的电能不仅可以回馈至商用输电网络,还能供独立电网系统使用。光伏逆变器在商业光伏储能电站和家庭独立储能系统等应用领域中得到了广泛的应用。光耦合器,以其高速信号传输、出色的共模抑制比以及单向信号传输和光电隔离的特性,在光伏逆变器中扮演着至关重要的角色。它确保了系统的安全隔离、干扰的有效隔离以及通信信号的精准传输。光耦合器的使用不仅提高了系统的稳定性和安全性,而且由于其低功耗的
    晶台光耦 2024-12-02 10:40 50浏览
  • 《高速PCB设计经验规则应用实践》+PCB绘制学习与验证读书首先看目录,我感兴趣的是这一节;作者在书中列举了一条经典规则,然后进行详细分析,通过公式推导图表列举说明了传统的这一规则是受到电容加工特点影响的,在使用了MLCC陶瓷电容后这一条规则已经不再实用了。图书还列举了高速PCB设计需要的专业工具和仿真软件,当然由于篇幅所限,只是介绍了一点点设计步骤;我最感兴趣的部分还是元件布局的经验规则,在这里列举如下:在这里,演示一下,我根据书本知识进行电机驱动的布局:这也算知行合一吧。对于布局书中有一句:
    wuyu2009 2024-11-30 20:30 82浏览
  • 学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&
    youyeye 2024-11-30 14:30 61浏览
  • 最近几年,新能源汽车愈发受到消费者的青睐,其销量也是一路走高。据中汽协公布的数据显示,2024年10月,新能源汽车产销分别完成146.3万辆和143万辆,同比分别增长48%和49.6%。而结合各家新能源车企所公布的销量数据来看,比亚迪再度夺得了销冠宝座,其10月新能源汽车销量达到了502657辆,同比增长66.53%。众所周知,比亚迪是新能源汽车领域的重要参与者,其一举一动向来为外界所关注。日前,比亚迪汽车旗下品牌方程豹汽车推出了新车方程豹豹8,该款车型一上市就迅速吸引了消费者的目光,成为SUV
    刘旷 2024-12-02 09:32 56浏览
  • RDDI-DAP错误通常与调试接口相关,特别是在使用CMSIS-DAP协议进行嵌入式系统开发时。以下是一些可能的原因和解决方法: 1. 硬件连接问题:     检查调试器(如ST-Link)与目标板之间的连接是否牢固。     确保所有必要的引脚都已正确连接,没有松动或短路。 2. 电源问题:     确保目标板和调试器都有足够的电源供应。     检查电源电压是否符合目标板的规格要求。 3. 固件问题: &n
    丙丁先生 2024-12-01 17:37 55浏览
  • 国产光耦合器因其在电子系统中的重要作用而受到认可,可提供可靠的电气隔离并保护敏感电路免受高压干扰。然而,随着行业向5G和高频数据传输等高速应用迈进,对其性能和寿命的担忧已成为焦点。本文深入探讨了国产光耦合器在高频环境中面临的挑战,并探索了克服这些限制的创新方法。高频性能:一个持续关注的问题信号传输中的挑战国产光耦合器传统上利用LED和光电晶体管进行信号隔离。虽然这些组件对于标准应用有效,但在高频下面临挑战。随着工作频率的增加,信号延迟和数据保真度降低很常见,限制了它们在电信和高速计算等领域的有效
    腾恩科技-彭工 2024-11-29 16:11 105浏览
  • 在电子技术快速发展的今天,KLV15002光耦固态继电器以高性能和强可靠性完美解决行业需求。该光继电器旨在提供无与伦比的电气隔离和无缝切换,是现代系统的终极选择。无论是在电信、工业自动化还是测试环境中,KLV15002光耦合器固态继电器都完美融合了效率和耐用性,可满足当今苛刻的应用需求。为什么选择KLV15002光耦合器固态继电器?不妥协的电压隔离从本质上讲,KLV15002优先考虑安全性。输入到输出隔离达到3750Vrms(后缀为V的型号为5000Vrms),确保即使在高压情况下,敏感的低功耗
    克里雅半导体科技 2024-11-29 16:15 119浏览
  • 艾迈斯欧司朗全新“样片申请”小程序,逾160种LED、传感器、多芯片组合等产品样片一触即达。轻松3步完成申请,境内免费包邮到家!本期热荐性能显著提升的OSLON® Optimal,GF CSSRML.24ams OSRAM 基于最新芯片技术推出全新LED产品OSLON® Optimal系列,实现了显著的性能升级。该系列提供五种不同颜色的光源选项,包括Hyper Red(660 nm,PDN)、Red(640 nm)、Deep Blue(450 nm,PDN)、Far Red(730 nm)及Ho
    艾迈斯欧司朗 2024-11-29 16:55 152浏览
  • 国产光耦合器正以其创新性和多样性引领行业发展。凭借强大的研发能力,国内制造商推出了适应汽车、电信等领域独特需求的专业化光耦合器,为各行业的技术进步提供了重要支持。本文将重点探讨国产光耦合器的技术创新与产品多样性,以及它们在推动产业升级中的重要作用。国产光耦合器创新的作用满足现代需求的创新模式新设计正在满足不断变化的市场需求。例如,高速光耦合器满足了电信和数据处理系统中快速信号传输的需求。同时,栅极驱动光耦合器支持电动汽车(EV)和工业电机驱动器等大功率应用中的精确高效控制。先进材料和设计将碳化硅
    克里雅半导体科技 2024-11-29 16:18 157浏览
  • 光耦合器作为关键技术组件,在确保安全性、可靠性和效率方面发挥着不可或缺的作用。无论是混合动力和电动汽车(HEV),还是军事和航空航天系统,它们都以卓越的性能支持高要求的应用环境,成为现代复杂系统中的隐形功臣。在迈向更环保技术和先进系统的过程中,光耦合器的重要性愈加凸显。1.混合动力和电动汽车中的光耦合器电池管理:保护动力源在电动汽车中,电池管理系统(BMS)是最佳充电、放电和性能监控背后的大脑。光耦合器在这里充当守门人,将高压电池组与敏感的低压电路隔离开来。这不仅可以防止潜在的损坏,还可以提高乘
    腾恩科技-彭工 2024-11-29 16:12 117浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦