RTT小师弟 · 2022年06月15日

基于 CherryUSB 调试 dwc2 usb host 笔记

本文由RT-Thread论坛用户@sakumisu原创发布:https://club.rt-thread.org/as...

背景

之前适配 DWC2 USB IP 的时候,主要是基于 st 的 hal 库来走的,当时我就对他们的 hal 库代码不满,只是无奈,迫于时间就没重构,果不其然,usb bug 一堆,随意举例,这还只是冰山一角。
https://club.rt-thread.org/as...

https://club.rt-thread.org/as...

再论 usb 的性能,那 hal 库写的,性能直接歇菜,根本没法用。

排坑

ok,现在我们开始一步步排坑

  • 全局中断 SOF
    首先是全局中断 SOF ,这是一个比较坑的,尤其是带了 OS 以后,几个意思,跟我 os 抢中断呢?sof 中断 1ms会触发一次,很费中断。为什么会有这个中断开启?后面再来说,结论就是 dwc2 这个ip太辣鸡,硬件做的很随意,功能没有做到硬件上去,而这个 sof 主要就是给中断传输和同步传输用的。
     title=
  • HCFG 中的 bit 0-1

这也是坑,我们直接看结论,人家手册里说了,每次设置时,需要复位,st 代码中楞是一个字没看见。小坑
 title=

  • HCINTMSK 中的 USB_OTG_HCINTMSK_NAKM

这里面中断标志那是相当多,最坑的是什么,USB_OTG_HCINTMSK_NAKM,我可以说,论坛出现的所有 NAK 的原因都是他造成的,什么枚举 NAK,U盘 NAK,都是他。究其原因,NAK 表示当前没有准备好,需要重试,但是其实并不需要,st 的代码中,进入 NAK 中断以后会关闭当前通道传输,然而,对于控制和批量传输这是没有必要的,传输是可以等到完成的。开了这个,就会造成,各种地方需要手动重发,然后读 HAL_HCD_HC_GetURBState,没有必要,关掉该中断给你带来无限可能。
 title=

  • HAL_HCD_HC_SubmitRequest

大坑来了,此函数就是配置发送需要的 size、packet、buf地址等等。坑1:有 dma 没见你用。坑2:hc->xfer_len 并不能为所欲为的传任何值。坑3:开了 fifo 不为空中断,却没有该中断处理。
 title=
 title=

修改

  • 能用 dma 的全都用 dma
  • 关闭 NAK 中断,中断和同步传输保留
  • HAL_HCD_HC_SubmitRequest 函数设计太拉稀,我们需要做一个调用一次,大小随意,具体切包的实现在完成中断中,最后达到满意的大小后,释放信号量,达到最大带宽。比如我要发送 16K,我只管传16K,里面怎么发,设计好就行,后续看我代码吧。现在的函数是不行的。
  • 中断和同步传输,由于硬件太坑,只能用定时器了,因为中断和同步,调用类似 HAL_HCD_HC_SubmitRequest 的函数并不能帮我们完全的发出去,也就是即使我调用了,他也不一定会成功,相信看过 rt 源码的知道,drv_pipe_xfer 中有个 delay函数。而我们的做法则是挂到定时器中,链表式发送。
  • 最后是关于 HCTSIZ_XFRSIZ 这个寄存器 bits,需要格外注意, in 和 out 的含义是不一样的,并且数据发送接收完成以后,进入中断,再读取这个值,也是不一样的含义(藏个谜底,后续代码揭晓)

代码已更新

支持 dma 模式下调用一次收发函数,长度可达 16K 字节。并且 DMA 模式下自动分包。
https://github.com/sakumisu/C...

推荐阅读
关注数
8071
内容数
181
小而美的物联网操作系统,经过14年的累积发展,RT-Thread 已经拥有一个国内最大的嵌入式开源社区,同时被广泛应用于能源、车载、医疗、消费电子等多个行业,累积装机量超过4亿台,成为国人自主开发、国内最成熟稳定和装机量最大的开源 RTOS。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息