2050226 IMX 277バス設備駆動モデルプログラミングの駆動編

33910 ワード

2050226 IMX 277バス設備駆動モデルプログラミングの駆動編
2015-02-26 11:42李海縁
前の私達はすでにバスと設備のドライバを実現しました.これから私達の任務は駆動を実現します.
住所:http://www.cnblogs.com/lihaiyan/p/4301079.html
http://www.cnblogs.com/lihaiyan/p/4301072.html
ドライバを実現する前に、二つの問題を考えます.
一、問題分析
1.ドライバはいつバスで処理できる設備を探しますか?
driver_register(&mymymudiver)は、ドライバ登録時にバスの中で処理できるデバイスを探します.
2.なぜこの駆動は相応の設備を処理できるのですか?
バスはこのドライバが対応するデバイスを処理できるかどうかを判断します.バスの中にあります.match=my_Matchは,ドライバがバスの上にデバイスを見つけたときに,このドライバが処理デバイスに対応できるかどうかを判定するために使用されるもので,デバイスのdev->bus_を判断するのが原則である.IDとドライバのdriver->nameが等しいかどうかは、このドライバがこのデバイスを処理できることを示しています.    この時はドライバがデバイスを見つけたと説明します.次にドライバはprobeという関数を呼び出します.
 
バスをロードした後、先にドライバをロードしてもいいし、先にドライバをローディングしたら、デバイスを登録する時に、バスの上でドライバを探します.先にデバイスをローディングしたら、ドライバを登録する時に、ドライバはバスの中で該当のデバイスがあるかどうかを探します.
二、プログラム分析
1.バスを含む
前のデバイスプログラムと同じように、先にバスを含みます.

2.駆動構造体を定義する
20150226 IMX257 总线设备驱动模型编程之驱动篇_第1张图片
structのメンバーに注意してください.nameは、ドライバとデバイスが合っているかどうかを調べるためにこの名前を見ます.
my_probeとmuremoveとは、ドライバとデバイスが関連している場合、または関連していない場合にそれぞれ呼び出される関数です.
 
3.属性ファイルを定義する構造体
20150226 IMX257 总线设备驱动模型编程之驱动篇_第2张图片
static DRIVER_についてATTR(drv、SuIRUGO、mydriverGaushow、NULL);このようなマクロは、ここではもうナンセンスではなく、linuxのソースコードまたは前のbus編の解説を見ることができます.
 
4.init関数にドライバを登録してプロパティファイルを作成する
また前と同じです.もう無駄をしません.
20150226 IMX257 总线设备驱动模型编程之驱动篇_第3张图片
 
5.exit関数からドライバを削除する
20150226 IMX257 总线设备驱动模型编程之驱动篇_第4张图片
 
三、コンパイルテスト
コンパイル、mybus.ko mydev.o mydrv.koの生成に成功しました.
20150226 IMX257 总线设备驱动模型编程之驱动篇_第5张图片
読み込み
プログラムはまずドライバをロードしてから、デバイスローディング順序mybus.ko mydrv.ko mydev.koをロードします.
設備をロードすると、駆動中のmy_をプリントアウトします.probeのコード:ドライバがデバイスを見つけたと教えてください.
20150226 IMX257 总线设备驱动模型编程之驱动篇_第6张图片
除去すると、駆動中のmy_がプリントアウトされています.remove関数のコードDriver found device unpluged!図のように:
同じように、mybusはmydevとmydrvの二つを使っています.
20150226 IMX257 总线设备驱动模型编程之驱动篇_第7张图片
 
次に案二を試してみます.結果はどうなりますか?
プログラム2は先に設備をロードしてから、駆動ローディング順序mybus.ko mydev.ko mydrv.koをロードする.
結果は同じです.駆動をロードすると、駆動中のmy_がプリントアウトされます.probeのコード:ドライバがデバイスを見つけたと教えてください.
ここでは私たちの前の問題2の中の答えをさらに確認しました.
20150226 IMX257 总线设备驱动模型编程之驱动篇_第8张图片
 
次は私達が入る/sys/bus/my_bus/drivers/my_dev下にどんなファイルがあるか見てください.
20150226 IMX257 总线设备驱动模型编程之驱动篇_第9张图片
 
mybus.cドライバを添付します.

 1 #include <linux/device.h>
 2 #include <linux/module.h>
 3 #include <linux/kernel.h>
 4 #include <linux/init.h>
 5 #include <linux/string.h>
 6 
 7 
 8 static char *Version = "$LoverXueEr : 1.0 $";
 9 
