<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 業(yè)界動態(tài) > [ARM筆記]設(shè)備驅(qū)動概述

          [ARM筆記]設(shè)備驅(qū)動概述

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

            mknod命令建立一個(gè)目錄項(xiàng)和一個(gè)特殊文件的對應(yīng)索引節(jié)點(diǎn)。第一個(gè)參數(shù)Name項(xiàng)是設(shè)備的名稱,選擇一個(gè)描述性的設(shè)備名稱。

          本文引用地址:http://www.ex-cimer.com/article/201611/340660.htm

            mknod命令有兩種形式,它們有不同的標(biāo)志。mknod命令的第一種形式只能由root用戶或系統(tǒng)組成員執(zhí)行。在第一種形式中,使用了b或c標(biāo)志。b標(biāo)志表示這個(gè)特殊文件是面向塊的設(shè)備(磁盤、軟盤或磁帶)。c標(biāo)志表示這個(gè)特殊文件是面向字符的設(shè)備(其他設(shè)備)。在 mknod 命令的第二種形式中,使用了p標(biāo)志來創(chuàng)建FIFO(已命名的管道)。

            因此,標(biāo)志集合總共有三種選擇,如下:

            * b 表示特殊文件是面向塊的設(shè)備(磁盤、軟盤或磁帶)。

            * c 表示特殊文件是面向字符的設(shè)備(其他設(shè)備)。

            * p 創(chuàng)建 FIFO(已命名的管道)。

            在介紹創(chuàng)建設(shè)備文件時(shí),主設(shè)備號和從設(shè)備號是不可或缺的。傳統(tǒng)方式中的設(shè)備管理中,除了設(shè)備類型外,內(nèi)核還需要一對主次設(shè)備號的參數(shù),才能唯一標(biāo)識一個(gè)設(shè)備。主設(shè)備號相同的設(shè)備使用相同的驅(qū)動程序,次設(shè)備號用于區(qū)分具體設(shè)備的實(shí)例。比如PC機(jī)中的IDE設(shè)備,一般主設(shè)備號使用3,WINDOWS下進(jìn)行的分區(qū),一般將主分區(qū)的次設(shè)備號為1,擴(kuò)展分區(qū)的次設(shè)備號為2、3、4,邏輯分區(qū)使用5、6…。

            第一種形式的最后兩個(gè)參數(shù)便是指定主設(shè)備號和次設(shè)備號,它幫助操作系統(tǒng)查找設(shè)備驅(qū)動程序代碼,和指定具體的次設(shè)備。一個(gè)設(shè)備的主設(shè)備號和次設(shè)備號由該設(shè)備的配置方法分配。主設(shè)備號是由/usr/src/linux/include/linux/major.h定義的,如下定義了一個(gè)DOC設(shè)備:

            #define IGEL_FLASH_MAJOR 62

            如命令mknod doc b 62 0

            其中的doc為定義的名字,b指塊設(shè)備,0指的是整個(gè)DOC。如果把0換為1,則1指的是DOC的第一個(gè)分區(qū)。2是第2個(gè),依次類推。

            mknod console c 5 1

            console是設(shè)備的名字;c指字符設(shè)備,還可選b(塊設(shè)備);5是該設(shè)備在major.h中定義的標(biāo)記,主設(shè)備號/dev/devices里面記錄現(xiàn)有的設(shè)備,創(chuàng)建設(shè)備文件時(shí),找個(gè)系統(tǒng)中還沒有用過的就可以了;1是指第一個(gè)子設(shè)備。當(dāng)你要給兩個(gè)同樣的設(shè)備加載驅(qū)動的時(shí)候就要用到這些區(qū)別了。

            3. 驅(qū)動程序的加載和卸載

            內(nèi)核中采用可加載的模塊化設(shè)計(jì),一般情況下編譯的內(nèi)核是支持可插入式模塊的,也就是將最基本的核心代碼編譯在內(nèi)核中,其它的代碼可以選擇是在內(nèi)核中,或者編譯為內(nèi)核的模塊文件。如果需要某種功能,比如需要訪問一個(gè)NTFS分區(qū),就加載相應(yīng)的NTFS模塊。這種設(shè)計(jì)可以使內(nèi)核文件不至于太大,但是又可以支持很多的功能,必要時(shí)動態(tài)地加載。這是一種跟微內(nèi)核設(shè)計(jì)不太一樣,但卻是切實(shí)可行的內(nèi)核設(shè)計(jì)方案。

            3.1 Linux驅(qū)動的加載方式

            由于Linux系統(tǒng)內(nèi)核有如上的特點(diǎn),所以設(shè)備驅(qū)動程序也秉承了這種特性。常見的驅(qū)動程序就是作為內(nèi)核模塊動態(tài)加載的,比如聲卡驅(qū)動和網(wǎng)卡驅(qū)動等。而Linux最基礎(chǔ)的驅(qū)動,如CPU、PCI總線、TCP/IP協(xié)議、VFS等驅(qū)動程序則編譯在內(nèi)核文件中。因此,Linux驅(qū)動的加載可分為靜態(tài)加載和動態(tài)加載兩種不同的方式。

            * 靜態(tài)加載:系統(tǒng)啟動時(shí)自動加載驅(qū)動到內(nèi)核,自動的注冊設(shè)備并創(chuàng)建設(shè)備接點(diǎn),也就是說把驅(qū)動程序直接編譯到內(nèi)核,系統(tǒng)啟動后應(yīng)用程序可以直接運(yùn)行、調(diào)用。靜態(tài)加載的缺點(diǎn)是調(diào)試起來比較麻煩,每次修改一個(gè)地方都要重新編譯下載內(nèi)核,效率較低。

            * 動態(tài)加載:即模塊加載,系統(tǒng)啟動時(shí)不會進(jìn)行加載驅(qū)動程序,需要人為手動加載,就是說系統(tǒng)啟動后我們的應(yīng)用程序不能直接應(yīng)用驅(qū)動,而是我們必須手動的用insmod命令去加載模塊,然后才能使用相應(yīng)的設(shè)備和應(yīng)用,在不需要的時(shí)候用rmmod命令來卸載。

            其中動態(tài)加載我們又可以分為三種去研究:

            加載驅(qū)動后,我們自己去創(chuàng)建主設(shè)備號,從設(shè)備號,利用cat /proc/devices 去查看主設(shè)備號是否重復(fù),然后根據(jù)應(yīng)用程序中使用的設(shè)備名稱用mknod命令去創(chuàng)建設(shè)備文件接點(diǎn)。

            加載驅(qū)動后,驅(qū)動程序會利用register_chrdev()函數(shù)自動產(chǎn)生主設(shè)備號去在內(nèi)核中注冊設(shè)備,我們利用cat /proc/devices命令和驅(qū)動程序中注冊的設(shè)備名去查詢主設(shè)備號和從設(shè)備號后,在根據(jù)應(yīng)用程序使用的設(shè)備名,去利用mknod去創(chuàng)建。(利用驅(qū)動中注冊的設(shè)備名是查詢自動生成的主設(shè)備號,驅(qū)動中的設(shè)備名稱不一定要和創(chuàng)建的設(shè)備接點(diǎn)名相同,他們之間可以用主設(shè)備號去關(guān)聯(lián),而應(yīng)用程序的設(shè)備名稱則必須和創(chuàng)建的設(shè)備接點(diǎn)名相同)。

            加載驅(qū)動后,驅(qū)動程序利用devfs系統(tǒng),這個(gè)系統(tǒng)可以自動的產(chǎn)生主設(shè)備號,然后自動的創(chuàng)建設(shè)備接點(diǎn)。我們只要加載驅(qū)動后,直接運(yùn)行應(yīng)用程序就行了。

            一般嵌入式驅(qū)動開發(fā)者會先用動態(tài)加載的方式來調(diào)試,調(diào)試完畢后再編譯到內(nèi)核里。下面我們將向讀者介紹下如何使用insmod動態(tài)加載模塊。

            3.2 Linux驅(qū)動加載和卸載

            當(dāng)我們編寫好需要加載的模塊、創(chuàng)建了其在內(nèi)核的設(shè)備掛載節(jié)點(diǎn)之后,下一步要進(jìn)行的操作就是將該設(shè)備模塊加載到內(nèi)核,也就是把編譯后的驅(qū)動程序的.ko文件加載到內(nèi)核。這個(gè)工作將由insmod完成。這個(gè)程序?qū)⒓虞d模塊的代碼段和數(shù)據(jù)段到內(nèi)核,接著,執(zhí)行一個(gè)類似ld的函數(shù),它連接模塊中任何未解決的符號連接到內(nèi)核的符號表上。

            insmod接收許多命令行選項(xiàng),它能夠在連接到當(dāng)前內(nèi)核之前,為模塊中的參數(shù)賦值,加載時(shí)配置比編譯時(shí)配置給了用戶更多的靈活性,感興趣的讀者可以查閱相關(guān)的資料。一般常用的命令方式為:

            #insmod /路徑 模塊編譯后生成文件.ko

            模塊可以用rmmod工具從內(nèi)核去除。需要注意的是,如果內(nèi)核認(rèn)為模塊還在用,或者內(nèi)核被配置成不允許模塊去除,模塊去除會失敗。除了上述兩種命令,還有一些相關(guān)的命令,在模塊加載時(shí)可以用到。如下所示:

            lsmod:列出當(dāng)前系統(tǒng)中加載的模塊,其中顯示信息中分為三列,依次是:模塊名、模塊大小、模塊使用的數(shù)量。

            modprobe:使用modprobe命令,可以智能插入模塊,它可以根據(jù)模塊間的依存關(guān)系,以及/etc/modules.conf文件中的內(nèi)容智能插入模塊。

            insmod:也是插入模塊的命令,但是它不會自動解決依存關(guān)系。

            modinfo:用來查看模塊信息。

            4. 學(xué)習(xí)Linux驅(qū)動程序的基礎(chǔ)及方法

            Linux設(shè)備驅(qū)動的學(xué)習(xí)是一項(xiàng)浩大的工程,讀者需要一定的基礎(chǔ)。在前面,我們專門講到過驅(qū)動程序是連接硬件設(shè)備和操作系統(tǒng)的橋梁。

            因此,驅(qū)動的開發(fā)不僅要有良好的硬件基礎(chǔ),懂得SRAM、Flash、SDRAM、磁盤的讀寫方式,UART、I2C、USB等設(shè)備的接口,輪詢、中斷、DMA的原理,PCI總線的工作方式以及CPU的內(nèi)存管理單元(MMU)等硬件處理的方式;還需要對Linux內(nèi)核有一定的了解,雖然并不要求工程師對內(nèi)核各個(gè)部分有深入的研究,但至少要了解設(shè)備驅(qū)動與內(nèi)核的接口,尤其是對于塊設(shè)備、網(wǎng)絡(luò)設(shè)備、Flash設(shè)備、串口設(shè)備等復(fù)雜設(shè)備的驅(qū)動框架等。

            另外,在應(yīng)用中很有可能多個(gè)程序訪問同一個(gè)設(shè)備,這也就需要具有良好的多任務(wù)并發(fā)控制和同步的基礎(chǔ)。動手實(shí)踐永遠(yuǎn)是學(xué)習(xí)任何軟件開發(fā)的最好方法,學(xué)習(xí)Linux設(shè)備驅(qū)動也不例外。

            一般來說,編寫一個(gè)Linux設(shè)備驅(qū)動程序的大致流程如下:

            (1)查看原理圖、數(shù)據(jù)手冊,了解設(shè)備的操作方法。

            (2)在內(nèi)核中找到相近的驅(qū)動程序,以它為模板進(jìn)行開發(fā),有時(shí)候需要從零開始。

            (3)實(shí)現(xiàn)驅(qū)動程序的初始化:比如向內(nèi)核注冊這個(gè)驅(qū)動程序,這樣應(yīng)用程序傳入文件名時(shí),內(nèi)核才能找到相應(yīng)的驅(qū)動程序。

            (4)設(shè)計(jì)所要實(shí)現(xiàn)的操作,比如:open、close、read、write等函數(shù)。

            (5)實(shí)現(xiàn)中斷函數(shù)(中斷并不是每個(gè)設(shè)備驅(qū)動所必需的)。

            (6)編譯該驅(qū)動程序到內(nèi)核中,或者用insmod命令加載。

            (7)測試驅(qū)動程序。


          上一頁 1 2 3 下一頁

          關(guān)鍵詞: ARM Linux

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();