首页 > 代码库 > 06 字符设备---静态注册
06 字符设备---静态注册
一、字符设备结构体
1 /* #include <linux/cdev.h> */ 2 struct cdev { 3 struct kobject kobj; 4 struct module *owner; 5 const struct file_operations *ops; 6 struct list_head list; 7 dev_t dev; 8 unsigned int count; 9 }; 10 11 /* #include <linux/fs.h> */ 12 struct file_operations { 13 struct module *owner; 14 loff_t (*llseek) (struct file *, loff_t, int); 15 ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); 16 ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); 17 ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); 18 ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); 19 ssize_t (*read_iter) (struct kiocb *, struct iov_iter *); 20 ssize_t (*write_iter) (struct kiocb *, struct iov_iter *); 21 int (*iterate) (struct file *, struct dir_context *); 22 unsigned int (*poll) (struct file *, struct poll_table_struct *); 23 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); 24 long (*compat_ioctl) (struct file *, unsigned int, unsigned long); 25 int (*mmap) (struct file *, struct vm_area_struct *); 26 int (*open) (struct inode *, struct file *); 27 int (*flush) (struct file *, fl_owner_t id); 28 int (*release) (struct inode *, struct file *); 29 int (*fsync) (struct file *, loff_t, loff_t, int datasync); 30 int (*aio_fsync) (struct kiocb *, int datasync); 31 int (*fasync) (int, struct file *, int); 32 int (*lock) (struct file *, int, struct file_lock *); 33 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); 34 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); 35 int (*check_flags)(int); 36 int (*flock) (struct file *, int, struct file_lock *); 37 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); 38 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); 39 int (*setlease)(struct file *, long, struct file_lock **, void **); 40 long (*fallocate)(struct file *file, int mode, loff_t offset, loff_t len); 41 int (*show_fdinfo)(struct seq_file *m, struct file *f); 42 };
二、字符设备驱动流程
xxx_init():
1. 分配一个struct cdev结构体,静态或者动态
2. 注册设备号
3. 初始化struct cdev
4. 添加字符设备到操作系统中
xxx_exit():
1. 删除字符设备
2. 注销设备号
三、例子
1. 字符设备驱动
1 #include <linux/init.h> 2 #include <linux/module.h> 3 #include <linux/cdev.h> 4 #include <linux/fs.h> 5 6 #define MAJOR_NUM 233 7 8 // 定义结构体类型 9 struct char_device 10 { 11 struct cdev cdev; 12 }; 13 14 // 定义字符设备对象 15 struct char_device char_device; 16 17 int char_device_open(struct inode *inode, struct file *file) 18 { 19 printk("char_device_open\n"); 20 return 0; 21 } 22 23 int char_device_release(struct inode *inode, struct file *file) 24 { 25 printk("char_device_release\n"); 26 return 0; 27 } 28 29 ssize_t char_device_read(struct file *file, char __user *ubuf, size_t size, loff_t *offset) 30 { 31 printk("char_device_read\n"); 32 return 0; 33 } 34 35 ssize_t char_device_write(struct file *file, const char __user *ubuf, size_t size, loff_t *offset) 36 { 37 printk("char_device_write\n"); 38 return size; 39 } 40 41 struct file_operations fops = { 42 .owner = THIS_MODULE, 43 .open = char_device_open, 44 .release = char_device_release, 45 .read = char_device_read, 46 .write = char_device_write, 47 }; 48 49 static int char_device_init(void) 50 { 51 int ret = 0; 52 dev_t dev_num = 0; 53 54 // 设备号 55 dev_num = MKDEV(MAJOR_NUM, 0); 56 57 // 注册设备号 58 ret = register_chrdev_region(dev_num, 1, "char_device"); 59 if (ret != 0) 60 { 61 printk("register_chrdev_region error\n"); 62 goto err_register_chrdev_region; 63 } 64 65 // 初始化struct cdev 66 cdev_init(&(char_device.cdev), &fops); 67 68 // 添加字符设备 69 ret = cdev_add(&(char_device.cdev), dev_num, 1); 70 if (ret != 0) 71 { 72 printk("cdev_add error\n"); 73 goto err_cdev_add; 74 } 75 76 printk("char_device_init\n"); 77 return 0; 78 79 err_cdev_add: 80 // 注销设备号 81 unregister_chrdev_region(dev_num, 1); 82 83 err_register_chrdev_region: 84 return ret; 85 } 86 87 static void char_device_exit(void) 88 { 89 dev_t dev_num = MKDEV(MAJOR_NUM, 0); 90 91 // 删除字符设备 92 cdev_del(&(char_device.cdev)); 93 94 // 注销设备号 95 unregister_chrdev_region(dev_num, 1); 96 97 printk("char_device_exit\n"); 98 return; 99 } 100 101 module_init(char_device_init); 102 module_exit(char_device_exit); 103 104 MODULE_LICENSE("GPL"); 105 MODULE_AUTHOR("GNB");
2. Makefile
1 KERNEL_DIR = /lib/modules/$(shell uname -r)/build 2 PWD = $(shell pwd) 3 4 ifneq ($(KERNELRELEASE),) 5 6 obj-m := char_device.o 7 8 else 9 10 .PHONY:default clean 11 12 default: 13 $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules 14 15 clean: 16 $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean 17 18 endif
四、测试
(1)加载模块
sudo insmod mydev.ko
(2)创建设备节点并且指定权限
sudo mknod /dev/char_device c 233 0
sudo chmod 666 /dev/char_device
(3)测试字符设备
cat /dev/char_device 【读设备】
echo "test" > /dev/char_device 【写设备】
06 字符设备---静态注册
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。