Dynamic allocation of device numbers for Linux driver development (refer to the kernel driver source code - standard writing method)

First, write the driver file

#include <linux/init.h> // A header file that all modules must include 
#include <linux/module.h> // Some macro definitions, such as KERN_INFO here
#include <linux/fs.h>
#include < linux/device.h>
#include <linux/cdev.h>

#include "hello_world.h"

#define VICHIP_DEV "vichip"

static struct class *driver_class; // 定义类
static dev_t vichip_device_no; // 定义设备号

// 定义结构体
struct vichip_control {
struct cdev cdev;
};

static struct vichip_control vichip;

static int vichip_open(struct inode *inode, struct file *file)
{
int ret = 0; printk(KERN_INFO "----vichip_open----\n"); return ret; } static int vichip_release(struct inode *inode, struct file *file) { int ret = 0; printk(KERN_INFO "----vichip_release----\n"); return ret; } static const struct file_operations vichip_fops = { .owner = THIS_MODULE, .open = vichip_open,


















.release = vichip_release
};

static int __init hello_init(void)
{
int rc;
struct device *class_dev; rc = alloc_chrdev_region(&vichip_device_no, 0, 1, VICHIP_DEV); // dynamically allocate device number if (rc < 0) { pr_err( "alloc_chrdev_region failed %d\n", rc); return rc; } driver_class = class_create(THIS_MODULE, VICHIP_DEV); // create class if (IS_ERR(driver_class)) { rc = -ENOMEM; pr_err("class_create failed %d\ n", rc); goto exit_unreg_chrdev_region; } class_dev = device_create(driver_class, NULL, vichip_device_no, NULL, VICHIP_DEV); // create a device (which class of device this device belongs to) if (IS_ERR(class_dev)) {
















pr_err("class_device_create failed %d\n", rc);
rc = -ENOMEM;
goto exit_destroy_class;
} cdev_init(&vichip.cdev, &vichip_fops); // initialize character device vichip.cdev.owner = THIS_MODULE; rc = cdev_add(&vichip .cdev, MKDEV(MAJOR(vichip_device_no), 0), 1); // add a character device to the kernel  if (rc < 0) { pr_err("cdev_add failed %d\n", rc); cdev_del(&vichip. cdev); // remove character device from kernel goto exit_destroy_device; }     printk(KERN_INFO "----hello_init rc = [%d]----\n", rc); return rc; exit_destroy_device: device_destroy( driver_class, vichip_device_no); // Destroy the device exit_destroy_class: class_destroy (driver_class); // Destroy the class


















exit_unreg_chrdev_region:
unregister_chrdev_region(vichip_device_no, 1); // unregister the dynamically allocated device number
return rc;
}

static void __exit hello_exit(void)
{
cdev_del(&vichip.cdev);
device_destroy(driver_class, vichip_device_no); class_destroy
(driver_class);
unregister_chrdev_region( vichip_device_no, 1);     printk(KERN_INFO "----hello_exit----\n"); } module_init(hello_init);// The macro is used to specify the entry, and the loading function in the module will be called when the module is loaded   module_exit(hello_exit ); // the module's license  MODULE_LICENSE("GPL"); // the module's author MODULE_AUTHOR(DRIVER_AUTHOR); // the module's description












MODULE_DESCRIPTION(DRIVER_DESC);

Second, the header file hello_world.h

#define DRIVER_AUTHOR "[email protected]"

#define DRIVER_DESC   "A sample driver" 

3. Write Makefile

ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:                               
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:                                             
        $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
else
    obj-m := hello_world.o

endif

Fourth, compile the module 

make all

Five, install the kernel module

insmod hello_world.ko

Six, write the test file test.c

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

#define DEV_NAME "/dev/vichip"

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

        int fd = -1;

        printf("------------start---------------\n");

        fd = open(DEV_NAME, O_RDWR);
        if(fd < 0)
        {
                perror("open file error:");
                return -1;
        }

        close(fd);


        printf("------------end---------------\n");

        return 0;

}

Seven, compile the test file 

gcc test.c -o test

Eight, test driver

./test

9. Test results

1. View the created class

Result: There is a vichip directory in the /sys/class directory.

2. View the created device

Result: there are vichip device files in the /dev directory

crw-------   1 root root    243,   0 May  9 16:42 vichip

or cat /proc/devices

243 vichip

3. View the output message

dmesg

----hello_init rc = [0]----

4. Uninstall installed kernel modules

rmmod hello_world

Do the following:

cdev_del(&vichip.cdev);
device_destroy(driver_class, vichip_device_no);
class_destroy(driver_class);
unregister_chrdev_region(vichip_device_no, 1);

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326685063&siteId=291194637