詳解linux usb host驅(qū)動(dòng)編寫入門
usb協(xié)議是一個(gè)復(fù)雜的協(xié)議,目前涉及到的版本就有usb1.0, usb2.0, usb3.0。大家如果打開kernel usb host目錄,就會(huì)發(fā)現(xiàn)下面包含了ohci,uhci,ehci,xhci,whci等多種形式的控制器驅(qū)動(dòng)。那么,對(duì)于我們這些不是很了解usb的開發(fā)人員,如何了解usb的代碼結(jié)構(gòu)呢?
1、代碼分布
drivers/usb目錄下面,host目錄包括了host驅(qū)動(dòng)代碼,core目錄包含了主要的api接口代碼,而其他目錄則主要是device驅(qū)動(dòng)代碼。
2、device驅(qū)動(dòng)怎么看
device驅(qū)動(dòng)大多數(shù)和上層協(xié)議有關(guān),不涉及到具體的寄存器讀寫。示例代碼可以參考usb-skeleton.c
3、host驅(qū)動(dòng)怎么看
a,不妨以s3c2410的host作為范例進(jìn)行分析,首先找到Makefile,
obj-$(CONFIG_USB_OHCI_HCD_S3C2410) += ohci-s3c2410.o
b,再查看一下Kconfig,
config USB_OHCI_HCD_S3C2410 tristate "OHCI support for Samsung S3C24xx/S3C64xx SoC series" depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX) default y ---help--- Enables support for the on-chip OHCI controller on S3C24xx/S3C64xx chips.
c,通過Makefile和Kconfig發(fā)現(xiàn),s3c2410依賴于USB_OHCI_HCD_S3C2410 和 USB_OHCI_HCD,那USB_OHCI_HCD呢?
config USB_OHCI_HCD tristate "OHCI HCD (USB 1.1) support" depends on HAS_DMA && HAS_IOMEM ---help--- The Open Host Controller Interface (OHCI) is a standard for accessing USB 1.1 host controller hardware. It does more in hardware than Intel's UHCI specification. If your USB host controller follows the OHCI spec, say Y. On most non-x86 systems, and on x86 hardware that's not using a USB controller from Intel or VIA, this is appropriate. If your host controller doesn't use PCI, this is probably appropriate. For a PCI based system where you're not sure, the "lspci -v" entry will list the right "prog-if" for your USB controller(s): EHCI, OHCI, or UHCI. To compile this driver as a module, choose M here: the module will be called ohci-hcd.
d,USB_OHCI_HCD只依賴于DMA和IOMEM。繼續(xù)回到Makefile,判斷USB_OHCI_HCD會(huì)編譯哪些文件
obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o
e,看到這里,我們明白要打開s3c2410的host功能,只需要編譯ohci-hcd.c和ohci-s3c2410.c兩個(gè)文件就好了
f,通過觀察,發(fā)現(xiàn)ohci-hcd.c和ohci-s3c2410.c的代碼都很少,這原因是什么?下面這段代碼來自于ohci-hcd.c。
static const char hcd_name [] = "ohci_hcd"; #define STATECHANGE_DELAY msecs_to_jiffies(300) #define IO_WATCHDOG_DELAY msecs_to_jiffies(275) #define IO_WATCHDOG_OFF 0xffffff00 #include "ohci.h" #include "pci-quirks.h" static void ohci_dump(struct ohci_hcd *ohci); static void ohci_stop(struct usb_hcd *hcd); static void io_watchdog_func(struct timer_list *t); #include "ohci-hub.c" #include "ohci-dbg.c" #include "ohci-mem.c" #include "ohci-q.c"
g,通過觀察ohci-hcd.c文件,發(fā)現(xiàn)其實(shí)它其實(shí)已經(jīng)包括了很多其他的ohci文件。那么寄存器又是怎么操作的呢?下面這段代碼來自于ohci.h文件。
static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci, __hc32 __iomem * regs) { #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO return big_endian_mmio(ohci) ? readl_be (regs) : readl (regs); #else return readl (regs); #endif } static inline void _ohci_writel (const struct ohci_hcd *ohci, const unsigned int val, __hc32 __iomem *regs) { #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO big_endian_mmio(ohci) ? writel_be (val, regs) : writel (val, regs); #else writel (val, regs); #endif } #define ohci_readl(o,r) _ohci_readl(o,r) #define ohci_writel(o,v,r) _ohci_writel(o,v,r)
h,看到這里,你應(yīng)該發(fā)現(xiàn)大部分底層操作其實(shí)也都是ohci幫助一起完成的。每個(gè)host driver其實(shí)就是注冊(cè)了一下,告知了mem地址在哪。下面這段代碼就是ohci-s3c2410.c中probe函數(shù)的代碼。
hcd->regs = devm_ioremap_resource(&dev->dev, &dev->resource[0]); if (IS_ERR(hcd->regs)) { retval = PTR_ERR(hcd->regs); goto err_put; }
4、usb驅(qū)動(dòng)怎么學(xué)
如果從代碼結(jié)構(gòu)來說,上面這段分析算是入門了。但是,如果要深入了解usb host&device驅(qū)動(dòng),那么除了這些代碼邏輯,那么還要熟讀usb協(xié)議手冊(cè),更重要的學(xué)會(huì)用catc協(xié)議分析儀真正地去了解usb是如何發(fā)包和收包的。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 在linux下實(shí)現(xiàn) python 監(jiān)控usb設(shè)備信號(hào)
- arm linux利用alsa驅(qū)動(dòng)并使用usb音頻設(shè)備
- Linux中輕松使用USB移動(dòng)存儲(chǔ)器
- 在Linux環(huán)境中使用USB存儲(chǔ)器
- 通過案例深入解析linux NFS機(jī)制
- Linux NFS機(jī)制工作原理及實(shí)例解析
- IntelliJ IDEA遠(yuǎn)程Debug Linux的Java程序,找問題不要只會(huì)看日志了(推薦)
- Linux bzip2 命令的使用
- Linux如何使用libudev獲取USB設(shè)備VID及PID
相關(guān)文章
Linux 系統(tǒng)優(yōu)化的一些建議(內(nèi)核優(yōu)化)
這篇文章主要介紹了Linux 系統(tǒng)優(yōu)化的一些建議,幫助大家更好的使用Linux,感興趣的朋友可以了解下2020-08-08詳解Lamp環(huán)境搭建Linux CentOS6.5編譯安裝mysql5.6
這篇文章主要介紹了詳解Lamp環(huán)境搭建Linux CentOS6.5編譯安裝mysql5.6,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05Linux網(wǎng)絡(luò)搭建基礎(chǔ)實(shí)驗(yàn)(1)
這篇文章主要為大家詳細(xì)介紹了Linux網(wǎng)絡(luò)搭建基礎(chǔ)實(shí)驗(yàn)過程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04在Bash腳本中創(chuàng)建和使用數(shù)組方法總結(jié)
在本篇文章里小編給大家整理了關(guān)于在Bash腳本中創(chuàng)建和使用數(shù)組方法和相關(guān)知識(shí)點(diǎn),需要的朋友們?cè)趯W(xué)習(xí)下。2019-03-03