TinyUSB项目移植指南:从零开始为微控制器添加USB支持

TinyUSB项目移植指南:从零开始为微控制器添加USB支持

tinyusb An open source cross-platform USB stack for embedded system tinyusb 项目地址: https://gitcode.com/gh_mirrors/ti/tinyusb

概述

TinyUSB作为一个轻量级的USB协议栈,为嵌入式系统提供了强大的USB功能支持。本文将详细介绍如何为新的微控制器移植TinyUSB,使其能够支持USB设备功能。移植过程主要涉及底层硬件抽象层的实现,完成后可以轻松为各种项目添加USB支持。

准备工作

寄存器定义文件

移植的第一步是准备微控制器的寄存器定义文件和启动代码。这些文件通常由芯片厂商提供,需要放置在特定目录结构中:

  • ARM架构微控制器使用CMSIS定义文件
  • 文件应放置在hw/mcu/<厂商>/<芯片系列>目录下

建议选择一个常见的开发板作为测试平台,这样其他开发者也能方便地进行验证。为开发板创建对应的板级支持包(BSP)目录hw/bsp/<开发板名称>,可以复制现有开发板的配置作为起点。

构建系统配置

初始构建尝试

配置好基本目录结构后,可以尝试构建CDC+MSC设备示例:

make -C examples/device/cdc_msc BOARD=<开发板名称>

首次构建通常会失败,我们需要逐步解决这些问题。

关键配置项

  1. board.mk中设置-DCFG_TUSB_MCU标志,用于指定目标平台
  2. src/tusb_option.h中添加对应的平台定义
  3. 更新board.mk中的VENDOR和CHIP_FAMILY值
  4. 复制参考实现到src/portable/<厂商>/<芯片系列>目录

核心实现步骤

板级支持包(BSP)

BSP代码负责微控制器的初始化和USB外设的时钟/引脚配置,主要包括:

board_init()函数

  • 初始化微控制器核心
  • 配置USB时钟和引脚
  • 可选地初始化LED指示灯
  • 建议使用无晶振模式(如支持)
  • 调试技巧:设置基于USB时钟的PWM输出(如500Hz)以便验证

board_led_write()函数

  • 控制开发板LED状态
  • 可先跳过,待基本功能验证后再实现

操作系统抽象层(OSAL)

OSAL为TinyUSB提供基本的数据结构和并发处理支持:

  • 代码位于src/osal目录
  • 无RTOS时处理主代码与中断间的并发
  • 使用RTOS时,tud_task()/tuh_task()可在事件队列空时阻塞

设备控制器驱动(DCD)实现

USB设备功能的核心实现位于src/portable/<厂商>/<芯片系列>/dcd_<芯片系列>.c,主要包括以下几部分:

设备基础功能

dcd_init()

  • 初始化USB外设为设备模式
  • 启用内部D+/D-上拉电阻以便枚举

dcd_int_enable()/dcd_int_disable()

  • 启用/禁用USB设备中断
  • 防止主代码与中断间的数据竞争

dcd_int_handler()

  • 处理所有硬件产生的事件
  • 由MCU的USB中断处理程序调用

dcd_set_address()

  • 设备获得新总线地址时调用
  • 某些MCU会自动处理地址变更

dcd_remote_wakeup()

  • 从挂起状态唤醒主机时调用

dcd_connect()/dcd_disconnect()

  • 控制数据线上拉电阻的连接状态
特殊事件处理

必须通知TinyUSB以下关键事件的发生:

dcd_event_bus_signal()

  • 处理总线状态事件,包括:
    • DCD_EVENT_RESET(必须实现):总线复位事件
    • DCD_EVENT_SOF:帧起始事件

dcd_setup_received()

  • 处理SETUP包(控制端点0的特殊事务)
  • SETUP包固定为8字节长度
端点管理

USB数据传输的核心,包括控制、批量、中断和同步端点:

端点地址解析

uint8_t epnum = tu_edpt_number(ep_addr);  // 端点号
uint8_t dir   = tu_edpt_dir(ep_addr);     // 方向

dcd_edpt_open()

  • 启用并配置非控制端点
  • 根据端点描述符设置参数
  • 注意端点方向的影响

dcd_edpt_close()

  • 关闭端点(用于实现替代设置)
  • 可选实现

dcd_edpt_xfer()(核心函数)

  • 配置外设进行主机数据收发
  • 必须正确处理零长度状态包
  • 注意缓冲区对齐要求(CFG_TUSB_MEM_ALIGN)
  • 处理大于最大包长度的传输(可能需要分包)

dcd_xfer_complete()

  • 传输完成时从中断处理程序调用
  • 参数包括端点地址、实际传输长度等

dcd_edpt_stall()/dcd_edpt_clear_stall()

  • 设置/清除端点的stall状态
  • 用于指示错误条件

调试技巧

  1. 使用USB协议分析仪捕获总线流量

  2. 问题通常出现在枚举早期阶段:

    • SETUP包无应答:检查USB外设是否正确启动
    • SETUP包应答但无响应:检查USB时钟配置
    • 后续通信失败:检查中断处理和传输完成通知
  3. 验证技巧:

    • 使用PWM输出验证USB时钟
    • 逐步检查每个阶段的事件处理

总结

完成上述所有步骤后,新的微控制器应该能够支持TinyUSB的基本USB设备功能。移植过程中需要特别注意中断处理、端点管理和数据传输等核心功能的正确实现。通过系统化的调试方法,可以有效地解决可能出现的问题。

移植成功后,该微控制器将能够支持所有基于TinyUSB构建的项目,为开发者提供强大的USB功能支持。

tinyusb An open source cross-platform USB stack for embedded system tinyusb 项目地址: https://gitcode.com/gh_mirrors/ti/tinyusb

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

解然嫚Keegan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值