天天看點

正點原子ALPHA_字元裝置驅動開發總結1. 加載與解除安裝驅動子產品2. 字元裝置的注冊和登出3. 裝置驅動架構4. 編寫測試APP5. 編譯6. 運作測試7. 其他

linux分為核心态和使用者态,他兩不能直接通路,必須通過”中間商”聯系,關系如下:

使用者空間:應用程式

               |

               |系統調用(陷入)

               |  

核心:linux驅動

Linux驅動的重點就是驅動架構,驅動運作方式有兩種:

①:将驅動編譯進linux核心中,代碼release或者驅動子產品需要;

②:将驅動編譯成子產品(.ko檔案),再人為insmod/modprobe加載驅動子產品,一般在調試階段。

接下來就講講字元裝置驅動入門流程和注意事項。

目錄

1. 加載與解除安裝驅動子產品

注冊函數模闆:

2. 字元裝置的注冊和登出

3. 裝置驅動架構

4. 編寫測試APP

5. 編譯

6. 運作測試

7. 其他

1. 加載與解除安裝驅動子產品

注冊函數模闆:

static int __init xxx_init(void) //執行insmod的時候調用

static void __exit xxx_exit(void) //執行rmmod的時候調用

module_init(xxx_init); //起聲明作用

module_exit(xxx_exit); //起聲明作用

使用modprobe,因為modprobe更智能,能關聯加載驅動所需的其他驅動子產品(但是在簡單驅動開發驗證還是覺得insmod友善簡單)

2. 字元裝置的注冊和登出

register_chrdev(major(主裝置号), name(裝置名稱), fops(fileoperations類型指針))

unregister_chrdev(major(主裝置号), name(裝置名稱))

在上面的init和exit兩個函數中分别調用這兩個函數,還有需要定義一個fileoperations結構體。

3. 裝置驅動架構

Staitc chrtest_open 打開裝置

Staitc chrtest_read 從裝置讀取

Staitc chrtest_write 向裝置寫入

Staitc chrtest_release 關閉、釋放裝置

Static struct file_operations test_fops={

.owner = THIS_MODULE,

.open = chrtest_open,

.read = chrtest_read,

.write = chrtest_write,

.release = chrtest_release,

};

Staitc int __init xxx_init(void)

{

Int ret = 0;

ret = register_chrdev(200,”chrtest”,&test_fops);

If(ret < 0)

{

Return -1;

}

}

Static void __exit xxx_exit(void)

{

unregister_chrdev(200, “chrdev”);

}

module_init(xxx_init);

module_exit(xxx_exit);

MODULE_LICENSE(“GPL”);

4. 編寫測試APP

以操作檔案的形式open read write close,因為linux皆檔案。

int(fd) open(const char *pathname, int flags)

Pathname:檔案路徑、裝置

flags:O_RDONLY隻讀/WRONLY隻寫/RDWR讀寫......

ssize read(int fd, void * buf, size_t count)

ssize write(int fd,void *buf, size_t count)

int close(fd)

5. 編譯

驅動子產品的編譯:編寫一個Makefile,執行make 生成.ko子產品。

測試app的編譯:arm-linux-gnueabihf-gcc xxx.c -o xxx 因為編譯出來的執行檔案是要在arm核心下運作,是以使用交叉編譯器。

6. 運作測試

①:加載子產品:insmod xxx.ko/modprobe xxx.ko(執行不成功,要先執行depmod)

②:建立裝置節點:在/dev目錄下建立與之對應的裝置節點檔案,mknod /dev/xxx c 200 0

mknod /dev/xxx c(字元裝置) 200(主裝置号) 0(次裝置号)

③:裝置驗證:./xxx(APP) /dev/xxx 1(參數)

④:解除安裝:rmmod xxx.ko

7. 其他

①.裝置都有一個裝置号(32位),分别由主裝置号(12位 0-4095)和次裝置号(20位)組成。主裝置号是具體的驅動,像滑鼠驅動;次裝置号是主驅動的具體應用個數,像雷蛇、雙飛燕啊這些滑鼠插電腦會有幾個滑鼠裝置一樣,但是驅動的名字不一樣。

②.靜态配置設定裝置号:檢視目前系統所使用的裝置号:cat /proc/devices,在确定未使用的裝置号作為改驅動裝置号。

動态配置設定裝置号:int alloc_chrdev_region(dev_t *dev(裝置号),unsigned baseminor(次裝置号起始),unsigned count(申請裝置個數), const char *name(裝置名稱))

登出裝置:void unregister_chrdev_region(dev_t from(需要釋放裝置号), unsigned count(從from需要釋放個數))

③.Linux核心沒有printf,隻有printk。因為printf是運作在使用者态中(應該是為了做差別吧)。

printk可以根據宏定義,決定需要列印的資訊。因為核心空間和使用者空間不能直接操作,是以就會有從核心<==>使用者的接口函數:copy_to_user(核心->使用者read)和copy_from_user(使用者write->核心),這兩個函數都是站在使用者态了解和調用。

參考:【正點原子】I.MX6U嵌入式Linux驅動開發指南V1.4.pdf

繼續閱讀