1. 簡介
Gadget 英文是小物件,小裝置
Gadget 框架提供了一套標準API,USB設備控制器(USB Device Controller,UDC)驅動實現這一套API。
Gadget 是實現的 USB Device,一般普通的 Gadget 驅動只實現一個功能。
2. 驅動核心分析
printer_func_setup 處理底層驅動不能處理的 EP0 請求。即響應 usb host 發送來的 EP0 控制命令
向 usb ep0 發送數據使用通用接口 usb_ep_queue().
printer_bind_config 中
- 關聯上配成層的函數
- 註冊申請了字符設備節點,字符設備節點提供給應用程序讀寫的接口
- 申請 QLEN 個 大小是 USB_BUFSIZE 的 struct usb_request 的request,分別掛到 dev->tx_reqs 和 dev->tx_reqs 中,這裏可以理解爲內存池類似的東東。
字符節點打開函數 printer_open
根據 inode 找到 struct printer_dev 結構首地址,並放到 fd->private_data 中。
字符節點的讀函數 printer_read 函數中需要注意的
- req->buf 是存放數據的首地址
- req->actual 是現有數據長度
- req->rx_buffers 是接收了 USB Host 來的數據後各個 req 的鏈表頭
- 需要了解 req 的處理流程
3. 一次讀的req的處理流程
dev->rx_reqs 是緩存數據的 request 緩存池,他裏邊的request的流程是
setup_rx_reqs() 函數中把所有dev->rx_reqs 中的 req放入到了dev->out_ep端口裏,並掛到 dev->rx_reqs_active 鏈表中
[ dev->rx_reqs ] --> [ dev->rx_reqs_active ] 和 [ dev->out_ep 端口上 ]
usb驅動接收到數據後 req 從 dev->rx_reqs_active 中被去除,並在回調函數 rx_complete() 中
把處理了的 request
[ request ] --> [ dev->rx_buffers ]
沒有處理的,或者是失敗的,放回緩存池
[ request ] --> [ dev->rx_reqs ]
設備節點的讀函數 printer_read()
把有效數據發送給用戶層後
[ dev->rx_buffers ] --> [ dev->rx_reqs ]