Linux嵌入式驱动开发-platform 设备驱动

文章目录

  • platform 平台驱动
    • platform 总线
    • platform 驱动
      • platform_driver_register 注册 platform 驱动
      • platform_driver_unregister 卸载 platform 驱动
    • platform 设备
      • platform_device_register 注册设备
    • platform_device_unregister 注销设备

Linux 系统要考虑到驱动的可重用性,因此提出了驱动的分离与分层这样的软件思路,在这个思路下诞生了platform 设备驱动,也叫做平台设备驱动。

驱动的分隔,也就是将主机驱动和设备驱动分隔开来。

在这里插入图片描述

Linux 中的总线(bus)、驱动(driver)和设备(device)模型

在这里插入图片描述

当我们向系统注册一个驱动的时候,总线就会在右侧的设备中查找,看看有没有与之匹配的设备,如果有的话就将两者联系起来。同样的,当向系统中注册一个设备的时候,总线就会在左侧的驱动中查找看有没有与之匹配的设备,有的话也联系起来。

platform 平台驱动

在 SOC 中有些外设是没有总线这个概念的,但是又要使用总线、驱动和设备模型,Linux 提出了 platform 这个虚拟总线,相应的就有 platform_driver 和 platform_device。

platform 总线

Linux系统内核使用 bus_type 结构体表示总线,platform 总线是 bus_type 的一个具体实例

总线使用 match 函数来根据注册的设备来查找对应的驱动,或者根据注册的驱动来查找相应的设备,因此每一条总线都必须实现此函数。

match 函数有两个参数:dev 和 drv,这两个参数分别为 device 和 device_driver 类型,也就是设备和驱动。

//platform 总线实例
struct bus_type platform_bus_type = {.name = "platform",.dev_groups = platform_dev_groups,.match = platform_match,.uevent = platform_uevent,.pm = &platform_dev_pm_ops,
};

platform_bus_type 就是 platform 平台总线,其中 platform_match 就是匹配函数。

驱动和设备的匹配有四种方法

  1. 第一种匹配方式, OF 类型的匹配,也就是设备树采用的匹配方式。

  2. device_driver 结构体(表示设备驱动)中有个名为of_match_table的成员变量,此成员变量保存着驱动的compatible匹配表,设备树中的每个设备节点的 compatible 属性会和 of_match_table 表中的所有成员比较,查看是否有相同的条目,如果有的话就表示设备和此驱动匹配,设备和驱动匹配成功以后 probe 函数就会执行。

  3. 第二种匹配方式,ACPI 匹配方式。

  4. 第三种匹配方式,id_table 匹配。

  5. 每个 platform_driver 结构体有一个 id_table成员变量,顾名思义,保存了很多 id 信息。这些 id 信息存放着这个 platformd 驱动所支持的驱动类型。

  6. 第四种匹配方式,如果第三种匹配方式的 id_table 不存在的话就直接比较驱动和设备的 name 字段。

platform 驱动

platform 驱动并不是独立于字符设备驱动、块设备驱动和网络设备驱动之外的其他种类的驱动。platform 只是为了驱动的分离与分层而提出来的一种框架,其驱动的具体实现还是需要字符设备驱动、块设备驱动或网络设备驱动。

platform_driver结构体表示platform驱动 , 此结构体定义在文件include/linux/platform_device.h 中,内容如下

struct platform_driver
{int (*probe)(struct platform_device *);int (*remove)(struct platform_device *);void (*shutdown)(struct platform_device *);int (*suspend)(struct platform_device *, pm_message_t state);int (*resume)(struct platform_device *);struct device_driver driver;const struct platform_device_id *id_table;bool prevent_deferred_probe;
};

probe 函数,当驱动与设备匹配成功以后 probe 函数就会执行,非常重要的函数!!一般驱动的提供者会编写,如果自己要编写一个全新的驱动,那么 probe 就需要自行实现。

driver 成员,为 device_driver 结构体变量,Linux 内核里面大量使用到了面向对象的思维,device_driver 相当于基类,提供了最基础的驱动框架。plaform_driver 继承了这个基类,然后在此基础上又添加了一些特有的成员变量。

id_table 表,也就是 platform 总线匹配驱动和设备的时候采用的第 三 种方 法 , id_table 是 个 表 ( 也就 是数 组 ) ,每 个 元素 的 类型 为 platform_device_id

device_driver 结构体定义在 include/linux/device.h

device_driver 中of_match_table成员 就是采用设备树的时候驱动使用的匹配表,同样是数组,每个匹配项都为 of_device_id 结构体类型,此结构体定义在文件 include/linux/mod_devicetable.h 中

在编写 platform 驱动的时候,首先定义一个 platform_driver 结构体变量,然后实现结构体中的各个成员变量,重点是实现匹配方法以及 probe 函数。当驱动和设备匹配成功以后 probe函数就会执行,具体的驱动程序在 probe 函数里面编写,比如字符设备驱动等等。

platform_driver_register 注册 platform 驱动

当我们定义并初始化好 platform_driver 结构体变量以后,需要在驱动入口函数里面调用platform_driver_register 函数向 Linux 内核注册一个 platform 驱动。

int platform_driver_register (struct platform_driver *driver)

driver:要注册的 platform 驱动。
返回值:负数,失败;0,成功。

