【梦想终会实现】Linux驱动学习5

加油加油坚持住!

1、

Linux驱动模型:驱动模型即将各模型中共有的部分抽象成C结构体。Linux2.4版本前无驱动模型的概念,每个驱动写的代码因人而异,随后为规范书写方式,发明了驱动模型,即提取公共信息组成一个个类,为添加设备和驱动提供统一的接口,使得开发变得简单化、规范化,但驱动本身仍然存在开发难度,设备(触摸屏、蓝牙等)的最底层代码不需要驱动工程师搞,Linux设备模型也不需要驱动工程师搞,驱动工程师需要做的是把二者结合。早期的驱动是需要手动inmod的,有驱动模型后直接注册即可。

驱动模型分为四类:类、总线、设备、驱动、Kobject、sysfs、udev。

深入理解Linux设备模型与驱动开发-CSDN博客 (五星推荐)

比如led,rtc,beep,key这类结构简单的设备,它们的控制不需要时序,它们没有相应的物理总线。所以linux内核不会为它们创建驱动总线。为了是这部分设备的驱动开发也能够遵循设备驱动模型,linux内核引入了一种虚拟的总线——平台总线(platform bus)。

2、Linux的底层模型(主要是写内核的人写的,搞驱动的一般不用)

基本结构体Kobject:各类对象的最小单元,对象引用计数(kref)、维护对象链表(entry、parent)、对象上锁(kset)、对用户空间的描述(ktype)。

kobj_type:提供在sysfs下的操作。attribute:sysfs下的属性;sysfs_ops:对象在sysfs下的操作方法。

kset:描述sysfs下的目录关系。

驱动开发注意包含和引用的关系,包含是结构体成员,绑定是指针。如

struct kobject {const char		*name;struct list_head	entry;   // 上下节点    包含关系struct kobject		*parent; // 上下层之间   绑定关系struct kset		*kset;       // 上锁        绑定关系struct kobj_type	*ktype;struct sysfs_dirent	*sd;struct kref		kref;        // 对象引用计数unsigned int state_initialized:1;unsigned int state_in_sysfs:1;unsigned int state_add_uevent_sent:1;unsigned int state_remove_uevent_sent:1;unsigned int uevent_suppress:1;
};

3、Linux的上层模型

设备

struct device是硬件设备在内核驱动框架中的抽象。

device_register用于向内核驱动框架注册一个设备。

通常device不会单独使用,而是被包含在一个具体设备结构体中,如struct usb_device。

驱动

device_driver是驱动程序在内核驱动框架中的抽象。

name:驱动程序的名字,用于驱动与对应设备的匹配。

probe:用于检测此设备是否可以用本驱动,毕竟不同厂家的设备对应的驱动是不同的。

类:

相关结构体:struct class 和 struct class_device。

class的真正意义在于作为同属于一个class的多个设备的容器

内核中驱动会被类和总线双重管理。

模型思想即面向对象的思想,结构体包一层结构体即类继承类,有一个基类(device_driver),然后创建子类(usb_device)。驱动开发要有思想复杂度!一层套一层。

4、Linux设备总线开发目的是方便管理。

CPU与外部通信的方式:

32位地址总线寻址:片上外设可以通过SOC的内存寻址,因为设备是硬编码进SOC的,硬编码一般是数字前端工程师设计的,使用Verilog HDL语言。(在Linux中设计为平台总线形式,大部分设备均为平台总线)

通过IIC、SPI、USB总线与外部通信。

EXPORT_SYMBOL_GPL的应用:

// 如下代码表示函数允许被其他仅支持GPL的内核模块使用,而不是使用.h声明的方式
void platform_driver_unregister(struct platform_driver *drv)
{driver_unregister(&drv->driver);
}
EXPORT_SYMBOL_GPL(platform_driver_unregister);

platfrom设备驱动分析: 

// device驱动源码分析static struct platform_driver pm860x_backlight_driver = {  // .driver		= {.name	= "88pm860x-backlight",  // name为驱动唯一标识符.owner	= THIS_MODULE,},.probe		= pm860x_backlight_probe, // 驱动的侦测函数.remove		= pm860x_backlight_remove,// 驱动的卸载函数
};static int __init pm860x_backlight_init(void)
{return platform_driver_register(&pm860x_backlight_driver);
}
module_init(pm860x_backlight_init);  // 模块注册static void __exit pm860x_backlight_exit(void)
{platform_driver_unregister(&pm860x_backlight_driver);
}
module_exit(pm860x_backlight_exit);  // 模块卸载
static struct platform_device this_device = {.name   = "tv_ntsc",   // 设备名,用于内核设备树和其他机制中标识这个设备.id	= 0,.dev	= {.platform_data = &ntsc_panel_data,}
};static int __init ntsc_init(void)                  // __init阶段执行,执行完毕后释放该数据段
{int ret;ret = platform_driver_register(&this_driver);    // 注册驱动if (!ret) {ret = platform_device_register(&this_device);// 注册成功则注册该设备if (ret)platform_driver_unregister(&this_driver);// 否则,卸载设备,以保持内核稳定性。}return ret;
}module_init(ntsc_init);  // 模块注册

