05 Linux字符驱动---静态注册

时间:2024-01-10 22:14:02

1. mycdev.c

 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/cdev.h>
 #include <linux/fs.h>

 #define MAJOR_NUM 250

 struct mycdev
 {
     struct cdev cdev;
 };

 int mycdev_open(struct inode *inode, struct file *file)
 {
     printk("Call mycdev_open()\n");
     ;
 }

 struct file_operations fops = {
     .owner = THIS_MODULE,
     .open = mycdev_open,
 };

 struct mycdev mycdev;

 int mycdev_init(void)
 {
     ;
     dev_t dev;

     dev = MKDEV(MAJOR_NUM, );
     ret = register_chrdev_region(dev, , "mycdev");
     )
     {
         printk("register_chrdev_region() error\n");
         goto err_register_chrdev_region;
     }

     cdev_init(&(mycdev.cdev), &fops);

     ret = cdev_add(&(mycdev.cdev), dev, );
     )
     {
         printk("cdev_add() error\n");
         goto err_cdev_add;
     }

     printk("mycdev_init()\n");
     ;

 err_cdev_add:
     unregister_chrdev_region(dev, );

 err_register_chrdev_region:
     return ret;
 }

 void mycdev_exit(void)
 {
     dev_t dev = mycdev.cdev.dev;

     cdev_del(&(mycdev.cdev));
     unregister_chrdev_region(dev, );

     printk("mycdev_exit()\n");
     return;
 }

 module_init(mycdev_init);
 module_exit(mycdev_exit);

 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("GNB");

2. Makefile

 KERNEL_DIR = /lib/modules/$(shell uname -r)/build
 PWD = $(shell pwd)

 ifneq ($(KERNELRELEASE),)

 obj-m := mycdev.o

 else

 .PHONY:default clean

 default:
     $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules

 clean:
     $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean

 endif

3. 应用层app

 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>

 int main(int argc, const char *argv[])
 {
     int fd;

     fd = open("/dev/mycdev",O_RDONLY);
     printf("fd = %d\n",fd);
     );

     ;
 }

4. 加载驱动

sudo insmod mycdev.ko

5. 创建设备节点,并指定权限

sudo mknod /dev/mycdev c 250 0

sudo chmod 666 /dev/mycdev

6. 测试字符设备

cat /dev/mycdev

echo "hello world" > /dev/mycdev