05 字符设备驱动

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了05 字符设备驱动相关的知识,希望对你有一定的参考价值。

一、字符设备驱动函数接口

1.初始化cdev结构体
void cdev_init(struct cdev * cdev, const struct file_operations * fops)
功能:初始化cdev结构体
参数:
@cdev cdev结构体
@fops 操作函数的结构体

2.申请设备号
int register_chrdev_region(dev_t from, unsigned count, const char * name);
参数:
@from 包含主设备号的数字
@count 设备号的个数
@name 设备的名字 (在cat /proc/devices看到它)
返回值:
成功返回0,失败返回负的错误码

3.添加字符设备
int cdev_add(struct cdev *p, dev_t dev, unsigned count);
参数:
@p cdev结构体
@dev 设备号(第一个设备号)
@count 次设备的个数
返回值:
成功返回0,失败返回负的错误码

二、例子

1. 字符设备驱动

技术分享
 1 #include <linux/module.h>
 2 #include <linux/init.h>
 3 #include <linux/cdev.h>
 4 #include <linux/fs.h>
 5 
 6 MODULE_LICENSE("GPL");
 7 
 8 #define MAJOR  250
 9 
10 struct mycdev 
11 {
12     int major;
13     int minor;
14     struct cdev cdev;
15 };
16 
17 //int (*open) (struct inode *, struct file *);
18 int mycdev_open(struct inode *inode,struct file *file)
19 {
20     printk("Call mycdev_open()\\n");
21 
22     return 0;
23 }
24 
25 //ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
26 //ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
27 //int (*release) (struct inode *, struct file *);
28 
29 struct mycdev cdev_device;
30 
31 struct file_operations fops = {
32     .owner =  THIS_MODULE,
33     .open  =  mycdev_open,
34 };
35 
36 
37 int mycdev_init(void)
38 {
39     int ret;
40     dev_t dev_num;
41     
42     //cdev_init(struct cdev * cdev, const struct file_operations * fops)
43     cdev_init(&cdev_device.cdev,&fops);
44 
45     
46     dev_num = MKDEV(MAJOR, 0);
47     
48     //register_chrdev_region(dev_t from, unsigned count, const char * name)
49     ret = register_chrdev_region(dev_num,1,"mycdev");
50     if(ret != 0){
51         printk("Fail to register chrdev region\\n");
52         goto err_register_chrdev_region;
53     }
54 
55     cdev_device.major = MAJOR;
56     cdev_device.minor = 0;
57     
58     //cdev_add(struct cdev * p, dev_t dev, unsigned count)
59     ret = cdev_add(&cdev_device.cdev,dev_num,1);
60     if(ret != 0){
61         printk("Fail to cdev_add\\n");
62         goto err_cdev_add;
63         
64     }
65     
66     return 0;
67     
68 err_cdev_add:
69     //unregister_chrdev_region(dev_t from, unsigned count)
70     unregister_chrdev_region(dev_num,1);
71 
72 err_register_chrdev_region:
73     return ret;
74 }
75 
76 
77 void mycdev_exit(void)
78 {
79     dev_t dev_num = MKDEV(MAJOR,0); 
80         
81     //cdev_del(struct cdev * p)
82     cdev_del(&cdev_device.cdev);
83     unregister_chrdev_region(dev_num,1);
84 
85     return ;
86 }
87 
88 
89 module_init(mycdev_init);
90 module_exit(mycdev_exit);
View Code

2. 应用层open驱动

技术分享
 1 #include <sys/types.h>
 2 #include <sys/stat.h>
 3 #include <fcntl.h>
 4 #include <stdio.h>
 5 #include <stdlib.h>
 6 
 7 int main(int argc, const char *argv[])
 8 {
 9     int fd;
10 
11     fd = open("/dev/mycdev",O_RDONLY);
12     printf("fd = %d\\n",fd);
13     while(1);
14 
15     return 0;
16 }
View Code

3. Makefile

 




















以上是关于05 字符设备驱动的主要内容,如果未能解决你的问题,请参考以下文章

将 JavaScript 字符串拆分为固定长度的片段

带有神秘附加字符的 Javascript Date getTime() 代码片段

2021-12-24:划分字母区间。 字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。 力扣763。某大厂面试

c_cpp 快速代码片段,用于在统计(阻止)/ dev / rdsk中的设备时验证fstat64和stat64的行为。

在 Rails 上为连接、限制、选择等(不是条件)的 SQL 片段安全地转义字符串

21个常用代码片段