【linux-IMX6ULL-字符设备驱动简单框架实验】
目录
- 1. 字符设备驱动简介
- 1.1 重要函数
- 1.2 简单框架代码流程
- 1.3 linux中关于驱动的重要命令
- 2. 字符设备驱动简单框架编写
- 2.1 添加LICENSE信息
- 2.2 驱动模块的入口与出口
- 2.3 入口和出口函数的编写
- 2.4 设备操作结构体定义
- 2.4.1 结构体函数内容填充
- 3. 应用程序简介:
- 4. 应用程序的编写思路
1. 字符设备驱动简介
目前的驱动开发一般是分为三类,第一类就是字符设备驱动、块设备驱动、和网络驱动三类,其中字符设备驱动是最多最杂的,现在对字符设备驱动进行一个简要的介绍:
字符设备驱动,是指那些以字节流进行数据传输的设备、IIC、SPI、LCD、按键、例如键盘、鼠标、打印机等,其中包含以下几个关键的部分:
设备注册和注销:通过设备注册使设备能被系统识别;注销则相反;数据操作函数:通常包含open,read,write,realse等;中断处理:处理设备产生的中断,以响应特定事件;
通过字符型设备驱动,可以使系统方便统一管理不同的设备,这样就可以给上层应用提供相应的接口函数,方便应用程序与设备之间进行数据交换和通信;

本次的实验是通过简单的实验建立一个设备驱动开发的基本框架,为后续的学习打下基础,其中会列出重要的函数以及重要的挂载指令,当然其中有一些函数是比较老的,例如要手动分配设备号,但是为了便于学习目前就以简单的为主,因为越是抽象的越简单,但是越抽象就越难以理解;
1.1 重要函数
这里只是把本实验相关的重要函数给罗列出来了,主要的作用就是对本次实验的一个总结,如果没有做个这个实验,那么看着没啥感觉的;例如我下面罗列函数的顺序就是我们在编写驱动实验时整个流程的顺序,首先就是注册入口和出口函数,其次就是编写入口和出口函数,再次就是编写文件结构体的对应相关的函数内容;
MODULE-LICENSE("GPL"): 表示该内核模块遵循的许可协议是通用公共许可(GPL)。指定许可协议非常重要,它明确了该模块在使用、分发等方面的权利和限制。如果不写这个的话就会导致在装载设备驱动时出现警告;module_init(*****_init):模块的入口函数,进行初始化,也就是加载模块时第一个就是运行这个函数注册的函数*******;对模块进行初始化设置;module_exit(*****_exit):模块的出口函数,对模块进行卸载时就会执行这个函数注册的函数*******;static int __init *****_init(void):设备加载函数,进行模块的初始化和加载的设置;这个函数要被入口函数进行注册后起作用;register_chrdev(unsigned int major, const char *name, const struct file_operations *fops):对设备进行注册;static int __exit *****_exit(void):设备卸载函数、进行模块的卸载时这个函数内部的程序就会执行,不过要被出口函数进行注册;unregister_chrdev(unsigned int major, const char *name):对模块进行卸载;static const struct file_operations **_fops: struct file_operations是一个很重要的结构体,其中定义了很多与文件操作有关的函数指针,例如read,write,realse,open等等,这些函数可以按需进行填充,这样就方便与设备之间进行文件的操作;下面进行实验时会进行一个详细的说明;
1.2 简单框架代码流程
代码实验编写流程:

1.3 linux中关于驱动的重要命令
lsmod:显示有哪些模块被加载了,也就是显示所有的加载模块lsmod:显示有哪些模块被加载了,也就是显示所有的加载模块depmod:更新模块的依赖关系,也就是新加载一个模块时,要先运行一下这个命令,不然有错误modprob ***.ko:这个命令的作用就是加载模块***.komknod /dev/*** c 200 0:mknod:手动创建节点的命令。/dev/*** :创建设备的名称。c:字符型设备。200:主设备号,自己指定。0:次设备号,自己指定。cat /proc/devices:这个命令的作用是查看所有加载的模块,显示所有设备号等;rmmod ***.ko:卸载模块***.ko;cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq:这个命令是显示当成CPU的频率;
2. 字符设备驱动简单框架编写
上面已经介绍了驱动编写的则整体流程,以及介绍了重要的加载驱动的一些linux的命令,因此下面的代码就不做过多的介绍:
2.1 添加LICENSE信息
我们需要在代码中添加LICENSE信息,否则编译会出错,不过我们还可以添加一些其他的信息,例如作者,邮箱等等;
MODULE_LICENSE("GPL");
2.2 驱动模块的入口与出口
linux的驱动有两种加载形式,一就是编译进linux内核中,当内核启动,驱动也启动,另一种方法就是把启动编译成模块也就***.ko文件,通过insmode或者modprob的命令进行加载模块,这样做的好处就是便于调试,而且不用重启linux内核;代码如下,下面两个函数的作用就是对模块进行加载和卸载,并在加载和卸载函数中对字符设备进行注册,如我们裸机编程中系统中断函数对中断服务函数的注册一样;
/* * 模块入口和出口函数注册*/
module_init(chrdevbase_init);/*入口,加载模块*/
module_exit(chrdevbase_exit);/*出口,卸载模块*/
2.3 入口和出口函数的编写
注意,入口函数是通过__init来修饰(注意是两个杠),而对于出口函数通过__exit进行修饰,在出入口函数中对设备进行注册,CHRDEVBASE_MAJOR是设备号,CHREEVBAScE_NAME是设备名,chrdevbase_fops是文件操作结构体;出口函数是类似的;
#define CHRDEVBASE_MAJOR 200
#define CHREEVBASE_NAME "chrdevbase"static int __init chrdevbase_init(void)
{printk("chrdevbase_init3\r\n");/*注册字符设备*/register_chrdev(CHRDEVBASE_MAJOR, CHREEVBASE_NAME,&chrdevbase_fops);return 0;
}
static void __exit chrdevbase_exit(void)
{printk("chrdevbase_exit\r\n");unregister_chrdev(CHRDEVBASE_MAJOR,CHREEVBASE_NAME);
}
2.4 设备操作结构体定义
对于设备的操作file_operations结构体,也称为文件操作结构体,这也是为什么linux下一切皆文件,我们的操作大部分都是通过文件来进行管理,我们可能用不到那么多的功能,因此我们要用到什么功能就进行对应的添加和书写就行,代码如下,注意这里使用的是=:
static const struct file_operations chrdevbase_fops={.owner = THIS_MODULE,.open = chrdevbase_open,.release = chrdevbase_release,.read = chrdevbase_read,.write = chrdevbase_write,
};
2.4.1 结构体函数内容填充
可以看到,我们对上面的文件操作结构体中定义了四个函数指针,分别是:chrdevbase_open、chrdevbase_release、chrdevbase_read、chrdevbase_write,接下来就是对这四个函数进行内容填充:
static char readbuf[100];/*读缓冲*/
static char writebuf[100];
static char kerneldata[]={"kernel data!"};/************/
static ssize_t chrdevbase_read(struct file * file, char * buf, size_t count, loff_t *off)
{int ret=0;memcpy(readbuf,kerneldata,sizeof(kerneldata));ret = copy_to_user(buf,readbuf,count);if(ret<0){printk("Error!");}else{}return 0;
}
/************/
static ssize_t chrdevbase_write(struct file * file, const char * buf, size_t count,loff_t *off)
{int ret =0;ret = copy_from_user(writebuf,buf,count);printk("Kernel recevdata:%s\r\n",writebuf);if(ret = 0){printk("Kernel recevdata:%s\r\n",writebuf);}return 0;
}
static int chrdevbase_release(struct inode * inode, struct file * file)
{printk("chrdevbase_ralease\r\n");return 0;
}
static int chrdevbase_open(struct inode * inode, struct file * file)
{printk("chrdevbase_open\n");return 0;
}
3. 应用程序简介:
当驱动程序编写完毕后,要通过应用程序进行调用驱动函数的一些接口函数,这些功能的实现是在应用程序中实现的,这样就实现了应用程序与驱动程序的分离;可以这样类比,我们写应用程序就相当于我们在windows系统上写C程序,我们写C程序时也没有关注下层,这就是一种分离,不过这两者是可以相互进行数据交换的,不过要用特定的方法;注意驱动程序和应用程序的编译是不一样的:对于应用程序的编译是下面的指令:
arm-linux-gnueabihf-gcc ***APP.c -o ***APP:应用程序的编译指令$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules:驱动程序的编译:Make部分核心指令
从上面的编译指令中就可以看出区别,对于驱动的编译要用到一系列的库,这些库包含板子的信息,以及一些arm中的一些库等等,最终生成一个驱动模块,属于下层的驱动文件;
而对于应用程序的编译则是用到了一个.c文件以及基础库,就像我们编译C语言一样,只不过我们写一个hello.c文件用的是gcc编译器,生成的是x86架构的可执行文件,同理,我们使用arm-linux-gnueabihf-gcc交叉编译器生成的是arm架构的可执行文件,这明显是上层的应用程序,不过我们写上层应用程序时通过传参命令的形式就可以与下层的驱动进行数据文件交换;
4. 应用程序的编写思路
编写测试APP就是编写Linux应用程序,需要用到C库和文件操作相关的一些函数,open、read、write 和 close 这四个函数;这些函数可以根据下面的命令进行找详细帮助:“man 1”通常是用户命令的手册页;“man 2”一般是系统调用的手册页;“man 3”可能是 C 库函数的手册页;
wyj@BK:~$ man 2 read
wyj@BK:~$ man 2 write
wyj@BK:~$ man 2 close
wyj@BK:~$ man 2 open
因此在应用程序中编写程序就是如何对驱动程序进行调用和使用,不过要注意的是对于驱动的编写属于内核态,而对于应用程序的编写属于应用态,应用态不能直接操作内核态,要通过一定的程序从而间接操作内核态:
int mian(int argc,char *argv[])
{int ret = 0;int fd = 0;char *filename;char readbuf[100];char writebuf[100];static char usrdata[]={"Usr data!Usr data!Usr data!"};filename=argv[1];fd = open(filename, O_RDWR);if(fd<0){printf("Can't open file %s\r\n",filename);}/*read*/if(atoi(argv[2])==1){ret=read(fd, readbuf, 50); printf("\r\nAPP read data:%s\r\n",readbuf);}/*write*/if(atoi(argv[2])==2){memcpy(writebuf,usrdata,sizeof(usrdata));ret = write(fd, writebuf,50);}/*close*/ret = close(fd);if(ret<0){printf("Can't close %s\r\n",filename);}return 0;
}
相关文章:
【linux-IMX6ULL-字符设备驱动简单框架实验】
目录 1. 字符设备驱动简介1.1 重要函数1.2 简单框架代码流程1.3 linux中关于驱动的重要命令 2. 字符设备驱动简单框架编写2.1 添加LICENSE信息2.2 驱动模块的入口与出口2.3 入口和出口函数的编写2.4 设备操作结构体定义2.4.1 结构体函数内容填充 3. 应用程序简介:4.…...
3D模型旋转显示不全怎么办---模大狮模型网
在3D建模和渲染过程中,我们有时会遇到旋转模型时显示不全的问题。这种情况可能由多种原因造成,包括模型本身的问题、软件设置不当、硬件配置不足等。本文将为您详细介绍几种可能的解决方法,帮助您解决3D模型旋转显示不全的问题。 一、检查模型…...
DLRover:蚂蚁集团开源的AI训练革命
在当前的深度学习领域,大规模训练作业面临着一系列挑战。首先,硬件故障或软件错误导致的停机时间会严重影响训练效率和进度。其次,传统的检查点机制在大规模训练中效率低下,耗时长且容易降低训练的有效时间。资源管理的复杂性也给…...
ubuntu_概念
su(switch user) wget(Web Get) cd(change directory) dpkg(Debian Packager)为 “Debian” 专门开发的套件管理系统,方便软件的安装、更新及移除。 chmod(Change Mode)用于改变文件或目录的权限 ps(Process Status)进程状态 grep(Global Regular Expression Print)…...
Oracle递归查询笔记
目录 一、创建表结构和插入数据 二、查询所有子节点 三、查询所有父节点 四、查询指定节点的根节点 五、查询指定节点的递归路径 六、递归子类 七、递归父类 一、创建表结构和插入数据 CREATE TABLE "REGION" ( "ID" VARCHAR2(36) DEFAULT SYS_GUI…...
FaceFusion源码框架解读
FaceFusion源码框架解读 我的视频讲解:FaceFusion入门教学 FaceFusion官网 FaceFusion是一款开源的AI换脸工具,一款非常好用的换脸工具,操作简单,上手容易。 Facefusion:GitHub - facefusion/facefusion: Next gene…...
React项目知识积累(三)
1.primary-color 公共样式 less文件中的primary-color,会在config.js中的theme中统一写,方便统一更改。 config.js: theme{"primary-color":"#f0f0f0","font-size":"16px", }less: .classname{color:primary-…...
前端实现打印功能
1、引入打印相关的库 在您的Vue项目中,需要先安装一个用于打印的库,如print-js。您可以通过以下命令安装: npm install print-js --save2、在组件中引入并使用,在需要实现打印功能的组件中,先import print-js模块: import print…...
创建型模式之工厂模式
文章目录 概述1.简单工厂概念结构图 2.工厂方法概念结构图 3.抽象工厂概念结构图 小结 概述 工厂模式用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。 其实,工厂还可以…...
「动态规划」按摩师
力扣原题链接,点击跳转。 一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列nums,总共有n个预约,替按摩师找到…...
小程序-滚动触底-页面列表数据无限加载
// index/index.vue <template> <!-- 自定义导航栏 --> <CustomNavbar /> <scroll-view scrolltolower"onScrolltolower" scroll-y class"scroll-view"> <!-- 猜你喜欢 --> <Guess ref"guessRef" /> </s…...
监控上网的软件有哪些?含泪推荐的电脑监控软件
监控上网的软件有很多,企业选择的时候应该遵循什么样的原则呢?鄙人愚见,认为以下四项原则是选择监控软件时首要考虑的。 1、功能需求: 监控软件不应该只是起到控制上网的作用,因为一些泄密行为可能是通过USB接口、打印…...
linux系统防火墙开放端口命令
目录 linux相关命令参考文章1.开放端口1.1 开发单个端口1.2 一次性开放多个端口 2.保存设置3.查看所有开放的端口4.查看防火墙状态 linux相关命令参考文章 管理、设置防火墙规则(firewalld): https://download.csdn.net/blog/column/8489557/137911049 i…...
WebGL渲染引擎优化方向——渲染帧率的优化
作者:caven chen 对此内容感兴趣还可以看前文: WebGL渲染引擎优化方向——加载性能优化 前言 WebGL 是一种强大的图形渲染技术,可以在浏览器中快速渲染复杂的 3D 场景。但是,由于 WebGL 的高性能和高质量要求,如果…...
【文献阅读】ESG评级分化和企业绿色创新
ESG评级分化和企业绿色创新 摘要 (1)本研究通过实证探讨了ESG评级差异是否以及如何影响企业绿色创新。以中国上市公司为样本,我们发现ESG评级差异对企业绿色创新有积极的影响 。经过几次稳健性检查后,该结果仍然成立。 ÿ…...
2024-5-6-从0到1手写配置中心Config之实现配置中心客户端
配置加载原理 在Spring中PropertySource类实现了所有属性的实例化。 启动赋值: 定义自定义属性配置源,从config-server获取全局属性;Spring启动时,插入自定义属性配置源;绑定属性会优先使用,给自定义属性…...
【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十一)
课程地址: 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程,一套精通鸿蒙应用开发 (本篇笔记对应课程第 18 节) P18《17.ArkUI-状态管理Observed 和 ObjectLink》 第一件事:嵌套对象的类型上加上 Observed 装饰器…...
Amesim示例篇-案例1:空间中的铝块散热
前言 本文将通过一个案例继续对Thermal库的元件进一步讲解。 案例1:一个300mm*300mm*1000mm(长*宽*高)的铝板初始温度为45℃,竖直在环境为25℃的空间内静置60min。对流换热系数设置为5W/m2K。本文将通过两种建模方法对铝块的温度…...
深度神经网络——什么是自动编码器?
自动编码器 自动编码器(Autoencoders)是无监督学习领域中一种重要的神经网络架构,它们主要用于数据压缩和特征学习。 自动编码器的定义: 自动编码器是一种无监督机器学习算法,它通过反向传播进行训练,目标…...
初见flyway
flyway (一种数据库版本控制工具 document) 两种文件 V 和 R V: V 开头是不可重复执行的文件,每次修改完都该更改名称 R: R 开头是可重复执行的文件,需要保证内部sql都是可以重复执行的 名称格式: V__table_name.sql, R__table_name.sql …...
Python自动化办公:3种方法给PDF批量添加文字水印(附完整代码)
Python自动化办公:3种高效PDF水印方案与实战技巧 合同专员小李每周要处理上百份对外发送的PDF合同,手动添加"机密"水印让她疲惫不堪。直到发现Python能自动完成这项工作,她的效率提升了10倍——这正是现代办公人员亟需掌握的技能。…...
3大核心功能解析:飞秋Mac版如何实现高效局域网通信
3大核心功能解析:飞秋Mac版如何实现高效局域网通信 【免费下载链接】feiq 基于qt实现的mac版飞秋,遵循飞秋协议(飞鸽扩展协议),支持多项飞秋特有功能 项目地址: https://gitcode.com/gh_mirrors/fe/feiq 还在为Mac与Windows设备间的通…...
hello-uniapp技术债务管理:平衡开发速度与代码质量的终极指南 [特殊字符]
hello-uniapp技术债务管理:平衡开发速度与代码质量的终极指南 🚀 【免费下载链接】hello-uniapp uni-app框架演示示例 项目地址: https://gitcode.com/gh_mirrors/he/hello-uniapp 在快速发展的移动应用开发领域,hello-uniapp作为uni-…...
你的QQ空间记忆会消失吗?GetQzonehistory终极备份方案让你完整珍藏青春印记
你的QQ空间记忆会消失吗?GetQzonehistory终极备份方案让你完整珍藏青春印记 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 在数字时代,我们的青春记忆大多散落在…...
Phi-3-mini-128k-instruct企业级应用:基于Dify构建智能客服知识库
Phi-3-mini-128k-instruct企业级应用:基于Dify构建智能客服知识库 最近和几个做企业服务的朋友聊天,大家普遍有个头疼的问题:客服团队每天要处理大量重复的产品咨询和技术问题,人力成本高不说,新员工培训周期还特别长…...
【实战指南】Windows10链路聚合配置:从LBFO报错到NetSwitchTeam的完美切换
1. 为什么需要链路聚合?从原理到应用场景 当你用笔记本连着WiFi下载大文件时,突然需要视频会议,是不是常遇到网络卡顿?这就是单网口的瓶颈。链路聚合(Link Aggregation)就像把多条车道合并成高速公路&#…...
一天一个开源项目(第63篇):lil agents - 住在 macOS Dock 上的迷你 AI 伙伴
引言 “Tiny AI companions that live on your macOS dock.” 这是「一天一个开源项目」系列的第 63 篇文章。今天介绍的项目是 lil agents(GitHub)。 很多人把 AI 编程助手放在 IDE 里(Cursor / VSCode 插件),或者放…...
主流AI培训机构评测:关键指标全对比
引言 随着AI技术的飞速发展,AI培训市场也日益繁荣。然而,无论是企业还是创业者在选择AI培训机构时,都面临着诸多挑战。企业端存在缺乏数字化运营团队、不懂AI工具使用、短视频内容生产效率低、打造个人IP能力不足、同城获客成本高且精准度低…...
Fish Speech 1.5语音克隆5分钟快速部署:零基础小白也能玩转AI配音
Fish Speech 1.5语音克隆5分钟快速部署:零基础小白也能玩转AI配音 1. 认识Fish Speech 1.5语音克隆技术 Fish Speech 1.5是当前最易上手的开源语音克隆工具之一。想象一下,你只需要录制10秒钟的语音样本,就能让AI用你的声音朗读任何文本——…...
新手必看:AI人脸隐私卫士从部署到使用,完整操作指南
新手必看:AI人脸隐私卫士从部署到使用,完整操作指南 1. 引言:为什么需要AI人脸隐私保护? 在日常生活中,我们经常需要分享照片到社交媒体或工作群聊。但你是否想过,这些照片中可能无意间暴露了他人的隐私信…...
