【Linux】【驱动】自动创建设备节点
【Linux】【驱动】自动创建设备节点
- 续
- 驱动代码
- 操作指令
- linux端
- 从机端
续
这里展示了如何自动的方式去创建一个字符类的节点
下面就是需要调用到的程序
函数
void cdev_init(struct cdev *, const struct file_operations *);
第一个参数 要初始化的 cdev
第二个参数 文件操作集 cdev->ops = fops; //实际就是把文件操作集写给 ops
功能 cdev_init()函数用于初始化 cdev 的成员,并建立 cdev 和 file_operations 之间的连接。
函数
int cdev_add(struct cdev *, dev_t, unsigned);
第一个参数 cdev 的结构体指针
第二个参数 设备号
第三个参数 次设备号的数量
功能 cdev_alloc()函数用于动态申请一个 cdev 内存
void cdev_del(struct cdev *);
cdev 的结构体指针
生成设备节点
字符设备注册完以后不会自动生成设备节点。我们需要使用 mknod 命令创建一个设备节点
格式:mknod 名称 类型 主设备号 次设备号
mknod /dev/test c 247 0
驱动代码
代码实现的流程
从 hello_init 函数开始看,
- 注册设备号,
- 初始化 cdev
- 向系统注册设备
- 创建 class 类
- 在 class 类下创建设备
从hello_exit 来看
- 注销设备号
- 删除设备
- 注销设备
- 删除类
#include <linux/init.h>
#include <linux/module.h> //最基本的文件,支持动态添加和卸载模块。
#include <linux/fs.h> //包含了文件操作相关 struct 的定义,例如大名鼎鼎的 struct file_operations
#include <linux/kdev_t.h>
#include <linux/cdev.h> //对字符设备结构 cdev 以及一系列的操作函数的定义。//包含了 cdev 结构及相关函数的定义。
#include <linux/device.h> //包含了 device、class 等结构的定义#define DEVICE_NUMBER 1 //定义次设备号的个数
#define DEVICE_SNAME "schrdev" //定义静态注册设备的名称
#define DEVICE_ANAME "achrdev" //定义动态注册设备的名称
#define DEVICE_MINOR_NUMBER 0 //定义次设备号的起始地址#define DEVICE_CLASS_NAME "chrdev_class" //宏定义类名
#define DEVICE_NODE_NAME "chrdev_test" //宏定义设备节点的名字static int major_num, minor_num; //定义主设备号和次设备号struct class *class; //定义类
struct device *device; /* 设备 */
struct cdev cdev;//定义一个 cdev 结构体module_param(major_num,int,S_IRUSR); //驱动模块传入普通参数 major_num
module_param(minor_num ,int,S_IRUSR);//驱动模块传入普通参数 minor_numdev_t dev_num;/**
* @description: 打开设备
* @param {structinode} *inode:传递给驱动的 inode
* @param {structfile} *file:设备文件,file 结构体有个叫做 private_data 的成员变量,
* 一般在 open 的时候将 private_data 指向设备结构体。
* @return: 0 成功;其他 失败
*/
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};/**
* @description: 驱动入口函数
* @param {*}无
* @return {*} 0 成功;其他 失败
*/
static int hello_init(void)
{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);//MKDEV 将主设备号和次设备号合并为一个设备号ret = register_chrdev_region(dev_num, DEVICE_NUMBER,DEVICE_SNAME);//注册设备号if(ret<0){printk("register_chrdev_region error\n");}//静态注册设备号成功,则打印。printk("register_chrdev_region ok\n");}else{/*动态注册设备号*/ret = alloc_chrdev_region(&dev_num,DEVICE_MINOR_NUMBER,1, DEVICE_ANAME);if(ret<0){printk("alloc_chrdev_region error\n");}//动态注册设备号成功,则打印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);//打印传入进来的次设备号}// 初始化 cdevcdev.owner = THIS_MODULE;//cdev_init 函数初始化 cdev 结构体成员变量cdev_init(&cdev, &chrdev_ops);//完成字符设备注册到内核cdev_add(&cdev, dev_num, DEVICE_NUMBER);//创建类class = class_create(THIS_MODULE, DEVICE_CLASS_NAME);// 在 class 类下创建设备device = device_create(class, NULL, dev_num, NULL, DEVICE_NODE_NAME);return 0;
}//drivers for exit
static void hello_exit(void)
{//注销设备号unregister_chrdev_region(MKDEV(major_num, minor_num), DEVICE_NUMBER);//删除设备cdev_del(&cdev);//注销设备device_destroy(class, dev_num);//删除类class_destroy(class);printk("gooodbye! \n");}module_init(hello_init);
module_exit(hello_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("Chris");
下面就是app的代码
#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;char buf[64] = {0};fd = open("/dev/chrdev_test",O_RDWR); //打开设备节点if(fd < 0){perror("open error \n");return fd;}//read(fd,buf,sizeof(buf)); //从文件中读取数据放入缓冲区中close(fd);return 0;
}
操作指令
linux端
arm-buildroot-linux-gnueabihf-gcc -o app app.c
cp app /home/book/nfs_rootfs/
从机端
驱动卸载掉,再加载新编译好的的驱动
rmmod chrdev
insmod chrdev.ko
我们输入以下命令查看/sys/class 下面是否生成类,
ls /sys/class/chrdev_class/
查看下是否生成了设备节点
ls /sys/class/
来验证生成的设备节点是否可以使用
./app
相关文章:

【Linux】【驱动】自动创建设备节点
【Linux】【驱动】自动创建设备节点 续驱动代码操作指令linux端从机端 续 这里展示了如何自动的方式去创建一个字符类的节点 下面就是需要调用到的程序 函数 void cdev_init(struct cdev *, const struct file_operations *);第一个参数 要初始化的 cdev 第二个参数 文件操作…...

自实现getprocaddress(名称查找或者序号查找)
通过名称去找 // MyGETPRCOADDRESS.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 //#include <iostream> #include<Windows.h>/*WINBASEAPI //导出不需要使用,那么我们注释掉*/ FARPROC WINAPI MyGetProcAddress(_In_ HMO…...

如何DIY制作干洗店洗护小程序
洗护行业正逐渐迎来线上化的浪潮,传统的干洗店也开始尝试将业务线上化,以提供更便捷的服务给消费者。而制作一款洗护小程序,成为了干洗店实现线上化的重要一环。今天,我们就来分享一下如何使用第三方制作平台制作洗护小程序的教程…...

微前沿 | 第1期:强可控视频生成;定制化样本检索器;用脑电重建视觉感知;大模型鲁棒性评测
欢迎阅读我们的新栏目——“微前沿”! “微前沿”汇聚了微软亚洲研究院最新的创新成果与科研动态。在这里,你可以快速浏览研究院的亮点资讯,保持对前沿领域的敏锐嗅觉,同时也能找到先进实用的开源工具。 本期内容速览 01. 强可…...

SQLite数据库C_C++接口(保姆级API应用 1.4W字)(全网最详细介绍,学完必掌握)
目录 sqlite3的C/C API应用 前言 SQLite3库安装 API函数 打开、关闭、错误处理 打开 返回值 关闭 错误调试 实际应用 执行SQL(DDL、DML) API介绍 实际应用 回调函数查询 API介绍 实际应用 全缓冲查询 API介绍 实际应用 字节缓冲查询…...

倒计时:心理的镇静剂还是焦虑的火种?
倒计时:心理的镇静剂还是焦虑的火种? 目录 引言倒计时的作用与原理倒计时的双面性:缓解焦虑还是引发焦虑?如何正确使用倒计时结论 引言 在我们的日常生活和工作中,倒计时被广泛的应用。无论是在网购的抢购活动中&a…...

迅睿系统二开自定义函数和插件的自定义函数
全局的自定义函数: 全局的自定义函数文件:dayrui/My/Helper.php 此文件用于放网站自定义函数,程序会自动加载 当前站点的自定义函数文件:网站主目录/config/custom.php 插件的自定义函数: 基于App目录下的插件或模块…...

传统品牌如何通过3D虚拟数字人定制和动捕设备加速年轻化发展?
步入Z时代,年轻一代消费者的生活方式深受互联网技术和媒介环境影响,对新潮事物感兴趣,消费思维也相对前卫,品牌需要探索契合Z世代的消费观念,寻找新的链接拉近品牌与消费者的距离,而3D虚拟数字人定制可以帮…...

sql:SQL优化知识点记录(五)
(1)explain之例子 (2)索引单表优化案例 上面的功能已经实现,但是分析功能, 使用explain分析这条sql: 发现type为All Extra:有Using filesort (文件内排序) 这…...

1.3 Metasploit 生成SSL加密载荷
在本节中,我们将介绍如何通过使用Metasploit生成加密载荷,以隐藏网络特征。前一章节我们已经通过Metasploit生成了一段明文的ShellCode,但明文的网络传输存在安全隐患,因此本节将介绍如何通过生成SSL证书来加密ShellCodeÿ…...

redis windows 版本安装
1. 下载windows安装包并解压 如果是Linux版本可以直接到官网下载,自3.x起官网和微软网站就没有redis安装包更新了,好在github有开发者在编译发布更新(目前最新有5.0.9版本可下),地址:redis windows 5版本下…...

限流算法深入
限流定义及目的 当系统流量达到系统或下游承受能力的阈值时对系统进行限流控制以防止系统或下游挂掉,减少影响面。 限流组成:阈值及限流策略。阈值是指系统单位时间接收到的请求qps总数;限流策略是指限流行业触发后对应的系统行为ÿ…...

java 基础知识 循环的几个题目
1、输出1~100的累加和 结果显示在屏幕,显示在文件res1.txt中 2、输出1-~100的偶数和 结果显示在屏幕,显示在文件res2.txt中 3、输出所有水仙花数: 100~999的数中出现个位数的立方十位数的立方百位数的立方这个数本身 4、输出由9行9列星号组成…...

Spring Boot使用LocalDateTime、LocalDate作为入参
0x0 背景 项目中使用LocalDateTime系列作为dto中时间的类型,但是spring收到参数后总报错,为了全局配置时间类型转换,尝试了如下3中方法。 注:本文基于Springboot2.0测试,如果无法生效可能是spring版本较低导致的。PS&…...

第七周第七天学习总结 | MySQL入门及练习学习第二天
实操练习: 1.创建一个名为 cesh的数据库 2.在这个数据库内 创建一个名为 xinxi 的表要求该表可以包含:编号,姓名,备注的信息 3.为 ceshi 表 添加数据 4.为xinxi 表的数据设置中文别名 5.查询 在 xinxi 表中编号 为2 的全部…...

【考研数学】线形代数第三章——向量 | 3)向量组秩的性质、向量空间、过渡矩阵
文章目录 引言三、向量组等价、向量组的极大线性无关组与秩3.2 向量组秩的性质 四、 n n n 维向量空间4.1 基本概念4.2 基本性质 写在最后 引言 紧接前文学习完向量组秩的基本概念后,继续往后学习向量的内容。 三、向量组等价、向量组的极大线性无关组与秩 3.2 向…...

