在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<abbr id="27omo"></abbr>

<menu id="27omo"><dl id="27omo"></dl></menu>
    • <label id="27omo"><tt id="27omo"></tt></label>

      新聞中心

      EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > linux 基礎(chǔ)復(fù)習(xí)(9)設(shè)備驅(qū)動(dòng)入門(mén)

      linux 基礎(chǔ)復(fù)習(xí)(9)設(shè)備驅(qū)動(dòng)入門(mén)

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

      struct inode提供了關(guān)于設(shè)備文件/dev/driver(假設(shè)此設(shè)備名為driver)的信息。struct file 提供關(guān)于被打開(kāi)的文件信息,主要用于與文件系統(tǒng)對(duì)應(yīng)的設(shè)備驅(qū)動(dòng)程序使用。struct file 較為重要,這里列出了它的定義:

      struct file {

      mode_t f_mode;/*標(biāo)識(shí)文件是否可讀或可寫(xiě),F(xiàn)MODE_READ或FMODE_WRITE*/

      dev_t f_rdev; /* 用于/dev/tty */

      off_t f_pos; /* 當(dāng)前文件位移 */

      unsigned short f_flags; /* 文件標(biāo)志,如O_RDONLY、O_NONBLOCK和O_SYNC */

      unsigned short f_count; /* 打開(kāi)的文件數(shù)目 */

      unsigned short f_reada;

      struct inode *f_inode; /*指向inode的結(jié)構(gòu)指針 */

      struct file_operations *f_op;/* 文件索引指針 */

      };

      設(shè)備驅(qū)動(dòng)程序主要組成

      (1)設(shè)備注冊(cè)

      設(shè)備注冊(cè)使用函數(shù)register_chrdev,調(diào)用該函數(shù)后就可以向系統(tǒng)申請(qǐng)主設(shè)備號(hào),如果register_chrdev操作成功,設(shè)備名就會(huì)出現(xiàn)在/proc/devices 文件里。

      register_chrdev等函數(shù)語(yǔ)法要點(diǎn)所需頭文件 #i nclude 函數(shù)原型 int register_chrdev(unsigned int major, const char *name,struct file_operations *fops) major:設(shè)備驅(qū)動(dòng)程序向系統(tǒng)申請(qǐng)的主設(shè)備號(hào) 如果為0 則系統(tǒng)為此驅(qū)動(dòng)程序動(dòng)態(tài)地分配一個(gè)主設(shè)備號(hào)函數(shù)傳入值 name:設(shè)備名 fops:對(duì)各個(gè)調(diào)用的入口點(diǎn)函數(shù)返回值 成功:如果是動(dòng)態(tài)分配主設(shè)備號(hào),此返回所分配的主設(shè)備號(hào) 且設(shè)備名就會(huì)出現(xiàn)在/proc/devices文函數(shù)返回值 件里

      出錯(cuò):-1

      (2)設(shè)備解除注冊(cè)

      在關(guān)閉設(shè)備時(shí),通常需要解除原先的設(shè)備注冊(cè),此時(shí)可使用函數(shù)unregister_chrdev,此后該設(shè)備就會(huì)從/proc/devices 里消失。

      unregister_chrdev等函數(shù)語(yǔ)法要點(diǎn)

      所需頭文件 #i nclude

      函數(shù)原型 int unregister_chrdev(unsigned int major, const char *name)

      major:設(shè)備的主設(shè)備號(hào),必須和注冊(cè)時(shí)的主設(shè)備號(hào)相同。

      函數(shù)傳入值 name:設(shè)備名

      函數(shù)返回值 成功:0,且設(shè)備名從/proc/devices文件里消失。

      出錯(cuò):-1

      (3)打開(kāi)設(shè)備

      打開(kāi)設(shè)備的接口函數(shù)是open,根據(jù)設(shè)備的不同,open函數(shù)完成的功能也有所不同,但通常情況下在open函數(shù)中要完成如下工作。

      · 遞增計(jì)數(shù)器。

      · 檢查特定設(shè)備的特殊情況。

      · 初始化設(shè)備。

      · 識(shí)別次設(shè)備號(hào)

      其中遞增計(jì)數(shù)器是用于設(shè)備計(jì)數(shù)的。由于設(shè)備在使用時(shí)通常會(huì)打開(kāi)較多次數(shù),也可以由不同的進(jìn)程所使用,所以若有一進(jìn)程想要關(guān)閉該設(shè)備,則必須保證其他設(shè)備沒(méi)有使用該設(shè)備。因此使用計(jì)數(shù)器就可以很好地完成這項(xiàng)功能。

      這里,實(shí)現(xiàn)計(jì)數(shù)器操作的是用在中定義的3 個(gè)宏如下。

      · MOD_INC_USE_COUNT:計(jì)數(shù)器加一。

      · MOD_DEC_USE_COUNT:計(jì)數(shù)器減一。

      · MOD_IN_USE:計(jì)數(shù)器非零時(shí)返回真。

      另外,當(dāng)有多個(gè)物理設(shè)備時(shí),就需要識(shí)別次設(shè)備號(hào)來(lái)對(duì)各個(gè)不同的設(shè)備進(jìn)行不同的操作,在有些驅(qū)動(dòng)程序中并不需要用到。

      雖然這是對(duì)設(shè)備文件執(zhí)行的第一個(gè)操作,但卻不是驅(qū)動(dòng)程序一定要聲明的操作。若這個(gè)函數(shù)的入口為NULL,那么設(shè)備的打開(kāi)操作將永遠(yuǎn)成功,但系統(tǒng)不會(huì)通知驅(qū)動(dòng)程序。

      (4)釋放設(shè)備

      釋放設(shè)備的接口函數(shù)是release。要注意釋放設(shè)備和關(guān)閉設(shè)備是完全不同的。當(dāng)一個(gè)進(jìn)程釋放設(shè)備時(shí),其他進(jìn)程還能繼續(xù)使用該設(shè)備,只是該進(jìn)程暫時(shí)停止對(duì)該設(shè)備的使用;而當(dāng)一個(gè)進(jìn)程關(guān)閉設(shè)備時(shí),其他進(jìn)程必須重新打開(kāi)此設(shè)備才能使用。

      釋放設(shè)備時(shí)要完成的工作如下。

      · 遞減計(jì)數(shù)器MOD_DEC_USE_COUNT。

      · 在最后一次釋放設(shè)備操作時(shí)關(guān)閉設(shè)備。

      (5)讀寫(xiě)設(shè)備

      讀寫(xiě)設(shè)備的主要任務(wù)就是把內(nèi)核空間的數(shù)據(jù)復(fù)制到用戶(hù)空間,或者從用戶(hù)空間復(fù)制到內(nèi)核空間,也就是將內(nèi)核空間緩沖區(qū)里的數(shù)據(jù)復(fù)制到用戶(hù)空間的緩沖區(qū)中或者相反。這里首先解釋一個(gè)read和write函數(shù)的入口函數(shù),如下表所示。

      read、write函數(shù)語(yǔ)法要點(diǎn)

      所需頭文件 #i nclude

      函數(shù)原型 ssize_t (*read) (struct file *filp, char *buff, size_t count, loff_t *offp)

      ssize_t (*write) (struct file *filp, const char *buff, size_t count, loff_t *offp)

      filp:文件指針

      函數(shù)傳入值 buff:指向用戶(hù)緩沖區(qū)

      count:傳入的數(shù)據(jù)長(zhǎng)度

      offp:用戶(hù)在文件中的位置

      函數(shù)返回值 成功:寫(xiě)入的數(shù)據(jù)長(zhǎng)度

      雖然這個(gè)過(guò)程看起來(lái)很簡(jiǎn)單,但是內(nèi)核空間地址和應(yīng)用空間地址是有很大區(qū)別的,其中之一就是用戶(hù)空間的內(nèi)存是可以被換出的,因此可能會(huì)出現(xiàn)頁(yè)面失效等情況。所以就不能使用諸如memcpy 之類(lèi)的函數(shù)來(lái)完成這樣的操作。在這里就要使用copy_to_user 或copy_from_user 函數(shù),它們就是用來(lái)實(shí)現(xiàn)用戶(hù)空間和內(nèi)核空間的數(shù)據(jù)交換的。copy_to_user 和copy_from_user 的格式如下表

      所需頭文件 #i nclude

      函數(shù)原型 Unsigned long copy_to_user(void *to, const void *from, unsigned long count)

      Unsigned long copy_from_user(void *to, const void *from, unsigned long count)

      To:數(shù)據(jù)目的緩沖區(qū)

      函數(shù)傳入值 From:數(shù)據(jù)源函數(shù)傳入值 緩沖區(qū)

      count:數(shù)據(jù)長(zhǎng)度

      函數(shù)返回值 成功:寫(xiě)入的數(shù)據(jù)長(zhǎng)度

      失敗:-EFAULT

      這兩個(gè)函數(shù)不僅實(shí)現(xiàn)了用戶(hù)空間和內(nèi)核空間的數(shù)據(jù)轉(zhuǎn)換,而且還會(huì)檢查用戶(hù)空間指針的有效性。如果指針無(wú)效,那么就不進(jìn)行復(fù)制

      (6)獲取內(nèi)存

      在應(yīng)用程序中獲取內(nèi)存通常使用函數(shù)malloc,但在設(shè)備驅(qū)動(dòng)程序中動(dòng)態(tài)開(kāi)辟內(nèi)存可以有基于內(nèi)存地址和基于頁(yè)面為單位兩類(lèi)。其中,基于內(nèi)存地址的函數(shù)有kmalloc,注意的是,kmalloc函數(shù)返回的是物理地址,而malloc 等返回的是線(xiàn)性地址,因此在驅(qū)動(dòng)程序中不能使用malloc函數(shù)。與malloc()不同,kmalloc()申請(qǐng)空間有大小限制。長(zhǎng)度是2的整次方,并且不會(huì)對(duì)所獲取的內(nèi)存空間清零。

      基于頁(yè)為單位的內(nèi)存有函數(shù)族有如下。

      · get_zeroed_page:獲得一個(gè)已清零頁(yè)面。



      關(guān)鍵詞:

      評(píng)論


      相關(guān)推薦

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

      關(guān)閉