一、字元驅動框架
問:應用程式open、read、write如何找到驅動程式的open、read、write函式?
答:應用程式的open、read、write是在c庫裡面實現的,它裡面通過swi val指令去觸發乙個異常,這個異常就會進入到核心空間,在核心的異常處理函式裡面有根據我們傳入的val來決定呼叫system_open還是system_read、system_write函式,這些函式根據我們開啟不同的檔案、不同的檔案就有不同的屬性(例如裝置型別(字元裝置還是塊裝置還是網路裝置)、主裝置號),根據這些屬性找到更底層的驅動程式。
問:什麼是主裝置號,什麼是次裝置號
答:linux主裝置號用來區分不同硬體裝置型別,如led和串列埠之間的區別;
linux次裝置號用來區分不同硬體裝置,如串列埠1和串列埠2之間的區別;
問:通過什麼樣的方法來找到驅動程式的open函式
答:通過乙個註冊函式+裝置節點
註冊函式如下(舊的註冊函式,新的以後再說):
register_chrdev(unsigned int major, const char * name, const struct file_operations * fops)
引數1:主裝置號(重要)
引數2:名字(不重要)
引數3:file_operations結構體(重要)
裝置節點:
可以手工建立也可以自動建立,這裡暫且只說手工建立
mknod /dev/*** c 252 0
建立乙個名為/dev/***的裝置節點,c表示字元裝置節點,252是主裝置號,0是次裝置號。
問:應用程式一般是由main函式開始執行,那麼驅動程式一般是先執行什麼?
答:通過乙個巨集,指定驅動程式的入口函式,當裝載驅動時就會執行入口函式。
例如:module_init(first_drv_init); //用於修飾入口函式
自然地,驅動程式的出口函式,則是在解除安裝驅動時就會執行出口函式。
例如:module_exit(first_drv_exit); //用於修飾出口函式
驅動源程式如下:
#include #include #include #include #include #include #include #include int major;
static int first_drv_open(struct inode * inode, struct file * filp)
static int first_drv_write(struct file * file, const char __user * buffer, size_t count, loff_t * ppos)
/* file operations struct for character device */
static const struct file_operations first_drv_fops = ;
/* 驅動入口函式 */
static int first_drv_init(void)
/* 驅動出口函式 */
static void first_drv_exit(void)
module_init(first_drv_init); //用於修飾入口函式
module_exit(first_drv_exit); //用於修飾出口函式
module_author("lwj");
module_description("just for demon");
module_license("gpl"); //遵循gpl協議
makefile原始碼如下:
ifneq ($(kernelrelease),)
obj-m := first_drv.o
else
kdir := /home/opt/embedsky/linux-2.6.30.4
all:
make -c $(kdir) m=$(pwd) modules arch=arm cross_compile=arm-linux-
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers
endif
測試程式如下:
#include #include #include #include #include int main(void)
write(fd,&val,4);
return 0;
}
開發板上的測試步驟如下:
[wj2440]# insmod first_drv.ko
[wj2440]# ./first_test
open error //沒有建立裝置節點
[wj2440]# cat proc/devices
character devices:
1 mem
4 /dev/vc/0
4 tty
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
13 input
14 sound
29 fb
81 video4linux
89 i2c
90 mtd
116 alsa
128 ptm
136 pts
180 usb
188 ttyusb
189 usb_device
204 tq2440_serial
252 first_drv //我們建立的字元裝置,主裝置號252
253 usb_endpoint
254 rtc
block devices:
259 blkext
7 loop
8 sd
31 mtdblock
65 sd
66 sd
67 sd
68 sd
69 sd
70 sd
71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc
[wj2440]# mknod /dev/*** c 252 0 //手動建立乙個字元裝置節點
[wj2440]# ls -l /dev/***
crw-r--r-- 1 root root 252, 0 jan 1 20:49 /dev/***
[wj2440]# ./first_test //有裝置節點後成功我們的應用程式執行了
first_drv_open
first_drv_write
[wj2440]#
本文參考: Linux裝置驅動之《字元裝置驅動》
linux裝置中最大的特點就是裝置操作猶如檔案操作一般,在應用層看來,硬體裝置只是乙個裝置檔案。應用程式可以像操作檔案一樣對硬體裝置進行操作,如open close read write 等。下面是乙個字元裝置驅動程式的簡單實現test.c 模組分析 1.初始化裝置驅動的結構體 struct fil...
Linux裝置驅動之字元裝置驅動
一 linux裝置的分類 linux系統將裝置分成三種基本型別,每個模組通常實現為其中某一類 字元模組 塊模組或網路模組。這三種型別有 字元裝置 字元裝置是個能夠像位元組流 類似檔案 一樣被訪問的裝置,由字元裝置驅動程式來實現這種特性。字元裝置可以通過檔案系統節點來訪問,比如 dev tty1等。這...
驅動程式概念介紹
學習目標 了解linux系統中驅動程式的概念 作用,為後續學習驅動程式編寫打下基礎!u boot的目的是啟動核心,核心的目的是啟動應用程式。應用程式中可能會涉及到讀寫檔案 點亮led 獲取按鍵值等操作,而對於寫應用程式的人來說不必去關心具體硬體如何操作,僅僅只呼叫open rend write等標準...