本文轉(zhuǎn)自公眾號(hào)歡迎關(guān)注
基于DWC2的USB驅(qū)動(dòng)開(kāi)發(fā)-數(shù)據(jù)不能發(fā)送問(wèn)題分析案例 (qq.com)
一.前言
對(duì)于驅(qū)動(dòng)的開(kāi)發(fā),調(diào)試是一個(gè)很痛苦的過(guò)程,尤其對(duì)于不熟悉的領(lǐng)域,很小的一個(gè)問(wèn)題可能就需要花費(fèi)大量的時(shí)間去調(diào)試,甚至以月時(shí)間計(jì),甚至可能就解決不了。所以經(jīng)驗(yàn)變得很重要,經(jīng)驗(yàn)即對(duì)相應(yīng)的IP的熟悉程度,這里的熟悉不是做過(guò),而是分析過(guò)調(diào)試過(guò)。包括遇到過(guò)的各種坑,對(duì)各種細(xì)節(jié)的了解,對(duì)各種行為的了解,只有遇到足夠多的坑且是實(shí)在的去調(diào)試分析過(guò)的,才可能不斷積累經(jīng)驗(yàn),否則就算做一萬(wàn)遍也算不上經(jīng)驗(yàn)(這也是在嵌入式開(kāi)發(fā)尤其是驅(qū)動(dòng)開(kāi)發(fā)中做過(guò)十年的不一定比做過(guò)三年的有經(jīng)驗(yàn),做過(guò)十年只是改個(gè)參數(shù),構(gòu)建下,跑一下,真算不上任何經(jīng)驗(yàn),而后者如果能從零開(kāi)始或者真的進(jìn)行了底層的調(diào)試分析那么就是實(shí)在的經(jīng)驗(yàn))。DWC2的USB控制器也是一個(gè)比較復(fù)雜的IP,我們從零開(kāi)始編寫(xiě)驅(qū)動(dòng)必然會(huì)遇到各種問(wèn)題,所以這里就會(huì)對(duì)遇到的各種問(wèn)題及其分析過(guò)程進(jìn)行記錄,以作為經(jīng)驗(yàn)積累,為后續(xù)提供checklist。
本篇分析一個(gè)IN時(shí)數(shù)據(jù)無(wú)法發(fā)出的問(wèn)題。
二.分析過(guò)程
問(wèn)題背景是代碼原本是使用高速傳輸,現(xiàn)在需要支持全速傳輸,所以將DCFG寄存器中速度配置為了全速,但是枚舉失敗。
先確認(rèn)問(wèn)題點(diǎn)大致對(duì)應(yīng)的代碼位置,
通過(guò)打印確認(rèn)復(fù)位后,全速速度枚舉正常。

所以我們繼續(xù)打印中斷信息,以確認(rèn)更詳細(xì)的位置,
可以看出軟件收到了設(shè)備描述符請(qǐng)求的8字節(jié)內(nèi)容并進(jìn)行了解析,
也準(zhǔn)備了DMA的描述符以發(fā)送18字節(jié)的內(nèi)容。
但是沒(méi)有預(yù)期的產(chǎn)生IN的XferComplete中斷

于是我們使用分析儀確認(rèn)總線上的情況
可以看到SETUP之后。主機(jī)IN時(shí)設(shè)備一直是NAK,確實(shí)是沒(méi)有返回?cái)?shù)據(jù)

此時(shí)我們已經(jīng)定位到了問(wèn)題出現(xiàn)在了設(shè)備準(zhǔn)備了DMA的描述符以返回18字節(jié)數(shù)據(jù),但是DMA沒(méi)有執(zhí)行,因?yàn)闆](méi)有產(chǎn)生XferComplete中斷。
以上自然而然我們就要去排查DMA的狀態(tài)了,這個(gè)時(shí)候就需要我們熟悉相關(guān)的寄存器了(所以前面專門(mén)講寄存器的的內(nèi)容就派上用場(chǎng)了)。
我們從手冊(cè)中看到DMA描述符的第一個(gè)WORD以下字段表示DMA狀態(tài)


于是我們查看該字段為01即DMA busy

