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