字符设备驱动流程

字符设备驱动:

linux系统驱动程序分为三大类,字符设备驱动块设备驱动网络设备驱动。其中字符设备驱动是使用最多的一种,从点灯到llC,SPI,音频设备等的驱动都是字符设备驱动。块设备和网络设备驱动要比字符设备驱动复杂,就是因为其复杂所以半导体厂商一般都给我们编写好了,大多数情况下都是直接可以使用的。所谓的块设备驱动就是存储器设备的驱动,比如EMMC、NAND、SD卡和U盘等存储设备,因为这些存储设备的特点是以存储块为基础,因此叫做块设备。网络设备驱动就更好理解了,就是网络驱动,不管是有线的还是无线的,都属于网络设备驱动的范畴。一个设备可以属手多种设备驱动类型,比如USB WIFI,由于其使用USB接口,所以属于字符设备,但是其又能上网,所以也属于网络设备驱动。

字符设备驱动简介:

字符设备是Linux驱动中最基本的一类设备驱动,字符设备就是—个—个字节,按照字节流进行读写操作的设备,读写数据是分先后顺序的。比如我们最常见的点灯、按键、IIC、SPI、LCD等等都是字符设备,这些设备的驱动就叫做字符设备驱动。

linux系统中万物皆文件,驱动程序加载后会在/dev目录下生成一个对应的文件,如/dev/led。应用程序就是先用open打开该文件,用write控制led的亮灭,用read读取led的亮灭,用完之后用close关闭该文件。
这里需要注意的是,应用程序运行在用户空间,驱动程序运行在内核空间。应用程序必须使用一个叫做“系统调用”的方法来实现从用户空间“陷入”到内核空间,这样才能实现对底层驱动的操作。一个open函数执行的过程如下

linux源码中字符设备驱动程序存放在driver/char目录下,我们也可以将我们自己的驱动程序保存在该目录下

1)写一个加载和卸载驱动:



16和17行分别用两个带参宏指出驱动程序初始 化入口点和退出入口点。

19、20表示该驱动程序遵守的协议和 驱动程序的编写者。

2)注册设备号

字符设备驱动程序 将来被linux加载的时候需要注册这个驱动程序。其实无论哪种 驱动程序,按照linux的做法在加载时都需要注册

int register_chrdev(unsigned int major, const char *name, 
const struct file_operations *fops);

参数:

1.unsigned int major:主设备号(一个字符设备或者块设备都有一个主设备号和次设备号。主设备号和次设备号统称为设备号。主设备号用来表示一个特定的驱动程序。次设备号用来表示使用该驱动程序的设备,注意:设置一个静态的主设备号,比如200。设置时一定要注意不能使 用已经用了的主设备号):使用cat /proc/devices命令即可查看

2.const char *name:你的驱动程序起一个名字

3.struct file_operations *fops:这是一个指向file_operations结构 体变量的指针,这个结构体里面的成员绝大多数都是函数的指针。如常用的

        ①  open 函数用于打开设备文件

        ② release 函数用于释放(关闭)设备文件,与应用程序中的 close 函数对应

        ③ read 函数用于读取设备文件

        ④ write 函数用于向设备文件写入(发送)数据

        ⑤ owner 拥有该结构体的模块的指针,一般设置为 THIS_MODULE

为了调用注册字符设备驱动 函数,不得不先准备一个file_operations结构体变量,而这个结 构体变量中必要的成员,必须提前准备几个函数。注意:使用copy_to_user函数把内核空间的数据拷贝到用户空间;

然后定义一个file_operations结构体变量,并将函数入口地址赋 值给各自的成员

以上就是字符驱动程序的编写,那如何编译呢?有两种方法

方法一:

第一种方法是告诉linux的Makefile我们添加了一个新的驱动程序, 这种方法需要我们的驱动源码就放在driver/char目录中

1)打开 drivers/char/Kconfig 文件并添加如下内容

Kconfig文件被称之为内核配置文件,这里我们添加了一个名为 FIRST_DRIVER的配置选项,该配置选项为三态的,所谓三态是 指将来的编译结果可以是模块可以直接编译进内核可以不编译default m是指默认编译成模块。最后那段是帮助文本。

2)运行make menuconfig,依次进入Device Driver- >Character devices;看到My first driver按空格切换选择’M’ ,编译成模块,以方便之后的调试

3)打开 drivers/char/Makefile并添加下面内容(需要在 Makefile 中把内核配置选项和真正的源代码联系起来)