platform_driver_unregister 卸载 platform 驱动

在驱动卸载函数中通过 platform_driver_unregister 函数卸载 platform 驱动

void platform_driver_unregister(struct platform_driver *drv)

drv:要卸载的 platform 驱动。
返回值:无。

platform 设备

platform_device 这个结构体表示 platform 设备,如果内核支持设备树的话就不要再使用 platform_device 来描述设备了,因为改用设备树去描述了。

如果一定要用 platform_device 来描述设备信息的话也是可以的。platform_device 结构体定义在文件include/linux/platform_device.h 中。

platform_device_register 注册设备

在以前不支持设备树的Linux版本中,用户需要编写platform_device变量来描述设备信息,
然后使用 platform_device_register 函数将设备信息注册到 Linux 内核中

int platform_device_register(struct platform_device *pdev)

platform_device_unregister 注销设备

如果不再使用 platform 的话可以通过 platform_device_unregister 函数注销掉相应的 platform
设备,platform_device_unregister 函数原型如下:

void platform_device_unregister(struct platform_device *pdev)

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

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

相关文章

03-JAVA设计模式-命令模式

命令模式 什么是命令模式 命令模式(Command Pattern)是一种行为设计模式,它将请求封装为对象,从而使你可用不同的请求把客户端与请求的处理者解耦,也称动作模式或事物模式。 在命令模式中,命令对象封装了接收者对象…

索引【MySQL】

文章目录 什么是索引测试表 磁盘和 MySQL 的交互了解磁盘MySQL 的工作原理Buffer Pool 理解索引引入Page 的结构页内目录(Page Directory)多页情况B 树和 B树聚簇索引和非聚簇索引 主键索引创建 唯一索引主要特点与主键索引的区别使用场景创建 联合索引工…

53、图论-课程表

思路: 其实就是图的拓扑排序,我们可以构建一个图形结构,比如[0,1]表示1->0,对于0来说入度为1。 遍历结束后,从入度为0的开始遍历。引文只有入度为0的节点没有先决条件。然后依次减少1。直到所有节点入度都为0.然后…

hive中建立MySQL表格时有乱码

我们启动hive 建立一个学生students表格 使用desc students查看表格结构时 发现有出现乱码的情况 遇到这种问题 我们可以修改一下 打开MySQL mysql -u root -p123456; 切换数据库 use hive; 执行 修改字段注释字符集 alter table COLUMNS_V2 modify column COMMENT varchar…

实验 1--SQL Server2008数据库开发环境

文章目录 实验 1--SQL Server2008数据库开发环境2.4.1 实验目的2.4.2 实验准备2.4.3 实验内容1.利用 SSMS 访问系统自带的Report Server 数据库。2.熟悉了解 SMSS对象资源管理器树形菜单相关选择项的功能。(1)右键单击数据库Report Server,查看并使用相关功能;(2)选…

对接支付宝支付

前言 这里讨论的主要是一个验签出错的问题,至于具体的对接流程并不复杂,直接找官网的文档就行了 问题表现 后台拉起支付后要返回一个form表单给前端,然后前端说报了这个错,于是进行一系列排查 猜测1 很明显的就会怀疑支付宝的公钥或者私钥出了问题才引起这个问题,但是对比了以…

Spring Boot中JUnit 4与JUnit 5的如何共存

文章目录 前言一、先上答案二、稍微深入了解2.1 maven-surefire-plugin是什么2.2 JUnit4和JUnit5有什么区别2.2.1 不同的注解2.2.2 架构 前言 在maven项目中,生成单测时是否有这样的疑问:该选JUnit4还是JUnit5?在执行 mvn test 命令时有没有…

IDEA更换新版本启动没反应

目前安装了新的IDEA(压缩包方式),由于老版本的IDEA还在用,所以并没有删除,但是安装完后发现点击idea64.exe后没有反应,于是网上找了好多方法最后解决了 下面是我的解决过程 新版本:IntelliJIdea2024.1 老版本: Intelli…

全球AI投资减少,生成式AI面临挑战;Command R + 成首个击败GPT-4的开源模型

🦉 AI新闻 🚀 全球AI投资减少,生成式AI面临挑战 摘要:2023年,随着投资者对于人工智能(AI)领域的热度有所降温,全球对AI的投资呈现持续下降趋势。斯坦福大学以人为本人工智能研究所…

指针专题(4)【qsort函数的概念和使用】

1.前言 上节我们学习了指针的相关内容,本节我们在有指针的基础的条件下学习一下指针的运用,那么废话不多说,我们正式进入今天的学习 2.回调函数 我们既然已经学习了指针的相关基础,那么我们此时就可以用指针来实现回调函数 而回…

云原生环境该怎样解决网络安全问题

随着云计算逐渐迈向成熟阶段,云原生技术以其“生在云上、长在云上”的核心理念,被普遍认为是云计算未来十年发展的关键方向。该技术不仅能够有效破解传统云实践中所面临的应用升级缓慢、架构臃肿、迭代效率低下等难题,更为业务创新注入了强大…

SpringBoot+layuimini实现左侧菜单动态展示

layuimini左侧菜单动态显示 首先我们看一下layuimini的原有菜单显示格式 {"homeInfo": {"title": "首页","href": "page/welcome-2.html?t2"},"logoInfo": {"title": "LAYUI MINI","…