本文由 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 次要就是给中断传输和同步传输用的。 - HCFG 中的 bit 0-1
这也是坑,咱们间接看论断,人家手册里说了,每次设置时,须要复位,st 代码中楞是一个字没看见。小坑
- HCINTMSK 中的 USB_OTG_HCINTMSK_NAKM
这外面中断标记那是相当多,最坑的是什么,USB_OTG_HCINTMSK_NAKM
, 我能够说,论坛呈现的所有 NAK 的起因都是他造成的,什么枚举 NAK,U 盘 NAK,都是他。究其原因,NAK 示意以后没有筹备好,须要重试,然而其实并不需要,st 的代码中,进入 NAK 中断当前会敞开以后通道传输,然而,对于管制和批量传输这是没有必要的,传输是能够等到实现的。开了这个,就会造成,各种中央须要手动重发,而后读 HAL_HCD_HC_GetURBState
,没有必要,关掉该中断给你带来有限可能。
- HAL_HCD_HC_SubmitRequest
大坑来了,此函数就是配置发送须要的 size、packet、buf 地址等等。坑 1:有 dma 没见你用。坑 2:hc->xfer_len
并不能随心所欲的传任何值。坑 3:开了 fifo 不为地面断,却没有该中断解决。
批改
- 能用 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…