5、

一个驱动可以对应多个设备。当设备加载进来时,会通过platform_match函数匹配对应的驱动(根据驱动名)。若存在,则调用driver的probe函数完成驱动的安装。

内核提供platform_device,写驱动的人提供platform_driver,可以全局检索name的形式检索驱动对应的设备。

设备于内核中的执行顺序:

s3c24xx_led -->mini2440_led1 -->mini2440_devices-->platform_add_devices-->platform_device_register 完成设备添加,可从/sys目录找到。

然后内核根据设备名s3c24xx_led查找对应的驱动,若存在,则执行。以此实现platform框架下的设备和驱动匹配。

static struct platform_device mini2440_led1 = {.name		= "s3c24xx_led",.id		= 1,.dev		= {.platform_data	= &mini2440_led1_pdata,    // 这段绑定关系交由各驱动模块自己执行},
};struct device {struct device		*parent;
.......
.......void		*platform_data;	/* Platform specific data, devicecore doesn't touch it */  // 此段指针交由各驱动自行绑定。.......
.......}// driver部分,将
static int s3c24xx_led_probe(struct platform_device *dev)
{struct s3c24xx_led_platdata *pdata = dev->dev.platform_data;  // 此处实现自定义数据的赋值操作struct s3c24xx_gpio_led *led;int ret;led = kzalloc(sizeof(struct s3c24xx_gpio_led), GFP_KERNEL);if (led == NULL) {dev_err(&dev->dev, "No memory for device\n");return -ENOMEM;}platform_set_drvdata(dev, led);............
}

6、

驱动的核心思考点:

能想清楚数据谁写的?给谁了?从哪里传递到哪里?谁接受到数据干啥了?

想想这么设计的优势、必要性是什么?

自己写一个出来。

以上三条就是驱动开发核心部分,区别是不同驱动对应的不同。

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

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

相关文章

WARNING(ORCAP-1589): Net has two or more aliases - possible short?

参考链接:ORCAD报错ORCAP-1589-CSDN博客 现象: Capture CIS 使用PCB-DRC检查原理图,报错Net has two or more aliases - possible short? 错误原因: 一个网络有两个网络名称。 问题本质: 原理图管脚型号的设定问题…

nvm:node 版本管理器

一、先安装git Git 安装完成后执行 git --version查看版本号是否安装成功 二、安装nvm (参考链接:mac 安装nvm详细教程 - 简书) 官网(https://github.com/nvm-sh/nvm/blob/master/README.md)查看最新版本安装命令 …

动态规划——路径问题①

文章目录 62. 不同路径算法原理代码实现 63. 不同路径 II算法原理代码实现 LCR 166. 珠宝的最高价值算法原理代码实现 62. 不同路径 题目链接:62. 不同路径 算法原理 状态表示: dp[i,j]:以[i, j]位置为结尾,走到[i, j]位置有多少…

NodeList 对象

NodeList 对象 概述 NodeList 对象是 DOM(文档对象模型)中的一种特殊类型,它代表了文档中一组元素的集合。NodeList 对象通常通过查询 DOM 树来获取,例如使用 document.querySelectorAll() 方法。NodeList 对象在 JavaScript 中非常有用,因为它允许开发者以编程方式遍历…

C++自研3D教程OPENGL版本---动态批处理的基本实现

又开始找工作了&#xff0c;借机休息出去旅行两个月&#xff0c;顺便利用这段时间整理下以前写的东西。 以下是一个简单的动态批处理实现&#xff1a; #include <GL/glew.h> #include <GLFW/glfw3.h> #include <iostream> #include <vector>// 顶点结…

61. Linux内核启动流程简介

一、vmlinux.lds简介 从arch/arm/kernel/vmlinux.lds分析Linux内核第一行启动代码。找到ENTRY(stext) 入口函数是stext&#xff0c;image和zImage是经过压缩的&#xff0c;Linux内核会先进行解压缩&#xff0c;解压缩完成以后就要运行Linux内核。要求&#xff1a; 1、MMU关闭 …

汽车智能座舱的技术演进与用户体验重构 —— 基于多模态交互与 AI 融合的范式创新

摘要&#xff1a; 汽车智能座舱作为人 - 车 - 环境交互的核心载体&#xff0c;正经历从功能驱动到体验驱动的范式变革。本文通过技术解构与用户行为分析&#xff0c;深入揭示智能座舱在异构计算、多模态感知、服务生态等维度的创新路径。研究表明&#xff0c;智能座舱的竞争焦…

使用 Let‘s Encrypt 和 OpenResty 实现域名转发与 SSL 配置

在搭建网站或服务时&#xff0c;确保域名的安全性和正确的流量转发是非常重要的。本文将介绍如何使用 Let’s Encrypt 获取免费的 SSL 证书&#xff0c;并将其配置到 OpenResty 中&#xff0c;同时实现特定的域名转发规则。这不仅可以提升网站的安全性&#xff0c;还能优化流量…

SpringBoot3整合Swagger3时出现Type javax.servlet.http.HttpServletRequest not present错误

目录 错误详情 错误原因 解决方法 引入依赖 修改配置信息 创建文件 访问 错误详情 错误原因 SpringBoot3和Swagger3版本不匹配 解决方法 使用springdoc替代springfox&#xff0c;具体步骤如下&#xff1a; 引入依赖 在pom.xml文件中添加如下依赖&#xff1a; <…

ChatGPT提问技巧:行业热门应用提示词案例-文案写作

ChatGPT 作为强大的 AI 语言模型&#xff0c;已经成为文案写作的得力助手。但要让它写出真正符合你需求的文案&#xff0c;关键在于如何与它“沟通”&#xff0c;也就是如何设计提示词&#xff08;Prompt&#xff09;。以下是一些实用的提示词案例&#xff0c;帮助你解锁 ChatG…

供排水水工公司开展企业获得用水营商环境满意度调查

为了持续提升企业的供水服务品质&#xff0c;进一步优化当地的营商环境&#xff0c;深圳市供排水公司水工公司紧密结合其实际工作情况&#xff0c;特别委托民安智库开展了2023年度优化营商环境调查专项工作。该项目的核心目的是深入了解并评估市各类获得用水企业的用水环境满意…

【Elasticsearch】分桶聚合功能概述

这些聚合功能可以根据它们的作用和应用场景分为几大类&#xff0c;以下是分类后的结果&#xff1a; 1.基础聚合&#xff08;Basic Aggregations&#xff09; • Terms&#xff08;字段聚合&#xff09; 根据字段值对数据进行分组并统计。 例子&#xff1a;按产品类别统计销…

mysql的cpu使用率100%问题排查

背景 线上mysql服务器经常性出现cpu使用率100%的告警&#xff0c; 因此整理一下排查该问题的常规流程。 1. 确认CPU占用来源 检查系统进程 使用 top 或 htop 命令&#xff0c;确认是否是 mysqld 进程导致CPU满载&#xff1a;top -c -p $(pgrep mysqld)2. 实时分析MySQL活动 …

人工智能赋能企业系统架构设计:以ERP与CRM系统为例

一、引言 1.1 研究背景与意义 在数字化时代&#xff0c;信息技术飞速发展&#xff0c;人工智能&#xff08;Artificial Intelligence, AI&#xff09;作为一项具有变革性的技术&#xff0c;正深刻地影响着各个领域。近年来&#xff0c;AI 在技术上取得了显著突破&#xff0c;…

使用jmeter进行压力测试

使用jmeter进行压力测试 jmeter安装 官网安装包下载&#xff0c;选择二进制文件&#xff0c;解压。 tar -xzvf apache-jmeter-x.tgz依赖jdk安装。 yum install java-1.8.0-openjdk环境变量配置&#xff0c;修改/etc/profile文件&#xff0c;添加以下内容。 export JMETER/…

深入理解流(Streams)—— 声明式数据处理的艺术

1. 引言 大家好&#xff01;欢迎来到本系列博客的第三篇。在前两篇文章中&#xff0c;我们已经领略了 Java 8 中 行为参数化 和 Lambda 表达式 的魅力。 在第 1 章 Java行为参数化&#xff1a;从啰嗦到简洁的代码进化中&#xff0c;我们了解到如何通过将行为&#xff08;代码…

【Linux】之【Get√】nmcli device wifi list 与 wpa_cli scan 和 wpa_cli scan_result 区别

nmcli device wifi list 是 NetworkManager 的命令行工具 nmcli 的一部分&#xff0c;它用于列出当前可用的无线网络。它的作用和 wpa_cli 的扫描功能类似&#xff0c;但有一些不同点。 1. nmcli device wifi list 功能&#xff1a; nmcli device wifi list 命令用于显示当前…

【蓝桥杯嵌入式】6_定时器输入捕获

全部代码网盘自取 链接&#xff1a;https://pan.baidu.com/s/1PX2NCQxnADxYBQx5CsOgPA?pwd3ii2 提取码&#xff1a;3ii2 这是两个信号发生器&#xff0c;可以通过调节板上的两个电位器R39和R40调节输出频率。 将PB4、PA15选择ch1&#xff0c;两个信号发生器只能选择TIM3和TIM…

详解SQLAlchemy的函数relationship

在 SQLAlchemy 中&#xff0c;relationship 是一个非常重要的函数&#xff0c;用于定义模型之间的关系。它用于在 ORM 层面上表示数据库表之间的关联关系&#xff08;如 1 对 1、1 对多和多对多&#xff09;。relationship 的主要作用是提供一个高级接口&#xff0c;用于在模型…

分桶函数的使用

除了 NTILE 函数&#xff0c;SQL 中还有其他一些与 分桶&#xff08;bucketization&#xff09;相关的函数&#xff0c;虽然它们的实现方式不同&#xff0c;但都涉及将数据分成多个区间或组。以下是一些常用的分桶函数&#xff1a; 1. CASE 语句 虽然 CASE 不是开窗函数&…