ドライバ階層概念
15761 ワード
個人の駆動階層に対する理解を書いて、簡単に言えば駆動階層を駆動中のハードウェア操作のコードとソフトウェア処理のコードを2つの部分に分けて、ソフトウェア関連のコードは比較的に安定して、ハードウェア関連のコードはハードウェアの変動によって相応の調整を行う可能性があります.このような利点は、私たちのプログラミングで書いた関数が機能をモジュール化し、モジュール化するメリットのように、大規模な駆動を記述するのに便利であることです.ここでは言いません.
JZ 2440開発ボードの点灯ledの操作でまとめ、駆動はled_dev.c,led_drvの2つの部分、もう1つのテストプログラムled_test.c
led_dev:ハードウェアリソース
led_devはハードウェアデバイスに関連するコードであり、その機能はスケジューリング可能なハードウェアリソースを含み、報告し、以下のいくつかの項目を完了することである. platformを宣言デバイスタイプの構造体 この構造体にはname、id、resource等の内容 が含む. devとdrvは同じ.name(.nameはdevとdrvが同時に一致する) を含む
init関数上記構造体 を登録する. exit関数上記構造体 をアンインストールする.修飾入口、出口関数 led_drv:ハードウェア操作
led_drvは、ハードウェアの操作を処理するソフトウェア、すなわちソフトウェアに関連するコードであり、その階層とled_devは似ていますが、ハードウェア操作がいくつか増えた関数にすぎません. platformを宣言driverタイプの構造体 構造体にはprobe、remove関数、driver構造体 が含む. driver構造体にはdevと同名の.name が含まれる. probeは登録デバイスの関数 である. removeはデバイスをアンインストールする関数 である.
init関数上記構造体 を登録する. exit関数上記構造体 をアンインストールする.修飾入口、出口関数 led_test:テストプログラム
テストプログラムについてあまり説明しない
以下に、それぞれ3つのファイルのソースコードを添付します.
JZ 2440開発ボードの点灯ledの操作でまとめ、駆動はled_dev.c,led_drvの2つの部分、もう1つのテストプログラムled_test.c
led_dev:ハードウェアリソース
led_devはハードウェアデバイスに関連するコードであり、その機能はスケジューリング可能なハードウェアリソースを含み、報告し、以下のいくつかの項目を完了することである.
led_drvは、ハードウェアの操作を処理するソフトウェア、すなわちソフトウェアに関連するコードであり、その階層とled_devは似ていますが、ハードウェア操作がいくつか増えた関数にすぎません.
テストプログラムについてあまり説明しない
以下に、それぞれ3つのファイルのソースコードを添付します.
1 /**************************************
2 led_dev.c
3 **************************************/
4
5 #include <linux/module.h>
6 #include <linux/version.h>
7
8 #include <linux/init.h>
9
10 #include <linux/kernel.h>
11 #include <linux/types.h>
12 #include <linux/interrupt.h>
13 #include <linux/list.h>
14 #include <linux/timer.h>
15 #include <linux/init.h>
16 #include <linux/serial_core.h>
17 #include <linux/platform_device.h>
18
19
20 /* / / platform_device */
21
22 static struct resource led_resource[] = {
23 [0] = {
24 .start = 0x56000050,
25 .end = 0x56000050 + 8 - 1,
26 .flags = IORESOURCE_MEM,
27 },
28 [1] = {
29 .start = 5,
30 .end = 5,
31 .flags = IORESOURCE_IRQ,
32 }
33
34 };
35
36 static void led_release(struct device * dev)
37 {
38 }
39
40
41 static struct platform_device led_dev = {
42 .name = "myled",
43 .id = -1,
44 .num_resources = ARRAY_SIZE(led_resource),
45 .resource = led_resource,
46 .dev = {
47 .release = led_release,
48 },
49 };
50
51 static int led_dev_init(void)
52 {
53 platform_device_register(&led_dev);
54 return 0;
55 }
56
57 static void led_dev_exit(void)
58 {
59 platform_device_unregister(&led_dev);
60 }
61
62 module_init(led_dev_init);
63 module_exit(led_dev_exit);
64
65 MODULE_LICENSE("GPL");
1 /**************************************
2 led_drv.c
3 **************************************/
4
5
6 #include <linux/module.h>
7 #include <linux/version.h>
8
9 #include <linux/init.h>
10 #include <linux/fs.h>
11 #include <linux/interrupt.h>
12 #include <linux/irq.h>
13 #include <linux/sched.h>
14 #include <linux/pm.h>
15 #include <linux/sysctl.h>
16 #include <linux/proc_fs.h>
17 #include <linux/delay.h>
18 #include <linux/platform_device.h>
19 #include <linux/input.h>
20 #include <linux/irq.h>
21 #include <asm/uaccess.h>
22 #include <asm/io.h>
23
24 static int major;
25
26
27 static struct class *cls;
28 static volatile unsigned long *gpio_con;
29 static volatile unsigned long *gpio_dat;
30 static int pin;
31
32 static int led_open(struct inode *inode, struct file *file)
33 {
34 //printk("first_drv_open
");
35 /* */
36 *gpio_con &= ~(0x3<<(pin*2));
37 *gpio_con |= (0x1<<(pin*2));
38 return 0;
39 }
40
41 static ssize_t led_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
42 {
43 int val;
44
45 //printk("first_drv_write
");
46
47 copy_from_user(&val, buf, count); // copy_to_user();
48
49 if (val == 1)
50 {
51 //
52 *gpio_dat &= ~(1<<pin);
53 }
54 else
55 {
56 //
57 *gpio_dat |= (1<<pin);
58 }
59
60 return 0;
61 }
62
63
64 static struct file_operations led_fops = {
65 .owner = THIS_MODULE, /* , __this_module */
66 .open = led_open,
67 .write = led_write,
68 };
69
70 static int led_probe(struct platform_device *pdev)
71 {
72 struct resource *res;
73
74 /* platform_device ioremap */
75 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
76 gpio_con = ioremap(res->start, res->end - res->start + 1);
77 gpio_dat = gpio_con + 1;
78
79 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
80 pin = res->start;
81
82 /* */
83
84 printk("led_probe, found led
");
85
86 major = register_chrdev(0, "myled", &led_fops);
87
88 cls = class_create(THIS_MODULE, "myled");
89
90 class_device_create(cls, NULL, MKDEV(major, 0), NULL, "led"); /* /dev/led */
91
92 return 0;
93 }
94
95 static int led_remove(struct platform_device *pdev)
96 {
97 /* */
98 /* iounmap */
99 printk("led_remove, remove led
");
100
101 class_device_destroy(cls, MKDEV(major, 0));
102 class_destroy(cls);
103 unregister_chrdev(major, "myled");
104 iounmap(gpio_con);
105
106 return 0;
107 }
108
109 /* / / platform_driver */
110 struct platform_driver led_drv = {
111 .probe = led_probe,
112 .remove = led_remove,
113 .driver = {
114 .name = "myled",
115 }
116 };
117
118
119 static int led_drv_init(void)
120 {
121 platform_driver_register(&led_drv);
122 return 0;
123 }
124
125 static void led_drv_exit(void)
126 {
127 platform_driver_unregister(&led_drv);
128 }
129
130 module_init(led_drv_init);
131 module_exit(led_drv_exit);
132
133 MODULE_LICENSE("GPL");
1 /**************************************
2 led_test.c
3 **************************************/
4
5
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <stdio.h>
10
11 /* led_test on
12 * led_test off
13 */
14 int main(int argc, char **argv)
15 {
16 int fd;
17 int val = 1;
18 fd = open("/dev/led", O_RDWR);
19 if (fd < 0)
20 {
21 printf("can't open!
");
22 }
23 if (argc != 2)
24 {
25 printf("Usage :
");
26 printf("%s <on|off>
", argv[0]);
27 return 0;
28 }
29
30 if (strcmp(argv[1], "on") == 0)
31 {
32 val = 1;
33 }
34 else
35 {
36 val = 0;
37 }
38
39 write(fd, &val, 4);
40 return 0;
41 }