基于Linux的USB主/從設備之間的三種通信方式
![]() |
一旦在設備中實(shí)現了用戶(hù)定制的內核模塊,就可以使該設備完成相當復雜的功能,例如仿真一個(gè)文件系統,從而允許嵌入式應用將其USB主機當作一個(gè)遠程存儲設備。除此以外,采用這種方法之后,設備還可以具備存儲轉發(fā)(store-and-forward)的功能,因而能夠在與USB主機的連接建立之前對來(lái)自嵌入式應用的數據流進(jìn)行緩沖。
在基于StrongARM的Linux設備中,內核代碼用于管理芯片所攜帶的USB設備控制器外設,通過(guò)調用函數sa1100_usb_open ()來(lái)初始化。在初始化之后,內核模塊還會(huì )調用函數sa1100_usb_get_descriptor_ptr() 和sa1100_usb_set_string_descriptor()來(lái)設置在設備查詢(xún)期間傳送給USB主機的描述符,其中包含設備的數字廠(chǎng)商號和產(chǎn)品標識符,以及可以讓主機用來(lái)識別設備的字符串,甚至還有一個(gè)序列號域,以便主機可以唯一地識別一個(gè)連接在USB接口上的設備,或者在同種型號的多個(gè)設備中進(jìn)行區分。
設備查詢(xún)過(guò)程是由USB設備控制器驅動(dòng)的,并且一旦和USB主機連上之后會(huì )自動(dòng)執行,所以?xún)群四K必須在USB通信開(kāi)始之前設置好每個(gè)設備的描述符。當準備工作就緒之后,USB設備模塊就會(huì )調用函數sa1100_usb_start()來(lái)通知內核接收主機發(fā)來(lái)的USB連接請求。如果設備模塊在連上USB 主機之前調用了函數sa1100_set_configured_callback(),那么接著(zhù)內核模塊就會(huì )在查詢(xún)過(guò)程結束時(shí)調用回調函數?;卣{函數很適合用來(lái)在設備上發(fā)出警告或給出一些形象的暗示,說(shuō)明連接已經(jīng)建立。
如果不再需要進(jìn)行USB通信,那么設備的內核模塊就會(huì )先調用函數sa1100_usb_stop(),然后調用sa1100_usb_close(),來(lái)關(guān)閉SA1100上的USB控制器。
StrongARM 的 USB控制器支持bulk-in和bulk-out兩種數據傳送方式。當接收來(lái)自USB主機的數據包時(shí),內核模塊會(huì )調用sa1100_usb_recv (),將一個(gè)數據緩沖區的地址和一個(gè)回調函數送給它。然后內核中的USB設備控制代碼會(huì )從主機取回一個(gè)bulk-out數據包,將其內容存入制定的緩沖區,接著(zhù)調用回調函數。
下一步,回調函數從接收緩沖區中提取出數據,將其存放到其他地方,或者將緩沖區空間添加到一個(gè)隊列中,然后分配一個(gè)新的緩沖區來(lái)接收下一個(gè)數據包。然后,如果還有數據需要接收,那么回調函數會(huì )重新調用sa1100_usb_recv(),準備接收另一個(gè)數據包。
向USB 主機發(fā)送數據的過(guò)程與此類(lèi)似。內核模塊收集了一幀數據之后,將數據的存放地址、數據長(cháng)度和回調函數的地址送給sa1100_usb_send()函數。接著(zhù),在數據傳送結束之后,內核模塊會(huì )調用回調函數。
在www.embedded.com/code.htm (arch/arm/mach-sa1100/usb-char.c)可以找到一個(gè)叫做usb-char的模塊,這是一個(gè)很好的設備端SA1110 Linux USB模塊的例子。該模塊將USB設備與USB 主機之間的連接變成一種高速串行鏈接。此外, usb-eth( arch/arm/mach-sa1100/usb-eth.c)模塊也是個(gè)不錯的例子,該模塊將USB變成了一種虛擬的以太型網(wǎng)絡(luò )。后面會(huì )深入探討這兩種模塊。
2. USB主機端通信過(guò)程
有些很好的主機端USB驅動(dòng)程序的例子是隨主流Linux操作系統的發(fā)布而提供的,位于The Linux Kernel Archives (kernel.org)發(fā)布的原始內核源代碼中。其中,Handspring Visor 模塊(drivers/usb/serial/visor.c)是一個(gè)編寫(xiě)得更清晰,也更易理解的模塊,它同時(shí)也是USB 主機端模塊(drivers/usb/usb-skeleton.c)的模板。
利用USB實(shí)現高速串行通信
1. USB設備端通信過(guò)程
為了達到最實(shí)用的效果,我們可以將USB總線(xiàn)簡(jiǎn)單地看作一個(gè)高速串口,然后,在一些嵌入式設備和應用中,我們就可以用USB接口來(lái)模擬串口。 StrongARM處理器的Linux內核就提供了一個(gè)名為usb-char的USB設備驅動(dòng)程序,它所完成的恰好就是用USB模擬串口的功能。
當需要與USB 主機通信時(shí),Linux操作系統中的USB設備應用只是簡(jiǎn)單地打開(kāi)一個(gè)與其usb-char設備節點(diǎn)的連接(連接類(lèi)型為字符型,major number 為10, minor 為240),然后就開(kāi)始讀寫(xiě)數據。在與USB 主機的連接建立之前,read()和write()操作均返回一個(gè)錯誤信息。一旦連接建立好,并且設備查詢(xún)完成之后,USB接口就開(kāi)始象一個(gè)點(diǎn)對點(diǎn)的串口一樣與主機進(jìn)行通信。
這種進(jìn)行USB數據傳送的方法非常簡(jiǎn)單有效,因而usb-char設備模塊發(fā)布之后一直很受歡迎。而且,該模塊還為通過(guò)其他方法進(jìn)行USB通信提供了一個(gè)參考。
linux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂)linux相關(guān)文章:linux教程
評論