linux字符设备驱动开发入门

linux字符设备驱动开发入门

1.基本步骤

graph LR;
	a("申请设备号")-->b("注册设备号")-->c("设置设备对应的file_operations")-->d("加入到内核链表")
	ab("MKDEV(major,minor)")-->ac("register_chrdev_region()")-->ad("cdev_init()")-->ae("cdev_add()")

2.实例

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//驱动程序源码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#define BUFFER_SIZE;
struct mychar
{
dev_t devnum;
unsigned long curlen;
struct dev mydev;
char buffer[BUFFER_SIZE];
}mychardev;
//设备打开函数
static int mychar_open(struct inode *node,struct file *filp)
{
//获取结构体地址
filp->private_data = (void*)container_of(node->i_cdev,struct mychar,mydev);
return 0;
}
static int mychar_close(struct inode *node,struct file *filp)
{
return 0;
}
static long mychar_read(struct file *filp,char __user *buffer,long unsigned int count,long long int *pos)
{
return 0;
}
static long mychar_write(struct file *filp,const char __user *buffer,long unsigned int count,long long int *pos)
{
return 0;
}
static long mychar_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
{
return 0;
}
int __init my_init(void)
{
//申请设备号
mychardev.devnum = MKDEV(11,256);
//注册设备号
if(register_chrdev_region(mychardev.devnum,1,"mychar")!=0)
{
if(alloc_chrdev_region(&mychardev.devnum,256,1,"mychar")!=0)
{
printk("register devnum error!\n");
return 0;
}
}
struct file_operations fops=
{
.owner = THIS_MODULE,
.open = mychar_open,
.release = mychar_close,
.read = mychar_read,
.write = mychar_write,
.unlocked_ioctl = mychar_ioctl,
}
//设置对应的文件操作函数
cdev_init(&mychardev.mydev,&fops);
//加入到内核链表
cdev_add(&mychardev.mydev,mychardev.devnum,1);
return 0;
}
void __exit my_exit(void)
{
cdev_del(&mychardev.mydev);
unregister_chrdev_region(mychardev.devnum,1);
return;
}

module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("404NotFound");
MODULE_DESCRIPTION("just a char devices driver!");
1
2
3
4
5
6
7
8
//项目的Makefile
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD ?= $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm *.o *.mod *.symvers
obj-m += main.o

linux字符设备驱动开发入门
https://dreamaccount.github.io/2022/06/24/linux字符设备驱动开发入门/
作者
404NotFound
发布于
2022年6月24日
许可协议