【技术】SpringBoot Word 模板替换
SpringBoot Word 模板替换 什么是 Word 模板替换如何实现 Word 模板替换 什么是 Word 模板替换 模板一般是具有固定格式的内容,其中一部分需要替换。Word 模板通俗的讲是以 Word 的形式制作模板,固定格式和内容,然后将其中的一部分数据替换掉…...

java jni nv21和nv12互转
目录 libyuv性能比较 NV12 NV21 YUV420格式介绍 jni YUV420toYUV420SemiPlanar java YUV420toYUV420SemiPlanar java NV12toYUV420SemiPlanar jni NV12toYUV420SemiPlanar...

后端面试话术集锦第二篇:spring boot面试话术
🚗后端面试集锦目录 💖后端面试话术集锦第一篇:spring面试话术💖 💖后端面试话术集锦第二篇:spring boot面试话术💖 💖后端面试话术集锦第三篇:spring cloud面试话术💖 💖后端面试话术集锦第四篇:ElasticSearch面试话术💖 💖后端面试话术集锦第五篇:r…...

Doris中分区和分桶使用教程
1 分区与分桶 Doris中有两层的数据划分,第一层是分区(Partition),第二层是分桶(Bucket), Partition又能分为Range分区和List分区。 Bucket仅支持Hash方式。 1.1 Partition 只能指定…...

