2. 從硬件軟件角度理解 Gadget 框架
USB 傳輸?shù)暮诵氖?endpoint,使用 endpoint 可以收發(fā)數(shù)據(jù)。在 endpoint 之上,就可以模擬 USB 串口、USB 觸碰屏、USB 攝像頭。基于這個角度,Gadget 框架可以分為兩層:
- 底層 endpoint 操作
- 上層模擬各類 USB 設(shè)備
2.1 底層硬件操作_UDC 驅(qū)動
不同平臺采用的 USB 控制器型號不同,確認(rèn)型號方法是從 dtb 反編譯,找到包含 otg 字符的節(jié)點,在 Linux code 中搜索 dts 節(jié)點的 compatible,可以找到對應(yīng)的 usb 從機(jī)控制器驅(qū)動。
對于底層 endpoint 的代碼,需要從 UDC 驅(qū)動開始分析:
ci_hdrc_imx_probe
ci_hdrc_add_device
pdev = platform_device_alloc("ci_hdrc", id);
// Linux-4.9.88driversusbchipideacore.c
static struct platform_driver ci_hdrc_driver = {
.probe = ci_hdrc_probe,
.remove = ci_hdrc_remove,
.driver = {
.name = "ci_hdrc",
.pm = &ci_pm_ops,
},
};
ci_hdrc_probe
ret = ci_hdrc_gadget_init(ci);
udc_start
- STM32MP157 的代碼:
Linux-5.4driversusbdwc2platform.c
dwc2_driver_probe
retval = dwc2_gadget_init(hsotg);
2.2 上層軟件操作
模擬各類 USB 設(shè)備時,軟件怎么分層?以訪問設(shè)備、獲取描述符為例:
- Host 要分配地址、把地址發(fā)送給設(shè)備:不管要模擬什么設(shè)備,Gadget 都必須接收地址,這部分由 usb_gadget (硬件相關(guān)的驅(qū)動程序)實現(xiàn)
- Host 要讀取各類描述符,這些描述符是由上層的驅(qū)動程序提供的
- 怎么把上層的描述符通過底層的 usb_gadget 傳回給 Host?還需要一個中間層。Host 獲取描述符時,方法是固定、通用的,這些方法可以由內(nèi)核統(tǒng)一提供,這就是:usb_gadget_driver。
所以,從獲取描述符的角度看看,上層軟件至少分為 2 層:
- usb_gadget_driver:實現(xiàn)一些通用的 USB 訪問方法,比如 Host 訪問描述符時,由 usb_gadget_driver 提供
- 在這上面提供各類描述符,實際上,描述符的提供還可以分為兩層:
軟件層次可以進(jìn)一步細(xì)化,如下圖:
這涉及 2 個結(jié)構(gòu)體:
- usb_composite_dev:它里面匯集有各類描述符、有一個 usb_funciton 鏈表(實現(xiàn)數(shù)據(jù)傳輸)
struct usb_composite_dev {
struct usb_gadget *gadget;
struct usb_request *req;
struct usb_request *os_desc_req;
struct usb_configuration *config;
/* OS String is a custom (yet popular) extension to the USB standard. */
u8 qw_sign[OS_STRING_QW_SIGN_LEN];
u8 b_vendor_code;
struct usb_configuration *os_desc_config;
unsigned int use_os_string:1;
/* private: */
/* internals */
unsigned int suspended:1;
struct usb_device_descriptor desc;
struct list_head configs;
struct list_head gstrings;
struct usb_composite_driver *driver;
u8 next_string_id;
char *def_manufacturer;
/* the gadget driver won't enable the data pullup
* while the deactivation count is nonzero.
*/
unsigned deactivations;
/* the composite driver won't complete the control transfer's
* data/status stages till delayed_status is zero.
*/
int delayed_status;
/* protects deactivations and delayed_status counts*/
spinlock_t lock;
/* public: */
unsigned int setup_pending:1;
unsigned int os_desc_pending:1;
};
- usb_udc:UDC 的本意是"usb device controller",usb_udc 結(jié)構(gòu)體里面有 usb_gadget (表示 UDC 本身)、usb_gadget_driver()
struct usb_udc {
struct usb_gadget_driver *driver;
struct usb_gadget *gadget;
struct device dev;
struct list_head list;
bool vbus;
};
-
嵌入式
+關(guān)注
關(guān)注
5103文章
19268瀏覽量
310026 -
Linux
+關(guān)注
關(guān)注
87文章
11373瀏覽量
211298 -
框架
+關(guān)注
關(guān)注
0文章
403瀏覽量
17614
發(fā)布評論請先 登錄
相關(guān)推薦
從硬件角度解析下這個USB Type-C

[分享]從Java的角度理解設(shè)計模式(連載)
從需求的角度去理解Linux系列:總線、設(shè)備和驅(qū)動
從需求的角度去理解嵌入式Linux:總線、設(shè)備和驅(qū)動
字符設(shè)備驅(qū)動、設(shè)備驅(qū)動模型、sysfs、平臺設(shè)備驅(qū)動的關(guān)系 -----從需求的角度去理解Linux之三
從數(shù)字化實現(xiàn)的角度理解PI環(huán)節(jié)
應(yīng)用于嵌入式系統(tǒng)軟件和硬件接口問題的設(shè)計

如何理解現(xiàn)場總線?從工業(yè)通信的角度看看資料下載

從仿真器的角度理解Verilog語言1

從仿真器的角度理解Verilog語言2

AMD Xilinx Linux 2022.1 USB Gadget使用
USB Gadget serial應(yīng)用實例(上)

怎樣理解Gadget框架

從獲取描述符的角度理解Gadget框架

從數(shù)據(jù)傳輸?shù)?b class='flag-5'>角度理解Gadge框架

評論