嵌入式Linux(8):字符设备驱动--注册字符类设备

这篇具有很好参考价值的文章主要介绍了嵌入式Linux(8):字符设备驱动--注册字符类设备。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

杂项设备
注册杂项设备:

misc_register(&misc_dev);

注销杂项设备:

misc_deregister(&misc_dev);

字符类设备
文件:include/linux/cdev.h

struct cdev {
	struct kobject kobj;
	struct module *owner;
	const struct file_operations *ops;
	struct list_head list;
	dev_t dev;
	unsigned int count;
} __randomize_layout;

步骤流程:

  1. 定义一个cdev结构体。
  2. 使用cdev_init函数初始化cdev结构体成员变量。
void cdev_init(struct cdev *, const struct file_operations *);

参数:

  • 第一个:要初始化的cdev结构体
  • 第二个:文件操作集:cdev->ops = fops;//实际就是把文件操作集写ops
  1. 使用cdev_add函数注册到内核。
int cdev_add(struct cdev*, dev_t, unsigned);

参数:

  • 第一个:cdev的结构体指针。
  • 第二个:设备号。
  • 第三个:次设备号的数量。
  1. 创建字符设备节点

字符设备注册完以后不会自动生成设备节点(杂项设备在注册完以后就会自动生成设备节点)。

上面的代码里面没有自动创建字符设备节点。

需要使用mknod命令(命令行手动输入创建)创建一个设备节点。
格式:mknod 名称 类型 主设备号 次设备号
举例:mknod /dev/test c 236 0

上代码

chrdev.c

#include <linux/init.h> // 包含宏定义
#include <linux/module.h> // 包含初始化、加载模块的头文件
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>


#define DEVICE_NUMBER 1
#define DEVICE_SNAME   "schrdev"
#define DEVICE_ANAME   "achrdev"

#define DEVICE_MINOR_NUMBER  0

static int major_num, minor_num;

struct cdev cdev;

int chrdev_open(struct inode *inode, struct file *file)
{
    printk("chrdev_open\n");
    return 0;
}

struct file_operations chrdev_ops = {
    .owner = THIS_MODULE,
    .open = chrdev_open
};

module_param(major_num, int, S_IRUSR);
module_param(minor_num, int, S_IRUSR);


static int hello_init(void)
{
    dev_t dev_num;
    int ret;

    if(major_num)
    {
        printk("major_num: %d\n", major_num);
        printk("minor_num: %d\n", minor_num);

        dev_num = MKDEV(major_num, minor_num);

        ret = register_chrdev_region(dev_num, DEVICE_NUMBER, DEVICE_SNAME);

        if(ret < 0)
        {
            printk("register_chrdev_region error\n");
        }
        else
            printk("register_chrdev_region ok\n");
    }
    else
    {
        ret = alloc_chrdev_region(&dev_num, DEVICE_MINOR_NUMBER, DEVICE_NUMBER, DEVICE_ANAME);
        if(ret <0)
        {
            printk("alloc_chrdev_region error\n");
        }
        else
            printk("alloc_chrdev_region ok\n");

        major_num = MAJOR(dev_num);
        minor_num = MINOR(dev_num);

        printk("major_num: %d\n", major_num);
        printk("minor_num: %d\n", minor_num);
    }

	printk("major_num = %d, minor_num = %d\n",major_num, minor_num);

    cdev.owner = THIS_MODULE;
    cdev_init(&cdev, &chrdev_ops);

    cdev_add(&cdev, dev_num, DEVICE_NUMBER);

	return 0;
}
static void hello_exit(void)
{
    unregister_chrdev_region(MKDEV(major_num, minor_num), DEVICE_NUMBER);

    cdev_del(&cdev);
    
	printk("Bye Bye\n");
}

/* 模块的入口 */
module_init(hello_init);
/* 模块的出口 */
module_exit(hello_exit);

/* 模块声明 */
MODULE_LICENSE("GPL");

Makefile

# 定义内核源码的目录
KERN_DIR ?= /home/liefyuan/Linux/rk356x_linux/kernel
# 定义当前目录
PWD        := $(shell pwd)
# 要生成的内核模块
obj-m += chrdev.o

all:
	make -C $(KERN_DIR) M=$(PWD) modules

clean:
	rm -rf *.order *o *.symvers *.mod.c *.mod *.ko

编译模块

export ARCH=arm64 
export CROSS_COMPILE=aarch64-linux-gnu-
make

需要手动创建设备节点:

[root@RK356X:/opt]# insmod chrdev.ko
[29223.082788] alloc_chrdev_region ok
[29223.082898] major_num: 236
[29223.08290[root@RK356X:/opt]# 7] minor_num: 0
[29223.082915] major_num = 236, minor_num = 0

[root@RK356X:/opt]# mknod /dev/test c 236 0
[root@RK356X:/opt]# ls /dev/test
/dev/test

app.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
	int fd;
    //打开设备节点
	fd = open("/dev/test",O_RDWR);
	if(fd < 0)
	{
        //打开设备节点失败
		perror("open error \n"); 
		return fd;
	}
	close(fd);
	return 0;
}

编译

aarch64-linux-gnu-gcc app.c -o app.armelf