既然DMA的作用是根據(jù)DMA描述符從用戶存儲(chǔ)搬運(yùn)數(shù)據(jù)到TxFIFO中去,DMA描述符已經(jīng)準(zhǔn)備好了,但是還是DMA busy那么就只能和TxFIFO有關(guān),
猜測(cè)就是TxFIFO里沒(méi)有足夠 的空間可以滿足本次DMA的搬運(yùn)。
那么為什么會(huì)導(dǎo)致TxFIFO中空間不夠呢,
要不是分配的不夠,要不就是之前里面有數(shù)據(jù)沒(méi)有發(fā)送出去,
前者和初始化配置有關(guān),后者和端點(diǎn)狀態(tài)是否工作狀態(tài)有關(guān)。于是分別確認(rèn)。
先查看端點(diǎn)寄存器狀態(tài)


EPEna為1是軟件設(shè)置的,硬件的DMA搬運(yùn)完后自動(dòng)清零(見(jiàn)前面專門(mén)的寄存器講解的文章),這里沒(méi)有搬運(yùn)完所以一直是1,
USBACtEp為1說(shuō)明該端點(diǎn)是使能的。
那么排除了端點(diǎn)狀態(tài)不對(duì)的問(wèn)題,端點(diǎn)確實(shí)是工作的。
那么繼續(xù)排查是否TxFIFO緩沖區(qū)不夠的問(wèn)題,
看到TxFIFO的大小配置為了4個(gè)WORD即16字節(jié),不足18字節(jié),所以DMA無(wú)法一次搬進(jìn)去。


那么我們是否可以驗(yàn)證下呢,可以手動(dòng)改下只發(fā)16個(gè)字節(jié)試一下
此時(shí)可以看到,發(fā)送了出去,那么確認(rèn)就是這個(gè)原因了。

此時(shí)問(wèn)題就好查了,那么對(duì)照下代碼確認(rèn)應(yīng)該就是初始化配置時(shí)配置的了
代碼如下全速時(shí)配置為了包大小為8,且計(jì)算TxFIFO時(shí)根據(jù)雙緩沖,2x8/2=4個(gè)WORD和寄存器值一樣。
pep0_in->maxpacket= ((usb_handle -> setspeed& 0x0F) == USB_SPEED_HIGH) ? 64: 8;

那么問(wèn)題就定位了,但是到此就完了嗎?我們?cè)賮?lái)回顧下,全速的控制端點(diǎn)也是可以配置最大包大小為8個(gè)字節(jié)大小的,理論上也應(yīng)該可以呀?
我們?cè)賮?lái)看上面的端點(diǎn)0的IN控制寄存器里配置的值
Bit[1:0]為00確是64字節(jié),


再來(lái)看代碼
原來(lái)是寫(xiě)死了