10 //          ,dev->bus_id   driver->name   
11 static int my_match(struct device *dev ,struct device_driver *driver){
12     return !strncmp(dev_name(dev),driver->name,strlen(driver->name));
13 }
14 
15 static void my_bus_release(struct device *dev){
16     printk("<0>my bus release
"); 17 } 18 19 // dev_set_name(&dev,"name"); 20 struct device my_bus = { 21 .init_name = "my_bus0", 22 .release = my_bus_release, 23 }; 24 25 struct bus_type my_bus_type = { 26 .name = "my_bus", 27 .match = my_match, 28 }; 29 EXPORT_SYMBOL(my_bus); // 30 EXPORT_SYMBOL(my_bus_type); 31 32 // 33 static ssize_t show_bus_version(struct bus_type *bus,char *buf){ 34 return snprintf(buf,PAGE_SIZE,"%s
",Version); 35 } 36 37 // bus_attr_version 38 static BUS_ATTR(version,S_IRUGO, show_bus_version, NULL); 39 40 static int __init my_bus_init(void){ 41 int ret; 42 /* */ 43 ret = bus_register(&my_bus_type); 44 if(ret) 45 return ret; 46 /* */ 47 if(bus_create_file(&my_bus_type, &bus_attr_version)) 48 printk("<0>Fail to create version attribute!
"); 49 50 /* */ 51 ret = device_register(&my_bus); 52 if(ret) 53 printk("<0>Fail to register device: my_bus"); 54 return ret; 55 } 56 57 static void my_bus_exit(void){ 58 bus_unregister(&my_bus_type); 59 device_unregister(&my_bus); 60 } 61 62 module_init(my_bus_init); 63 module_exit(my_bus_exit); 64 65 66 MODULE_AUTHOR("Lover "); 67 MODULE_LICENSE("GPL");
View Code
 
mydev.cドライバを添付します.

 1 #include <linux/device.h>
 2 #include <linux/module.h>
 3 #include <linux/kernel.h>
 4 #include <linux/init.h>
 5 #include <linux/string.h>
 6 
 7 //    
 8 extern struct device my_bus;
 9 extern struct bus_type my_bus_type;
10 
11 static void my_dev_release(struct device *dev){
12     printk("<0>my_dev release !
"); 13 } 14 15 // dev_set_name(&dev,"name"); 16 struct device my_dev = { 17 .bus = &my_bus_type, 18 .parent = &my_bus, // my_bus 19 .release = my_dev_release, 20 }; 21 22 ssize_t mydev_show(struct device *dev,struct device_attribute *attr,char *buf){ 23 return sprintf(buf, "%s
", "This is my device"); 24 } 25 26 // bus_attr_version 27 static DEVICE_ATTR(dev,S_IRUGO,mydev_show,NULL); 28 29 static int __init my_dev_init(void){ 30 int ret = 0; 31 32 /* */ 33 dev_set_name(&my_dev,"my_dev"); 34 35 /* */ 36 ret = device_register(&my_dev); 37 if(ret) 38 printk("<0>Fail to register device: my_dev"); 39 /* */ 40 if(device_create_file(&my_dev, &dev_attr_dev)) 41 printk("<0>Fail to create device file: my_dev"); 42 43 return ret; 44 } 45 46 static void my_dev_exit(void){ 47 device_remove_file(&my_dev, &dev_attr_dev); 48 device_unregister(&my_dev); 49 } 50 51 module_init(my_dev_init); 52 module_exit(my_dev_exit); 53 54 55 MODULE_AUTHOR("Lover "); 56 MODULE_LICENSE("GPL");
View Code
 
mydrv.cドライバを添付します.

 1 #include <linux/device.h>
 2 #include <linux/module.h>
 3 #include <linux/kernel.h>
 4 #include <linux/init.h>
 5 #include <linux/string.h>
 6 
 7 //    
 8 extern struct device my_bus;
 9 extern struct bus_type my_bus_type;
10 
11 static int my_probe(struct device *dev){
12     printk("<0>Driver found device which my driver can handle !
"); 13 return 0; 14 } 15 16 static int my_remove(struct device *dev){ 17 printk("<0>Driver found device unpluged !
"); 18 return 0; 19 } 20 // 21 struct device_driver my_driver = { 22 .name = "my_dev", // 23 .bus = &my_bus_type, 24 .probe = my_probe, 25 .remove = my_remove, 26 }; 27 28 ssize_t mydriver_show(struct device_driver *driver,char *buf){ 29 return sprintf(buf, "%s
", "This is my driver"); 30 } 31 32 // driver_attr_drv 33 static DRIVER_ATTR(drv,S_IRUGO,mydriver_show,NULL); 34 35 static int __init my_driver_init(void){ 36 int ret = 0; 37 38 /* */ 39 ret = driver_register(&my_driver); 40 if(ret) 41 printk("<0>Fail to register driver: my_driver"); 42 /* */ 43 if(driver_create_file(&my_driver, &driver_attr_drv)) 44 printk("<0>Fail to create driver file: my_drv"); 45 46 return ret; 47 } 48 49 static void my_driver_exit(void){ 50 driver_remove_file(&my_driver, &driver_attr_drv); 51 driver_unregister(&my_driver); 52 } 53 54 module_init(my_driver_init); 55 module_exit(my_driver_exit); 56 57 58 MODULE_AUTHOR("Lover "); 59 MODULE_LICENSE("GPL");
View Code
 
makefileのプログラムを添付します.

 1 ifeq ($(KERNELRELEASE),)
 2     KERNELDIR ?= /home/study/system/linux-2.6.31
 3     PWD := $(shell pwd)
 4 modules:
 5     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
 6 modules_install:
 7     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
 8 clean:
 9     rm -rf *.o *~ core .depend  *.cmd *.ko *.mod.c .tmp_versions *.markers *.order *.symvers
10 
11 else
12     obj-m := mybus.o mydev.o mydrv.o
13 endif
View Code
 
 
はい、これで私達のバス-設備-駆動モデルはもう実現しました.でも、もう分かりました.ここでまた無駄話をします.多くの原理知識は味気ないですが、やはり見たいです.プログラムを書くだけではだめです.どうして分かりますか?
 
私も勉强の段阶にあります.これらは全部私の简単な経験です.皆さんの早い入门を助けることができます.残りはまだです.入門すると比較的簡単になります.
多くの人がlinuxドライバを学ぶのは難しいと言っていますが、それは未知への恐怖からです.簡単に言えば、いくつかの構造体、アルゴリズムとAPIの使用です.
任重くして道が遠いです.頑張ってください.
 
次に私たちの任務はプラットフォームの設備のドライバのpltformの学習を実現することです.お楽しみに.