本文轉(zhuǎn)自公眾號系列文章,歡迎關注
基于DWC2的USB驅(qū)動開發(fā)-USB包詳解 (qq.com)
前言
http://194w.cn/outside?redirect=https://mp.weixin.qq.com/s/gm5OAutfnYv6H_5Ce8GEqA一文中我們介紹了控制傳輸,中斷相關寄存器,尤其是DOEPINTn.XferCompl,DOEPINTn.SetUp,DOEPINTn.StsPhseRcvd幾個狀態(tài)的組合非常重要,因為由他們可以確定當前控制傳輸處于什么階段。前文我們對此進行了介紹,但是個人覺得講的還不夠透徹,原理還沒有講清楚,知其然知其所以然是我們一開始就強調(diào)的,所以針對這個幾個標志位我們再次更詳細的介紹,先來介紹最關鍵的DOEPINTn.SetUp。
DOEPINTn.SetUp
Setup是DOEPINTn寄存器中的一個標志,用于表示Setup階段是否完成。
我們這里可能要問DIEPINTn為什么沒有SetUp標志,因為Setup總是HOST->DEV的,所以總是OUT傳輸,所以總是對應OUT端點的,IN端點的寄存器不可能有。這里強調(diào)一下我們一定要多問為什么,先思考猜測,然后再從手冊規(guī)格書中查找答案,只有這樣才能加深理解,USB開發(fā)中這是很重要的,當然任何技術性的工作這一點都重要。
我們從寄存器的描述中也可以看到,該位表示SetUP階段完成,并且只有控制OUT端點有。
還有個信息是本次控制傳輸沒有連續(xù)的SETUP,意味著軟件可以開始解析SETUP的8字節(jié)的內(nèi)容以決定下一步要干嘛了。如果有連續(xù)的SETUP則是最后一個SETUP完成才能進行。
那么究竟SETUP完成對應的一個什么狀態(tài)呢? 硬件是怎么知道SETUP階段完成的呢? 主機和設備判斷SETUP完成有什么區(qū)別嗎? 我們會拋出一連串問題,如果能拋出這些問題說明你很適合做底層和驅(qū)動開發(fā)!
后面我們會抽絲剝繭,從原理到實踐,從猜測到手冊中求證,一層層剖析。
這里我們要回顧下控制傳輸,
我們從規(guī)格書中的拓撲圖可以看到,控制傳輸?shù)腟ETUP階段過程如下
或者換個表達方式如下
或者從USB分析儀抓包數(shù)據(jù)來看,更形象。
SETUP階段對應3個包:SETUP令牌包;DATA0的數(shù)據(jù)包,始終是HOST->DEV;設備的響應ACK。
這里順便提一下,SETUP的數(shù)據(jù)始終使用DATA0;而設備要么正常接收并接受ACK,要么接收錯誤或者沒接收到不響應,只有這兩種情況,不能接收了不接受而NAK或者STALL等。
這里還順便提一下接收和接受的概念區(qū)別。接收通常指的物理層數(shù)據(jù)正確接收到了,而接受則指的軟件能夠處理,或者說愿意處理。 接收了也可能不接受。
這里協(xié)議層面我們可以看到SETUP階段完成的標志是,設備ACK響應了。
如下所示
仔細思考下,這里只是協(xié)議上的定義,也就是對應的總線上的數(shù)據(jù),至于SETUP完不完成是要由參與者HOST和DEV去確定的,換句話說總線上的狀態(tài)并不意味參與者就是這個狀態(tài)了,因為參與者還要正確接收到總線上的數(shù)據(jù)才算。
對于主機接收到了設備發(fā)送的ACK那么主機認為SETUP階段完成,如果設備發(fā)了ACK但是主機沒收到呢?那么主機認為SETUP沒完成,會認為本次失敗,從頭發(fā)SETUP包重來。
同樣的對于設備來說將ACK發(fā)送到總線上去后,設備并不知道HOST接收沒接收到,設備并不知道主機的狀態(tài)。所以主機和設備對SETUP完成的狀態(tài)確認存在不同步。
那怎么辦呢? 設備并不知道主機認為SETUP完成了沒有,因為設備并不知道主機收沒收到ACK。就好比子非魚安知魚之樂,有點繞了。
其實也沒什么辦法,設備確實現(xiàn)在不知道主機是不是認為SETUP完成了,但是設備可以根據(jù)主機下一步的行動來確定。因為主機如果接收到了ACK,認為SETUP完成了那么主機下一步就會發(fā)IN或者OUT令牌進入數(shù)據(jù)階段(或者狀態(tài)階段),否則則會重發(fā)SETUP重新進入SETUP階段。
設備可以據(jù)此來進行判斷,如果收到了主機的IN或者OUT令牌,則確認主機認為SETUP已經(jīng)完成了,于是設備也知道SETUP完成了,這里設備和主機判斷SETUP完成的時間點是不一樣的,這就是協(xié)議定義和實際判定存在的區(qū)別。所以對于協(xié)議設計一定要考慮這種區(qū)別,協(xié)議設計了要考慮如何實現(xiàn),也就一直強調(diào)的理論要結合實踐,對于驅(qū)動編寫更需要考慮從這些細節(jié)。
以上恭喜你從頭開始推導出了設備判斷SETUP完成的原理,那么回到上面的標志位DOEPINTn.SetUp即表示SETUP階段完成,DWC2控制也是這么判斷的嗎?所謂英雄所見略同,DWC2控制器還真是這么判斷的。
上面寄存器的描述中只提了該標志的含義,并沒提其具體置位的原理和時機,實際編程指導手冊中是有說明的。
如下位置,手冊就進行了說明當,SETUP令牌之后,接收到了IN或OUT令牌則置位DOEPINTn.SetU,和我們推導的完全一致。
為什么是IN或OUT呢,因為控制傳輸可能是控制寫,控制讀,還可能無數(shù)據(jù)階段的控制傳輸,所以后面要不就是IN數(shù)據(jù)或者OUT數(shù)據(jù)或者IN狀態(tài),如下所示
控制寫
控制讀
無數(shù)據(jù)階段的控制傳輸
驅(qū)動編寫注意事項
從上面可以看到設備是延遲才能確認SETUP完成的,也就是在SETUP后設備收到了主機發(fā)的IN和OUT之后才確認,中斷也是在此時產(chǎn)生。
對于控制寫,上面設備確認SETUP完成產(chǎn)生中斷,中斷服務函數(shù)開始去解析8字節(jié)的SETUP內(nèi)容,來確定數(shù)據(jù)階段要干嘛,后面數(shù)據(jù)階段是IN還是OUT或者還是沒有數(shù)據(jù)階段直接狀態(tài)階段,其實是數(shù)據(jù)階段(狀態(tài)階段)已經(jīng)啟動,設備延遲了。
此時中斷服務函數(shù)還未執(zhí)行,軟件還沒根據(jù)解析準備IN或者OUT描述符,所以此時對于這個IN或者OUT,硬件只能自動NAK,如下所描述:
所以這種情況下,中斷服務函數(shù)中進行了解析,并知道要準備OUT描述進行接收時,設置EPEna=1時還要同時設置CNAK=1,清除硬件的自動NAK狀態(tài),讓硬件根據(jù)OUT描述符去接收數(shù)據(jù)。
對于控制讀后面是IN數(shù)據(jù)階段,或者無數(shù)據(jù)階段的控制傳輸后面是IN狀態(tài),也是類似的。
總結
以上對DOEPINTn.SetUp進行了詳細的解析,因為它太重要了,SETUP階段是控制傳輸?shù)暮诵?,因為只有SETUP完成才能去解析8字節(jié)的內(nèi)容,才能決定后續(xù)干嘛,對于驅(qū)動編寫接收到8字節(jié)的SETUP數(shù)據(jù)是第一個關鍵步。以上也可以看出一定要從原理上去理解,這也是驅(qū)動編寫的重要原則,必須知其然知其所以然,精確的知道各個時間點的各個時間,以及其條件等,注意精確兩個字。
審核編輯:湯梓紅
-
寄存器
+關注
關注
31文章
5433瀏覽量
124244 -
usb
+關注
關注
60文章
8173瀏覽量
272412 -
驅(qū)動開發(fā)
+關注
關注
0文章
134瀏覽量
12302 -
DWC2
+關注
關注
0文章
35瀏覽量
250
發(fā)布評論請先 登錄
基于DWC2的USB驅(qū)動開發(fā)-0x01開篇介紹與新思DWC2 USB2.0控制器簡介

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

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

基于DWC2的USB驅(qū)動開發(fā)-USB復位詳解

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

基于DWC2的USB驅(qū)動開發(fā)-高速設備枚舉為全速設備問題案例分析

基于DWC2的USB驅(qū)動開發(fā)-設備類驅(qū)動框架

基于DWC2的USB驅(qū)動開發(fā)-發(fā)送相關的寄存器DMA寄存器詳解

基于DWC2的USB驅(qū)動開發(fā)-數(shù)據(jù)不能發(fā)送問題分析案例

新思 DWC2 的參考手冊從哪里可以下載
如何對基于hal庫的DWC2 USB IP進行調(diào)試呢
使用USB OTG端口作為以太網(wǎng)小工具無法工作是為什么?
抽絲剝繭系列——一個T拓撲

基于DWC2的USB驅(qū)動開發(fā)-抽絲剝繭再論切換到狀態(tài)階段標志DOEPINTn.StsPhseRcvd

評論