首页 > 代码库 > 05 字符设备驱动

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 字符设备驱动