4)之后在源码顶层目录下执行make modules就可以完成编译

· 编译完成之后在driver/char目录下可以找到一个名为 first_driver.ko文件,这个就是我们需要的驱动程序

· 将first_driver.ko通过nfs复制到开发板上,使用insmod xxx.ko命令 加载驱动程序

· 使用lsmod查看已经加载的驱动

· 使用rmmod xxx卸载驱动程序,注意不用加.ko

5)加载好驱动程序以后,查看一下/dev目录,这里并没有出现我们 所说的设备文件,这是因为目前我们的驱动程序还不能自动创 建设备文件;用手动的方法创建设备文件,命令为:

mknod [OPTIONS] NAME TYPE MAJOR MINOR

该命令中[OPTIONS]选项可不填;NAME就是/dev下的设备文件 名;TYPE是设备型号,这里是字符设备用c表示;MAJOR主设备 号;MINOR子设备号。

mknod /dev/first_device c 200 0

以后应用程序就是以文件 /dev/first作为入口点调用驱动程序的。

方法二:

将我们写好的驱动 源码放在任意一个文件夹内,如linux源码目录下的my_driver目录, 并在该目录下创建一个Makefile文件

 第1行:获得linux源码顶层目录,根据实际情况填写

 第2行:获得驱动源码所在目录

 第3行:定义目标文件并指定目标文件为模块形式

 第8行:具体的编译命令,后面的 modules 表示编译模块,-C 表示将当前的工作 目录切换到指定目录中,也就是 KERNERLDIR 目录。M 表示模块源码目 录,”make modules”命令中加入 M=dir 以后程序会自动到指定的 dir 目录中读取 模块的源码并将其编译为.ko 文件

 之后使用make命令编译同样得到xxx.ko文件,加载什么的操作就和之前一样了。

程序调用:

正如之前所提到的,驱动程序的调用是通过应用程序的文件IO 实现的。所以调用驱动程序就是编写一个简单的文件IO程序。在nfs/rootfs下。

使用下面这个命令进行交叉编译,生成一个.app的可执行文件

执行.app

这样字符驱动编写流程就完成了。

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

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

相关文章

5.12 VUE项目实现Google 第三方登录

VUE项目实现Google 第三方登录 目录一、Google开发者平台配置1. 新建项目2. 配置 OAuth 权限请求页面并选择范围3. 启动API 和 服务 二、 登录代码实现1. 参考Google官网文档2. Google官网代码生成器3. 项目中实装 目录 一、Google开发者平台配置 Google Cloud: https://conso…

盒模型,BFC以及行内块级元素

一.盒模型篇 css基础框盒模型介绍: 当对一个文档进行布局的时候,浏览器的渲染引擎会根据标准之一的css基础框盒模型,将所有元素表示为一个个矩形的盒子,每个盒子由四部分组成,分别是内容 内边距 边框 外边距&#xff…

如何快速搭建nginx虚拟主机

华子目录 实验1:基于IP地址的虚拟主机原理 实验2:基于端口号的虚拟主机原理 实验3:基于域名的虚拟主机原理 实验1:基于IP地址的虚拟主机 原理 如果一台服务器有多个IP地址,而且每个IP地址与服务器上部署的每个网站一一…

beacon-chain+ethereum打镜像及推送镜像

部署详情 1、编写Dockerfile镜像 beacon chain对应Dockerfile文件 # 使用 Ubuntu 20.04 作为基础镜像 FROM ubuntu:20.04# 安装必要的系统库和工具 RUN apt-get update && \apt-get install -y curl && \apt-get clean# 创建存储数据的目录 RUN mkdir -p /dat…

HarmonyOS开发案例:【计算器】

