嵌入式Linux驱动开发(一)chrdevbase虚拟字符设备

news2024/9/24 15:22:13

Linux下三大驱动:字符设备,块设备,网络设备。一个硬件可以从属于不同的设备分类。

0. Linux应用程序对驱动程序的调用流程

在这里插入图片描述
在这里插入图片描述

  驱动加载成功后会在/dev目录下生成一个文件,对该文件的操作就是对设备的操作。当我们在用户态调用一个函数,会经过“系统调用(C库的一部分)”方法陷入内核空间,内核空间中有对应的驱动函数,由此实现控制。应用访问内核资源的三个方式:系统调用,异常(中断),陷入(软中断)
  Linux内核文件include/linux/fs.h中file_operations结构体保存了内核驱动操作函数集合。
  **Linux驱动有两种运行方式:①将驱动编译进内核,内核启动后自动运行;②驱动编译成.ko模块,内核启动后需要以“insmod”命令加载。**调试驱动一般编译为模块,避免每次都编译一遍linux。

1. 字符驱动设备

  字符设备是指逐字节流进行顺序读写操作的设备,比如LED,KEY,IIC,SPI,LCD等。

1.1 驱动模块加载卸载

字符驱动设备加载卸载函数模板:

static struct file_operations test_fops;  # 设备具体操作函数在这里面

/* 驱动入口函数 */
static int __init xxx_init(void)          # 定义xxx_init驱动入口函数,使用__init修饰
{
	/* 入口函数具体内容 */
	int retvalue = 0;
	/* 注册字符设备驱动 */
	retvalue = register_chrdev(200, "chrtest", &test_fops);
	if(retvalue < 0){
		/* 字符设备注册失败,自行处理 */
	}
	return 0;
}
 
/* 驱动出口函数 */
static void __exit xxx_exit(void)
{
	/* 出口函数具体内容 */
	/* 注销字符设备驱动 */
	unregister_chrdev(200, "chrtest");
}

/* 将上面两个函数指定为驱动的入口和出口函数 */
module_init(xxx_init);      # 调用函数module_init注册xxx_init为驱动入口函数,加载驱动时调用
module_exit(xxx_exit);

模块加载命令:
①insmod:如果一个模块依赖另一个模块,必须先insmod依赖模块。
modprobe:会自动分析依赖并全部加载。
模块卸载命令:
rmmod:对应insmod。
②modprobe -r:对应modpeobe。全部卸载依赖可能导致其它模块受到影响。

1.2 字符设备加载卸载

  模块加载之后需要进行字符设备加载,字符设备注册一般在模块入口函数xxx_init中进行,注销在模块卸载函数xxx_exit中进行。函数原型为:

# major-主设备号	name-设备名	   fops-指向设备操作函数集合变量
static inline int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops)
static inline void unregister_chrdev(unsigned int major, const char *name)

  注册设备时必须确保主设备号没被占用,使用**“cat /proc/devices”查看当前已用设备号**。

1.3 设备具体操作函数

假设对设备有打开(open)关闭(release),读(read)写(write)操作的要求。
App中的函数就这样绑定到了驱动函数。

 static struct file_operations test_fops = {
	.owner = THIS_MODULE, 
	.open = chrtest_open,
	.read = chrtest_read,
	.write = chrtest_write,
	.release = chrtest_release,
};

1.4 添加LICENSE和作者信息

MODULE_LICENSE("GPL");           # 必须添加,采用GPL协议
MODULE_AUTHOR("finches");        # 可加可不加

2. Linux设备号

  Linux中每个设备都有设备号,由主设备号次设备号组成。
  主设备号表示某一个具体的驱动,次设备号表示使用这个驱动的各个设备。设备号由dev_t数据类型表示(其实就是unsigned int 32类型),其中高12位主设备号,低20位次设备号。所以主设备号范围为0-4095。

2.1 主设备号分配

1)静态分配:开发者指定一个设备号,使用“cat /proc/devices”查看,没被占用就可以用。
2)动态分配:注册字符设备之前申请一个设备号,卸载时释放设备号。推荐使用。
 设备号申请函数:

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
# dev:保存申请到的设备号
# baseminor:次设备号起始地址,一个alloc_chrdev_region可以申请多个主设备号相同,次设备号不同的硬件
# count:申请设备数
# name:设备名

 设备号释放函数:

void unregister_chrdev_region(dev_t from, unsigned count)
# from:要释放的设备号
# count:从from开始,要释放的设备号数量

3. chrdevbase字符设备驱动开发实验

chrdevbase设备是一个虚拟设备,具有各100字节的读和写缓冲区。
1)编写驱动文件chrdevbase.c:
2)编写测试APP:

# open:pathname-要打开的设备或文件名。   flags-打开模式。
# 打开模式(必选的3个):O_RDONLY只读;O_WRONLY只写;O_RDWR读写。
# 返回值:打开成功返回文件的描述符
int open(const char *pathname, int flags)

