新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 嵌入式數(shù)據(jù)采集系統(tǒng)中的ADS8364驅動程序設計

嵌入式數(shù)據(jù)采集系統(tǒng)中的ADS8364驅動程序設計

作者: 時間:2012-03-23 來源:網絡 收藏

4 的驅動程序設計概述

4.1 驅動程序的LKM實現(xiàn)機制

內核提供了兩種機制來開發(fā),一種是直接把驅動程序編譯進內核,成為內核的一部分。另一種是通過LKM(Loadable Kernel Module,即可加載模塊化機制)來開發(fā)可動態(tài)加載和卸載的驅動模塊[3]。驅動程序如果編譯進內核的話,會增加內核的大小,還要改動內核的源文件,而且不能動態(tài)的卸載,不利于調試,所以本系統(tǒng)把的驅動程序編寫成了 LKM型驅動程序(就是把的驅動程序作為一個獨立的單元模塊,在使用時可以使用insmod命令加載到核心中,用完后使用rmmod命令卸載的那種)。

4.2 驅動程序的注冊與注銷

向系統(tǒng)增加一個驅動程序則意味著要賦予它一個主設備號,這一賦值過程是在驅動程序模塊的初始化中完成的。ADS8364的初始化入口函數(shù)定義如下:

int _init ads8364_init_module(void)全功能版J-LINK ARM仿真器V6.0

{ …..

ret = register_chrdev(11, ADS8364, ad_fops);

……}

在用insmod命令將編譯好的模塊調入內存時,ads8364_init_module( )函數(shù)被調用。在這里,ads8364_init_module( )只做了一件事,它調用函數(shù)register_chrdev( )向內核注冊該。函數(shù)register_chrdev()定義在linux/fs-h> 中。register_chrdev需要三個參數(shù),參數(shù)一是希望獲得的設備號,如果是零的話,系統(tǒng)將自動選擇一個沒有被占用的設備號作為該的主設備號并返回。參數(shù)二是設備文件名,這個名字必須插入到/dev目錄中,并與驅動程序的主設備號和次設備號相連。參數(shù)三用來登記驅動程序實際執(zhí)行操作的函數(shù)的指針。如果登記成功,返回設備的主設備號,不成功,返回一個負值。在此,我們選用當前不用的設備號11作為ADS8364的主設備號,設備名為 ADS8364。

在關閉或塊設備時,還需要通過unregister_chrdev( )從內核中注銷設備,并釋放主設備號。在用rmmod卸載該驅動模塊時,cleanup_module函數(shù)被調用,它釋放字符設備ADS8364在系統(tǒng)字符設備表中占有的表項。

void ads8364_cleanup_module(void)

{ unregister_chrdev(11, ADS8364); info("ADS8364 cleanup module ok!"); }

4.3 file_operations結構體的設計

中,字符設備向內核提供的接口函數(shù)集就是文件操作集file_operations結構體。在Linux系統(tǒng)中,打開的設備在內核內部由設備文件file結構標識,內核使用file_operations(文件操作)結構訪問驅動程序的函數(shù)。每個文件都與自己的函數(shù)集相關聯(lián)(通過包含指向file_operations結構的f_ops指針段實現(xiàn)),這些操作主要負責系統(tǒng)調用的實現(xiàn)[4]。為了使驅動程序在結構的定義發(fā)生變化時更具可移植性,并且使得代碼更加緊湊且易讀,我們首先采用標記化格式聲明ADS8364的file_operations結構:

static struct file_operations ad_fops = {全功能版J-LINK ARM仿真器V6.0

owner: THIS_MODULE,/* ad_fops所屬的設備模塊 */

read:ads8364_read,/*從設備中讀數(shù)據(jù)*/

poll:ads8364_poll, /*查詢設備狀態(tài)*/

ioctl:ads8364_ioctl,/*設備I/O控制*/全功能版J-LINK ARM仿真器V6.0

open:ads 8364_open,/*打開設備操作*/

release:ads 8364_release,/*釋放操作*/

};

file_operations結構體把系統(tǒng)調用和驅動程序關聯(lián)起來。這個結構的每一個成員的名字都對應著一個系統(tǒng)調用。用戶進程利用系統(tǒng)調用在對設備文件進行諸如read、write、open等操作時,系統(tǒng)調用通過設備文件的主設備號找到相應的,然后讀取這個數(shù)據(jù)結構相應的函數(shù)指針,接著把控制權交給該函數(shù)。這就是ADS8364驅動程序工作的基本原理。既然是這樣,則編寫的主要工作就是編寫子函數(shù),并填充 file_operations的各個域。下面我們就把file_operations的各個域的功能和主要調用函數(shù)加以介紹。

1)設備I/O控制操作函數(shù)

與普通文件相比,設備文件的操作要復雜得多,不可能簡單地通過 read、write 和llseek 等來實現(xiàn)。所有其它類型的操作都可以通過VFS的ioctl調用來執(zhí)行,函數(shù)定義如下:

static int ads8364_ioctl(struct inode * inode, struct file *filp, unsigned int cmd, unsigned long arg)

ads8364_ioctl是ADS8364驅動程序中對設備的I/O通道進行管理的函數(shù)。其中參數(shù)inode就是用戶程序打開ADS8364時使用open函數(shù)返回的文件標示符,cmd就是用戶程序對ADS8364的控制命令,它是唯一聯(lián)系用戶程序命令和驅動程序支持的途徑,該函數(shù)通過cmd區(qū)分操作,通過arg傳遞參數(shù)和結果。在驅動程序中實現(xiàn)的ads8364_ioctl函數(shù)體內,有一個switch{case}結構,每一個case對應一個命令碼,做出一些相應的操作。 ads8364_ioctl的設計的關鍵就是,如何將cmd命令碼在用戶程序里生成以及在驅動程序里的解析,所以switch{case}結構在 ads8364_ioctl中至關重要,因為對設備的I/O控制都是通過這一部分的代碼實現(xiàn)的。

linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)


評論


相關推薦

技術專區(qū)

關閉