驱动基础开发
1、字符设备传统开发模板
字符设备驱动框架,首先我们需要去用module_init这个宏去修饰整个驱动的入口函数,用module_exit去修饰整个驱动的出口函数,然后还需要用MODULE_LICENSE用于声明模块的许可证类型。
在入口函数里面我们需要注册字符设备,使用register_chrdev()注册字符设备,使用class_create来注册区分一个类,在用device_create来为这个类创造一个设备节点,供我们在linux根目录下的dev目录下给应用层程序访问。在register_chrdev注册时最重要的是要提供字符设备的结构体file_operations,这个结构体启动了内核和应用层交互数据的功能。需要实现file_operations结构体的open,write,read,release函数,对应于应用层的open,write,read,close
#include "asm-generic/errno-base.h"
#include "asm-generic/gpio.h"
#include "asm/uaccess.h"
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/timer.h>struct gpios
{int gpio;int irq;char *name;
};static gpois gpios_s[2]={{115,0,"sr51"},
};static int major=0;
static struct class *cls=NULL;static ssize_t sr51_read(struct file *file, char __user *buf, size_t size, loff_t * loff)
{char ker_buf[2]={0};int err=0;err=copy_from_user(ker_buf, buf, 1);if(err){return -EINVAL;}ker_buf[1]=gpio_get_value(gpios_s[0].gpio);copy_to_user(buf, ker_buf,2)return 2;
}static int sr51_release(struct inode *node, struct file *file)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);printk("fd close\n");return 0;}static int sr51_open(struct inode *node, struct file *file)
{printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);return 0;
}ssize_t sr51_write(struct file *file, const char __user *buf , size_t size , loff_t * loff)
{printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);return 0;
}static struct file_operations sr51_driver={.owner=THIS_MODULE,.open=sr51_open,.write=sr51_write,.read=sr51_read,.release=sr51_release,
};static int __init sr51_driver_init(void)
{int err;err=gpio_request(gpios_s[0].gpio, gpios[0].name);if (err < 0) {printk("can not request gpio %s %d\n", gpios_s[0].gpio, gpios[0].name);return -ENODEV;}gpio_direction_output(gpios[0].gpio, 1);major=register_chrdev(0, "sr51",&sr51_driver);cls=class_create(THIS_MODULE,"sr51_class");if(IS_ERR(cls)){printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major,"sr51");return PTR_ERR(cls);}device_create(&cls, NULL, MKDEV(major, 0), NULL, "sr51");return 0;
}static void __exit sr51_driver_exit(void)
{device_destroy(cls, MKDEV(major, 0));unregister_chrdev(major,"sr51");class_destroy(cls);gpio_free(gpios_s[0].gpio);
}module_init(sr51_driver_init);
module_exit(sr51_driver_exit);
MODULE_LICENSE("GPL");
2、不使用register_chrdev的另外一类驱动的注册方法
register_chrdev其实是cdev封装好的一个函数,他其实也会调用cdev_init(),cdev_add(),
初始化设备号的另一种方法
1、int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);
1、dev_t *dev
这个参数是一个指向 dev_t 类型的指针。dev_t 是一个在 <sys/types.h> 中定义的数据类型,用于表示设备号。在调用 alloc_chrdev_region() 函数时,你需要传递一个 dev_t 类型的变量的地址给这个函数。如果函数成功地为你的字符设备驱动程序分配了一个设备号,那么它会将这个设备号存储在 dev 指针所指向的变量中。
2、unsigned baseminor次设备号
3、unsigned count几个次设备号
4、const char *name设备名称
2、void cdev_init(struct cdev *cdev, const struct file_operations *fops);
cdev设备号
fops字符设备结构体
3、int cdev_add(struct cdev *p, dev_t num, unsigned int count);
struct cdev *p:指向已经初始化的cdev结构体的指针。
dev_t num:分配给这个字符设备的设备号。这通常是通过alloc_chrdev_region()函数获得的。
unsigned int count:通常设置为1,除非你的字符设备支持多个次设备号。
3、当下用的最多的驱动开发,设备树加platform总线模型
设备树的作用:用于描述硬件的具体的功能。像gpio控制器,ii2c控制器,io多路复用控制器,spi控制器,中断控制器gic都需要使用设备树去描述这个硬件。
platform总线模型:他是一个虚拟的总线模型,内核里面使用bus_type这个结构体来描述这个虚拟总线,这个虚拟中心又分为左边一部分和右边一部分,左边一部分使用platform_device来描述,这个结构体它可以由程序员编写,也可以直接使用设备树自动生成(目前使用的是这个),而右边是使用的是platform_driver这个是由当下的驱动程序员来编写的,虚拟总线的功能就是让这两个设备相匹配,如果匹配到了,那么驱动就会被加载进内核当中。
3.1他们是怎么匹配到,然后加载进入内核的详细过程
1、设备树通常在系统引导阶段由引导加载器(如U-Boot)从预定义的配置文件加载,并传递给内核,它包含了硬件的层次结构和属性(如内存地址、中断号和GPIO配置等)。
2、设备树中的节点会被映射到内核中的platform_device结构体实例。每个设备节点通常包含compatible属性,此属性用于标识设备类型和需要加载的驱动。(第一次会比对)
3、设备通过platform_device_register函数在内核中注册。这个过程会为设备创建一个platform_device实例,并将其添加到platform_bus_type所代表的总线上。
设备注册后,内核会使用platform_bus_type中的.match函数来查找和该设备兼容的驱动程序。
4、驱动程序使用platform_driver_register函数注册自己,并提供一个platform_driver结构体,其中包含驱动程序的名称、匹配表、以及回调函数,如.probe和.remove。
.match回调函数确定一个驱动程序是否适用于某个特定的设备,这通常是基于设备的compatible属性进行匹配的。
5、当设备和驱动成功匹配时,驱动的.probe函数被调用,这是驱动初始化设备的地方。例如,驱动可能会配置设备使用的GPIO引脚,设置初始状态,或注册更高层的服务(如输入设备或网络接口)。
4、设备树的使用
设备树的常见属性:
compatible:用于在驱动匹配时使用的匹配字符串。
#address-cells:常见于父节点中用于规定子节点使用多少字长来描述硬件的起始地址。
#size-cells:常见于父节点中用于规定子节点使用多少字长来描述硬件的地址长度。
/ {
#address-cells = <1>;
#size-cells = <1>;
memory {
reg = <0x80000000 0x20000000>;
};
};
status:表示这个设备的状态
reg 节点:的本意是 register,用来表示寄存器地址。
但是在设备树里,它可以用来描述一段空间。反正对于 ARM 系统,寄存器和
内存是统一编址的,即访问寄存器时用某块地址,访问内存时用某块地址,在访
问方法上没有区别
chosen 节点:可以通过设备树文件给内核传入一些参数。
相关文章:
驱动基础开发
1、字符设备传统开发模板 字符设备驱动框架,首先我们需要去用module_init这个宏去修饰整个驱动的入口函数,用module_exit去修饰整个驱动的出口函数,然后还需要用MODULE_LICENSE用于声明模块的许可证类型。 在入口函数里面我们需要注册字符设…...
从苹果AppStore看AI开发者生态
从苹果 App Store 看 AI 开发者生态 在人工智能迅速发展的今天,我们不禁要问:未来的 AI 开发者生态将会是什么样子?为了回答这个问题,我们不妨回顾一下移动互联网时代最成功的开发者生态之一——苹果的 App Store。 通过分析 App …...
【Python学习-UI界面】PyQt5 小部件1-Label
QLabel 对象可用作显示不可编辑的文本、图像或动态GIF影片的占位符。 它还可以用作其他小部件的助记键。 标签可以显示普通文本、超链接或富文本。 1、普通文本 直接双击输入即可 2、添加超链接 选中对应Label,右键选择多信息文本,添加链接,…...
【Linux详解】进度条实现 Linux下git 的远程上传
📃个人主页:island1314 🔥个人专栏:Linux—登神长阶 ⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞 🚀前言 &#x…...
Android进阶之路 - res、raw、assets 资源解析、区别对比
那天遇到一个资源目录层级的问题,索性重新整理记录一下,希望能帮到如吾往昔之少年的你们,哈哈哈哈哈哈… 一脸茫然,越写越多,时间成本属实有点大,就当一起来基础扫盲吧 resdrawablemipmapvaluescolor asset…...
从数字化到数智化:消费零售企业如何实现门店数智化管理?
随着信息技术的飞速发展,数字化已成为企业转型的必经之路。然而,数字化本身并不是目的,而是通往数智化的桥梁。数智化,即数据智能化,是指企业通过数字化手段收集和分析数据,进而利用这些数据驱动决策和创新…...
Linux中ES的安装
文章目录 一、ES是什么1.1、ES概念介绍1.2、技术架构1.2.1、Lucene介绍 1.3、ES的工作原理1.4、ES的适用场景 二、安装前的配置2.1、创建普通用户2.2、调整文件描述符数量和虚拟内存2.3、设置shell会话的资源限制(软限制和硬限制)2.4、增加虚拟内存的设置…...
Redis远程字典服务器(5) —— hash类型详解
目录 一,hash基本情况 二,hash常用命令详解 2.1 hset,hget,hexists,hdel 2.2 hexists,hdel 2.3 hkeys,hvals 2.4 hgetall,hmget 2.5 hlen,hsetnx 2.6 hincrby&am…...
MySQL | 行锁——记录锁、间隙锁 、临键锁、插入意向锁
1、InnoDB中的行锁 行锁(Row Lock) 也称为记录锁,顾名思义,就是锁住某一行(某条记录row)。需要注意的是,MySQL服务器层并没有实现行锁机制,行级锁只在存储引擎层实现。 优点&#x…...
【网络编程】TCP通信基础模型实现
tcpSer.c #include <myhead.h> #define SER_IP "192.168.119.143" // 设置IP地址 #define SER_PORT 6666 // 设置端口号 int main(int argc, const char *argv[]) {// 1.创建socketint serfd socket(AF_INET, SOCK_STREAM, 0);// 参数1表示ipv4// 参数2表…...
css rem之2024
话题开始前 我们都知道1rem是等于html fontSize标签的字体大小的,我们主要用来做移动端网页设计稿等比例在手机上面的显示。 看到的问题 这个html fontsize的大小是通过js动态计算的,而这个js的运行时晚于html渲染的,所以会导致一个问题&am…...
python自动化笔记:pytest框架
目录 一、pytest介绍二、测试用例命名规则2.1、pytest命名规则2.2、python命名规范 三、pytest运行方式3.1、主函数方式3.2、命令行方式3.3、通过pytest.ini的配置文件运行(常用) 四、跳过测试用例4.1 无条件跳过4.2 有条件跳过 五、用例的前后置&#x…...
wpf 路径动画 举例
先,我们需要在XAML中定义一个Path,这个Path将定义动画的路线。然后,我们将使用DoubleAnimationUsingPath来沿着这个路径移动一个元素(比如一个矩形)。 <Window x:Class"WpfApp.MainWindow" xmlns"…...
【C++】classes and object 2.8 取地址及const取地址操作符重载
这两个默认成员函数一般不用重新定义 ,编译器默认会生成。 #define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> using namespace std; class Date { public:Date* operator&(){return this;}const Date* operator&()const{return this;} privat…...
milvus helm k8s开启监控
https://milvus.io/docs/monitor.md 文章写的很清晰 ,我这边做一下个人补充,初版可能只是配置,具体的grafana 监控报表后期补一下。 架构如下: values.yaml 配置 enabled: true 改为true metrics:enabled: trueserviceMonitor:…...
牛奶饮用学习笔记
1. 常见牛奶类型 1.1 蒙牛-每日鲜语-0脂肪鲜牛奶 项目每100mL NRV%能量146kJ 能量计算 250 mL 146 kJ / 100 mL 365 kJ 250\text{mL}\times146\text{kJ}/100\text{mL} 365\text{kJ} 250mL146kJ/100mL365kJ 1.2 伊利-舒化-高钙型无乳糖牛奶 项目每100mL NRV%能量269kJ …...
php防止页面重复刷新或者重复提交
2.核心代码 显示的逻辑: //获取防止刷新的唯一标识符,start $intFlag substr(md5(time()),6); $strFlag BAOXIAOSS_.$my_user_id.$intFlag; $smarty->assign(check_is_agin_post, $strFlag); //获取防止刷新的唯一标识符,end注意:前端页面提交加入…...
Springboot3 配置sql打印到控制台
一、pom.xml <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId><version>3.1.2</version></dependency> 二、application.yml com.lingyang.system # log4j2配…...
深入理解 GO 语言并发
1. 使用并发 在深入了解 Go 如何处理并发之前,先查看并发的概念。在计算机发展的早期阶段,计算机系统只有一个处理器负责执行所有指令。由于这种体系结构,计算机程序被编写成以串行的方式运行,在这种方式下,程序按照预定义的顺序逐个指令地执行。 随着计算机程序变得越来越…...
leetcode39组合总和
题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选…...
【JPCS独立出版,EI稳定检索】2024年工业机器人与先进制造技术国际学术会议(IRAMT 2024,9月27-29)
2024年工业机器人与先进制造技术国际学术会议(IRAMT 2024)将于2024年9月27-29日在中国成都举办。 此次会议将围绕工业机器人、机电技术、机械及制造等领域的最新研究成果展开讨论,并广泛邀请了国内外领域内的著名专家与学者。会议旨在搭建一个…...
Fal.ai Flux 1-Pro/Viva.ai/哩布哩布AI:AI绘图部分免费工具+原图提示词Prompt
目录 #1 找软件 #2 懂提示词 #3 更难的一步,会英文 我个人认为,想要玩文生图,你要会3个步骤: #1 找软件 主流文生图软件:Midjourney、Stable Diffusion、Dall-E 3 巧了,我用的都是小众、免费的画笔工…...
C++学习笔记----2、使用C++进行优雅编程(十)---- 格式化
许多人因为编程风格的问题被搞得焦头烂额,就因为对于在if中使用几个空格争论不休,导致友谊的小船说翻就翻。如果公司有相应的编程规范,只能说你比较幸运。因为有可能你不喜欢这些规范,但做为一个正常人来讲,至少有规范…...
双指针| Java | (hot100) 力扣283, 11, 15, 42做题总结
leetcode 11 盛最多水的容器 双层for循环暴力 超出时间限制 class Solution {public int maxArea(int[] height) {int h0;int v0;for(int i0; i<height.length; i) {for(int ji1; j<height.length; j) {h Math.min(height[i],height[j]);v Math.max(v, h*(j-i));}}…...
matlab求解方程
【MATLAB】求解含有三角函数的方程_matlab求解三角函数方程-CSDN博客 Matlab求解方程或函数的根,root,fzero,solve,fsolve的区别_matlab root-CSDN博客 非线性方程(组):MATLAB内置函数 solve, vpasolve, fsolve, fzero, roots [MATLAB] - GentleMin - …...
MySQL基础--视图,存储过程
介绍 视图是一种虚拟存在的表,视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。 通俗的讲,视图只保存了查询的 SQL 逻辑,不保存查询结果,所以我…...
学习记录第二十六天
进程运行 1,子进程和父进程做相同的事----创建子进程 执行任务 2,子进程做与父进程不同的事 ----fork exec exec族 l VS v :主要是第二个参数的传参方式不同 p :表示寻找可执行文件 是通过PATA环境变量 e : 表示可以给…...
Polars简明基础教程十一:可视化(一)
到本次讲座结束时,你将能够: 使用Polars的内部plot方法从Polars创建图表使用外部绘图库从Polars创建图表了解这些库如何支持Polars 通常,需要可视化库的最新版本来实现最大程度的兼容性 import polars as plimport hvplot as hv import ma…...
实战项目:贪吃蛇游戏的实现(上)
前言 Hello, 今天我们来一起完成一个实战项目:贪吃蛇。 相信大家都不会对这个游戏感到陌生,贪吃蛇游戏是久负盛名的游戏,他和俄罗斯方块,扫雷游戏等游戏位列世界经典游戏之列。这次我们旨在通过实战项目贪吃蛇的实现,…...
SHT30温湿度传感器全解析——概况,性能,MCU连接,样例代码
常见温湿度传感器测量范围:(价格仅供参考,具体性能要看折线图) 型号DHT11DHT20AHT10AHT20AHT30SHT20价格¥ 2.49¥3.04¥ 1.9¥1.4¥ 1.3¥5.5温度测量范围20—90%RH0—100%RH0—100%RH0—…...
电气工程专业毕业设计代做网站/宁波seo运营推广平台排名
前端开发中我们经常会遇到跨域请求的情况,处理跨域请求方式很多,特整理如下: 浏览器的同源策略 提到跨域不能不先说一下”同源策略”。 同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。 何为同源…...
天津港电子商务网/佛山做seo推广公司
要在Unicode字符集环境下把CString转化为char* 方法: CString str _T("D://校内项目//QQ.bmp");//leo这个NB 可以降在Unicode下的CString转化为char* //声明标识符 USES_CONVERSION; //调用函数,T2A和W2A均支持ATL和MFC中的字符转换 char *…...
郑州网站建设公司招聘/网站优化搜索排名
为什么80%的码农都做不了架构师?>>> http://www.open-open.com/lib/view/open1442664464415.html 转载于:https://my.oschina.net/fltsp/blog/620264...
做英语真题的网站/舆情分析报告案例
废话前后两千万,拍照更清晰。大家好,这里是OPPO R11独家冠名赞助播出的大型情感类电视连续剧《Android高德之旅》,我是主持人大公爵。(开篇占位)简介这篇文章来讲个简单的,行政区划搜索。api极其简单,只需要一个行政区…...
辽宁省精神文明建设工作三大创建活动网站/360推广
当满足以下三个条件时,两者会输出相同信息。 1. 服务器为80端口 2. apache的conf中ServerName设置正确 3. HTTP/1.1协议规范 不同点: 通常情况: _SERVER[“HTTP_HOST”] 在HTTP/1.1协议规范下,会根据客户端的HTTP请求输出信息…...
我想学做网站/重庆排名优化整站优化
通过对全球2944位首席信息官的年度调查,全球领先的信息技术研究和顾问公司Gartner发现人们现已深处数字商业时代,许多企业正根据数字化能力重构业务与运营模式。本文探讨了2016年中国首席信息官议程的三项主要调查结果,此次调查包含来自中国8…...