本文轉(zhuǎn)自公眾號,歡迎關(guān)注
基于DWC2的USB驅(qū)動開發(fā)-高速設(shè)備枚舉為全速設(shè)備問題案例分析 (qq.com)
一.前言
本文分享一個高速設(shè)備被枚舉為全速的問題。
高速設(shè)備速度握手參見本系列的文章。
二.問題
我們設(shè)計的UVC攝像頭工作在高速模式,接一個第三方的主機(jī)用于顯示和無線上傳,主機(jī)也支持高速模式。
我們的UVC攝像頭接PC測試都能正常枚舉為高速,從來沒有失敗過。接第三方的主機(jī)時總是被枚舉為全速,偶爾能成功一兩次枚舉為高速,幾乎都是枚舉為全速。
三.分析過程
既然接電腦沒問題,接第三方主機(jī)有問題,那么就懷疑第三方主機(jī)的兼容性問題。先前軟件做了一些分析,調(diào)試沒法確認(rèn)問題,進(jìn)行了一些打印信息的調(diào)試,在中斷中關(guān)鍵事件進(jìn)行打印,發(fā)現(xiàn)接入第三方設(shè)備時進(jìn)行了兩次復(fù)位和速度握手。這是一個異常信號,正常一次復(fù)位和速度握手就能完成。于是使用示波器監(jiān)控,對比接PC正常的和接第三方設(shè)備不正常的復(fù)位,速度握手過程。
接PC正常的波形,由于要抓長時間所以圖中高速握手的細(xì)節(jié)顯示不了了,但是整體依舊可以知道各個階段
接第三方主機(jī)不正常的
對比可以看到接PC一次完成高速握手
而接第三方復(fù)位了兩次第一次嘗試高速握手主機(jī)無響應(yīng),第二次沒有嘗試高速握手了,注意這里沒有抓前面初始化過程了。
這里主機(jī)第一次沒有響應(yīng)設(shè)備的Chirp K是不對的,這里因為主機(jī)是按鍵喚醒的,懷疑是剛上電未就緒,但是主機(jī)為什么未就緒就要發(fā)送復(fù)位呢,應(yīng)該是USB初始化完后就緒才發(fā)復(fù)位的,所以這里主機(jī)肯定是不對的,而且為什么主機(jī)要發(fā)兩次復(fù)位也不得而知,但是肯定是不正常的,有些第三方的東西做的不健壯也沒辦法,我們現(xiàn)在也沒辦法知道主機(jī)的處理邏輯。
既然主機(jī)不對,這個先不管,但是為什么設(shè)備在第2次復(fù)位時沒有發(fā)Chirp K進(jìn)行高速握手了呢。
這要從上一篇說的設(shè)備驅(qū)動說起。
設(shè)備驅(qū)動的流程如下
1.初始化配置DevSpd設(shè)置期望的工作速度,按照該速度去握手
2.配置EnumDoneMsk使能中斷,清除中斷標(biāo)志EnumDone
3.等待中斷,中斷中查詢實際握手的速度EnumSpd,根據(jù)該速度再次重新配置DevSpd設(shè)置實際工作速度。并清除中斷標(biāo)志EnumDone。
上述的邏輯是用戶可以設(shè)置最高期望的工作速度,但是實際主機(jī)支持多少就工作在多少,這樣不管主機(jī)是什么速度,代碼都不需要修改,初始化指定為高速即可,最終按照實際握手結(jié)果而定。
原因就在于上述紅色字體部分,第一次由于主機(jī)沒有響應(yīng)Chirp K所以設(shè)備握手結(jié)果是全速,所以中斷服務(wù)函數(shù)中設(shè)置為了工作模式為全速,下一次復(fù)位時依然會按照全速握手此時就不會發(fā)Chirp K了。
即如圖所示
那么是不是可以在復(fù)位中斷中重新再配置為高速來達(dá)到下一次復(fù)位進(jìn)行高速握手呢,因為復(fù)位中斷是在握手完成中斷之前的,這樣是不行的,因為設(shè)備檢測到復(fù)位進(jìn)入復(fù)位中斷時硬件已經(jīng)開始進(jìn)行后續(xù)的握手處理了,軟件的修改已經(jīng)來不及了。此時設(shè)備已經(jīng)是正常的全速工作了,并不知道在何時需要重新設(shè)置為高速以等待下一次的復(fù)位握手,畢竟這個兩次復(fù)位握手不是標(biāo)準(zhǔn)流程,是主機(jī)的異常導(dǎo)致的。以上導(dǎo)致了第一次握手為全速之后后面就只能是全速了。
既然如此我們還可以修改中斷服務(wù)函數(shù)中的處理,不在中斷服務(wù)函數(shù)中根據(jù)前一次握手速度設(shè)置實際工作速度,這樣第二次就可以握手為高速了,如下所示
這樣看似解決了問題,但是實際導(dǎo)致了用戶API邏輯問題,原來用戶API初始化設(shè)置期望的速度為高速,如果主機(jī)不支持高速則握手為全速工作,沒有問題,
現(xiàn)在這種情況如果主機(jī)不支持高速,則設(shè)備一直工作在高速將沒辦法工作,所以這個修改會導(dǎo)致和其他主機(jī)通訊異常,不可取。即改變了原來API的邏輯。
四.解決方法
雖然問題在于主機(jī),但是出于兼容性考慮還是要想解決辦法的,畢竟第三方設(shè)備健壯性沒法保證,寫驅(qū)動考慮兼容性,甚至兼容非標(biāo),非健壯設(shè)備也是要考慮的。
所以這里對API接口再增加參數(shù)區(qū)分,原來的參數(shù)還是表示期望速度,但是實際工作速度按照握手結(jié)果決定,原來的邏輯不變。再增加一個參數(shù)即強(qiáng)制固定速度,也就是如果設(shè)置為固定速度則握手完成中斷中不根據(jù)握手結(jié)果更新速度,設(shè)置多少就多少不再改。這樣通過參數(shù)來應(yīng)對原來的用戶邏輯和兼容這個有問題的主機(jī)。需要修改的地方是API增加一組強(qiáng)制固定速度和原來的期望速度對應(yīng),中斷服務(wù)函數(shù)中根據(jù)是強(qiáng)制速度還是期望速度處理,期望速度就根據(jù)握手值更新速度,固定值則不更改。
五.總結(jié)
本篇以一個實際的案例進(jìn)行分析,體現(xiàn)了對USB高速握手過程理解的重要性,所以前一篇高速握手詳解的文章非常重要,在此基礎(chǔ)上才能很快的定位問題。之前一直強(qiáng)調(diào)知其然知其所以然很重要,只有深入理解才能快速解決問題。同時也體現(xiàn)了驅(qū)動開發(fā)比一般嵌入式開發(fā)更深入的要求,不僅要考慮正常設(shè)備能工作,還要兼容不正常的,不標(biāo)準(zhǔn)的,不健壯的設(shè)備,這也需要更深的理解和功力。
-
接口
+關(guān)注
關(guān)注
33文章
8691瀏覽量
151911 -
usb
+關(guān)注
關(guān)注
60文章
7980瀏覽量
266067 -
API
+關(guān)注
關(guān)注
2文章
1510瀏覽量
62393 -
USB驅(qū)動
+關(guān)注
關(guān)注
1文章
137瀏覽量
20275 -
DWC2
+關(guān)注
關(guān)注
0文章
35瀏覽量
150
發(fā)布評論請先 登錄
相關(guān)推薦
評論