大地资源网视频在线观看新浪,日本春药精油按摩系列,成人av骚妻潮喷,国产xxxx搡xxxxx搡麻豆

您現在的位置:智能制造網>技術中心>嵌入式Linux下的USB設備驅動技術

直播推薦

更多>

企業動態

更多>

推薦展會

更多>

嵌入式Linux下的USB設備驅動技術

2010年06月25日 09:31:12人氣:1038來源:

前言:Linux以其穩定、、易定制、硬件支持廣泛、源代碼開放等特點,已在嵌入式領域迅速崛起,被上許多大型的跨國企業用作嵌入式產品的系統平臺。

  USB是Universal Serial Bus (通用串行總線)的縮寫,是1995年由Microsoft、Compaq、IBM等公司聯合制定的一種新的PC串行通信協議。它是一種快速、靈活的總線接口。與其它通信接口相比較,USB接口的zui大特點是易于使用,這也是USB的主要設計目標。USB的成功得益于在USB標準中除定義了通信的物理層和電器層標準外。還定義了一套相對完整的軟件協議堆棧。這使得多數USB設備都很容易在各種平臺上工作。作為一種高速總線接口,USB適用于多種設備(如數碼相機、MP3播放器、高速數據采集設備等)。另外,USB接口還支持熱插拔,而且所有的配置過程都由系統自動完成,無須用戶干預。

  1 Linux下的USB設備驅動

  在Linux內核的不斷升級過程中,驅動程序的結構相對穩定。由于USB設備也是外圍設備的一種,因此,它的驅動程序結構與普通設備的驅動程序相同。Linux系統的設備分為字符設備(CharDevice)和塊設備(BlockDevice)。字符設備支持面向塊字符的I/O操作,它不通過系統的快速緩存,而只支持順序存取。塊設備則支持面向塊的I/O操作,所有塊設備的I/O操作都通過在內核地址空間的I/O緩沖區進行,可以支持幾乎任意長度和任意位置上的I/O請求。塊設備與字符設備還有一點不同,就是塊設備必須能夠隨機存取(RandomAccess),字符設備則沒有這個要求。典型的字符設備包括鼠標、鍵盤、串行口等,而塊設備主要包括硬盤軟盤設備、CD-Rom等。由于USB設備主要都是通過快速串行通訊來讀寫數據,因此一般都可作為字符設備來進行處理。

  2 Linux下的USB core

  2.1 Linux中USB core與USB的結構關系

  Linux操作系統中有一個叫做“USB core”的子系統,可提供支持USB設備驅動程序的API和USB主機控制器的驅動程序。同時提供有許多數據結構、宏定義和功能函數來對硬件或設備進行支持。在Linux下編寫USB設備的驅動程序時,從嚴格意義上講,就是使用這些USB core的子系統所定義的數據結構、宏和函數來編寫數據的處理功能。在Linux下,core、host controller和driver三者之間的關系如圖1所示。


  2.2 USB core的初始化

  USB core從USB子系統的初始化開始。USB子系統的初始化則在文件drivers/usb/core/usb.c里。其代碼如下:

  subsys_initcall(usb_init);
  module_exit(usb_exit);

  代碼中的subsys_initcall是一個宏,相當于module_init,只不過因為這部分代碼是核心,通常把它看作一個子系統,而不僅僅是一個模塊。因為USB core模塊代表的不是某一個設備,而是所有USB設備賴以生存的模塊。因此,在Linux中,像這樣把一個類別的設備驅動歸結為一個子系統(比如PCI子系統、scsi子系統等)。基本上,drivers/目錄下面*層的每個目錄都可算作一個子系統,因為它們代表了一類設備。一般地,usb_init是真正的初始化函數,而usb_exit()則是整個USB子系統結束時的清理函數:


  函數usb_init主要完成初始化和注冊設備。

  2.3 USB里的設備模型

  Linux里一個很重要的概念是設備模型。對于驅動來說,設備的概念就是總線和與其相連的各種設備。在內核里,總線、設備、驅動也就是bus、device、driver是設備模型很重要的三個概念,它們都有自己專屬的結構。在include/linux/devide.h里的定義為:

  struct bus_type {……};
  struct device {……);
  struct device_driver {……};

  每次出現一個設備都要向總線注冊,每次出現一個驅動,也要向總線注冊。系統初始化時,應掃描連接許多設備,并為每一個設備建立一個struct device的變量。每一次都應有一個驅動程序,并要準備一個struct device_driver結構的變量。還要把這些變量加入相應的鏈表(如把device插入devices鏈表,driver插入drivers鏈表)。這樣,通過總線就能找到每一個設備和每一個驅動。然而,假如計算機里只有設備卻沒有對應的驅動,那么設備將無法工作。反過來,倘若只有驅動卻沒有設備,驅動也起不了任何作用。對于USB設備,它可以在計算機啟動以后再插入或者拔出計算機。由于device可以在任何時刻出現,而driver也可以在任何時刻被加載,所以,每當一個struct device誕生時,它就會去BUS的drivers鏈表中尋找自己的另一半。如果找到了匹配的設備,就調用device_bind_driver,并綁定好。

  Linux設備模型中的總線落實在USB子系統里就是usb_bus_type,它在usb_init函數中可用retval=bus_register(&usb_bus_type)語句注冊,而在driver.c文件里的定義如下:
 

  該函數的形參對應的就是總線兩條鏈表里的設備和驅動。當總線上有新設備和驅動時,這個函數就會被調用。

  3 USB驅動程序的描述符

  一個設備可以有多個接口,一個接口可代表一個功能,因此,每個接口都對應著一個驅動。例如一個USB設備有兩種功能,一個鍵盤,上面還帶一個揚聲器,這就是兩個接口,就需要兩個驅動程序,一個是鍵盤驅動程序,一個是音頻流驅動程序。

  一個驅動程序是否支持一個設備,要通過讀取設備的描述符來判斷。那么,什么是USB的描述符呢?USB的描述符是一個帶有預定義格式的數據結構,里面保存有USB設備的各種屬性和相關信息,可以通過向設備請求獲得它們的描述符內容來深刻了解和感知一個USB設備。主要有四種USB描述符,分別為:接口描述符、端點描述符、設備描述符和配置描述符。

  協議規定:一個USB設備必須支持這四大描述符,還有些描述符不是必須包含的,有些特殊設備用來描述設備的不同特性,但這四大描述符是一個都不能少的。USB設備里有一個eeprom,可用來存儲設備本身信息,設備的描述符就存儲在這里。

  上述四個描述符分別放在了include/linux/usb.h文件中的struct usb_host_interface、structusb_host_endpoint、struct usb_device、struetusb_host_config里,而描述符結構體本身定義在include/linux/usb/ch9.h里.并分別用struct usb_interface_descriptor、struct usb_host_endpoint、structusb_device_descriptor和struct usb_config_descriptor來表示。描述符結構體的定義應*按照USB協議對描述符的規定來定義。

  4 USB接口驅動

  4.1 接口結構

  平時編寫的USB驅動通常指的是寫USB接口的驅動,一個接口對應一個接口驅動程序,需要以一個struct usb_driver結構的對象為中心,并以設備的接口提供的功能為基礎,來進行USB驅動程序的編寫。struct usb_driver結構體一般定義在include/linux/usb.h文件里。具體如下:

  struct usb_driver{
  const char*name;
  int(*probe) (struct usb_interface*intf,const
  struct usb_device_jd*id);
  void(*disconnect) (struct usb_interface*intf);
  int(*ioctl) (struct usb_interface*intf,unsigned
  int code,void*buf);
  int (*suspend) (struct usb_interface*intf,
  pm_message_t message);
  int(*resume) (struct usb_interface*intf);
  void(*pre_reset) (struct usb_interface*intf);
  void(*post_reset)(struct usb_interface*intf);
  const struct usb_device_id*id_table;
  struct usb_dynids dynids;
  struct usbdrv_wrap drvwrap;
  unsigned int no_dynamic_id:1;
  unsigned int supports_autosuspend:1;
  };

  Name為驅動程序的名字,對應于/sys/bus/usb/drivers/下面的子目錄名稱。它只是彼此區別的一個代號,這里的名字在所有的USB驅動中必須是*的。probe用來看看這個USB驅動是否愿意接受某個接口的函數。Disconnect函數將在接口失去或使用rmmod卸載驅動將它和接口強行分開時被調用。Ioctl函數則用在驅動通過usbfs和用戶空間進行交流時使用。Suspend、esume分別在設備被掛起和喚醒時使用。pre_reset、post_reset分別在設備將要復位(reset)和已經復位后使用。id_table的變量可用來判斷是否支持某個設備接口。Dynids是支持動態id的。實際上,即使驅動已經加載了,也可以添加新的id給它。drvwrap是給USB core區分設備驅動和接口驅動用的。no_dynamic_id可以用來禁止動態id。supports_autosuspend可對autosuspend提供支持,如果設置為0,則不再允許綁定到這個驅動的接口autosuspend。

  當insmod或modprobe驅動的時候,經過一個曲折的過程,就會調用相應USB驅動里的xxx_init函數,進而去調用usb_register (),以將相應的USB驅動提交給設備模型,添加到USB總線的驅動鏈表里。當rmmod驅動時,同樣,在經過一個曲折的過程之后,再調用相應驅動里的xxx_cleanup函數,進而調用usb_deregister ()將相應的USB驅動從USB總線的驅動鏈表里刪除。

  5 結束語

  本文介紹了Linux下USB core的工作原理,同時介紹了驅動USB必須了解的四個描述符。此外,還介紹了Linux下usb接口驅動的工作原理。本文介紹的方法能適應于Linux下各種不同的USB設備驅動程序的開發。

