【IMX6ULL驱动开发学习】02.hello驱动程序之cdev注册字符设备驱动程序和设置次设备号

news2024/7/6 0:13:05

目录

​编辑

一、register_chrdev

二、解决方法

2.1 alloc_chrdev_region函数:注册一系列字符设备编号

2.2 cdev_init函数:初始化cdev结构体 

2.3  cdev_add函数:将字符设备添加到系统中

 三、驱动程序


一、register_chrdev

major = register_chrdev(0, "100ask_hello", &hello_drv);

【IMX6ULL驱动开发学习】01.编写第一个hello驱动+自动创建设备节点(不涉及硬件操作)_阿龙还在写代码的博客-CSDN博客

在之前的hello驱动程序中,入口函数会用 register_chrdev来注册字符设备驱动程序,好处是方便快捷,缺点是霸占了主设备号下的所有此设备号。当我们手动创建一个设备节点(主设备号相同),因为有多个次设备号,所以用上面的设备节点也可以访问hello驱动程序。

Linux内核提供的主设备号是有限的,如果设备很多的情况下主设备号就可能不够用了,那怎么办呢?
解决办法:可以在注册驱动设备的时候,给设备分配好固定的次设备号。

二、解决方法

先定义两个静态全局变量

static struct cdev hello_cdev;
static dev_t dev;

2.1 alloc_chrdev_region函数:注册一系列字符设备编号

int ret;
// major = register_chrdev(0, "100ask_hello", &hello_drv);

ret = alloc_chrdev_region(&dev, 0, 2, "hello");  // dev/hello c 245 0
if (ret < 0) {
	printk(KERN_ERR "alloc_chrdev_region() failed for hello\n");
	return -EINVAL;
}
  • register_chrdev 该函数会把主设备号下所有次设备号都霸占了

  • dev为输出变量,这个结构体里会含有设备的主次设备号

  • 0为次设备号,2为想获得几个次设备号,hello为名字

  • 如果自己创建设备节点 mknod /dev/xyz c 245(具体数字看对应的主设备号) 1

  • 因为有两个次设备号,所以用上面的设备节点也可以访问驱动程序

2.2 cdev_init函数:初始化cdev结构体 

cdev_init(&hello_cdev, &hello_drv);
  • 初始化hello_cdev,让hello_cdev与hello_drv结构体挂钩

2.3  cdev_add函数:将字符设备添加到系统中

ret = cdev_add(&hello_cdev, dev, 2);
if (ret)
{
	printk(KERN_ERR "cdev_add() failed for hello\n");
	return -EINVAL;
}
  • 添加hello_cdev 2为此设备号个数

 三、驱动程序

hello_drv.c

#include "asm-generic/errno-base.h"
#include "asm/cacheflush.h"
#include "linux/cdev.h"
#include "linux/fs.h"
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mman.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/raw.h>
#include <linux/tty.h>
#include <linux/capability.h>
#include <linux/ptrace.h>
#include <linux/device.h>
#include <linux/highmem.h>
#include <linux/backing-dev.h>
#include <linux/shmem_fs.h>
#include <linux/splice.h>
#include <linux/pfn.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/uio.h>
#include <linux/uaccess.h>


static struct class *hello_class;
static struct cdev hello_cdev;
static dev_t dev;

static unsigned char hello_buf[100];

static int hello_open (struct inode *node, struct file *filp)
{
    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    return 0;
}
static ssize_t hello_read (struct file *filp, char __user *buf, size_t size, loff_t *offset)
{
    unsigned long len = size > 100 ? 100 : size;

    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);

    copy_to_user(buf, hello_buf, len);

    return len;
}

static ssize_t hello_write(struct file *filp, const char __user *buf, size_t size, loff_t *offset)
{
    unsigned long len = size > 100 ? 100 : size;

    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    copy_from_user(hello_buf, buf, len);

    return len;
}

static int hello_release (struct inode *node, struct file *filp)
{
    printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    return 0;
}

/* 1. create file_operations */
static const struct file_operations hello_drv = {
    .owner      = THIS_MODULE,
	.read		= hello_read,
	.write		= hello_write,
	.open		= hello_open,
    .release    = hello_release,
};


/* 2. register_chrdev */

