从 SD 卡到电脑 U 盘:PSoC E84 + RT-Thread + CherryUSB 实战与排错记录

发布时间:2026/10/22 7:26:23
从 SD 卡到电脑 U 盘:PSoC E84 + RT-Thread + CherryUSB 实战与排错记录 在 EDGI-TALK 开发板上把板载 SD 存储通过 USB MSC 提供给 Windows 访问。本文记录最终配置、启动代码以及从“编译通过但没有设备”到文件读写成功的完整排错过程。拿到开发板后我想做一个实用功能不借助读卡器直接通过开发板的 USB 接口让电脑访问板载 SD 存储里的文件。看起来只需要勾选 USB MSC 和 SDIO实际调试却遇到了驱动未参与编译、DFS 依赖缺失、MSC 线程配置缺失、SD 检测线程栈溢出以及 USB 初始化没有被调用等问题。最终Windows 成功识别出磁盘读取、写入和重新连接后的数据保持测试均通过。这篇文章先给出最终可用配置再解释每个问题是如何定位的。文中的配置针对本次 BSP 工程其他版本和开发板需要核对驱动及硬件资源。1. 实验环境与实现原理项目本次环境开发板PSoC E84 EDGI-TALK当前运行核心Cortex-M33开发工具RT-Thread Studio操作系统RT-Thread 5.0.2USB 协议栈CherryUSB 1.6.0工程内版本USB 模式Device / MSC / HSUSB 控制器驱动dwc2_infineon存储设备SDIO1 驱动注册的sd块设备验证平台Windows这里的 MSC 是 Mass Storage Class即 USB 大容量存储设备类。电脑担任 USB Host开发板担任 USB Device。电脑发出的读写请求经 CherryUSB MSC 转换为对 RT-Thread 块设备的访问再由 SDIO 驱动完成实际存储操作。![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_urlimages%2F01-data-path.pngpos_idimg-mdYfM5GT-1792336447947图 1数据通路示意。箭头表示请求和数据的往返关系开发板这一侧完成 USB 与 SD 块设备之间的转接。因此这个功能需要两条链路都打通一条是SDIO 驱动 → SD 块设备另一条是USB 控制器 → CherryUSB MSC → 块设备绑定。本次由电脑解析卡上的文件系统板端没有挂载 SD 文件系统。开启 DFS 是为了满足本次 BSP 中块设备代码的依赖并不等于板端必须挂载 FAT 文件系统。2. 最终配置先把参数选对2.1 CherryUSB 配置进入menuconfig中的Using USB with CherryUSB配置如下。配置项最终设置说明USB Device 模式开启开发板作为设备连接电脑USB Host 模式关闭当前由电脑担任主机Select usb device speedHS选择高速模式Select usb device ipdwc2_infineon使用英飞凌对应的控制器驱动Enable usb msc device勾选开启大容量存储设备类其他 USB 类不勾选本次只使用 MSC控制传输最大缓冲区512本次保持默认MSC 最大数据缓冲区512本次保持默认Select usb device templatemsc_blkdev使用实际块设备作为存储介质USB MSC block device namesd必须与实际设备名一致这里容易混淆的地方有三个Device IP指 USB 控制器的硬件 IP不是网络 IP 地址。msc_ram使用 RAM 模拟存储本次访问 SD 卡应选择msc_blkdev。电脑通过 USB 连接开发板并不意味着要选 WinUSB。本次目标是标准 MSC 磁盘不需要选winusbv1 / winusbv2。2.2 板级驱动和 DFS进入Hardware Drivers Config开启板级 USB 和 SDIO配置位置设置Onboard Peripheral Drivers → Enable USB开启On-chip Peripheral Drivers → Enable SDIO开启SDIO1开启SDIO0关闭本次在 SDIO1 配置下完成了实际识别与读写验证。换到其他开发板时不应直接照搬控制器编号需要核对原理图和 BSP。另外在RT-Thread Components中开启DFS: device virtual file system本次使用DFS v1.0。没有为了导出 U 盘而额外开启 Elm FatFs。几个关键配置最终如下供检查时对照不建议直接用这几行替换整个rtconfig.h#defineBSP_USING_USB#defineBSP_USING_SDIO#defineBSP_USING_SDIO1#defineRT_USING_SDIO#defineRT_MMCSD_STACK_SIZE4096#defineCONFIG_USBDEV_MSC_BLOCK_DEV_NAMEsd2.3 打开 MSC 工作线程本次实际使用的 USB 配置头文件位于libraries/Common/board/ports/usb/usb_config.h取消下面这一行的注释#defineCONFIG_USBDEV_MSC_THREAD当前块设备模板要求 MSC 读写在线程上下文执行。这个配置缺失时模板会通过#error阻止编译后文会说明。3. 先确认 SD 设备再启动 USBSD 驱动末尾已经有自动初始化注册INIT_DEVICE_EXPORT(rt_hw_sdio_init);因此不需要在main()中重复调用 SDIO 初始化。驱动源码必须参与构建且相关配置有效自动初始化流程才有意义。下载固件并运行后在串口msh /提示符下输入list device注意本次工程用的是list device中间为空格。实际设备列表如下图 2实际设备名是sd类型为Block Device。这一步也纠正了前面的一个临时配置开始时设备名暂填为sd0但实际注册的是sd所以 MSC 配置必须同步修改。设备名不是 Windows 的盘符也不是磁盘卷标。4. 补上 MSC 初始化入口SD 设备正常后电脑连接 USB 仍然没有反应。继续搜索发现msc_ram_init()在工程中有定义但没有找到调用文件末尾也没有自动初始化注册。这说明勾选模板只是把相关代码加入工程还需要明确的启动入口。图 3模板内部查找并打开块设备注册描述符、添加 MSC 接口最后调用usbd_initialize()。虽然文件名叫msc_ram_template.c但它也包含通过条件编译启用的块设备适配代码不能只根据文件名判断是否选错模板。4.1 在 main.c 顶部添加声明已有头文件无需重复添加。#includertthread.h#includertdevice.h#includeboard.h#includestdint.hexternvoidmsc_ram_init(uint8_tbusid,uintptr_treg_base);4.2 在 main() 的无限循环之前添加启动代码/* 等待 SD 块设备注册最多等待约 5 秒 */intretry;for(retry0;retry50;retry){if(rt_device_find(sd)!RT_NULL){break;}rt_thread_mdelay(100);}if(rt_device_find(sd)!RT_NULL){rt_kprintf([APP] SD ready, starting USB MSC...\n);/* 本板使用 USB 总线 0 和 USBHS_BASE */msc_ram_init(0,(uintptr_t)USBHS_BASE);rt_kprintf([APP] USB MSC init returned\n);}else{rt_kprintf([APP] SD not found, USB MSC not started\n);}这里的总线编号和控制器地址参考了本板官方 M33 USB 示例并在本次工程中验证通过。需要注意四点等待sd注册完成后再启动 MSC。模板会立即查找设备找不到会触发断言。只调用一次msc_ram_init()。不要放进while (1)反复执行。不要额外重复调用usbd_initialize()。模板内部已经调用。这段代码是上电启动方案不包含完整的 SD 卡热插拔恢复流程。它也依赖本次“板端不挂载 SD 文件系统”的使用方式。5. 调试中遇到的五个问题 问题一宏开了驱动却没有参与编译现象SDIO 配置已经开启编译没有报错但运行后没有 SD 块设备。为了验证驱动是否真的参与编译我在drv_sdio.c的条件编译之外临时加入#errorSDIO_BUILD_CHECK重新构建仍然没有出现这个错误。随后检查工程状态发现该文件被排除构建。同步工程源文件列表及构建配置、使对应驱动参与构建后这条临时错误终于触发。验证结束后再删除它继续正常编译。这次排查的关键是把两个问题分开宏有没有开启以及源文件有没有被编译。不要因为某个驱动没生效就将整个 Common 或驱动目录全部取消排除。另外Common 目录显示排除标记不意味着其中的.h文件不能使用。头文件通过#include被读取不会单独编译成目标文件需要关注实际头文件搜索路径。 问题二缺少 dfs_fs.h驱动参与构建后gpt.c、block_dev.c出现dfs_fs.h: No such file or directory本次工程中的块设备代码依赖 DFS 相关头文件。开启 DFS、保存并同步工程后错误消失。这个问题也提醒我启用外设驱动时要检查它依赖的系统组件而不只是板级宏。 问题三MSC 要求在线程中处理读写继续编译时MSC 模板主动报错Please enable CONFIG_USBDEV_MSC_THREAD, move msc read write from isr to thread打开实际使用的usb_config.h后发现CONFIG_USBDEV_MSC_THREAD被注释。取消注释后编译通过。这里不应该删除模板中的#error。它在提示一项必要配置当前块设备模板需要让 MSC 读写在线程上下文执行。 问题四读到容量后MMC/SD 检测线程栈溢出运行后串口先输出 SD 容量随后出现栈溢出[I/SDIO] SD card capacity 483840 KB. thread:mmcsd_de stack overflow图 4读到容量说明识别流程已有进展但随后检测线程发生栈溢出不能据此认定 SD 初始化全部完成。在menuconfig中按/搜索RT_MMCSD_STACK_SIZE看到原值为1024图 5这是修改前的搜索结果。按结果旁的数字跳转到配置项最终将 1024 改为 4096。修改后配置为#defineRT_MMCSD_STACK_SIZE4096重新编译、下载并复位后栈溢出不再出现终端恢复正常交互随后成功查看到sd块设备。这里改的是MMCSD 检测线程栈不是RT_SDIO_STACK_SIZE也与 SD 卡剩余空间无关。本次通过增加栈空间解决了现象但没有进一步测量峰值栈用量不能将 4096 当成所有项目的固定最优值。 问题五SD 正常USB 却没有启动此时编译通过、sd已注册但连接应用 USB 接口后电脑没有识别到磁盘。检查 MSC 函数的定义、调用和自动初始化注册后定位到缺少启动入口。补上第 4 节的代码等待块设备就绪后调用一次msc_ram_init()电脑随后成功识别磁盘。这个问题的核心是代码参与编译不代表对应功能已经执行初始化。对每个模块都需要明确它是自动初始化还是由应用显式启动。6. 最终结果与验证重新下载固件后串口出现了应用启动信息和 USB 控制器日志图 6MSC 初始化函数返回USB 控制器相关日志开始输出。函数返回本身不等于枚举成功还要结合电脑端结果判断。使用支持数据传输的 USB 线连接开发板的应用 USB 接口后Windows 显示出新的磁盘并能读取原有文件图 7本次 Windows 分配了 E 盘。盘符由电脑决定与 RT-Thread 中的设备名sd无关。随后完成了以下验证测试内容结果注册 SD 块设备成功名称为sdWindows 识别 USB 磁盘成功查看原有文件目录成功将已有文件复制到电脑并打开成功写入文本文件并保存成功安全弹出、重新连接后读取成功内容保留这些结果说明本次基本功能已经打通但不代表完成了吞吐率测试、长时间压力测试或异常断电测试。 保留的问题与使用边界启动日志中仍出现过descriptor ... not found和standard request error。本次测试没有因此阻止磁盘识别和文件读写但尚未进一步定位、消除这些日志因此不能说所有 USB 异常都已修复。电脑通过 MSC 访问期间不要让板端或另一个核心同时挂载并操作同一张卡的文件系统。若后续需要“板端采集保存”和“电脑导出文件”两种模式需要另外设计访问权切换而不是只给单次读写加锁。拔线前先在 Windows 中安全弹出修改工程前建议保留这份已经通过功能验证的版本。7. 这次调试留下的方法这次任务并不是从零编写 USB 协议栈而是把 BSP、RT-Thread 块设备和 CherryUSB 集成起来。真正花时间的地方是确认配置、构建和运行三者是否一致。以后再遇到“配置都开了功能还是不工作”的情况可以按下面的顺序检查配置层宏、依赖组件、设备名是否正确构建层源文件是否参与编译头文件是否来自预期路径启动层初始化函数由谁调用调用时依赖设备是否已经就绪运行层是否出现断言、栈溢出或驱动错误验证层是否完成了实际文件读写而不只是看到一个盘符按这个顺序逐层缩小范围比同时改动多个配置更容易找到原因。参考资料EDGI-TALK 官方 BSP 仓库官方 M33 USB RoleSwitch 示例说明官方 M33 USB 示例 main.cCherryUSB MSC 示例说明本文配置和排错结论来自本次实测。官方示例与文档可能更新复现时应以本地 BSP、配置文件和源码为准。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询