全年征稿/資訊合作 聯系郵箱:1271141964@qq.com

免責聲明

  • 凡本網注明"來源:智能制造網"的所有作品,版權均屬于智能制造網,轉載請必須注明智能制造網,http://www.xashilian.com。違反者本網將追究相關法律責任。
  • 企業發布的公司新聞、技術文章、資料下載等內容,如涉及侵權、違規遭投訴的,一律由發布企業自行承擔責任,本網有權刪除內容并追溯責任。
  • 本網轉載并注明自其它來源的作品,目的在于傳遞更多信息,并不代表本網贊同其觀點或證實其內容的真實性,不承擔此類作品侵權行為的直接責任及連帶責任。其他媒體、網站或個人從本網轉載時,必須保留本網注明的作品來源,并自負版權等法律責任。
  • 如涉及作品內容、版權等問題,請在作品發表之日起一周內與本網聯系,否則視為放棄相關權利。

<
更多 >

工控網機器人儀器儀表物聯網3D打印工業軟件金屬加工機械包裝機械印刷機械農業機械食品加工設備制藥設備倉儲物流環保設備造紙機械工程機械紡織機械化工設備電子加工設備水泥設備海洋水利裝備礦冶設備新能源設備服裝機械印染機械制鞋機械玻璃機械陶瓷設備橡塑設備船舶設備電子元器件電氣設備


