当前位置: 首页 > news >正文

驱动基础开发

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、字符设备传统开发模板 字符设备驱动框架&#xff0c;首先我们需要去用module_init这个宏去修饰整个驱动的入口函数&#xff0c;用module_exit去修饰整个驱动的出口函数&#xff0c;然后还需要用MODULE_LICENSE用于声明模块的许可证类型。 在入口函数里面我们需要注册字符设…...

从苹果AppStore看AI开发者生态

从苹果 App Store 看 AI 开发者生态 在人工智能迅速发展的今天&#xff0c;我们不禁要问&#xff1a;未来的 AI 开发者生态将会是什么样子&#xff1f;为了回答这个问题&#xff0c;我们不妨回顾一下移动互联网时代最成功的开发者生态之一——苹果的 App Store。 通过分析 App …...

【Python学习-UI界面】PyQt5 小部件1-Label

QLabel 对象可用作显示不可编辑的文本、图像或动态GIF影片的占位符。 它还可以用作其他小部件的助记键。 标签可以显示普通文本、超链接或富文本。 1、普通文本 直接双击输入即可 2、添加超链接 选中对应Label&#xff0c;右键选择多信息文本&#xff0c;添加链接&#xff0c…...

【Linux详解】进度条实现 Linux下git 的远程上传

&#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;Linux—登神长阶 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f49e; &#x1f49e; &#x1f49e; &#x1f680;前言 &#x…...

Android进阶之路 - res、raw、assets 资源解析、区别对比

那天遇到一个资源目录层级的问题&#xff0c;索性重新整理记录一下&#xff0c;希望能帮到如吾往昔之少年的你们&#xff0c;哈哈哈哈哈哈… 一脸茫然&#xff0c;越写越多&#xff0c;时间成本属实有点大&#xff0c;就当一起来基础扫盲吧 resdrawablemipmapvaluescolor asset…...

从数字化到数智化:消费零售企业如何实现门店数智化管理?

随着信息技术的飞速发展&#xff0c;数字化已成为企业转型的必经之路。然而&#xff0c;数字化本身并不是目的&#xff0c;而是通往数智化的桥梁。数智化&#xff0c;即数据智能化&#xff0c;是指企业通过数字化手段收集和分析数据&#xff0c;进而利用这些数据驱动决策和创新…...

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会话的资源限制&#xff08;软限制和硬限制&#xff09;2.4、增加虚拟内存的设置…...

Redis远程字典服务器(5) —— hash类型详解

目录 一&#xff0c;hash基本情况 二&#xff0c;hash常用命令详解 2.1 hset&#xff0c;hget&#xff0c;hexists&#xff0c;hdel 2.2 hexists&#xff0c;hdel 2.3 hkeys&#xff0c;hvals 2.4 hgetall&#xff0c;hmget 2.5 hlen&#xff0c;hsetnx 2.6 hincrby&am…...

MySQL | 行锁——记录锁、间隙锁 、临键锁、插入意向锁

1、InnoDB中的行锁 行锁&#xff08;Row Lock&#xff09; 也称为记录锁&#xff0c;顾名思义&#xff0c;就是锁住某一行&#xff08;某条记录row&#xff09;。需要注意的是&#xff0c;MySQL服务器层并没有实现行锁机制&#xff0c;行级锁只在存储引擎层实现。 优点&#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标签的字体大小的&#xff0c;我们主要用来做移动端网页设计稿等比例在手机上面的显示。 看到的问题 这个html fontsize的大小是通过js动态计算的&#xff0c;而这个js的运行时晚于html渲染的&#xff0c;所以会导致一个问题&am…...

python自动化笔记:pytest框架

目录 一、pytest介绍二、测试用例命名规则2.1、pytest命名规则2.2、python命名规范 三、pytest运行方式3.1、主函数方式3.2、命令行方式3.3、通过pytest.ini的配置文件运行&#xff08;常用&#xff09; 四、跳过测试用例4.1 无条件跳过4.2 有条件跳过 五、用例的前后置&#x…...

wpf 路径动画 举例

先&#xff0c;我们需要在XAML中定义一个Path&#xff0c;这个Path将定义动画的路线。然后&#xff0c;我们将使用DoubleAnimationUsingPath来沿着这个路径移动一个元素&#xff08;比如一个矩形&#xff09;。 <Window x:Class"WpfApp.MainWindow" xmlns"…...

【C++】classes and object 2.8 取地址及const取地址操作符重载

这两个默认成员函数一般不用重新定义 &#xff0c;编译器默认会生成。 #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 文章写的很清晰 &#xff0c;我这边做一下个人补充&#xff0c;初版可能只是配置&#xff0c;具体的grafana 监控报表后期补一下。 架构如下&#xff1a; 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.核心代码 显示的逻辑&#xff1a; //获取防止刷新的唯一标识符,start $intFlag substr(md5(time()),6); $strFlag BAOXIAOSS_.$my_user_id.$intFlag; $smarty->assign(check_is_agin_post, $strFlag); //获取防止刷新的唯一标识符,end注意&#xff1a;前端页面提交加入…...

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 &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...