代码
#include <linux/module.h>#include <linux/fs.h>#include <linux/uaccess.h>#include <linux/init.h>#include <linux/cdev.h>#define DEMO_NAME "my_demo_dev"static dev_t dev;static struct cdev *demo_cdev;static signed count = 1;static int demodrv_open(struct inode *inode, struct file *file){int major = MAJOR(inode->i_rdev);int minor = MINOR(inode->i_rdev);printk("%s: major=%d, minor=%d\n", __func__, major, minor);return 0;}static int demodrv_release(struct inode *inode, struct file *file){return 0;}static ssize_tdemodrv_read(struct file *file, char __user *buf, size_t lbuf, loff_t *ppos){printk("%s enter\n", __func__);return 0;}static ssize_tdemodrv_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos){printk("%s enter\n", __func__);return 0;}static const struct file_operations demodrv_fops = {.owner = THIS_MODULE,.open = demodrv_open,.release = demodrv_release,.read = demodrv_read,.write = demodrv_write};static int __init simple_char_init(void){int ret;ret = alloc_chrdev_region(&dev, 0, count, DEMO_NAME);if (ret) {printk("failed to allocate char device region");return ret;}demo_cdev = cdev_alloc();if (!demo_cdev) {printk("cdev_alloc failed\n");goto unregister_chrdev;}cdev_init(demo_cdev, &demodrv_fops);ret = cdev_add(demo_cdev, dev, count);if (ret) {printk("cdev_add failed\n");goto cdev_fail;}printk("succeeded register char device: %s\n", DEMO_NAME);printk("Major number = %d, minor number = %d\n",MAJOR(dev), MINOR(dev));return 0;cdev_fail:cdev_del(demo_cdev);unregister_chrdev:unregister_chrdev_region(dev, count);return ret;}static void __exit simple_char_exit(void){printk("removing device\n");if (demo_cdev)cdev_del(demo_cdev);unregister_chrdev_region(dev, count);}module_init(simple_char_init);module_exit(simple_char_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("zhouchengzhu <1073355312@qq.com>");MODULE_DESCRIPTION("A simple hello world driver");MODULE_VERSION("2:1.0");
使用
[root@imx6ull:~/NFS]# insmod simple_char.koMajor number = 245, minor number = 0[root@imx6ull:~/NFS]# cat /proc/devices | grep my_demo_dev245 my_demo_dev# 然后我们查看/dev/下是否存在 主设备号 245 的设备[root@imx6ull:~/NFS]# ls -al /dev | grep 245# 发现并没对应主设备号的设备# 那么我们自动手动创建两个# 设备名称为 demo_drv 字符设备 主设备号 245 次设备号 0[root@imx6ull:~/NFS]# mknod /dev/demo_drv c 245 0[root@imx6ull:~/NFS]# mknod /dev/demo_drv1 c 245 1
上面我们创建了设备,现在可以使用设备了。使用下面的测试用例测试
# 输出了主次设备号[root@imx6ull:~/NFS]# ./testdemodrv_open: major=245, minor=0
测试用例
#include <stdio.h>#include <fcntl.h>#include <unistd.h># 前面我们创建的设备名称#define DEMO_DEV_NAME "/dev/demo_drv"int main(){char buffer[64];int fd;fd = open(DEMO_DEV_NAME, O_RDONLY);if (fd < 0) {printf("open device %s failded\n", DEMO_DEV_NAME);return -1;}read(fd, buffer, 64);close(fd);return 0;}
使用函数简介
fs/char_dev.c:214int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,const char *name)void unregister_chrdev_region(dev_t from, unsigned count)struct cdev *cdev_alloc(void)void cdev_init(struct cdev *cdev, const struct file_operations *fops)int cdev_add(struct cdev *p, dev_t dev, unsigned count)void cdev_del(struct cdev *p)
下一篇文章我们将会来分析一下使用到的这些函数。