所以這個(gè)驅(qū)動(dòng)寫(xiě)的就有問(wèn)題,應(yīng)該根據(jù)配置參數(shù)自動(dòng)調(diào)整而不是寫(xiě)死。
所以根本原因其實(shí)是在這里。
MPS改為8,也是可行的,發(fā)送18字節(jié)就會(huì)拆分為多包發(fā)送,這里不再記錄了,可以自行驗(yàn)證。
以上問(wèn)題根本點(diǎn)即端點(diǎn)的MPS配置的不對(duì),當(dāng)然更上一層的根本原因是,TxFIFO的大小不能太小,至于是小于多少呢,小于MPS和發(fā)送數(shù)據(jù)的最小值,因?yàn)榘l(fā)送數(shù)據(jù)可以小于MPS的。于是這里我們又總結(jié)出了一個(gè)checklist,即FIFO大小不能小于MPS和最小一次發(fā)送數(shù)據(jù)大小的最小值。
三.總結(jié)
以上以一個(gè)實(shí)例進(jìn)行分析,雖然問(wèn)題不是復(fù)雜的問(wèn)題,總結(jié)一下就是TxFIFO緩沖區(qū)不足,使得DMA無(wú)法從用戶指定的描述符中指定的存儲(chǔ)區(qū)域搬運(yùn)指定大小數(shù)據(jù)到TxFIFO,使得DMA一直處于Busy狀態(tài)。
但是如果對(duì)此不熟則很可能也會(huì)耽誤很多時(shí)間去分析,以上問(wèn)題可以總結(jié)出checklist以后遇到類(lèi)似問(wèn)題可以直接查看,確認(rèn)排查,這也是經(jīng)驗(yàn)積累的過(guò)程。對(duì)于公司技術(shù)的積累也是依賴于此,而不是依賴于人。
主要的是要熟悉整個(gè)分析過(guò)程,分析思路,對(duì)驅(qū)動(dòng)開(kāi)發(fā)這是常態(tài),你將會(huì)發(fā)現(xiàn)經(jīng)常改了一點(diǎn)內(nèi)容可能就有問(wèn)題,我們一定要找到根本原因,而不是通過(guò)修改代碼去回避,這在驅(qū)動(dòng)開(kāi)發(fā)中也是很重要的思想。
以下做一個(gè)簡(jiǎn)單的方法總結(jié):
1.縮小范圍,定位代碼對(duì)應(yīng)位置,確認(rèn)問(wèn)題點(diǎn),比如上面的定位到問(wèn)題出現(xiàn)在,準(zhǔn)備了IN描述符,但是沒(méi)有產(chǎn)生IN的XferComplete中斷之間。一般使用打印,斷點(diǎn),逐步增刪代碼,二分法增刪代碼邏輯等技術(shù)手段進(jìn)行。
2.定位數(shù)據(jù)交互在哪里出現(xiàn)問(wèn)題,比如上面定位到發(fā)了請(qǐng)求設(shè)備沒(méi)有返回?cái)?shù)據(jù)。一般使用邏輯分析儀,USB分析儀,協(xié)議分析軟件等技術(shù)手段,配合上述軟件的定位。
3.確認(rèn)位置后通過(guò)狀態(tài)寄存器等確認(rèn)具體的問(wèn)題,比如上面通過(guò)描述符DMA的狀態(tài)去判斷。一般需要熟悉IP對(duì)應(yīng)的寄存器,尤其是一些狀態(tài)寄存器。
審核編輯 黃宇
-
usb
+關(guān)注
關(guān)注
60文章
8066瀏覽量
269644 -
驅(qū)動(dòng)
+關(guān)注
關(guān)注
12文章
1878瀏覽量
86343 -
DWC2
+關(guān)注
關(guān)注
0文章
35瀏覽量
210
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
基于DWC2的USB驅(qū)動(dòng)開(kāi)發(fā)-0x01開(kāi)篇介紹與新思DWC2 USB2.0控制器簡(jiǎn)介

基于DWC2的USB驅(qū)動(dòng)開(kāi)發(fā)-0x02 DWC2 USB2.0 IP功能特征介紹

基于DWC2的USB驅(qū)動(dòng)開(kāi)發(fā)-0x07 DWC2 USB2.0 IP 配置參數(shù)
基于DWC2的USB驅(qū)動(dòng)開(kāi)發(fā)-0x0E 使用邏輯分析儀分析ULPI數(shù)據(jù)

基于DWC2的USB驅(qū)動(dòng)開(kāi)發(fā)-IAD描述符詳解

基于DWC2的USB驅(qū)動(dòng)開(kāi)發(fā)-USB復(fù)位詳解

基于DWC2的USB驅(qū)動(dòng)開(kāi)發(fā)-USB連接詳解

基于DWC2的USB驅(qū)動(dòng)開(kāi)發(fā)-高速設(shè)備枚舉為全速設(shè)備問(wèn)題案例分析

基于DWC2的USB驅(qū)動(dòng)開(kāi)發(fā)-設(shè)備類(lèi)驅(qū)動(dòng)框架

基于DWC2的USB驅(qū)動(dòng)開(kāi)發(fā)-發(fā)送相關(guān)的寄存器DMA寄存器詳解

基于DWC2的USB驅(qū)動(dòng)開(kāi)發(fā)-USB包詳解

新思 DWC2 的參考手冊(cè)從哪里可以下載
RK3399平臺(tái)上USB控制器和PHY的連接方式和配置說(shuō)明
如何對(duì)基于hal庫(kù)的DWC2 USB IP進(jìn)行調(diào)試呢
基于DWC2的USB驅(qū)動(dòng)開(kāi)發(fā)-抽絲剝繭再論切換到狀態(tài)階段標(biāo)志DOEPINTn.StsPhseRcvd

評(píng)論