前言
为啥是TinyUSB?给强大的RT配个轻巧的USB栈!
USB这个让我们方便快捷的接口,几乎无处不在。在嵌入式世界里,尤其是用上了像NXP i.MX RT这样性能强劲的跨界MCU,我们自然希望它能轻松驾驭USB通信。官方所提供的示例只涵盖了USB基础类,对于诸如ECM、NCM等特定类的开发而言,若要从头开始构建,有可能会拖延客户项目的推进。
这时候,TinyUSB闪亮登场!
想象一下,一个开源(MIT 协议)、轻量级、跨平台、示例友好的USB协议栈,是不是有点小激动?
选择TinyUSB的几大优势:
轻巧高效:资源占用小,对内存和 Flash 都很友好。对于性能本就充裕的RT系列,更是能跑得飞起
功能全面:支持常见的设备类(CDC, MSC, HID, MIDI, Vendor等)和主机功能,甚至复杂的复合设备也不在话下。你想让你的RT板子变成U盘、虚拟串口、键盘鼠标?TinyUSB都能帮你搞定
易于移植:清晰的架构设计和OSAL,无论是裸机还是RTOS环境,移植起来都相对顺畅
社区活跃 & 开源免费:MIT协议方便客户使用。同时提供了大量的例程,即使是初学者也可以通过这个项目入门USB开发
一、准备事项:装备检查
动手之前,确保你的“武器库”齐全:
MCUXpresso IDE: NXP 的官方 IDE,我们的主战场(版本越新越好)
Git: 版本控制神器,管理代码和子模块的必备佳品
Make: 构建工具,跑 TinyUSB 自带脚本会用到
Python: 同样是跑脚本用
开辟工作目录并获取TinyUSB源码。创建项目文件夹,然后用 Git 初始化,拉取TinyUSB库。
|
mkdir //TinyUSB_Porting
|
把TinyUSB官方仓库加进来,用子模块的方式,既能保持项目整洁,又能方便地到最新版。
|
git submodule add https://github.com/hathach/tinyusb.git tinyusb
|

二、小试牛刀:命令行下的“热身运动”
在直接跳进IDE的“大坑”之前,咱们先在命令行下跑个官方示例,确保TinyUSB和 NXP的底层驱动能跑通,能避免很多不必要的麻烦。
步骤1: 选个入门示例开动
TinyUSB 的examples/device 目录下有很多好玩的示例。我们就选 cdc_msc 这个经典的“二合一”设备(虚拟串口 + U盘)开刀。
|
cd tinyusb/examples/device/cdc_msc
|
步骤2:TinyUSB获取NXP的依赖项
TinyUSB支持很多芯片和开发板,对于NXP RT,它提供了脚本来自动下载 MCUXpresso SDK的相关驱动。
|
# 告诉 Make 我们用的是 RT1060EVK 板子
|
!!友情提示:NXP 的 Kinetis、LPC、MCX等系列需要用不同的参数去拉取各自的依赖包,别搞混了,对于同一个系列的MCU,只需要拉取一次就可以了。
步骤3: 编译!看看会不会“炸”
是时候检验成果了。用Make命令编译这个示例:
|
# 参数解释:
|

