尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

RT-Thread CherryUSB 中 OHCI 主机控制器驱动的移植与配置指南

RT-Thread CherryUSB 中 OHCI 主机控制器驱动的移植与配置指南 操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载导读本文以 components/drivers/usb/cherryusb/port/ohci/README.md 为骨架系统讲解 RT-Thread 中 CherryUSB 组件所携带的 OHCIOpen Host Controller InterfaceUSB 主机控制器驱动它既是 EHCI 的伴生控制器companion controller也可脱离 EHCI 独立承担低速LS/全速FSUSB 设备的接入。读完本文你将掌握 OHCI 驱动的两种工作模式伴生/独立、官方支持芯片清单、全部相关配置宏的含义、初始化与中断处理流程以及基于 port/ohci 目录源码将其移植到新平台的具体步骤。OHCI 与 EHCI伴生控制器的来龙去脉在 USB 主机控制器的发展历史上EHCIEnhanced Host Controller Interface负责高速HS480 Mbps传输而全速12 Mbps与低速1.5 Mbps设备则需要由另一套控制器来处理。行业惯例是让 EHCI 配一个“伴生控制器”companion controller把低速/全速端口“分流”给后者。OHCI 正是这种经典伴生控制器角色This OHCI is a companion controller of EHCI. But you can use OHCI only withoutCONFIG_USB_EHCI_WITH_OHCIdefinition.这句话点明了本驱动最核心的设计定位包含两层含义默认是 EHCI 的伴生控制器在 EHCI 主机控制器上低速/全速设备通过 OHCI 端口接入高速设备走 EHCI 端口。也可以独立使用只要不定义CONFIG_USB_EHCI_WITH_OHCI宏OHCI 驱动会自行注册为完整的 USB 主机控制器HCD单独完成根集线器枚举与 URB 提交此时它不再依赖 EHCI。这一设计在源码中得到了直接印证port/ohci/usb_hc_ohci.c 末尾有一段被#ifndef CONFIG_USB_EHCI_WITH_OHCI包起来的“独立模式适配层”当宏未定义时驱动会补齐usb_hc_init、usb_hc_deinit、usbh_roothub_control、usbh_submit_urb、usbh_kill_urb、USBH_IRQHandler等 HCD 顶层接口全部转发到对应的ohci_*函数从而作为一个完整的主机栈独立运行。而当宏被定义时这些顶层接口由 EHCI 驱动port/ehci/usb_hc_ehci.c提供OHCI 仅暴露ohci_*内部接口供 EHCI 在初始化、枚举、URB 路由时按端口属性调用。两种工作模式EHCI 伴生与 OHCI 独立伴生模式定义 CONFIG_USB_EHCI_WITH_OHCI当平台同时具备 EHCI 与 OHCI 硬件例如 Allwinner F133、Artinchip d13x/d21x、Nuvoton 全系列推荐开启伴生模式。需要在配置文件如 cherryusb_config_template.h 所示的模板实际项目通常复制为cherryusb_config.h中取消以下宏的注释#define CONFIG_USB_EHCI_WITH_OHCI在伴生模式下EHCI 初始化流程会按“是否内置 Transaction TranslatorTT”决定 OHCI 的启用方式见 port/ehci/usb_hc_ehci.cif (g_ehci_hcd[bus-hcd.hcd_id].has_tt) { #ifdef CONFIG_USB_EHCI_WITH_OHCI USB_LOG_INFO(EHCI uses tt for ls/fs device, so cannot enable this macro\r\n); return -USB_ERR_INVAL; #endif } ... if (g_ehci_hcd[bus-hcd.hcd_id].has_tt) { USB_LOG_INFO(EHCI uses tt for ls/fs device\r\n); } else { #ifdef CONFIG_USB_EHCI_WITH_OHCI USB_LOG_INFO(EHCI uses companion controller for ls/fs device\r\n); ohci_init(bus); #else USB_LOG_WRN(Do not enable companion controller, you should use a hub to support ls/fs device\r\n); #endif }从源码可以看出两个关键结论如果 EHCI 控制器自带 TT如 MCU 内部集成的 chipidea 控制器则不应开启CONFIG_USB_EHCI_WITH_OHCI否则直接返回-USB_ERR_INVAL如果 EHCI 没有 TT则定义该宏后会自动调用ohci_init(bus)初始化伴生控制器用于处理低速/全速设备若未定义宏驱动会告警提示“需要外接 HUB 才能支持 ls/fs 设备”。同理在 port/ehci/usb_hc_ehci.c 中usb_hc_deinit、usbh_roothub_control等接口也通过#ifdef CONFIG_USB_EHCI_WITH_OHCI将 OHCI 的ohci_deinit、ohci_roothub_control、ohci_get_frame_number纳入 EHCI 的宿主路径URB 层面则依据端点的速度属性在 EHCI/OHCI 之间分发对应 usb_hc_ehci.c 的usbh_submit_urb/usbh_kill_urb。另外注意伴生模式下 OHCI 的寄存器基址不再从 0x0 开始需要通过CONFIG_USB_OHCI_HCOR_OFFSET指定偏移。例如 ArtinchipAIC平台要求该值为 0x400其 glue 层在 port/ehci/usb_glue_aic.c 中有硬性校验#if CONFIG_USB_OHCI_HCOR_OFFSET ! 0x400 #error aic CONFIG_USB_OHCI_HCOR_OFFSET must be 0x400 #endifAllwinner T113 平台同样要求 0x400见 port/ehci/usb_glue_t113.c并额外提供了usb_select_phyTohci()这类 PHY 切换辅助函数以及将 OHCI 中断注册到vector 1的t113_ohci_isr。独立模式不定义 CONFIG_USB_EHCI_WITH_OHCI当目标芯片只有 OHCI 硬件典型如 NXP LPC4X/LPC5X 系列时保持CONFIG_USB_EHCI_WITH_OHCI不定义即可。此时 port/ohci/usb_hc_ohci.c 中的usb_hc_init会调用usb_hc_low_level_init(bus)弱函数由各平台 glue 文件实现底层时钟/复位/PHY 使能后再执行ohci_init(bus)整套主机栈完全由 OHCI 驱动承载行为与 EHCI 独立使用完全对等。授权与商用注意原文档明确强调了一条不可忽视的注意事项And you need to pay for using OHCI driver.也就是说CherryUSB 的这份 OHCI 驱动代码衍生自 NuttX 的include/nuttx/usb/ohci.h寄存器定义体系见 usb_ohci_reg.h 的版权头在商用场景下需要向原作者取得付费授权这一点与原文档中 EHCI 等其他控制器驱动的开源许可策略不同。在将 OHCI 驱动用于产品、商业固件发布之前请务必确认授权条款评估项目是否真的需要 OHCI例如芯片是否有 EHCITT 方案可替代可以在立项阶段就避免后续授权成本。官方支持芯片清单原文档给出了驱动已验证/官方支持的芯片列表这里完整继承并补充说明芯片厂商型号/系列支持模式AllwinnerTech全志F133EHCI OHCI伴生Nuvoton新唐全系列EHCI OHCI 或 OHCI 独立Artinchip矽昌d13x、d21xEHCI OHCI伴生NXPLPC4X / LPC5X仅 OHCI独立几点展开说明AllwinnerTech F133属于 Allwinner D1 家族周边芯片EHCIOHCI 伴生OHCI 寄存器偏移为 0x400相关移植参考 port/ehci/usb_glue_t113.cT113 与 F133 控制器同源。Nuvoton 全系列既支持伴生模式也支持 OHCI 独立模式用户可根据具体型号硬件决定。Artinchip d13x/d21x伴生模式CONFIG_USB_OHCI_HCOR_OFFSET必须为 0x400中断注册示例见 port/ehci/usb_glue_aic.c。NXP LPC4X/LPC5X只支持 OHCI 独立模式。对应的平台 glue 层为 port/ohci/usb_glue_lpc.c该文件开头直接声明#if defined(CONFIG_USB_EHCI_WITH_OHCI) #error lpc does not have ehci #endif即 LPC 平台如果误开伴生宏会直接编译报错从源头杜绝错误配置。源码构成与文件职责port/ohci 目录共 5 个文件职责划分如下文件职责usb_hc_ohci.cOHCI 主机控制器核心实现初始化/去初始化、根集线器控制、帧号读取、URB 提交/终止、中断处理usb_hc_ohci.h内部数据结构ED/TD 池、HCD 状态与对外ohci_*接口声明、配置宏默认值usb_ohci_reg.hOHCI 寄存器偏移/位定义、struct ohci_hcor操作寄存器组、ED/TD/HCCA 结构体usb_glue_lpc.cNXP LPC4X/LPC5X 平台底层 gluePHY 上电、时钟使能、复位、NVIC 中断注册README.md本文档骨架模式说明、授权提示、支持芯片清单核心结构体定义集中在 usb_hc_ohci.hstruct ohci_td_hw每个 Transfer DescriptorTD包含硬件struct ohci_gtd hw字段附带软件上下文urb、方向标志dir_in、缓冲区起始地址buf_start、长度length整体按 cachelineCONFIG_USB_OHCI_ALIGN_SIZE32 或 64 字节对齐struct ohci_ed_hw每个 Endpoint DescriptorED内嵌一个大小为CONFIG_USB_OHCI_TD_NUM的 TD 池td_pool[]并携带waitsem信号量用于 URB 完成等待struct ohci_hcd维护 ED 占用位图ohci_ed_used[]与根集线器端口数n_ports。usb_ohci_reg.h开头的版权声明说明其寄存器定义源自 NuttX 的include/nuttx/usb/ohci.h按 Apache-2.0 许可随 CherryUSB 进入 RT-Thread这也正是前面“商用需付费授权”提示的由来——寄存器头文件本身遵循开源许可但驱动实现与移植层的使用条款以原项目声明为准。关键配置项详解OHCI 驱动的全部可配置宏在 cherryusb_config_template.h 的 “OHCI Configuration” 段集中给出模板中的默认值如下/* ---------------- OHCI Configuration ---------------- */ #define CONFIG_USB_OHCI_HCOR_OFFSET (0x0) #define CONFIG_USB_OHCI_ED_NUM 10 #define CONFIG_USB_OHCI_TD_NUM 3 // #define CONFIG_USB_OHCI_DESC_DCACHE_ENABLE各宏含义与源码依据配置宏默认值含义源码依据CONFIG_USB_OHCI_HCOR_OFFSET0x0OHCI 操作寄存器组HcControl 等相对bus-hcd.reg_base的偏移。独立模式为 0x0AIC/T113 伴生模式必须为 0x400usb_hc_ohci.h 中OHCI_HCOR宏定义CONFIG_USB_OHCI_ED_NUM10ED端点描述符池大小即同时可管理的端点描述符数量usb_hc_ohci.h未定义时默认为 10CONFIG_USB_OHCI_TD_NUM3每个 ED 内置的 TD传输描述符数量决定单个端点可排队的传输数usb_hc_ohci.h默认 3CONFIG_USB_OHCI_DESC_DCACHE_ENABLE未定义使能描述符 D-Cache 维护。定义后 ED/TD 结构体会附加 cacheline 填充32 字节对齐时补 16 字节、64 字节对齐时补 48 字节避免 cache 一致性问题usb_hc_ohci.hCONFIG_USB_EHCI_WITH_OHCI未定义伴生模式开关定义后 OHCI 作为 EHCI 伴生控制器不定义则 OHCI 独立usb_hc_ohci.c 条件编译区此外还有两个由CONFIG_USB_ALIGN_SIZE派生的约束见 usb_hc_ohci.h#if CONFIG_USB_ALIGN_SIZE 32 #define CONFIG_USB_OHCI_ALIGN_SIZE 32 #elif CONFIG_USB_ALIGN_SIZE 64 #define CONFIG_USB_OHCI_ALIGN_SIZE 64 #else #error CONFIG_USB_ALIGN_SIZE must be 32 or 64 #endifCONFIG_USB_ALIGN_SIZE必须为 32 或 64否则编译报错。CONFIG_USB_OHCI_ALIGN_SIZE与 cacheline 对齐要求直接相关ohci_init会逐一校验 ED 与 TD 是否按 32 字节对齐不满足则打印USB_LOG_ERR并返回-USB_ERR_INVAL见 usb_hc_ohci.c。此外 ED/TD/HCCA 池均以USB_NOCACHE_RAM_SECTION放到非缓存 RAM 段usb_hc_ohci.c这一段的定义通常在各 BSP 的链接脚本中实现移植时需要确保芯片有可用的 non-cacheable RAM。初始化流程与寄存器操作ohci_initusb_hc_ohci.c按 OHCI 规范完成了从复位到运行态的完整序列软件上下文清零清空g_ohci_hcd、ED 池与 HCCA 中断表32 个表项并为每个 ED 创建waitsem信号量打印版本读取HcRevision寄存器并打印USB_LOG_INFO(OHCI hcrevision:0x%02x)屏蔽中断并复位控制器写HcInterruptDisable OHCI_INT_MIE清空HcControl置位HcCommandStatus.HCR发起控制器复位轮询等待 HCR 清零超时 100ms 返回-USB_ERR_TIMEOUT配置帧时序写入HcFmInterval DEFAULT_FMINTERVAL帧间隔 12000 bit time 减 1FSMPS 按公式(6 * (FI - 210)) / 7计算、HcPeriodicStart (FI * 9) / 10、HcLSThreshold 0x628对应 usb_hc_ohci.c 顶部的宏定义——注释明确指出“在 12 Mbps 下每 1 ms 帧有 12000 个 bit time”清空列表指针并绑定 HCCAHcControlHeadED/HcBulkHeadED置 0HcHCCA指向ohci_hcca[]该结构在 usb_ohci_reg.h 中要求 256 字节对齐清挂起中断进入 Operational 态回写HcInterruptStatus清中断设置HcControl的 HCFS 为 OPER、使能 Control/Bulk 列表CLE读取端口数并配置根集线器从HcRhDescriptorA取NDPNumber Downstream Ports存入n_ports清除 PSM/NPS 位置HcRhStatus的 SGPSet Global Power并延时 20ms使能中断HcInterruptEnable WDH | RHSC | MIE写回完成头、根集线器状态变化、主中断使能。ohci_deinitusb_hc_ohci.c是逆过程屏蔽并清除中断、清除 SGP、将 HCFS 置为 SUSPEND、删除全部waitsem。ohci_get_frame_numberusb_hc_ohci.c直接返回HcFmNumber寄存器低 16 位供主机栈计算帧号/调度周期传输。根集线器Root Hub控制与中断处理OHCI 驱动实现了完整的根集线器虚拟 HUB 语义。ohci_roothub_controlusb_hc_ohci.c解析 USB 标准 HUB 类请求并映射到 OHCI 根集线器寄存器设备级请求RECIPIENT_DEVICE支持HUB_FEATURE_HUB_C_LOCALPOWER、HUB_FEATURE_HUB_C_OVERCURRENT的 CLEAR/SET、GET_DESCRIPTOR、GET_STATUS端口级请求RECIPIENT_OTHER覆盖HUB_PORT_FEATURE_ENABLE、SUSPEND/C_SUSPEND、POWER、C_CONNECTION、C_ENABLE、C_OVER_CURREN、C_RESET的 CLEAR_FEATURE 与 SET_FEATURE含RESET端口复位及等待 PRS 位清零的忙等以及 GET_STATUS直接拷贝HcRhPortStatus[n]4 字节。 端口号由setup-wIndex携带越界!port || port nports返回-USB_ERR_INVAL。中断处理入口为OHCI_IRQHandler(uint8_t busid)usb_hc_ohci.c按HcInterruptStatus HcInterruptEnable区分事件源RHSC根集线器状态变化遍历CONFIG_USB_HOST_MAX_RHPORTS个端口若端口CSC连接状态变化置位当HcRhStatus.DRWEDevice Remote Wakeup Enable置位时视为远程唤醒事件不做处理否则将对应端口位写入bus-hcd.roothub.int_buffer[port 1]并调用usbh_hub_thread_wakeup唤醒 HUB 线程执行插拔处理WDHWriteback Done Head清中断标志传输完成队列的进一步消费由主机栈侧完成。独立模式下USBH_IRQHandler直接转发给OHCI_IRQHandler伴生模式下则分别由各平台的 OHCI 中断服务例程如 AIC 的aic_ohci_isr、T113 的t113_ohci_isr调用。RT-Thread 集成方式SConscriptRT-Thread 通过菜单配置Kconfig与 SConscript 构建脚本集成 CherryUSB。在 components/drivers/usb/cherryusb/SConscript 中AIC 平台的 EHCIOHCI 组合构建逻辑为if GetDepend([RT_CHERRYUSB_HOST_EHCI_AIC]): path [cwd /port/ehci] path [cwd /port/ohci] src Glob(port/ehci/usb_hc_ehci.c) src Glob(port/ehci/usb_glue_aic.c) src Glob(port/ohci/usb_hc_ohci.c)即选中RT_CHERRYUSB_HOST_EHCI_AIC后port/ohci目录会同时加入头文件搜索路径usb_hc_ohci.c会被编译进工程——此时便要求开启CONFIG_USB_EHCI_WITH_OHCIAIC glue 的#error会强制这一点。对应的 CMake 集成见 cherryusb.cmake。对于 NXP LPC4X/LPC5X 这类仅 OHCI 的平台则应选择独立的 OHCI 主机选项使 SConscript 走usb_glue_lpc.c的路径。移植到新平台的一般步骤综合以上源码分析将 OHCI 驱动移植到新芯片可按以下步骤进行从源码结构看这是 CherryUSB 各 port 目录的通例确认硬件归属确认目标芯片的 USB 控制器是 OHCI或 EHCIOHCI 伴生确定寄存器基址与 OHCI 操作寄存器偏移复制配置模板以 cherryusb_config_template.h 为模板生成cherryusb_config.h按需设置CONFIG_USB_OHCI_HCOR_OFFSET、CONFIG_USB_OHCI_ED_NUM、CONFIG_USB_OHCI_TD_NUM必要时开启CONFIG_USB_OHCI_DESC_DCACHE_ENABLE实现 glue 层仿照 port/ohci/usb_glue_lpc.c 实现usb_hc_low_level_init时钟、复位、PHY 上电、NVIC 中断使能与usb_hc_low_level_deinit并实现XXX_IRQHandler调用USBH_IRQHandler(0)独立模式下这是必须的伴生模式下则由 EHCI glue 中的ohci_isr承担提供非缓存 RAM 段ED/TD/HCCA 池声明为USB_NOCACHE_RAM_SECTION需在链接脚本中预留 non-cacheable 内存否则需开启CONFIG_USB_OHCI_DESC_DCACHE_ENABLE配合 cacheline 对齐注意CONFIG_USB_ALIGN_SIZE只能是 32 或 64接入构建系统在 SConscript 中新增平台分支把port/ohci/usb_hc_ohci.c与 glue 文件加入src、把port/ohci加入path并在 Kconfig 中暴露对应的 host 选项验证枚举链路上电后观察USB_LOG_INFO(OHCI hcrevision:0x%02x)与n_ports日志确认控制器进入 Operational 态插入全速/低速设备验证根集线器 CSC 中断、usbh_hub_thread_wakeup唤醒链路与设备枚举成功。总结RT-Thread 中的 CherryUSB OHCI 驱动是一份按 OHCI 规范实现的完整主机控制器驱动既可作为 EHCI 的伴生控制器承担低速/全速设备接入也可通过不定义CONFIG_USB_EHCI_WITH_OHCI独立运行官方支持 AllwinnerTech F133、Nuvoton 全系列、Artinchip d13x/d21x 与 NXP LPC4X/LPC5X。使用时需特别注意其商用授权声明并按 cherryusb_config_template.h 中的CONFIG_USB_OHCI_*系列宏正确配置 ED/TD 池、对齐与 cache 维护策略参考 port/ohci/usb_glue_lpc.c 完成底层 glue 即可快速移植到新平台。赞分享操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载相关推荐RT-Thread 中 CherryUSB 的 CHIPIDEA 设备控制器移植与配置指南RT Thread 中 CherryUSB 的 CHIPIDEA 设备控制器移植与配置指南 本篇指南以 RT Thread 仓库中 CherryUSB 组件下的操作系统嵌入式物联网嵌入式OSRTOSRT-Thread CherryUSB EHCI 主机控制器驱动支持芯片清单、移植要点与源码解析RT Thread CherryUSB EHCI 主机控制器驱动支持芯片清单、移植要点与源码解析 本指南以 RT Thread 仓库内 components/操作系统嵌入式物联网嵌入式OSRTOSRT-Thread CherryUSB MUSB 控制器驱动移植层全解析支持的芯片清单、FIFO 配置与设备/主机实现RT Thread CherryUSB MUSB 控制器驱动移植层全解析支持的芯片清单、FIFO 配置与设备/主机实现 本篇技术指南聚焦 RT Thread操作系统嵌入式物联网嵌入式OSRTOS上一篇冴羽博客GitHub_Trending/blo/BlogReact系列文章太空殖民实践下一篇告别歪歪扭扭的扫描件OCRmyPDF自动纠偏技术全解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表