本文轉自公眾號,歡迎關注
基于DWC2的USB驅動開發-設備類驅動框架 (qq.com)
一.前言
從軟件頂層,從數據流的角度來看USB的通訊,我們可以看到主要有兩類通訊,一類是”控制”相關,一類是”數據流”相關,前者一般通過控制端點0進行,而后者通過接口綁定的其他端點進行。其實這是一種常用的通訊設計范式,不是USB獨有,我們在其他自定義應用協議設計時也可以參考。比如ftp協議,服務器即使用21命令端口建立連接,其他端口傳輸數據,所以可以看到一些設計哲學都是相通的。
至于控制和數據流其實都是一個邏輯上的通道,管道的概念,不一定要物理區分。比如我們只有一個串口,可以定義串口幀,通過幀頭的標志區分,就可以虛擬任意個邏輯管道。類似的USB設備的端點和主機的管道也是同樣的概念。
所以我們一定要有頂層思維模式,抽象思維模式,尤其對于USB復雜的應用層協議,一定要理清楚其上層邏輯。在驅動編寫時只有摸清其框架,才能進行抽象,才能進行驅動程序的編寫。否則一上來就陷入到具體的設備的具體的協議內容中很快就會迷失,驅動也會寫的不具備移植性。畢竟每一個設備類的規格書都有100頁以上,這么多設備,協議文檔就多如牛毛,更不用說里面涉及的各種細節,所以有頂層框架性的理解很重要。比如對于UAC設備我們不需要一上來就去關注音量如何設置,而是先要了解其所有的屬性的操作是否有一定的框架即共性,是否可以抽象為編程的數據結構模型,操作模型。否則雖然能直接根據手冊,一個字節一個字節解析,但是結果是對于每一個屬性都要這樣單獨解析,代碼將不具備通用性,且變得很冗余,不可維護,增加一個屬性就需要改代碼,這不是驅動的設計方式,當然一些小型的嵌入式系統沒有驅動層的考慮有可能也會這么直接做,但是那畢竟是特定應用場景上的。
這一篇我們就從框架上,對我們后面要實現的設備協議棧進行整體設計,主要是考慮好數據結構,和操作模型,至于細節后面邊寫驅動,邊調試設備,邊修改優化。
二.框架設計
USB的設計初衷就是功能對應接口,即一個功能對應一個接口,接口里綁定端點,注意這里的端點是抽象概念比如終端和單元這些概念,邏輯上是一樣的。
但是隨著應用的復雜化和功能需求的多元化,后面出現了多功能設備,比如一個攝像頭有視頻也有音頻既是攝像頭也是喇叭也可能是麥克風,那么就需要多個接口來對應多個功能,于是UBS規范添加了IAD接口關聯描述符來聚合某個功能的接口。一個功能也不限制于一個接口了,也可能有多個接口,然后一個設備也可以有多個功能。
即由以下簡單的拓撲結構
變為了以下更復雜的拓撲結構,多了一層IAD做功能聚合對應一個功能,而IAD下面也可以有多個接口,接口下面有多個端點,注意這里的端點是抽象的概念,也可能是比如UVC里的終端和單元等。
那么看到上述圖形第一個想到的概念是什么呢,上述圖形就是一個鏈表結構,一層鏈接一層。
我們設備類驅動位于哪一層呢,從上可以看到設備類即對應功能那么就是IAD這一層。
那么我們的設備類驅動框架就應該是上圖改為如下
我們需要
定義驅動層實例,并提供接口可以綁定類實例
定義類層實例,并提供接口可以綁定接口實例
定義接口層實例,并提供接口可以綁定端口實例
定義端口實例,并提供接口可以綁定屬性實例
定義屬性實例,比如音量設置對應的CS,數據長度,操作類似是GET還是SET,SET GET回調等
至此恭喜你已經完成設備驅動框架的設計,看起來是多么的簡單簡潔,這就是抽象的威力,了解USB協議頂層邏輯很容易就抽象出該框架,并沒有復雜的思想和邏輯,也不需要使用復雜的技術,要說到技術那么上面使用一個單向鏈表足矣。
三.數據結構設計
上面我們對框架進行了設計,也就是房屋的框架設計階段完成了,現在去構建各個構建了,比如類模型就可以對應各個功能區怎么設計,比如地下室,停車場怎么設計,
接口模型則對應具體的功能區內的各個模塊的設計,比如停車場如何設計自動閘門,如何設計車位布局,端點模型就對應具體車位的設計了,比如車位大小,標志,附屬充電樁,編號等。
每個模型對應的數據結構的屬性和行為可能不同,但是有一點相同即都是通過單向鏈表連接同層實例,并且指向下一層鏈表。
比如對應接口的設計
具體設計這里就不再講了,每個人自行設計時考慮,可以后面邊寫驅動邊完善,但是可以肯定的是一定包括以下幾個元素:
屬性部分
行為部分
指向下一個同層實例的指針
指向下一層實例的鏈表頭指針
比如如下對于設備類數據結構的設計,即包含了上述4部分
/**
* struct usbd_dev_class
* 設備類節點
*/
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;
四.總結
以上進行了設備類驅動框架性的設計,我們遵循自頂向下的設計思路,先設計框架,=然后再填充框架,當然框架不可能一開始設計的就合理,我們后續實際調試具體的設備時可能發現需要修改,我們迭代即可,但是現在開始就需要考慮可擴展性,以便將來迭代擴展。
審核編輯 黃宇
-
usb
+關注
關注
60文章
7936瀏覽量
264473 -
驅動開發
+關注
關注
0文章
130瀏覽量
12072 -
驅動框架
+關注
關注
0文章
14瀏覽量
4033 -
DWC2
+關注
關注
0文章
35瀏覽量
125
發布評論請先 登錄
相關推薦
評論