TinyUSB 的移植

  1. 1. Getting Start
  2. 2. 添加配置文件
  3. 3. 修改代码
  4. 4. Example

TinyUSB 是一个开源的的跨平台 USB 主机/设备协议栈,用于嵌入式系统,它是内存安全的,没有动态内存分配,同时也是线程安全的,所有的中断事件都会被推迟,然后在非中断服务函数中处理。目前已经支持许多主流嵌入式平台。

这篇文章就介绍一下如何将 TinyUSB 添加至项目中,这里以 STM32 平台为例。

image-20210207132819334

Getting Start

首先需要将 TinyUSB 的源代码下载下来,放置项目文件夹内,然后将 tinyusb/src 文件夹下的所有 .c 文件添加至工程,,同时将 tinyusb/src 文件夹添加至包含路径,这里我使用的是 CMake:

1
2
3
file(GLOB_RECURSE SOURCES "Middlewares/Third_Party/tinyusb/src/*.c")
target_sources(${PROJECT_NAME}.elf $SOURCES})
target_include_directories(${PROJECT_NAME}.elf PUBLIC "Middlewares/Third_Party/tinyusb/src)

添加配置文件

tinyusb/example/device 文件夹中,找到想要使用的设备类型,这里我想创建一个 CDC 设备,将 tusb_config.husb_descriptors.c 拷出来,并将其添加进工程,根据自己的需要进行修改。

需要修改如下两个宏,设置 MCU 的类型和是否使用操作系统,可以添加至 CMakeLists.txt 中:

1
add_definitions(-DCFG_TUSB_MCU=OPT_MCU_STM32F1 -DCFG_TUSB_OS=OPT_OS_NONE)

修改代码

在 CubeMX 中配置好 USB,并使能 USB 的中断后,将中断回调函数对应上 TinyUSB 的接口:

1
2
3
4
5
6
7
8
9
10
11
void USB_HP_IRQHandler(void) { 
tud_int_handler(0);
}

void USB_LP_IRQHandler(void) {
tud_int_handler(0);
}

void USBWakeUp_IRQHandler(void) {
tud_int_handler(0);
}

接着初始化 TinyUSB,tud_task() 函数需要周期调用,以处理 USB 的传输:

1
2
3
4
5
6
7
8
int main(void) {

tusb_init();

while (1) {
tud_task();
}
}

Example

接着就可以使用 TinyUSB了,具体函数比较简单,可惜现在还没找到一份完整的 API 手册:

1
2
3
4
5
6
7
8
9
10
11
12
13
int main(void) {

tusb_init();

while (1) {
if (tud_cdc_connected()) {
tud_cdc_write_str("Hello World\r\n");
tud_cdc_write_flush();
}

tud_task();
}
}

在电脑上用串口调试软件打开对应的串口,就可以看到有输出了。

本网站所有文章除特别声明外,均采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。