本文轉(zhuǎn)自公眾號,歡迎關(guān)注
基于DWC2的USB驅(qū)動(dòng)開發(fā)-設(shè)備類驅(qū)動(dòng)框架 (qq.com)
一.前言
從軟件頂層,從數(shù)據(jù)流的角度來看USB的通訊,我們可以看到主要有兩類通訊,一類是”控制”相關(guān),一類是”數(shù)據(jù)流”相關(guān),前者一般通過控制端點(diǎn)0進(jìn)行,而后者通過接口綁定的其他端點(diǎn)進(jìn)行。其實(shí)這是一種常用的通訊設(shè)計(jì)范式,不是USB獨(dú)有,我們在其他自定義應(yīng)用協(xié)議設(shè)計(jì)時(shí)也可以參考。比如ftp協(xié)議,服務(wù)器即使用21命令端口建立連接,其他端口傳輸數(shù)據(jù),所以可以看到一些設(shè)計(jì)哲學(xué)都是相通的。
至于控制和數(shù)據(jù)流其實(shí)都是一個(gè)邏輯上的通道,管道的概念,不一定要物理區(qū)分。比如我們只有一個(gè)串口,可以定義串口幀,通過幀頭的標(biāo)志區(qū)分,就可以虛擬任意個(gè)邏輯管道。類似的USB設(shè)備的端點(diǎn)和主機(jī)的管道也是同樣的概念。
所以我們一定要有頂層思維模式,抽象思維模式,尤其對于USB復(fù)雜的應(yīng)用層協(xié)議,一定要理清楚其上層邏輯。在驅(qū)動(dòng)編寫時(shí)只有摸清其框架,才能進(jìn)行抽象,才能進(jìn)行驅(qū)動(dòng)程序的編寫。否則一上來就陷入到具體的設(shè)備的具體的協(xié)議內(nèi)容中很快就會迷失,驅(qū)動(dòng)也會寫的不具備移植性。畢竟每一個(gè)設(shè)備類的規(guī)格書都有100頁以上,這么多設(shè)備,協(xié)議文檔就多如牛毛,更不用說里面涉及的各種細(xì)節(jié),所以有頂層框架性的理解很重要。比如對于UAC設(shè)備我們不需要一上來就去關(guān)注音量如何設(shè)置,而是先要了解其所有的屬性的操作是否有一定的框架即共性,是否可以抽象為編程的數(shù)據(jù)結(jié)構(gòu)模型,操作模型。否則雖然能直接根據(jù)手冊,一個(gè)字節(jié)一個(gè)字節(jié)解析,但是結(jié)果是對于每一個(gè)屬性都要這樣單獨(dú)解析,代碼將不具備通用性,且變得很冗余,不可維護(hù),增加一個(gè)屬性就需要改代碼,這不是驅(qū)動(dòng)的設(shè)計(jì)方式,當(dāng)然一些小型的嵌入式系統(tǒng)沒有驅(qū)動(dòng)層的考慮有可能也會這么直接做,但是那畢竟是特定應(yīng)用場景上的。
這一篇我們就從框架上,對我們后面要實(shí)現(xiàn)的設(shè)備協(xié)議棧進(jìn)行整體設(shè)計(jì),主要是考慮好數(shù)據(jù)結(jié)構(gòu),和操作模型,至于細(xì)節(jié)后面邊寫驅(qū)動(dòng),邊調(diào)試設(shè)備,邊修改優(yōu)化。
二.框架設(shè)計(jì)
USB的設(shè)計(jì)初衷就是功能對應(yīng)接口,即一個(gè)功能對應(yīng)一個(gè)接口,接口里綁定端點(diǎn),注意這里的端點(diǎn)是抽象概念比如終端和單元這些概念,邏輯上是一樣的。
但是隨著應(yīng)用的復(fù)雜化和功能需求的多元化,后面出現(xiàn)了多功能設(shè)備,比如一個(gè)攝像頭有視頻也有音頻既是攝像頭也是喇叭也可能是麥克風(fēng),那么就需要多個(gè)接口來對應(yīng)多個(gè)功能,于是UBS規(guī)范添加了IAD接口關(guān)聯(lián)描述符來聚合某個(gè)功能的接口。一個(gè)功能也不限制于一個(gè)接口了,也可能有多個(gè)接口,然后一個(gè)設(shè)備也可以有多個(gè)功能。
即由以下簡單的拓?fù)浣Y(jié)構(gòu)
變?yōu)榱艘韵赂鼜?fù)雜的拓?fù)浣Y(jié)構(gòu),多了一層IAD做功能聚合對應(yīng)一個(gè)功能,而IAD下面也可以有多個(gè)接口,接口下面有多個(gè)端點(diǎn),注意這里的端點(diǎn)是抽象的概念,也可能是比如UVC里的終端和單元等。
那么看到上述圖形第一個(gè)想到的概念是什么呢,上述圖形就是一個(gè)鏈表結(jié)構(gòu),一層鏈接一層。
我們設(shè)備類驅(qū)動(dòng)位于哪一層呢,從上可以看到設(shè)備類即對應(yīng)功能那么就是IAD這一層。
那么我們的設(shè)備類驅(qū)動(dòng)框架就應(yīng)該是上圖改為如下
我們需要
定義驅(qū)動(dòng)層實(shí)例,并提供接口可以綁定類實(shí)例
定義類層實(shí)例,并提供接口可以綁定接口實(shí)例
定義接口層實(shí)例,并提供接口可以綁定端口實(shí)例
定義端口實(shí)例,并提供接口可以綁定屬性實(shí)例
定義屬性實(shí)例,比如音量設(shè)置對應(yīng)的CS,數(shù)據(jù)長度,操作類似是GET還是SET,SET GET回調(diào)等
至此恭喜你已經(jīng)完成設(shè)備驅(qū)動(dòng)框架的設(shè)計(jì),看起來是多么的簡單簡潔,這就是抽象的威力,了解USB協(xié)議頂層邏輯很容易就抽象出該框架,并沒有復(fù)雜的思想和邏輯,也不需要使用復(fù)雜的技術(shù),要說到技術(shù)那么上面使用一個(gè)單向鏈表足矣。
三.數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
上面我們對框架進(jìn)行了設(shè)計(jì),也就是房屋的框架設(shè)計(jì)階段完成了,現(xiàn)在去構(gòu)建各個(gè)構(gòu)建了,比如類模型就可以對應(yīng)各個(gè)功能區(qū)怎么設(shè)計(jì),比如地下室,停車場怎么設(shè)計(jì),
接口模型則對應(yīng)具體的功能區(qū)內(nèi)的各個(gè)模塊的設(shè)計(jì),比如停車場如何設(shè)計(jì)自動(dòng)閘門,如何設(shè)計(jì)車位布局,端點(diǎn)模型就對應(yīng)具體車位的設(shè)計(jì)了,比如車位大小,標(biāo)志,附屬充電樁,編號等。
每個(gè)模型對應(yīng)的數(shù)據(jù)結(jié)構(gòu)的屬性和行為可能不同,但是有一點(diǎn)相同即都是通過單向鏈表連接同層實(shí)例,并且指向下一層鏈表。
比如對應(yīng)接口的設(shè)計(jì)
具體設(shè)計(jì)這里就不再講了,每個(gè)人自行設(shè)計(jì)時(shí)考慮,可以后面邊寫驅(qū)動(dòng)邊完善,但是可以肯定的是一定包括以下幾個(gè)元素:
屬性部分
行為部分
指向下一個(gè)同層實(shí)例的指針
指向下一層實(shí)例的鏈表頭指針
比如如下對于設(shè)備類數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì),即包含了上述4部分
/**
* struct usbd_dev_class
* 設(shè)備類節(jié)點(diǎn)
*/
typedef struct usbd_dev_class {
/* 屬性部分 */
uint8_t id;
char* name;
/* 行為部分 */
void (*init)(void *dwc);
void (*deinit)(void *dwc);
void (*setup)(void *dwc, ureq_t setup);
void (*setitf)(void *dwc, ureq_t setup);
/* 同級鏈接 */
struct usbd_dev_class* next;
/* 下一層鏈接 */
itf_t *itf_list;
} usbd_dev_class;
四.總結(jié)
以上進(jìn)行了設(shè)備類驅(qū)動(dòng)框架性的設(shè)計(jì),我們遵循自頂向下的設(shè)計(jì)思路,先設(shè)計(jì)框架,=然后再填充框架,當(dāng)然框架不可能一開始設(shè)計(jì)的就合理,我們后續(xù)實(shí)際調(diào)試具體的設(shè)備時(shí)可能發(fā)現(xiàn)需要修改,我們迭代即可,但是現(xiàn)在開始就需要考慮可擴(kuò)展性,以便將來迭代擴(kuò)展。
審核編輯 黃宇
-
usb
+關(guān)注
關(guān)注
60文章
7988瀏覽量
266250 -
驅(qū)動(dòng)開發(fā)
+關(guān)注
關(guān)注
0文章
130瀏覽量
12120 -
驅(qū)動(dòng)框架
+關(guān)注
關(guān)注
0文章
14瀏覽量
4075 -
DWC2
+關(guān)注
關(guān)注
0文章
35瀏覽量
156
發(fā)布評論請先 登錄
相關(guān)推薦
基于DWC2的USB驅(qū)動(dòng)開發(fā)-0x01開篇介紹與新思DWC2 USB2.0控制器簡介
![基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-0x01開篇介紹與新思<b class='flag-5'>DWC2</b> <b class='flag-5'>USB</b>2.0控制器簡介](https://file1.elecfans.com//web2/M00/82/92/wKgaomRYypOAKwq2AAAmRtEv6o4083.png)
基于DWC2的USB驅(qū)動(dòng)開發(fā)-0x02 DWC2 USB2.0 IP功能特征介紹
![基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-0x02 <b class='flag-5'>DWC2</b> <b class='flag-5'>USB</b>2.0 IP功能特征介紹](https://file1.elecfans.com//web2/M00/82/95/wKgaomRZq22ATFNiAAAtAuJdxpU526.png)
基于DWC2的USB驅(qū)動(dòng)開發(fā)-0x0C 驅(qū)動(dòng)框架設(shè)計(jì)
![基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-0x0C <b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>框架</b>設(shè)計(jì)](https://file1.elecfans.com/web2/M00/89/36/wKgaomR9p32AU_DFAADWKg1sT0c229.jpg)
基于DWC2的USB驅(qū)動(dòng)開發(fā)-IAD描述符詳解
![基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-IAD描述符詳解](https://file1.elecfans.com/web2/M00/8B/7A/wKgZomSaPbaAEbh7AAAgl2G2IkY286.png)
基于DWC2的USB驅(qū)動(dòng)開發(fā)-USB復(fù)位詳解
![基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>USB</b>復(fù)位詳解](https://file1.elecfans.com/web2/M00/8C/30/wKgZomSng_2AGXsAAABUiaQmGaQ671.png)
基于DWC2的USB驅(qū)動(dòng)開發(fā)-USB連接詳解
![基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>USB</b>連接詳解](https://file1.elecfans.com/web2/M00/8C/2F/wKgaomSnbLCAUQo4AAArjuuBYsU207.png)
基于DWC2的USB驅(qū)動(dòng)開發(fā)-高速設(shè)備枚舉為全速設(shè)備問題案例分析
![基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-高速<b class='flag-5'>設(shè)備</b>枚舉為全速<b class='flag-5'>設(shè)備</b>問題案例分析](https://file1.elecfans.com/web2/M00/8C/67/wKgZomSry42ABNOiAAAdwkjt7eM162.png)
基于DWC2的USB驅(qū)動(dòng)開發(fā)-發(fā)送相關(guān)的寄存器DMA寄存器詳解
![基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-發(fā)送相關(guān)的寄存器DMA寄存器詳解](https://file1.elecfans.com/web2/M00/8C/DB/wKgaomSzrSiAGPKLAAE26HSudps200.jpg)
基于DWC2的USB驅(qū)動(dòng)開發(fā)-USB包詳解
![基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>USB</b>包詳解](https://file1.elecfans.com/web2/M00/8D/8A/wKgZomS87r-AT_nQAABsVjrtMrY013.jpg)
基于DWC2的USB驅(qū)動(dòng)開發(fā)-控制傳輸中斷相關(guān)寄存器
![基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-控制傳輸中斷相關(guān)寄存器](https://file1.elecfans.com/web2/M00/8D/8B/wKgZomS9UAOANWTFAAAxMxJuNTY487.jpg)
基于DWC2的USB驅(qū)動(dòng)開發(fā)-數(shù)據(jù)不能發(fā)送問題分析案例
![基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-數(shù)據(jù)不能發(fā)送問題分析案例](https://file1.elecfans.com/web2/M00/8F/B1/wKgaomTRne-Ad71BAAAaATok9k0470.png)
新思 DWC2 的參考手冊從哪里可以下載
如何對基于hal庫的DWC2 USB IP進(jìn)行調(diào)試呢
HDF驅(qū)動(dòng)框架中USB DDK的解析與開發(fā)指導(dǎo)
基于DWC2的USB驅(qū)動(dòng)開發(fā)-抽絲剝繭再論切換到狀態(tài)階段標(biāo)志DOEPINTn.StsPhseRcvd
![基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>-抽絲剝繭再論切換到狀態(tài)階段標(biāo)志DOEPINTn.StsPhseRcvd](https://file1.elecfans.com/web2/M00/8D/A9/wKgaomS-TH6AY5_QAAQY40xBkJA935.jpg)
評論