步骤4: 下载!是骡子是马拉出来遛遛
把编译好的固件烧录到你的RT板子上,插上USB线(连接到板子的 USB Device 端口)。如果你的电脑成功识别出一个U盘,那就稳了!这证明TinyUSB和NXP底层驱动这对“CP”在你这块板子上是能正常工作的。
三、主战场:MCUXpresso IDE集成
热身完毕,该进入主战场——MCUXpresso IDE了。我们要把TinyUSB“塞”进一个标准的IDE工程里。
步骤1: 建立“根据地” (创建基础工程)
在 IDE 里,为你的 RT MCU创建一个新的工程。你可以从 hello_world 这种简单的 SDK 示例开始,或者干脆创建一个只包含必要驱动的空工程。确保这个基础工程能独立编译、下载、运行。
步骤2: 给 TinyUSB 安个“家” (添加源码文件夹)
为了不让项目结构乱成一锅粥,我们在 IDE 里给 TinyUSB 单独创建一个“家”(源文件夹)。
1.右键项目-> New -> Source Folder。
2.取个名字,比如tinyusb。
步骤3: 搬运 TinyUSB 的“家当” (复制核心文件)
把之前 Git 下载的 tinyusb/src目录下的核心文件复制到刚创建的 tinyusb 文件夹里。注意只选择需要的device端代码即可。主要包括:
src/common: 通用工具函数
src/device: USB 设备协议栈核心代码
src/class: 你需要用到的 USB 功能类驱动(比如cdc, msc)
src/osal: 操作系统抽象层
src/portable/nxp/chipidea/ci_hs和nxp/ehci: NXP RT 芯片上USB 控制器的底层驱动
src/tusb.c, src/tusb.h:TinyUSB 的主入口和核心头文件

步骤4: 把“说明书”和“应用代码”也拿过来 (复制配置和示例文件)
cdc_msc 示例能跑起来,还需要几个关键的配置文件和应用层代码。把它们从 examples/device/cdc_msc/src/ 复制到 IDE 项目的主源码目录(通常叫source 或src):
main.c: 示例的主函数(替换掉hello_world.c)
msc_disk.c / .h: U盘功能的底层存储接口(你需要实现它来读写你的存储器)
tusb_config.h: TinyUSB的配置文件。所有功能的开关、参数都在这里调
示例代码会调用TinyUSB重写的板级初始化函数。检查下 examples/device/cdc_msc/src/ 和 hw/bsp 目录下类似 board_api.h family.c 这样的文件,有的话也一并复制到你项目的board 或bsp目录。
步骤6: 给编译器“指路” (配置 IncludePaths)
现在文件都搬过来了,但编译器还不知道去哪找头文件。我们需要在 IDE 里配置包含路径:

TinyUSB 用宏定义来识别目标平台和开关功能。我们需要告诉它现在是在为谁工作:
右键项目-> Properties -> C/C++ Build -> Settings -> Tool Settings -> MCUC Compiler -> Preprocessor。
CFG_TUSB_MCU=OPT_MCU_MIMXRT1XXX: 关键!这就是告诉 TinyUSB:“现在需要跑在 NXP RT 芯片上!”

步骤8: 配置“硬件接口” (Pin Mux 和 Clock)
别忘了硬件!它们负责开发板上的各种PINMUX,直接使用TinyUSB中:tinyusbhwspimxrtoardsmimxrt1060_evk下提供的配置替换即可!

集成路上总会有些小坎坷:
family.c和board_api.h的“戏份”: 这些文件通常负责板级的初始化(比如 board_init())。确保它们已经正确移植好!
tusb_config.h (协议栈的“控制面板”):
class文件夹:参考cdc/msc,其他类型的示例移植方法也是类似的。
五、胜利收官:总结展望
恭喜!如果你一路跟着走到这里,并且成功让你的NXP RT开发板在电脑上被识别为一个 USB disk 设备,那么你已经掌握了在MCUXpresso IDE环境下移植TinyUSB 的核心技巧。


现在,RTMCU已经插上了TinyUSB的“翅膀”,可以更自由地翱翔在USB的世界里了。以此为起点,我们可以探索TinyUSB 支持的其他USB Class (HID, MIDI, 网卡等)、将TinyUSB集成到你的实际项目中,实现更复杂的USB功能或者host端协议栈!这些就留给感兴趣的小伙伴来尝试了!
[参考链接]:
https://github.com/hathach/tinyusb
https://docs.tinyusb.org/en/stable/reference/getting_started.html
恩智浦MCU加油站
恩智浦半导体NXP Semiconductors N.V.(纳斯达克股票代码:NXPI)是汽车、工业物联网、移动设备和通信基础设施市场值得信赖的合作伙伴,致力于提供创新解决方案。
全部0条评论
快来发表一下你的评论吧 !