/* 3. entry function */
static int hello_init(void)
{
    int ret;

    //申请主次设备号的空间 主次设备号放在dev结构体中
    //dev为输出变量,这个结构体里会含有设备的主次设备号
    //0为次设备号,2为想获得几个次设备号,hello为名字
	ret = alloc_chrdev_region(&dev, 0, 2, "hello");// dev/hello c 245 0
	if (ret < 0) {
		printk(KERN_ERR "alloc_chrdev_region() failed for hello\n");
		return -EINVAL;
	}

    //初始化hello_cdev,让hello_cdev与hello_drv结构体挂钩
    cdev_init(&hello_cdev, &hello_drv);

    //添加hello_cdev 2为此设备号个数
    ret = cdev_add(&hello_cdev, dev, 2);
	if (ret)
    {
		printk(KERN_ERR "cdev_add() failed for hello\n");
		return -EINVAL;
    }
		    
	hello_class = class_create(THIS_MODULE, "hello_class");
	if (IS_ERR(hello_class)) {
		printk("failed to allocate class\n");
		return PTR_ERR(hello_class);
	}

    device_create(hello_class, NULL, dev, NULL, "hello");  /* /dev/hello */
    return 0;
}


/* 4. exit function */
static void hello_exit(void)
{
    device_destroy(hello_class, dev);

    class_destroy(hello_class);

    //unregister_chrdev(major, "100ask_hello");
    cdev_del(&hello_cdev);
    unregister_chrdev_region(dev, 2);
}


module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/849338.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java SPI机制的原理和实践

SPI 全称 Service Provider Interface&#xff0c;是 Java 提供的&#xff0c;旨在由第三方实现或扩展的 API&#xff0c;它是一种用于动态加载服务的机制。Java 中 SPI 机制主要思想是将装配的控制权移到程序之外&#xff0c;在模块化设计中这个机制尤其重要&#xff0c;其核心…

【图像去噪】基于混合自适应(EM 自适应)实现自适应图像去噪研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

SpringMVC的架构有什么优势?——表单和数据校验(四)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

Qt5.14.2+QtCreator+PDB 查看源码

1. 在Creator添加源码 2. 安装PDB文件 Qt下载时没有整合最新的PDB文件下载&#xff0c;如果没有安装PDB文件&#xff0c;即使安装了src也无法调试。 双击MaintenanceTool.exe->设置->资料档案库->临时资料档案库->添加按钮&#xff0c;添加如下下载源&#xff1a…

Android平台GB28181设备接入端如何实现多视频通道接入?

技术背景 我们在设计Android平台GB28181设备接入模块的时候&#xff0c;有这样的场景诉求&#xff0c;一个设备可能需要多个通道&#xff0c;常见的场景&#xff0c;比如车载终端&#xff0c;一台设备&#xff0c;可能需要接入多个摄像头&#xff0c;那么这台车载终端设备可以…

接口测试—Fiddler工具

文章目录 Fiddler 知识1. 导语2. 配置3. 常用命令面试题1. 利用Fiddler抓取android设备https请求 Fiddler 知识 未完待续 1. 导语 为什么要用Fiddler&#xff1f; 提高测试效率. 测试人员通过使用Fiddler自己调试接口&#xff0c;无需麻烦后台同学帮忙. 模拟多种测试环境. 可…

项目管理者联盟创始人宣晓锋受邀为第十二届中国PMO大会演讲嘉宾

项目管理者联盟创始人宣晓锋先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;项目集管理PgMP&#xff1a;升维项目管理认知与能力。大会将于8月12-13日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1a; 从组织战略…

【C语言题解】将一句话的单词进行倒置,标点不倒置。

题目描述&#xff1a;将一句话的单词进行倒置&#xff0c;标点不倒置。比如 “I like beijing.”&#xff0c;经过处理后变为&#xff1a;“beijing. like I”。 文章目录 原题目题目描述&#xff1a;输入描述&#xff1a;输出描述&#xff1a;题目链接&#xff1a; 整体思路分…

rv1126移植并部署自写手写数字识别模型

首先搭建好rknntoolkit以及rknpu环境 --> MNIST->https://github.com/warren-wzw/MNIST-pytorch.git 大致流程 生成rknn文件----------------------------------------------------------------------------------------- 1&#xff1a;进入docker docker run -t -i…

【工具插件类教学】电脑端移动端缩放大图自适应Simple Zoom

目录 简介 1.创建Canvas并设置 2.使用预制体Zoom 3.商店地址 简介 特点: •易于使用和高度可定制。 •支持鼠标(桌面)和触摸(移动)。 •指定最小和最大缩放的限制。 •缩放指针(鼠标/手指)或屏幕上预定义的自定义位置。 •变焦时使用夹紧/弹性变焦类型。 •定义缩…

