一、字符设备驱动函数接口
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);
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 }
3. Makefile
时间: 2024-10-01 07:08:42