字符设备驱动05 | 学习笔记

简介: 快速学习字符设备驱动05

开发者学堂课程【物联网开发 - Linux驱动开发实操演练:字符设备驱动05】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/657/detail/10877


字符设备驱动05


内容介绍

一、课前知识回顾

二、字符设备驱动编写


一、课前知识回顾

所有的字符驱动都是基于内核模块完成的。

内核模块三要素:入口,出口函数,GPL 的声明

字符设备驱动的框架是围绕一个 cdv 结构体来进行的。

首先,第一步是申请 cdv 结构体,为 cdv 结构体申请一部分空间。

再进行初始化,完成后添加到内核。

在过程中需要一个设备号,结合上节分配设备号和申请注册设备号两种方法

将驱动注册到内核,执行初始化和添加到内核的动作。

将驱动从内核中卸载,应将申请到的资源释放掉,同时将字符设备驱动从内核中注销掉。

再卸载时,调用卸载函数或目标函数。

所以这些动作是在相应的位置去完成的

首先分配初始化与添加这些动作应该放在入口处去进行,加载时去执行。

 

二、字符设备驱动编写

1、第一步

实际上是为 cdv 去分配地址空间,此过程需要用到 cdv-t 类型的设备号。在使用 cdev-add 字符设备前,必须去分配一个设备号。

在一个位置去申请设备号存在两种方法:

(1)自动分配alloc -chrdev-region

(2)指定设备号注册register-chrdev-region

建议使用 alloc -chrdev-region,因为使用的设备号由内核来管理。

内核知道当前设备号是否使用,将未使用的设备号分配出来。一般情况下均可成功。若去注册,并不支出设备号是否使用,有可能失败。

因此建议使用 alloc -chrdev-region,

第一步:

//@alloc dev-t devno

alloc -chrdev-region(dev-t*,unsigned ,unsigned count char*)

根据自动补全函数的类型去传递时长

根据已知的alloc -chrdev-region的功能参数返回值

第一个是传入 dev-t 数据类型的指针,目的获取设备号以后,保存地址。

因此使用前,定义一个 dev-t 类型的设备号 Dev-t devno。

传入 dev-t* 时,传入地址,可以将 alloc  dev-t devno 可作为主设备号。

第二个

unsigned baseminor

次设备号的起始

进行宏定义

#define BASEMINOR 0

#define COUNT    3

#define  NAME   “chrdev-demo”

进行参数传递

alloc -chrdev-region(devno BASEMINNOR COUNT NAME )

接下来,由于存在失败的可能,进行返回值。

定义一个变量来接受返回值

Int ret

Ret =alloc -chrdev-region(devno BASEMINNOR COUNT NAME )

If(ret<0){

Printk(KERN-ERR“alloc -chrdev-region failed...\n”);

Retun ret;

} 

2、第二步

//1.alloc cdev

分配 cdev 结构体

运用函数 Cdev-alloc()

对于该函数,是没有参数的,

存在返回值,返回值为结构体指针

定义结构体指针变量接收返回值

Cdevp

对于 Cdev-alloc 返回结构体,若失败返回为空,

因此进行判断

