【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 …...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...