<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 業(yè)界動(dòng)態(tài) > [ARM筆記](méi)設備驅動(dòng)概述

[ARM筆記](méi)設備驅動(dòng)概述

作者: 時(shí)間:2016-11-24 來(lái)源:網(wǎng)絡(luò ) 收藏

  1. 設備驅動(dòng)和操作系統

本文引用地址:http://dyxdggzs.com/article/201611/340660.htm

  1.1 無(wú)操作系統時(shí)的設備驅動(dòng)

  在沒(méi)有操作系統的情況下,設備驅動(dòng)的接口直接提交給應用軟件工程師,應用軟件沒(méi)有跨越任何層次就可以直接訪(fǎng)問(wèn)設備驅動(dòng)的接口。驅動(dòng)包含的接口函數也與硬件的功能直接吻合,沒(méi)有任何附加功能。

  1.2 有操作系統時(shí)的設備驅動(dòng)

  沒(méi)有操作系統時(shí),設備驅動(dòng)直接被應用程序調用,不與任何操作系統關(guān)聯(lián)。當系統中包含操作系統后,設備驅動(dòng)會(huì )變得怎樣?

  首先,無(wú)操作系統時(shí)設備驅動(dòng)的硬件操作仍然是必不可少的,沒(méi)有這一部分,設備驅動(dòng)不可能與硬件打交道,也就是說(shuō)在無(wú)操作系統時(shí)驅動(dòng)所做的工作,在有操作系統時(shí)也是要做的。

  其次,我們還需要將設備驅動(dòng)融入操作系統內核。應用程序是通過(guò)調用操作系統的API來(lái)實(shí)現對硬件的操作的,所以設備驅動(dòng)需要融入到內核中。為了實(shí)現這種融合,必須在所有的設備驅動(dòng)中設計面向操作系統內核的接口,這樣的接口由操作系統規定,對一類(lèi)設備而言結構一致,獨立于具體的設備。不同的操作系統中定義的設備驅動(dòng)架構是不一樣的,要將設備驅動(dòng)融入系統內核中,就需要按照操作系統給出的獨立于設備的接口架構設計,如此這般,應用程序就可以使用統一的系統調用接口來(lái)訪(fǎng)問(wèn)各種設備。其中內核的API 包括并發(fā)/同步控制、阻塞/喚醒、中斷底半部調度、內存和I/O 訪(fǎng)問(wèn)等。

  由此可見(jiàn),當系統中存在操作系統時(shí),設備驅動(dòng)變成了鏈接硬件和內核的橋梁,操作系統的存在使得單一的“驅動(dòng)硬件設備工作”變?yōu)椴僮飨到y與硬件交互的模塊,它對外呈現為操作系統API,不再給應用軟件工程師直接提供接口。因此,驅動(dòng)工程師不僅需要牢固的硬件基礎,如硬件的工作原理、寄存器設置等,還需要對驅動(dòng)中所涉及的內核知識有良好的掌握,包括內核支持的API、內核驅動(dòng)架構等,才能設計開(kāi)發(fā)出好的設備驅動(dòng)程序。也就是說(shuō)設備驅動(dòng)從無(wú)操作系統時(shí)的應用程序和硬件設備之間的橋梁轉變成操作系統和硬件設備之間的溝通紐帶。

  2. 設備驅動(dòng)

  2.1 設備的分類(lèi)及特點(diǎn)

  驅動(dòng)針對的對象是存儲器和外設(包括CPU內部集成的存儲器和外設),而不是針對CPU核。系統中將存儲器和外設分為3個(gè)基礎大類(lèi):字符設備、塊設備和網(wǎng)絡(luò )設備。

  2.1.1 字符設備

  概括的講,字符設備指那些必須以串行順序依次進(jìn)行訪(fǎng)問(wèn)的設備,如觸摸屏、磁帶驅動(dòng)器、鼠標等。字符設備是一種可以當作一個(gè)字節流來(lái)存取的設備,字符驅動(dòng)就負責實(shí)現這種行為。這樣的驅動(dòng)常常至少實(shí)現open,close,read,和write系統調用。字符驅動(dòng)很好地展

  現了流的抽象,它通過(guò)文件系統結點(diǎn)來(lái)存取,也就是說(shuō),字符設備被當作普通文件來(lái)訪(fǎng)問(wèn)。字符設備和普通文件之間唯一的不同就是:你可以在普通文件中移來(lái)移去,但是大部分字符設備僅僅是數據通道,你只能順序存取。然而,也存在看起來(lái)象數據區的字符設備,你可以在里面移來(lái)移去的訪(fǎng)問(wèn)數據。例如,frame grabber經(jīng)常這樣,應用程序可以使用mmap或者lseek 存取整個(gè)要求的圖像。

  2.1.2 塊設備

  塊設備是可以用任意順序訪(fǎng)問(wèn),以塊為單位進(jìn)行操作,如硬盤(pán)、軟驅等。一般來(lái)說(shuō),塊設備和字符設備并沒(méi)有明顯的界限。如同字符設備,塊設備也是通過(guò)文件系統結點(diǎn)進(jìn)行存取。一個(gè)塊設備是可以駐有一個(gè)文件系統的。Linux系統中允許應用程序讀寫(xiě)一個(gè)塊設備象一個(gè)字符設備一樣,它允許一次傳送任意數目的字節,當然也包括一個(gè)字節。塊和字符設備的區別僅僅在內核在內部管理數據的方式上,如字符設備不經(jīng)過(guò)系統的快速緩沖,而塊設備經(jīng)過(guò)系統的快速緩沖,并且在內核/驅動(dòng)的軟件接口上不同。雖然它們之間的區別對用戶(hù)是透明的,它們都使用文件系統的操作接口open()、close()、read()、write()等函數進(jìn)行訪(fǎng)問(wèn),但是它們的驅動(dòng)設計存在很大的差異。

  2.1.3 網(wǎng)絡(luò )設備

  網(wǎng)絡(luò )設備是面向數據包的接收和發(fā)送而設計的,它與字符設備、塊設備不同,并不對應于文件系統中的節點(diǎn)。內核與網(wǎng)絡(luò )設備的通信和內核與字符設備、塊設備的通信方式可以說(shuō)是完全不同的。任何網(wǎng)絡(luò )事務(wù)都通過(guò)一個(gè)接口來(lái)進(jìn)行,就是說(shuō),一個(gè)能夠與其他主機交換數據的設備。通常,一個(gè)接口是一個(gè)硬件設備,但是它也可能是一個(gè)純粹的軟件設備,比如環(huán)回接口,因此網(wǎng)絡(luò )設備也可以稱(chēng)為網(wǎng)絡(luò )接口。在內核網(wǎng)絡(luò )子系統的驅動(dòng)下,網(wǎng)絡(luò )設備負責發(fā)送和接收數據報文。網(wǎng)絡(luò )驅動(dòng)對單個(gè)連接一無(wú)所知,它只處理報文。

  既然網(wǎng)絡(luò )設備不是一個(gè)面向流的設備,一個(gè)網(wǎng)絡(luò )接口就不象字符設備、塊設備那么容易映射到文件系統的一個(gè)結點(diǎn)上。Linux提供的對網(wǎng)絡(luò )設備的存取方式仍然是通過(guò)給它們分配一個(gè)名字,但是這個(gè)名字在文件系統中沒(méi)有對應的入口,其并不用read和write等函數,而是通過(guò)內核調用和報文傳遞相關(guān)的函數來(lái)實(shí)現。

  近年來(lái),某些設備驅動(dòng)類(lèi)別也已經(jīng)添加到Linux內核中,如FireWire驅動(dòng)。與內核處理USB和SCSI驅動(dòng)相同的方式,內核開(kāi)發(fā)者集合了類(lèi)別范圍內的特性,并把它們輸出給驅動(dòng)實(shí)現者,以避免重復工作,因此簡(jiǎn)化和加強了編寫(xiě)類(lèi)似驅動(dòng)的過(guò)程。

  除了上面對設備的分類(lèi)的方式之外,還有其他的劃分方式,與上面的設備類(lèi)型是正交的。通常,某些類(lèi)型的驅動(dòng)與給定類(lèi)型設備其他層的內核支持函數一起工作。例如,你可以說(shuō)USB模塊,串口模塊,SCSI模塊等等。每個(gè)USB設備由一個(gè)USB模塊驅動(dòng),與USB子系統一起工作,但是設備自身在系統中表現為一個(gè)字符設備(比如一個(gè)USB串口),一個(gè)塊設備(一個(gè)USB內存讀卡器),或者一個(gè)網(wǎng)絡(luò )設備(一個(gè)USB以太網(wǎng)接口)。

  2.2 不同設備的驅動(dòng)設計概述

  上述的三類(lèi)設備,除了網(wǎng)絡(luò )設備外,字符設備與塊設備都被映射到Linux文件系統的文件和目錄,通過(guò)文件系統的系統調用接口open()、write()、read()、close()等函數訪(fǎng)問(wèn)。塊設備比字符設備復雜,在它上面會(huì )有一個(gè)磁盤(pán)/Flash文件系統,該文件系統對存儲介質(zhì)上的文件和目錄進(jìn)行規范化的組織。

  2.2.1 字符設備驅動(dòng)

  Linux字符設備驅動(dòng)的核心是file_operations結構體,驅動(dòng)的主體是實(shí)現其中的read()、write()、ioctl()、open()、release()等方法,這些方法將完成系統需要對設備進(jìn)行的操作功能。

  其結構形式如下所示:

  struct file_operations xxx_fops =

  {

  .owner = THIS_MODULE,

  .read = xxx_read,

  .write = xxx_write,

  .ioctl = xxx_ioctl,

  ...

  }

  open()方法:該方法提供給驅動(dòng)程序初始化設備的能力,從而為以后的設備操作做好準備,主要完成如下工作:檢查設備特定的錯誤(例如設備沒(méi)準備好,或者類(lèi)似的硬件錯誤);如果它第一次打開(kāi),初始化設備;如果需要,更新file_operations指針;分配并填充要放進(jìn)filp->private_data的任何數據結構等。此外open操作一般還會(huì )遞增使用計數,用以防止文件關(guān)閉前模塊被卸載出內核。

  release()方法:與open方法相反,它主要是釋放由open分配的filp->private_data中的所有內容;在最后一次關(guān)閉操作時(shí)關(guān)閉設備;使用計數減1等操作。

  read()和write()方法:read方法完成將數據從內核拷貝到應用程序空間,write方法相反,將數據從應用程序空間拷貝到內核。

  ioctl()方法:ioctl 方法主要用于對設備進(jìn)行讀寫(xiě)之外的其他控制,比如配置設備、進(jìn)入或退出某種操作模式,這些操作一般都無(wú)法通過(guò) read/write文件操作來(lái)完成。

  2.2.2 塊設備驅動(dòng)

  Linux塊設備驅動(dòng)并不直接實(shí)現file_operations成員函數,其主體變成處理實(shí)現block_device_operations成員函數以及處理上層下達的I/O請求。block_device_operations結構體中包含了ioctl()、open()、release()方法,因為字符設備和塊設備的存取方法不同,其I/O處理請求可以看作是塊設備中的read()和write()方法。塊設備調用函數block_read( )和block_write( )來(lái)進(jìn)行數據讀寫(xiě),這兩個(gè)函數將向設備請求表中Linux塊設備驅動(dòng)并不直接實(shí)現file_operations成員函數,其主體變成處理實(shí)現block_device_operations成員函數以及處理上層下達的I/O請求。block_device_operations結構體中包含了ioctl()、open()、release()方法,因為字符設備和塊設備的存取方法不同,其I/O處理請求可以看作是塊設備中的read()和write()方法。塊設備調用函數block_read( )和block_write( )來(lái)進(jìn)行數據讀寫(xiě),這兩個(gè)函數將向設備請求表中增加讀寫(xiě)請求,以便Linux內核可以對請求順序進(jìn)行優(yōu)化。由于是對內存緩沖區而不是直接對設備進(jìn)行操作的,因此很大程度上加快了讀寫(xiě)速度。如果內存緩沖區中沒(méi)有所要讀入的數據,或者需要執行寫(xiě)操作將數據寫(xiě)入設備,那么就要執行真正的數據傳輸。

  處理I/O請求的典型流程如下所示:

  static void xxx_request(request_queue_t *q)

  {

  struct request *req;

  while ((req = elv_next_request(q)) != NULL)

  {

  struct xxx_dev *dev = req->rq_disk->private_data;

  if (!blk_fs_request(req)) //不是文件系統請求

  {

  printk(KERN_NOTICE "Skip non-fs requestn");

  end_request(req, 0);//通知請求處理失敗

 ?。?/p>

  continue;

  }

  xxx_transfer(dev, req->sector, req->current_nr_sectors, req->buffer,rq_data_dir(req)); //處理這個(gè)請求

  end_request(req, 1); //通知成功完成這個(gè)請求

  }


上一頁(yè) 1 2 3 下一頁(yè)

關(guān)鍵詞: ARM Linux

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>