嵌入式学习(二)之字符设备

92 阅读1分钟

设备号

image.png

设备号的类型

image.png

image.png

设备号的分配

image.png

image.png

image.png

image.png

申请设备字符号

image.png

注册设备字符号

  1. cdev 结构体

image.png

  1. cdev_init

image.png

  1. cdev_add

image.png


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

dev_t dev_num;
struct cdev cdev_test;
struct file_operations ops = {
    .owner = THIS_MODULE
};

static int dev_init(void)
{
    int ret = alloc_chrdev_region(&dev_num, 0, 1, "morning-dev");
    if (ret < 0)
        printk("alloc_chrdev_region is error");
    cdev_test.owner = THIS_MODULE;
    cdev_init(&cdev_test, &ops);
    cdev_add(&cdev_test, dev_num, 1);
    printk("hello init");
    return 0;
}

static void dev_exit(void)
{
    unregister_chrdev_region(dev_num, 1);
    cdev_del(&cdev_test);
    printk("hello bye");
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("MCC");
MODULE_VERSION("V1.0");

file_operations 结构体

image.png

image.png

image.png

image.png

设备节点

image.png

image.png

手动创建

image.png

image.png

自动创建设备节点

image.png

image.png

image.png

image.png

image.png

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

dev_t dev_num;
struct cdev cdev_test;
struct class *class;
struct device *device;

static int cdev_test_open(struct inode *, struct file *)
{
    printk("cdev_test_open ");
    return 0;
}

struct file_operations ops = {
    .owner = THIS_MODULE,
    .open = cdev_test_open};

static int dev_init(void)
{
    int ret = alloc_chrdev_region(&dev_num, 0, 1, "morning-dev");
    if (ret < 0)
        printk("alloc_chrdev_region is error");
    unsigned int maj = MAJOR(dev_num);
    unsigned int min = MINOR(dev_num);
    printk("maj=%d\n", maj);
    printk("min=%d\n", min);
    cdev_test.owner = THIS_MODULE;
    cdev_init(&cdev_test, &ops);
    cdev_add(&cdev_test, dev_num, 1);

    class = class_create(THIS_MODULE, "morning-device-class");
    device = device_create(class, NULL, dev_num, NULL, "morning-device");
    printk("hello init");
    return 0;
}

static void dev_exit(void)
{
    unregister_chrdev_region(dev_num, 1);
    cdev_del(&cdev_test);
    device_destroy(class, dev_num);
    class_destroy(class);
    printk("hello bye");
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("MCC");
MODULE_VERSION("V1.0");

image.png

内核空间

  1. 内核空间和用户空间

image.png

  1. 如何从用户空间进入内核空间

image.png

  1. 数据交换

image.png

image.png