1. 项目概述与核心价值
如果你正在用瑞萨的RX系列MCU做嵌入式开发,并且需要让设备通过USB和电脑通信,那么USB CDC(通信设备类)绝对是你绕不开的一个关键技术。简单来说,它能让你的RX设备在电脑上被识别成一个标准的串口(COM口),就像你插了一个USB转串口线一样。这样一来,你就能用任何串口调试助手、终端软件,甚至是自己写的上位机程序,通过这个虚拟出来的串口和设备进行双向数据收发,调试、升级、数据交换都变得异常方便。
这个方案的技术价值非常明确: 标准化和免驱 。在Windows 10及以后的系统上,系统自带CDC驱动,用户插上设备就能用,无需额外安装驱动,极大地提升了产品的用户体验和部署便利性。对于开发者而言,瑞萨提供的FIT(Firmware Integration Technology)模块,特别是 r_usb_pcdc 和 r_usb_basic ,将复杂的USB协议栈封装成清晰的API,让我们可以专注于应用逻辑,而不是底层寄存器操作,开发效率成倍提升。
我这次要分享的,就是基于瑞萨RX系列MCU,利用其官方FIT模块实现USB PCDC(外设通信设备类驱动)虚拟串口通信的完整实战经验。这不是一篇照搬手册的翻译,而是结合了我多次在RX65N、RX72N等平台上实际踩坑、调试、优化后总结出来的“保姆级”指南。我会从原理、配置、代码实现到调试技巧,一步步拆解,目标是让你看完就能动手,做出来就能用。
2. 核心原理与架构设计拆解
在动手写代码之前,我们必须先搞清楚CDC和PCDC到底是什么,以及瑞萨FIT模块是如何组织这些功能的。这能帮你建立清晰的认知,后续遇到问题才知道该从哪里入手排查。
2.1 USB CDC与ACM模型解析
CDC是一个庞大的USB设备类家族,其中用于模拟串口的是它的一个子类,叫做“抽象控制模型”(Abstract Control Model, ACM)。你可以把ACM理解为一套“翻译规则”:
- 物理层虚拟化 :它把USB的批量传输(Bulk Transfer)和中断传输(Interrupt Transfer)通道,“伪装”成传统串口的TX、RX、RTS、CTS等信号线。
- 协议层映射 :它定义了一套标准的USB请求(Class Request),用来设置和获取串口参数,比如波特率、数据位、停止位、校验位。这就是
SetLineCoding和GetLineCoding请求的作用。 - 状态通知机制 :设备端可以通过中断传输通道,主动向主机报告串口线的状态变化,例如帧错误、奇偶校验错误等(对应
Serial State通知)。
当你的RX设备以CDC ACM类型枚举成功后,Windows系统就会调用内置的 usbser.sys 驱动,在设备管理器里生成一个“USB串行设备(COMx)”。你的终端软件向这个COM口写入数据,数据会通过USB批量OUT端点发送到设备;设备通过批量IN端点发送的数据,则会出现在终端软件的接收框里。整个过程对应用层是透明的,感觉就像在用一根真实的串口线。
2.2 瑞萨FIT模块的软件架构
瑞萨的FIT方案采用了清晰的分层设计,理解这个架构是正确使用API的关键。根据文档中的图2-1,我们可以梳理出以下层次关系(自下而上):
- 硬件层(H/W) :RX MCU内部的USB外设控制器。它负责最底层的电气信号、包传输、端点缓冲管理。
- USB基础驱动层(PCD - r_usb_basic) :这是FIT的核心基础模块(
r_usb_basic)。它直接操作USB硬件寄存器,管理USB全局状态(连接、断开、复位)、端点配置、数据传输(包括DMA)和中断服务。 我们一般不直接调用这一层的API,除非进行非常底层的定制。 - PCDC驱动层(PCDC - r_usb_pcdc) :这是我们本次重点使用的模块。它建立在
r_usb_basic之上,实现了CDC ACM的协议逻辑。它的主要职责是:- 解析和处理主机发来的CDC类请求(如
SetLineCoding)。 - 提供数据收发API,将应用层的读写请求,翻译成对底层
r_usb_basic模块的调用。 - 管理用于数据收发的批量端点(Bulk IN/OUT)和用于状态通知的中断端点(Interrupt IN)。
- 解析和处理主机发来的CDC类请求(如
- 应用层(APL) :这就是我们写的用户代码。我们调用
r_usb_pcdc模块提供的API来发送和接收数据,并注册回调函数来处理CDC请求(例如,当主机改变波特率时,我们需要知道并配置自己的真实UART)。
一个关键点 : r_usb_pcdc 模块 依赖 r_usb_basic 模块。在工程中,你必须同时添加这两个模块。通常,使用瑞萨的Smart Configurator或FIT Configurator工具,它们会自动处理这种依赖关系,并导入所有必要的源文件和头文件。
2.3 端点与管道配置的逻辑
USB通信基于“端点”(Endpoint)。在FIT模块的配置中,我们通过“管道”(Pipe)号来引用这些端点。这是配置中最容易出错的地方之一。文档第6章给出了明确的宏定义:
#define USB_CFG_PCDC_BULK_IN (USB_PIPE1) // 批量IN端点,设备->主机
#define USB_CFG_PCDC_BULK_OUT (USB_PIPE2) // 批量OUT端点,主机->设备
#define USB_CFG_PCDC_INT_IN (USB_PIPE6) // 中断IN端点,用于发送Serial State通知
为什么这么分配?
- 管道1-5 :通常用于批量传输端点。所以
BULK_IN和BULK_OUT一般在这里面选。 - 管道6-9 <


430

被折叠的 条评论
为什么被折叠?



