linux 驱动——杂项设备驱动

杂项设备驱动

在 linux 中,将无法归类的设备定义为杂项设备。
相对于字符设备来说,杂项设备的主设备号固定为 10,而字符设备不管是动态分配还是静态分配设备号,都会消耗一个主设备号,比较浪费主设备号。
杂项设备会自己调用 class_create()device_create() 来自动创建设备节点。所以可以将杂项设备看成是字符设备的一种。但是比平时写的字符设备降低了难度并节约了主设备号。

杂项设备的次设备号 minor 一般使用宏 MISC_DYNAMIC_MINOR,表示自动分配次设备号。杂项设备主要依赖次设备号来管理不同的杂项设备。

杂项设备的头文件为 #include <linux/miscdevice.h>

数据类型

struct miscdevice  {
   
	int minor;
	const char *name;
	const struct file_operations *fops;
	struct list_head list;
	struct device *parent;
	struct device *this_device;
	const struct attribute_group **groups;
	const char *nodename;
	umode_t mode;
};

API

int misc_register(struct miscdevice *misc);
void misc_deregister(struct miscdevice *misc);

驱动程序

#include <linux/device/class.h>
#include <linux/export.h>
#include <linux/uaccess.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>

#define CHRDEVBASE_NAME "misc_test1" /* 设备名 */

static char write_buf[100];
static char read_buf[100];

static char *string_test = "kernel data this tyustli test";

static int miscdev_open(struct inode *inode, struct file *file)
{
   
    printk("k: miscdev open\r\n");

    return 0;
}

static ssize_t miscdev_read(struct file *file, char __user *buf, size_t count,
                            loff_t *ppos)
{
   
    unsigned long ret = 0;

    printk("k: miscdev read\r\n");
    memcpy(read_buf, string_test, strlen(string_test));

    ret = copy_to_user(buf, read_buf, count);
    if (ret == 0) {
   
        printk("k: read data success\r\n");
    } else {
   
        printk("k: read data failed ret = %ld\r\n", ret);
    }

    return ret;
}

static ssize_t miscdev_write(struct file *file, const char __user *buf,
                             size_t count, loff_t *ppos)
{
   
    unsigned long ret = 0;

    printk("k: miscdev write\r\n");

    ret = copy_from_user(write_buf, buf, count);
    if (ret == 0) {
   
        printk("k: write data success write data is: %s\r\n", write_buf);
    } else {
   
        printk("k: write data failed ret = %ld\r\n", ret);
    }

    return count;
}

static int miscdev_release(struct inode *inode, struct file *file)
{
   
    printk("k: miscdev release\r\n");

    return 0;
}

static struct file_operations miscdev_fops = {
   
    .owner = THIS_MODULE,
    .open = miscdev_open,
    .read = miscdev_read,
    .write = miscdev_write,
    .release = miscdev_release,
};

static struct miscdevice miscdevice_dev = {
   
    .minor = MISC_DYNAMIC_MINOR,
    .name = CHRDEVBASE_NAME,
    .fops = &miscdev_fops,
};

static int __init miscdev_init(void)
{
   
    int err = 0;

    err = misc_register(&miscdevice_dev);
    if (err < 0) {
   
        printk("k: misc register err = %d\r\n", err);
        goto err_misc;
    }

    printk("k: misc module init!\r\n");

err_misc:
    return err;
}

static void __exit miscdev_exit(void)
{
   
    misc_deregister(&miscdevice_dev);

    printk("k: misc module exit!\r\n");
}

module_init(miscdev_init);
module_exit(miscdev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("tyustli");
MODULE_INFO(intree, "Y"); /* loading out-of-tree module taints kernel */

应用程序

#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"

static char usrdata[] = {
    "user data!" };

int main(int argc, char *argv[])
{
   
    int fd, retvalue;
    char *filename;
    char readbuf[100], writebuf[100];

    if (argc != 3) {
   
        printf("u: error Usage!\r\n");
        return -1;
    }

    filename = argv[1];

    /* 打开驱动文件 */
    fd = open(filename, O_RDWR);
    if (fd < 0) {
   
        printf("u: can't open file %s\r\n", filename);
        return -1;
    }

    /* 从驱动文件读取数据 */
    if (atoi(argv[2]) == 1) {
   
        retvalue = read(fd, readbuf, 50);
        if (retvalue < 0) {
   
            printf("u: read file %s failed!\r\n", filename);
        } else {
   
            /*  读取成功,打印出读取成功的数据 */
            printf("u: read data:%s\r\n", readbuf);
        }
    }

    /* 向设备驱动写数据 */
    if (atoi(argv[2]) == 2) {
   
        memcpy(writebuf, usrdata, sizeof(usrdata));
        retvalue = write(fd, writebuf, 50);
        if (retvalue < 0) {
   
            printf("u: write file %s failed!\r\n", filename);
        }
    }

    /* 关闭设备 */
    retvalue = close(fd);
    if (retvalue < 0) {
   
        printf("u: can't close file %s\r\n", filename);
        return -1;
    }

    return 0;
}

模块使用

查看字符设备 cat /proc/devices

~ # cat /proc/devices 
Character devices:
  1 mem
  2 pty
  3 ttyp
  4 /dev/vc/0
  4 tty
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  7 vcs
 10 misc
 13 input
 29 fb
 90 mtd
116 alsa
128 ptm
136 pts
180 usb
189 usb_device
204 ttyAMA
226 drm
249 rpmb
250 usbmon
251 ptp
252 pps
253 rtc
254 gpiochip

Block devices:
  8 sd
 31 mtdblock
 65 sd
 66 sd
 67 sd
 68 sd
 69 sd
 70 sd
 71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc
254 virtblk
259 blkext
~ # 

查看设备节点

ls /dev

在这里插入图片描述

模块安装

modprobe my_module

模块使用

lib/modules/6.5.7+/my_app /dev/misc_test1 1
lib/modules/6.5.7+/my_app /dev/misc_test1 2

模块运行日志

~ # /lib/modules/6.5.7+/my_app /dev/misc_test1 1
k: miscdev open
k: miscdev read
k: read data success
u: read data:kernel data this tyustli test
k: miscdev release
~ # /lib/modules/6.5.7+/my_app /dev/misc_test1 2
k: miscdev open
k: miscdev write
k: write data success write data is: user data!
k: miscdev release

相关推荐

  1. Linux内核驱动开发-001字符设备开发-002led杂项驱动

    2023-12-21 00:02:03       28 阅读
  2. Linux驱动开发之杂项设备注册和Linux2.6设备注册

    2023-12-21 00:02:03       40 阅读
  3. 驱动开发MISC 杂项驱动

    2023-12-21 00:02:03       41 阅读
  4. linux驱动之字符设备驱动框架

    2023-12-21 00:02:03       59 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-21 00:02:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-21 00:02:03       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-21 00:02:03       82 阅读
  4. Python语言-面向对象

    2023-12-21 00:02:03       91 阅读

热门阅读

  1. c语言实验七

    2023-12-21 00:02:03       58 阅读
  2. 5大算法策略

    2023-12-21 00:02:03       50 阅读
  3. 【matlab】Matlab矩阵计算和示例基础

    2023-12-21 00:02:03       57 阅读
  4. KL散度、CrossEntropy详解

    2023-12-21 00:02:03       58 阅读
  5. 4-区块链基础

    2023-12-21 00:02:03       58 阅读