If(NULL==cdevp {

Retun=ENOMEM;

}

失败最大可能为内存不够,添加提示语句

If(NULL==cdevp)

{

Prink(kern-err:cdev-alloc failled...\N”);

Retun=ENOMEM;

}

当编写至此时,存在问题

比如说,申请失败后退出,并未释放前面申请的资源

在申请 cdv 结构体失败后,释放掉资源

使用 goto 语句完成处理

Goto err1

跳转到 return 后面

Err1:

Return ret

此时

Ret=-ENOMEN

Goto err2

跳转完成后,释放掉申请的设备号资源

使用 unregister-chrdev-region 函数(devno count)

//2.cdev init

第二步进行初始化

使用函数 cdev-init

返回值为空

需要自己定义一个操作方法级

Fops={

进行初始化,是因为操作方法级是提供应用接口

是对应用设备的接口

对具体设备的控制

因为为初始化完成的内容操作方法级存在很多成员变量,所以当我们使用时便针对使用变量进行初始化。

必须要用到

Open

Release

针对这两个最基本接口进行初始化

Open      =‘

Release   =’

这种方法叫结构体的部分初始化

此外对 Owner 进行赋值

Owner=THIS-MOOULE

Open       =‘

Release    =’

根据函数的数据类型进行定义

Demo-open(struct inode *inode struct file *flip)

{

Return 0;

}

之后加调制语句,如果执行,进行打印

Demo-release (truct inode *inode struct file *flip)

{

Return 0;

}

之后加调制语句,如果执行,进行打印

3、第三步:添加内核管理

//3.cdev add

调用 cdev-add(cdevp,DEVNO, COUNT)函数

返回值代表

如果失败返回错误代码

错误判断

If(ret<0){

Prink(kern-err:cdev-alloc failled...\N”);

}

完成后,进行 goto 跳转释放申请资源

假设只申请设备号资源

跳转到

Err2 进行资源释放

在退出时进行释放资源

Cdev-del (cdevp)

unregister-chrdev-region(devno count)

当设备号申请成功以后

Printk(KERN-INFO “major”=%d\N”MAJOR

(devNo)

进行查看主设备号

相关文章
|
前端开发 JavaScript Java
基于Vue+ElementUI框架实现学生管理系统前端页面设计
基于Vue+ElementUI框架实现学生管理系统前端页面设计
329 1
|
Java jenkins 持续交付
Java项目jar包启动脚本,适用jenkins或定时任务或手动执行
Java项目jar包启动脚本,适用jenkins或定时任务或手动执行
477 3
|
6月前
|
存储 自然语言处理 关系型数据库
《揭开索引的神秘面纱:数据库高效检索的幕后英雄》
在数字化时代,数据库性能直接影响应用效率,而索引作为核心技术,是高效数据检索的关键。它通过构建特殊的数据结构,加速查询、确保唯一性、支持表间关联及优化排序分组操作。创建索引需选择合适的列与类型,避免过度索引,并合理设计复合索引。掌握索引的本质与应用,对提升数据库性能至关重要,也为未来数据价值挖掘奠定基础。
90 25
|
算法 搜索推荐 物联网
基于iBeacon蓝牙定位技术的反向寻车系统:打造高效智能的停车场导航体验
**基于iBeacon的反向寻车系统利用蓝牙信标实现停车场内车辆精确定位。车主停车时绑定手机,通过APP迅速导航至车辆。系统关键组件包括iBeacon硬件部署、数据处理与用户界面设计,采用高精度定位算法、实时数据处理和智能路径规划。随着技术发展,该系统有望在更多公共场所提升停车体验。**
467 1
基于iBeacon蓝牙定位技术的反向寻车系统:打造高效智能的停车场导航体验
|
移动开发 JavaScript 前端开发
UniApp H5 跨域代理配置并使用(配置manifest.json、vue.config.js)
这篇文章介绍了在UniApp H5项目中处理跨域问题的两种方法:通过修改manifest.json文件配置h5设置,或在项目根目录创建vue.config.js文件进行代理配置,并提供了具体的配置代码示例。
UniApp H5 跨域代理配置并使用(配置manifest.json、vue.config.js)
|
关系型数据库 MySQL Linux
CentOS7.9 安装 mysql-8.0.36 踩坑小记
CentOS7.9 安装 mysql-8.0.36排错指南
908 1
|
网络协议 Linux 网络安全
IP 数据包格式 ICMP协议
IP 数据包格式 ICMP协议
|
消息中间件 关系型数据库 MySQL
Maxwell 概述、安装、数据同步【一篇搞定】!
Maxwell 是一个由 Zendesk 开源的用于 MySQL 数据库实时数据捕获和同步的工具,支持多种数据库系统,以 JSON 格式输出变更数据。它实时监控数据库中的更新,将变化传递给其他系统,常用于实时数据管道、数据仓库和事件驱动架构。Maxwell 具有实时性、可配置性和高性能等特点。其工作流程包括 Binlog 解析、数据解析、重构、发布到消息队列(如 Kafka)以及事件处理。安装时需注意 JDK 版本,并配置 MySQL、Zookeeper 和 Kafka。此外,Maxwell 支持定向监听特定库表,并能进行历史和增量数据同步。
2217 1
|
分布式计算 监控 大数据
spark实战:实现分区内求最大值,分区间求和以及获取日志文件固定日期的请求路径
spark实战:实现分区内求最大值,分区间求和以及获取日志文件固定日期的请求路径
175 1
|
JSON 自然语言处理 Java
性能飙升20倍!!! 超高性能协议框架fury完爆protostuff
性能飙升20倍!!! 超高性能协议框架fury完爆protostuff
406 0