我要投稿
  • 投稿請發送郵件至:(郵件標題請備注“投稿”)1271141964.qq.com
  • 聯系電話0571-89719789
工業4.0時代智能制造領域“互聯網+”服務平臺
智能制造網APP

功能豐富 實時交流

智能制造網小程序

訂閱獲取更多服務

微信公眾號

關注我們

抖音

智能制造網

抖音號:gkzhan

打開抖音 搜索頁掃一掃

視頻號

智能制造網

公眾號:智能制造網

打開微信掃碼關注視頻號

快手

智能制造網

快手ID:gkzhan2006

打開快手 掃一掃關注
意見反饋
關閉
企業未開通此功能
詳詢客服 : 0571-87858618
主站蜘蛛池模板: 辽宁省| 巴塘县| 奉化市| 留坝县| 太湖县| 南投县| 永福县| 河西区| 全椒县| 珲春市| 合江县| 通渭县| 黔南| 图片| 辛集市| 手游| 阿城市| 黑龙江省| 东港市| 七台河市| 玉田县| 康保县| 顺义区| 万山特区| 湟源县| 盐津县| 资阳市| 隆尧县| 荔波县| 江门市| 上犹县| 鄂尔多斯市| 东阿县| 舒城县| 吕梁市| 图木舒克市| 伊宁市| 永福县| 阜新市| 常德市| 双鸭山市|