# read:fd-要读取的文件描述符。       buf:数据读取到该缓冲区。     count:要读取的字节数。
# 返回值:读取成功返回读取到的字节数,返回0代表读到了文件末尾。
ssize_t read(int fd, void *buf, size_t count)

# write:fd-要进行写的文件描述符。
# 返回值:返回写入的字节数。        返回0表示没有写入任何数据。
ssize_t write(int fd, const void *buf, size_t count);

# close:
int close(int fd);

3)编译驱动程序为.ko模块:
在这里插入图片描述
4)测试应用:

arm-linux-gnueabihf-gcc chrdevbaseApp.c -o chrdevbaseApp    # 编译
file chrdevbaseApp                                          # 查看应用信息

在ubuntu中将.ko和App拷贝到/lib/modules/4.1.15下,在开发板上运行:
1)加载驱动模块并检查

# 加载模块
modprobe chrdevbase.ko
# 若报错没有‘modules.dep’,输入‘depmod’命令即可自动生成

# 查看当前存在的模块
lsmod

# 查看系统所有设备
cat /proc/devices

2)创建设备节点文件

# 创建了chrdevbase节点文件,c表示字符设备,200为主设备号,0是次设备号
mknod /dev/chrdevbase c 200 0

3)设备操作测试
在这里插入图片描述
返回第一行:驱动程序中的chrdevbase_read函数输出信息
返回第二行:App输出的接收到的数据
4)卸载驱动模块

rmmod chrdevbase.ko

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

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

相关文章

Element-UI实现复杂table表格结构

Element-UI组件el-table用于展示多条结构类似的数据&#xff0c;可对数据进行排序、筛选、对比或其他自定义操作。将使用到以下两项&#xff0c;来完成今天demo演示&#xff1a;多级表头&#xff1a;数据结构比较复杂的时候&#xff0c;可使用多级表头来展现数据的层次关系。合…

Web3中文|Web3CN加速器第二期「Web3项目征集」火热报名

Web3CN加速器第二期「Web3项目征集」火热征集中&#xff0c;本次征集活动是由Web3CN加速器联合专业web3媒体Web3CN、VC机构Tiger VC DAO核心发起&#xff0c;数百家加密VC机构、加密社区等联合发起的&#xff0c;为早期Web3创新创业项目提供加速服务。如果你正在进行web3相关的…

VC常见问题(.obj : error LNK2019、fatal error C1083、编译64位Detours)

VC常用问题VC常见问题*.obj : error LNK2019: 无法解析的外部符号 __imp_FindWindow ,该符号在函数 YAWindows环境下用nmake编译常见问题fatal error C1083: 无法打开包括文件:“excpt.h”vs2012编译64位Detours&#xff08;其他vs版本同理&#xff09;vs项目设置选项编译使用了…

Java基础面试题(三)

Java基础面试题 一、JavaWeb专题 1.HTTP响应码有哪些 1、1xx&#xff08;临时响应&#xff09; 2、2xx&#xff08;成功&#xff09; 3、3xx&#xff08;重定向&#xff09;&#xff1a;表示要完成请求需要进一步操作 4、4xx&#xff08;错误&#xff09;&#xff1a;表示请…

Nuxt实战教程基础-Day01

Nuxt实战教程基础-Day01Nuxt是什么&#xff1f;Nuxt.js框架是如何运作的&#xff1f;Nuxt特性流程图服务端渲染(通过 SSR)单页应用程序 (SPA)静态化 (预渲染)Nuxt优缺点优点缺点安装运行项目总结前言&#xff1a;本教程基于Nuxt2&#xff0c;作为教程的第一天&#xff0c;我们先…

BUUCTF-[RoarCTF2019]polyre

题目下载&#xff1a;下载 这道题目是一个关于控制流平坦化和虚假流程。 首先了解一下控制流平坦化&#xff1a;利用符号执行去除控制流平坦化 - 博客 - 腾讯安全应急响应中心https://www.cnblogs.com/zhwer/p/14081454.htmlbuuctf RoarCTF2019 polyre writeup - 『脱壳破解区…

单点登录的几种实现方式探讨

单点登录&#xff08;Single Sign On&#xff09;&#xff0c;简称为 SSO&#xff0c;是解决企业内部的一系列产品登录问题的方案。SSO 的定义是在多个应用系统中&#xff0c;用户只需要登录一次就可以访问所有相互信任的应用系统&#xff0c;用于减少用户重复的登录操作&#…

PyTorch的自动微分(autograd)

PyTorch的自动微分(autograd) 计算图 计算图是用来描述运算的有向无环图 计算图有两个主要元素&#xff1a;结点&#xff08;Node&#xff09;和边&#xff08;Edge&#xff09; 结点表示数据&#xff0c;如向量、矩阵、张量 边表示运算&#xff0c;如加减乘除卷积等 用计算…

共话开源 | 开放原子开源基金会专题调研openKylin社区!

