驅動程式 - Linux Device Driver (LDD) - 使用範例 - C/C++ (PocketBeagle) - Char Device - Class Device



除了使用mknod工具建立Symbloic Link之外,字元驅動程式也可以自行建立這個Symbolic Link

建立步驟:

1. alloc_chrdev_region()
2. class_create()
3. device_create()
4. cdev_init()
5. cdev_add()

釋放步驟:

1. device_destroy()
2. cdev_del()
3. class_destroy()
4. unregister_chrdev_region()

main.c

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

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Steward Fu");
MODULE_DESCRIPTION("Linux Driver");

static int base = 0;
static struct cdev mycdev;
static struct class *myclass = NULL;

static int myopen(struct inode *inode, struct file *file)
{
    printk("%s\n", __func__);
    return 0;
}

static int myclose(struct inode *inode, struct file *file)
{
    printk("%s\n", __func__);
    return 0;
}

static const struct file_operations myfops = {
    .owner = THIS_MODULE,
    .open = myopen,
    .release = myclose,
};

int ldd_init(void)
{
    alloc_chrdev_region(&base, 0, 1, "myfile");
    myclass = class_create(THIS_MODULE, "myfile");      /* /sys/class/myfile */
    device_create(myclass, NULL, base, NULL, "myfile"); /* /dev/myfile       */
    cdev_init(&mycdev, &myfops);
    cdev_add(&mycdev, base, 1);
    return 0;
}
 
void ldd_exit(void)
{
    device_destroy(myclass, base);
    cdev_del(&mycdev);
    class_destroy(myclass);
    unregister_chrdev_region(base, 1);
}
 
module_init(ldd_init);
module_exit(ldd_exit);

ldd_init: 建立字元驅動程式
myopen: 對應User Application的open()
myclose: 對應User Application的close()
ldd_exit: 刪除字元驅動程式

安裝驅動

# insmod /boot/main.ko 

由於使用class device,因此,Symbolic已經建立完成,不再需要使用mknod建立

# ls -al /dev/myfile
    crw-r--r--    1 root     root      243,   0 Jan  1 00:00 /dev/myfile

開啟裝置

# echo "" > /dev/myfile
    myopen
    sh: write error: Invalid argument myclose