介绍 基于基础组件、容器组件,实现一个支持加减乘除混合运算的计算器。 说明: 由于数字都是双精度浮点数,在计算机中是二进制存储数据的,因此小数和非安全整数(超过整数的安全范围[-Math.pow(2, 53),Math.…

【稳定检索|投稿优惠】2024年新能源技术与环境工程国际会议(ICNTEE 2024)

2024 International Conference on New Energy Technology and Environmental Engineering 一、大会信息 会议名称:2024年新能源技术与环境工程国际会议会议简称:ICNTEE 2024收录检索:提交Ei Compendex,CPCI,CNKI,Google Scholar等会议官网&…

【运维】如何安装ubuntu-24.04? 如何分区?

如何安装ubuntu-24.04?如何分区 经过一系列折腾,我总结了这几点: (1)在BIOS启动设置里,如果是GPT的硬盘格式,那么对应的就是UEFI的启动方式;如果是MBR的硬盘格式,那么对…

森林消防的新利器:高扬程水泵的应用与优势/恒峰智慧科技

森林是地球上的绿色肺叶,保护森林安全对于维护生态平衡和人类生存环境至关重要。在森林消防领域,高效、快速的灭火设备是保障森林安全的重要武器。近年来,高扬程水泵作为一种新型的消防设备,在森林消防中发挥了重要作用。本文将详…

密室逃脱游戏-第12届蓝桥杯省赛Python真题精选

[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第58讲。 密室逃脱游戏&…

idea Maven 插件 项目多环境打包配置

背景 不同环境的配置文件不一样,打包方式也有差异 1. 准备配置文件 这里 local 为本地开发环境 可改为 dev 名称自定义 test 为测试环境 prod 为生产环境 根据项目业务自行定义 application.yml 配置: spring:profiles:#对应pom中的配置active: spring.…

3月10日PMP考试成绩已出!教你如何快速查询

3月10日PMP考试终于出成绩啦! 2024年3月10日PMP考试成绩正在陆续分批次发布,预计本周成绩会全部出来,目前已经有同学查询到自己的成绩,暂时没查到成绩的同学请耐心等待。 在等待成绩的同时,大家可以先对PMP证书和成绩…

CST电磁仿真软件远场源的导出调用和提取结果【小白必看】

远场源的导出&调用(1) 提取Hybrid仿真所需的远场源! Post-Processing > Tools > Result Templates Tools >Farfield and Antenna Properties > Export Farfields As Source 混合求解(Hybrid Simulation)是对安装在舰船等大型平台上的天线进行仿真…

为什么会查询不到DNS信息?怎么排查?

DNS(域名系统)是将域名转换为相应 IP 地址的关键系统。查询 DNS 信息具有重要作用,通过查询 DNS 信息,我们可以知道域名对应的 IP 地址,这是最主要的信息,使设备能与目标服务器进行通信;其次是域…

IPO压力应变桥信号处理系列隔离放大器 差分信号隔离转换0-10mV/0-20mV/0-±10mV/0-±20mV转4-20mA/0-5V/0-10V

概述: IPO压力应变桥信号处理系列隔离放大器是一种将差分输入信号隔离放大、转换成按比例输出的直流信号混合集成厚模电路。产品广泛应用在电力、远程监控、仪器仪表、医疗设备、工业自控等行业。该模块内部嵌入了一个高效微功率的电源,向输入端和输出端…

快速了解OV证书和DV证书的区别及使用场景

OV(Organization Validation,组织验证)证书和DV(Domain Validation,域名验证)证书都是SSL/TLS证书,用于保护网站数据传输的安全性和提供身份验证,但两者在验证深度、信任级别、提供的…

【Java EE】多线程(三)线程状态

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更…

Spring AOP(3)

目录 Spring AOP原理 代理模式 代理模式中的主要角色 静态代理 动态代理 总结:面试题 什么是AOP? Spring AOP实现的方式有哪些? Spring AOP实现原理 Spring使用的是哪种代理方式? JDK和CGLIB动态代理的区别? Spring AOP原理 代理模式 代理模式, 也叫委托模式. …

JavaScript 流程控制语句详解:if语句、switch语句、while循环、for循环等

JavaScript,作为一种广泛使用的编程语言,它的流程控制语句是构建逻辑和实现功能的基础。流程控制语句包括条件语句、循环语句和转向语句,它们是编程中不可或缺的部分。 接下来,我们将一一解析这些语句,带你走进JavaSc…

刷代码随想录有感(58):二叉树的最近公共祖先

题干: 代码: class Solution { public:TreeNode* traversal(TreeNode* root, TreeNode* p, TreeNode* q){if(root NULL)return NULL;if(root p || root q)return root;TreeNode* left traversal(root->left, p, q);TreeNode* right traversal(r…

NVIDIA Omniverse Cloud API支持数字孪生开发,可解决复杂AI问题 | 最新快讯

在全球范围内,价值超过 50 万亿美元的重工业市场,正在竞相实现数字化。 基于此,为帮助数字孪生技术更好地赋能千行百业,AI 企业 NVIDIA 在架构底层算力的同时,也搭建了 NVIDIA AI Enterprise 和 Omniverse 两大平台。 …