6_以module的方式注册设备

以模块的方式注册设备,这样的模块可自由加载和卸载

Posted by Jerry Chen on June 18, 2019

也就是module方式注册设备,module方式注册驱动。注意:函数和变量都用static修饰,只在当前文件中生效,避免重名带来的影响。

module注册设备

编写platform_device_hello.c,对应的Makefile只需改下编译输出命名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("jerry");

#define DEV_NAME "platform_hello"

static void hello_release(struct device *pdv){
	printk(KERN_EMERG "hello_release ok!\n");
};

static struct platform_device platform_dev_hello = {
	.name	= DEV_NAME,
	.id		= -1,
	.dev	= {
		.release = hello_release,
	},
};

static int hello_init(void){
	platform_device_register(&platform_dev_hello);
	return 0;
}
static void hello_exit(void){
	platform_device_unregister(&platform_dev_hello);
}

module_init(hello_init);
module_exit(hello_exit);

module注册驱动

编写platform_driver_hello.c,对应的Makefile只需改下编译输出命名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("jerry");

#define DRV_NAME "platform_hello"

static int hello_probe(struct platform_device *pdv){
	printk(KERN_EMERG "hello_probe ok!\n");
	
	printk(KERN_EMERG "pdv->name is %s\n",pdv->name);
	printk(KERN_EMERG "pdv->id is %d\n",pdv->id);
	
	pdv->dev.release(&pdv->dev); // only for test
	return 0;
}
static int hello_remove(struct platform_device *pdv){
	printk(KERN_EMERG "hello_remove ok!\n");
	
	return 0;
}

static void hello_shutdown(struct platform_device *pdv){
	printk(KERN_EMERG "hello_shutdown ok!\n");
}
static int hello_suspend(struct platform_device *pdv, pm_message_t state){
	printk(KERN_EMERG "hello_suspend ok!\n");
	return 0;
}
static int hello_resume(struct platform_device *pdv){
	printk(KERN_EMERG "hello_resume ok!\n");
	return 0;
}

static struct platform_driver platform_drv_hello = {
	.probe	= hello_probe,
	.remove	= hello_remove,
	.shutdown	= hello_shutdown,
	.suspend	= hello_suspend,
	.resume	= hello_resume,
	.driver	= {
		.name	= DRV_NAME,
		.owner	= THIS_MODULE,
	},
};

static int hello_init(void){
	platform_driver_register(&platform_drv_hello);
	return 0;
}
static void hello_exit(void){
	platform_driver_unregister(&platform_drv_hello);
}

module_init(hello_init);
module_exit(hello_exit);

先加载设备模块,再加载驱动模块可以正常匹配。结果和预期一致。

事实上,先加载驱动再加载设备模块也会调用一次驱动probe函数。