运行:

[root@RK356X:/opt]# ./app.armelf
[29334.729056] chrdev_open

没有问题。文章来源地址https://www.toymoban.com/news/detail-421085.html

到了这里,关于嵌入式Linux(8):字符设备驱动--注册字符类设备的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式linux驱动开发篇之设备树

    设备树(Device Tree)是一种用于描述嵌入式系统硬件组件及其连接关系的数据结构。它被广泛用于嵌入式 Linux 系统,尤其是针对使用多种不同架构和平台的嵌入式系统。它是一种与硬件描述相关的中间表示形式,将硬件信息抽象成一种可移植的格式,使得操作系统和引导加载

    2024年02月22日
    浏览(67)
  • 【嵌入式Linux学习笔记】platform设备驱动和input子系统

    对于Linux这种庞大的操作系统,代码重用性非常重要,所以需要有相关的机制来提升效率,去除重复无意义的代码,尤其是对于驱动程序,所以就有了platform和INPUT子系统这两种工作机制。 学习视频地址:【正点原子】STM32MP157开发板 platform 驱动框架分为总线、设备和驱动。总

    2024年02月07日
    浏览(57)
  • 嵌入式Linux驱动开发——解决/sys/bus/spi/devices下没有对应的spi设备文件

    最近在学习Linux驱动开发中SPI总线的驱动框架,但在修改完设备树添加完对应的spi设备节点后,理应在/sys/bus/spi下会有对应的spi设备,我的目录下面没有。 无spi设备 然后我查看了/proc/device-tree,发现有对应的spi设备节点,我就先没有过多理会这个问题。 /proc/device-tree下有对应

    2024年02月16日
    浏览(43)
  • 【嵌入式Linux内核驱动】04_Jetson nano GPIO应用 | 驱动开发 | 官方gpiolib、设备树与chip_driver

    0.暴露给应用层 应用 解决调试目录为空的问题 调试信息 1.最简读写文件(在/SYS下) 设备树 验证测试 编译文件 驱动 of_get_named_gpio_flags //获取设备树节点的属性 gpio_is_valid //判断是否合法 devm_gpio_request //申请使用gpio,并调用设置pinctrl device_create_file //根据设备树节点属性,创建

    2024年02月07日
    浏览(58)
  • 嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第五天-ARM Linux编程之设备节点 (物联技术666)

    链接:https://pan.baidu.com/s/1hOBKyRom-4EZMBpFn1H9kQ?pwd=1688 提取码:1688  Linux设备节点 设备管理是linux中比较基础的东西,但是由于Linux智能程度的越来越高,Udev的使用越来越广泛,使得越来越多的Linux新用户对 /dev 目录下的东西变得不再熟悉。有时候遇见问题就会变得抓狂 本文是我

    2024年02月22日
    浏览(47)
  • 韦东山嵌入式Liunx入门驱动开发一(Hello 驱动编程、GPIO基础知识、LED驱动、总线设备驱动模型)

    本人学习完韦老师的视频,因此来复习巩固,写以笔记记之。 韦老师的课比较难,第一遍不知道在说什么,但是坚持看完一遍,再来复习,基本上就水到渠成了。 看完视频复习的同学观看最佳! 基于 IMX6ULL-PRO 参考视频 Linux快速入门到精通视频 参考资料 :01_嵌入式Linux应用

    2024年04月25日
    浏览(78)
  • Linux 驱动学习笔记 ——(1)字符设备驱动

    《【正点原子】I.MX6U嵌入式Linux驱动开发指南》学习笔记 字符设备是 Linux 驱动中最基本的一类设备驱动,字节设备就是按照字节流来读写的设备,常见的字符设备包括:LED、蜂鸣器、按键、I2C 以及 SPI 等。 Linux 中一切皆文件,字符设备驱动加载成功后会在 /dev 目录下生成相

    2024年02月08日
    浏览(55)
  • Linux设备驱动——第三章字符驱动

    当对幸福的憧憬过于急切,那痛苦就在人的心灵深处升起。——加缪 本章的目的是编写一个完整的字符设备驱动。我们开发一个字符驱动是因为这一类适合大部分简单的硬件设备。字符驱动也比块驱动易于理解。本章的最终目的是编写一个模块化的字符驱动,但是我们不会在

    2024年02月08日
    浏览(80)
  • Linux 驱动之字符设备

    什么是设备号 Linux 规定每一个字符设备或者块设备都必须有一个专属的设备号。一个设备号由主设备号和次设备号组成。主设备号用来表示某一类驱动,如鼠标,键盘都可以归类到 USB 驱动中。而次设备号是用来表示这个驱动下的各个设备。比如第几个鼠标,第几个键盘等。

    2024年02月16日
    浏览(38)
  • Linux 驱动之高级字符设备

    什么是IO呢? IO 的英文全称是 input 和output,翻译过来就是输入和输出。 在冯.诺依曼结构中,将计算机分成分为5个部分: 运算器、控制器、存储器、输入设备、输出设备 。其中输入设备指的是向计算机输入数据或者信息,如鼠标,键盘都是输入设备。输出设备指的是用于接收

    2023年04月14日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包