3月8日&#xff0c;开放原子开源基金会秘书长冯冠霖、运营部部长李博、业务发展部部长朱其罡、研发部副部长周济一行莅临openKylin社区调研交流&#xff0c;麒麟软件高级副总经理韩乃平、副总裁董军平、终端研发部副总经理陆展、产品规划部经理常亚武、市场与政府事务部高级经理…

力扣sql简单篇练习(二十五)

力扣sql简单篇练习(二十五) 1 无效的推文 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # Write your MySQL query statement below SELECT tweet_id FROM Tweets WHERE CHAR_LENGTH(content)>151.3 运行截图 2 求关注者的数量 2.1 基本题目内…

【Linux实战篇】二、在Linux上部署各类软件

一、实战章节&#xff1a;在Linux上部署各类软件 二、MySQL数据库管理系统安装部署【简单】 简介 MySQL数据库管理系统&#xff08;后续简称MySQL&#xff09;&#xff0c;是一款知名的数据库系统&#xff0c;其特点是&#xff1a;轻量、简单、功能丰富。 MySQL数据库可谓是…

在矩池云运行 Stable Diffusion web UI,使用v1.5模型和 ControlNet 插件

今天给大家介绍下如何在矩池云使用 Stable Diffusion web UI v1.5 模型和 Stable Diffusion ControlNet 插件。 租用机器 租用机器需要选择内存大于8G的机器&#xff0c;比如 A2000&#xff0c;不然 Stable Diffusion web UI 启动加载模型会失败。&#xff08;Killed 内存不足…

近20个省市加快房屋网签备案,君子签电子签章助推掌上办理

2020年以来&#xff0c;上海、北京、深圳、长沙、武汉、杭州、山东、郑州、西安、佛山、青岛、江门、昆明、韶关、南京、石家庄等全国近20个省市纷纷响应住建部政策要求&#xff0c;鼓励使用电子签名、电子签章等技术加快推动商品房、二手房或租赁房交易合同网签备案&#xff0…

是面试官放水,还是公司实在是太缺人?这都没挂,字节原来这么容易进...

字节是大企业&#xff0c;是不是很难进去啊&#xff1f;” “在华为做软件测试&#xff0c;能得到很好的发展吗&#xff1f; 一进去就有10K&#xff0c;其实也没有想的那么难” 直到现在&#xff0c;心情都还是无比激动&#xff01; 本人211非科班&#xff0c;之前在字节和腾讯…

UEFI开发探索101 – PCD探究(helloworld中的使用)

2 如何使用PCD PCD可以使用于UEFI存在的大部分时间&#xff0c;除了在SEC阶段、早期的PEI和DXE阶段&#xff0c;基本都可以访问。在使用前&#xff0c;我们需要搞清楚PCD的结构和类型。 2.1 PCD的类型 PCD变量的格式有点像结构体&#xff1a; TokenSpaceGuidCName.PcdCName …

【SpringCloud】SpringCloud教程之Gateway实战

目录前言SpringCloud Gatewy网关一.网关功能和工作原理二.网关的类型三.搭建网关四.路由断言工厂(Route Predicate Factory)五.路由过滤器(属于GatewayFilter)六.DefaultFilter过滤器(属于GatewayFilter)七.全局过滤器(GlobalFilter)八.过滤器执行顺序九.Gateway解决跨域问题前…

什么蓝牙耳机适合长时间佩戴?长久佩戴舒适的蓝牙耳机

因为我每天使用蓝牙耳机时间比较长&#xff0c;而且在上下班的路上经常会听听音乐&#xff0c;所以还是非常在意耳机的舒适度&#xff0c;有些耳机压迫感很明显&#xff0c;用久了感觉很不舒服&#xff0c;近期就购入了许多蓝牙耳机&#xff0c;终于整理出了一起佩戴舒适度高的…

vue+echarts.js 实现中国地图——根据数值表示省份的深浅——技能提升

最近在写后台管理系统&#xff0c;遇到一个需求就是 中国地图根据数值 展示深浅颜色。 效果图如下&#xff1a; 直接上代码&#xff1a; 1.html部分 <div id"Map"></div>2.css部分——一定要设置尺寸 #Map {width: 100%;height: 400px; }3.js部分 …

【立体匹配论文阅读】AANet: Adaptive Aggregation Network for Efficient Stereo Matching

Authors: Haofei Xu, Juyong Zhang Link: https://arxiv.org/abs/2004.09548 Years: 2020 Credit Novelty and Question set up 主流的立体匹配模型的代价聚合操作主要用了3D卷积&#xff0c;这部分操作的算力和内存消耗过大&#xff0c;因此作者提出一种新的模型AANet&#x…

C#项目--GridControl数据绑定及数据引入

系列文章 C#项目–业务单据号生成器&#xff08;定义规则、自动编号、流水号&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129129787 C#项目–开始日期结束日期范围计算&#xff08;上周、本周、明年、前年等&#xff09; 本文链接&…