【科研人 学生党】AI辅助学术论文阅读

【适合于学生党和科研人】写文章往往需要找到好的研究点和方向&#xff0c;但是这并不是一件容易的事情&#xff0c;往往需要阅读大量的文献&#xff0c;阅读文献是一个耗时耗力的过程&#xff0c;而且你阅读了也不一定能提取出重要观点和信息。因此&#xff0c;借助GPT帮我们提…

深入理解 this

文章目录 1. 理解 this2. 为了进一步理解 this,我们再看一个案例3. this 的注意事项和使用细节 1. 理解 this 什么是 this&#xff1f; java虚拟机会给每一个对象分配 this&#xff0c;代表当前对象&#xff0c;坦白的讲&#xff0c;要明白 this不是件容易的事&#xff0c;打一…

容器安全的常见风险与防护实践

运行在云平台上的容器产品&#xff0c;因为具备一个完整的可移植应用程序环境&#xff0c;能够帮助用户轻松地完成对应用程序的开关控制&#xff0c;提升应用程序的敏捷性&#xff0c;同时节约企业的IT建设成本。在巨大优势作用下&#xff0c;容器产品的采用率在2021年达到了新…

爬虫来介绍ChromeF12 谷歌开发者工具 -Network

了解网页基础(HTML、CSS、JavaScript) 了解HTTP基本原理 了解JSON格式 了解Ajax请求 了解爬虫基本原理 (一)、Chrome开发者工具面板概述 Elements 查找网页源代码HTML中的任一元素,手动修改任一元素的属性和样式且能实时在浏览器里面得到反馈。 比如我们在Event Listener…

UML-A 卷-知识考卷

UML-A 卷-知识考卷 UML有多少种图&#xff0c;请列出每种图的名字&#xff1a; 常用的几种UML图&#xff1a; 类图&#xff08;Class Diagram&#xff09;&#xff1a;类图是描述类、接口、关联关系和继承关系的图形化表示。它展示了系统中各个类之间的静态结构和关系。时序…

WEB集群——负载均衡集群

目录 一、 LVS-DR 群集。 1、LVS-DR工作原理 2、LVS-DR模式的特点 3、部署LVS-DR集群 3.1 配置负载调度器&#xff08;192.168.186.100&#xff09; 3.2 第一台web节点服务器&#xff08;192.168.186.103&#xff09; 3.3 第二台web节点服务器&#xff08;192.168.186.…

高温老化房软件使用教程

高温老化炉软件通常具有以下几个模块&#xff1a; 1. 参数设置模块&#xff1a;该模块用于设置高温老化炉的相关参数&#xff0c;包括温度、时间、压力等。用户可以通过输入框、滑动条或下拉菜单等方式设定参数&#xff0c;并将参数发送给高温老化炉。 2. 监控模块&#xff1a;…

认识http的方法、Header、状态码以及简单实现一个http的业务逻辑

文章目录 http的方法http状态码http重定向http常见Header实现简单业务逻辑Protocol.hppUtil.hppServer.hppServer.cc 效果 http的方法 方法说明支持的HTTP版本GET获取资源1.0/1.1POST传输实体主体1.0/1.1PUT传输文件1.0/1.1HEAD获得报文首部1.0/1.1DELETE删除文件1.0/1.1OPTIO…

Centos7.6安装mysql8.0.20

安装前 1.安装mysql前&#xff0c;需将系统自带的mariadb卸载。 [rootk8s01 ~]#  rpm ‐qa|grep mariadbmariadb‐libs.x86_643[rootk8s01 ~]#  rpm ‐e ‐‐nodeps mariadb‐libs.x86_643[rootk8s01 ~]#  rpm ‐qa|grep mariadb 2. 下载mysql8.0.20 [rootk8s-01…

【王树森】深度强化学习(DRL)课程笔记:P1 基本概念(含gym安装)

课程信息 课程主讲&#xff1a;王树森&#xff08;史蒂文斯理工学院计算机科学系的终身制助理教授&#xff09; 课程内容&#xff1a;基本概念、价值学习、策略学习、Actor-Critic方法、AlphaGo、Monte Carlo (蒙特卡洛) 课程资料&#xff1a;https://github.com/wangshusen/D…