這時候你是不是有點不知所措呢?其實你不用著急,根據可知論,世界是可以被認知的,linux裝置驅動的一般性的設計和編寫方法也是存在的,所以,你大可不必驚慌。linux裝置驅動的設計一般可以遵循以下幾個步驟。
一、深刻理解datasheet和原理圖
這裡講的datasheet包括主控的datasheet和裝置晶元的datasheet,原理圖就指的是開發板的的原理圖了,
如果有pads版本的原理圖和貼片圖,那是最好的了,方便以後測量引腳的各項引數。閱讀和深刻理解裝置晶元的datasheet對第乙個步驟裡面最重要的組成部分,裝置驅動就是datasheet的最直觀表達,只有在深刻理解的datasheet的基礎之上,才有可能設計和開發出優秀的裝置驅動。另外,datasheet在一定程度上就是你做驅動軟體的需求文件。你做軟體總該有個需求吧,那麼這裡談到的datasheet就是驅動軟體的最好的、最清楚的需求分析。所以,在沒有理解datasheet之前就著手做驅動,那結果是可想而知的。
二、搭建起裝置驅動的框架
理解了datasheet之後,先不要急著去編寫**,你首先應該做的就是給你將要寫的驅動程式設計乙個框架。
那麼這裡的框架應該依據什麼搭建呢?具體怎麼搭建呢?
一般的,從usb驅動到i2c驅動,從spi驅動到串列埠驅動,從pci驅動到dma驅動,等等,不管是什麼型別的驅動,它總有一種或者幾種基本固定的套路供你選擇。如果你打算寫乙個touch驅動,而這個touch掛接在i2c上,那麼你就依據i2c裝置編寫的一一種固定套路先搭建框架。具體如何搭建,這裡就給出i2c裝置驅動編寫的一種固定套路給大家。
i2c裝置驅動的新式編寫方法為probe方法,這裡就講編寫i2c裝置驅動的probe方法的框架的搭建。
l 建立乙個i2c_driver
static struct i2c_driver ***x_driver = ,,,
,,,,
l 註冊i2c_board_info
對於probe方法,都要在平台**中要完成i2c_board_info的註冊。辦法如下:
static struct i2c_board_info __initdata tmp_i2c_devices = else {
result = alloc_chrdev_region(&***x_dev,0,1,"***x");
***x_major=major(***x_dev);
if (result < 0) {
printk(kern_notice "unable to get ***x region, error %d\n", result);
return result;
***x_setup_cdev(chip,0); /* 註冊字元裝置, 具體的請google一下 */
/* … 省略 …*/
l 字元裝置驅動的構建
struct
file_operations ***x_fops = {
.owner = this_module,
.ioctl = ***x_ioctl,
.open = ***x_open,
.release = ***x_release,
l 刪除i2c_driver
static void __exit ***x_exit(void)
i2c_del_driver(&***x_driver);
module_exit(***x_exit);
l 刪除字元裝置驅動
static int __devinit ***x_remove (struct i2c_client *client)
/*…省略…*/
你看到這裡,就應該明白上面講到的所謂裝置驅動程式的框架是什麼意思了吧。當然,這裡只寫出了i2c裝置驅動的一種框架,spi、usb、dma 驅動程式設計都有其各自的框架,具體的資訊可以從核心文件(
kernel
頂層目錄下的
documentation
目錄)獲得。總之,你要編寫什麼型別的驅動,首先根據實際情況搭建好框架。
三、填充框架
搭建好裝置驅動程式的框架之後,你應該做的就是根據實際情況往框架裡面填充內容了。填充內容可以分為兩個層次的填充,分別是:
l 和上層應用打交道的內容
主要包括:
? 基於devfs實現檔案操作結構體(file_operations)中的函式,目的是給上層提供系統呼叫(system call)
? 通過procfs或者sysfs給上層應用提供不同種類的介面
? 向虛擬檔案系統(vfs)註冊或者登出(新增或者刪除)裝置驅動,等等。
l 和主控以及裝置晶元打交道的內容
依據主控、裝置晶元的datasheet以及開發板原理圖,做以下填充:
? 定義裝置驅動的標頭檔案
? 填充系統呼叫中和裝置晶元直接打交道的部分
? 編寫裝置驅動程式電源管理模組
? 配置好i/o口的功能,等等。
四、開始裝置驅動的除錯
設計和編寫裝置驅動的一般方法
這時候你是不是有點不知所措呢?其實你不用著急,根據可知論,世界是可以被認知的,linux裝置驅動的一般性的設計和編寫方法也是存在的,所以,你大可不必驚慌。linux裝置驅動的設計一般可以遵循以下幾個步驟。一 深刻理解datasheet和原理圖 這裡講的datasheet包括主控的datasheet和...
裝置驅動除錯和移植的一般方法(一)
做linux底層軟體工作也有兩年了,算上研究生時期對底層軟體的研究,加起來也快四年了。慢慢地發現有必要總結一些一般性的方法了。因為一般性的方法有巨集觀上的指導意義,以後除錯和移植驅動時,經常性地回味這些一般性的方法可以防止自己犯同樣的錯誤,進而少走彎路,以最高的效率完成工作。當談到底層軟體,我們一般...
函式設計的一般原則和技巧
1.原則上盡量少使用全域性變數,因為全域性變數的生命週期太長,容易出錯,也會長時間占用空間.各個原始檔負責本身檔案的全域性變數,同時提供一對對外函式,方 便其它函式使用該函式來訪問變數。比如 niset valuename niget valuename 不要直接讀寫全域性變數,尤其是在多執行緒程式...