电脑不安装软件,怎么将手机文件传输到电脑?
很多人都知道,AirDroid有网页版(web.airdroid.com)。 想要文件传输,却不想在电脑安装软件时,AirDroid的网页版其实也可以传输文件。 然而,要将文件从手机传输文件到网页端所在的电脑时,如果按…...

vue3 publish 出现的问题
vue3项目使用 yarn build 编译出dist文件, 发布后出现错误 #问题与解决 1)登录迭代错误(Maximum call stack size exceeded) >deepclone 的问题 在 GrandhallLayout 中判断菜单和权限中; const mainMenu cloneDeep(router.getRoutes()) lodash.clonedee…...

网络防御和入侵检测
网络防御和入侵检测是维护网络安全的关键任务,可以帮助识别和阻止未经授权的访问和恶意行为。以下是一些基本的步骤和方法,用于进行网络防御和入侵检测。 网络防御: 防火墙设置: 部署防火墙来监控和控制网络流量,阻止…...

【科研论文配图绘制】task5 SciencePlots绘图包入门
【科研论文配图绘制】task5 SciencePlots绘图包入门 task5主要学习了SciencePlots拓展包的出图样式,掌握SciencePlots的安装及具体使用。 SciencePlots作为一个专门用于科研论文绘图的第三方拓展工具包,提供了主流英文科技 期刊(如 Nature、Science 和 …...

R语言常用数学函数
目录 1. - * / ^ 2.%/%和%% 3.ceiling,floor,round 4.signif,trunc,zapsamll 5.max,min,mean,pmax,pmin 6.range和sum 7.prod 8.cumsum,cumprod,cummax,cummin 9.sort 10. approx 11.approx fun 12.diff 13.sign 14.var和sd 15.median 16.IQR 17.ave 18.five…...

公网远程访问局域网SQL Server数据库
文章目录 1.前言2.本地安装和设置SQL Server2.1 SQL Server下载2.2 SQL Server本地连接测试2.3 Cpolar内网穿透的下载和安装2.3 Cpolar内网穿透的注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 数据库的重要性相信大家都有所了解&…...

Apache Celeborn 让 Spark 和 Flink 更快更稳更弹性
摘要:本文整理自阿里云/数据湖 Spark 引擎负责人周克勇(一锤)在 Streaming Lakehouse Meetup 的分享。内容主要分为五个部分: Apache Celeborn 的背景Apache Celeborn——快Apache Celeborn——稳Apache Celeborn——弹Evaluation…...

华为数通方向HCIP-DataCom H12-821题库(单选题:141-160)
第141题 Router-LSA 能够描述不同的链路类型,不属于Router LSA 链路类型的是以下哪一项? A、Link Type 可以用来描述到末梢网络的连接,即 SubNet B、Link Type 可以用来描述到中转网络的连接,即 TranNet C、Link Type 可以用来描述到另一…...

Windows-docker集成SRS服务器的部署和使用
Windows-docker集成SRS服务器的部署和使用 一、Windows Docker安装 Docker Desktop 官方下载地址: https://docs.docker.com/desktop/install/windows-install/ 下载windows版本的就可以了。 注意:此方法仅适用于 Windows 10 操作系统专业版、企业版、…...

element-ui table表格滚动条拉到最右侧 表头与内容不能对齐
1.问题概述 当表格数据太多,会出现纵向滚动条和横向滚动条,把横向滚动条拉到最右侧时,会出现表头与内容不能对齐的现象。 2.解决方法 1.当页面数据加载完毕后,在后面加上 this.$nextTick(() > {this.$refs.table.doLayout()…...