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

Linux设备驱动platform驱动

更全面的内容可以查看我的github
提供了示例代码

platform设备驱动

Linux 系统要考虑到驱动的可重用性,因此提出了驱动的分离与分层这样的软件思路,为了达到所有硬件都可以按照总线设备驱动模型来实现驱动,Linux从2.6起就加入了 platform 设备驱动,在内核中建立一条虚拟的总线platform,它可以将那些不依赖于传统总线(如PCI, USB, I2C等)的设备,虚拟的挂在了platform总线上,达到统一。

platform总线驱动

platform总线驱动的代码可以查看linux/drivers/base/platform.c文件

platform 设备驱动

重要结构体

platform_device结构体

内核使用platform_device结构体来描述一个platform设备,该结构体定义位于Linux/include/linux/platform_device.h

struct platform_device
{// 设备的名字,用于和驱动进行匹配的const char *name;// 内核中维护的所有的设备必须包含该成员struct device dev;//资源个数u32 num_resources;	//描述资源struct resource * resource;...
};

这个结构体是为驱动程序提供设备信息,包括硬件信息和软件信息。

对于硬件信息,使用platform_device中的成员resource来描述,结构体如下

struct resource {resource_size_t start;  // 资源的起始地址resource_size_t end;    // 资源的结束地址const char *name;       // 资源的名字unsigned long flags;    // 资源的类型
};

flags可以常见的有下面几种:

  • IORESOURCE_IO:用于 IO 地址空间,对应于 IO 端口映射方式
  • IORESOURCE_MEM:用于外设的可直接寻址的地址空间
  • IORESOURCE_IRQ:用于指定该设备使用某个中断
  • IORESOURCE_DMA:用于指定使用的 DMA 通道

struct resource一般按下面方法使用

struct resource	res[]={[0] ={.start = 0x139d0000,.end  = 0x139d0000 + 0x3,.flags = IORESOURCE_MEM,},[1] ={.start = 199,.end  = 199,.flags = IORESOURCE_IRQ,},	
};
platform_driver结构体

这个结构体用来描述一个驱动

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函数中
  • remove: 当设备被移除时,此函数被调用。
  • shutdown: 系统关闭时,此函数被调用。
  • suspend 和 resume: 电源管理相关的回调,用于设备挂起和恢复(已经过时)
  • driver: 这是一个 struct device_driver 结构体,包含了驱动的一些通用信息。
  • id_table: 往往一个驱动可能能同时支持多个硬件,这些硬件的名字都放在该结构体数组中。

API

注册/注销设备
int platform_device_register(struct platform_device *pdev);
void platform_device_unregister(struct platform_device *pdev);
注册/注销驱动API
int platform_driver_register(struct platform_driver *drv);
void platform_driver_unregister(struct platform_driver *drv);

对于上面的函数,可以使用下面的宏替代

module_platform_driver(platform_driver)
// platform_driver 是platform_driver结构体

这个宏会定义指定名称的平台设备驱动注册函数和平台设备驱动注销函数,并且在函数体内分别通过platform_driver_register()函数和platform_driver_unregister()函数注册和注销该平台设备驱动。

获取resource
struct resource *platform_get_resource(struct platform_device *dev,unsigned int type, unsigned int num);
  • dev:指向要获取哪个设备的资源
  • type:资源类型
  • num:资源编号

框架

platform的驱动一般分为两个.c文件,一个是platform_driver.c文件,一个是platform_device.c文件。

在platform_device.c中,我们一般需要填充struct platform_device结构体和struct resource结构体,并使用platform_device_register()函数注册设备。这个文件必须先于
platform_driver.c文件完成,因为platform_driver.c文件中需要使用到struct platform_device结构体。

在platform_driver.c文件中,我们需要填充platform_driver结构体,platform_driver结构体中定义了probe函数,probe函数中会调用platform_get_resource函数获取设备资源,然后调用platform_set_drvdata函数将设备资源设置到设备结构体中。

相关文章:

  • Springboot JVM监控 通过Promethus
  • PS怎么编程:深入探索Photoshop的编程奥秘
  • 静态网页实现-人脸识别-案例(web)
  • 代码随想录35期Day60-JavaScript
  • 产品经理的需求善变,利用规则引擎减少80%的需求变更成本
  • Python3 列表
  • 2023年简单易用的透明加密软件--安秉网盾企业数据防泄密方案
  • 选择正确的单位:百分比、视窗单位和像素单位在网页设计中的应用
  • [原创][Delphi多线程]TThreadedQueue的经典使用案例.
  • 双指针解题
  • uniapp uni-popup内容被隐藏问题
  • Python编程学习第一篇——Python零基础快速入门(五)—变量
  • k8s怎么监听资源的变更
  • Linux前端与Windows前端区别:深入剖析两大系统的前端差异
  • python 深浅拷贝
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • 【译】理解JavaScript:new 关键字
  • golang 发送GET和POST示例
  • iOS | NSProxy
  • zookeeper系列(七)实战分布式命名服务
  • 大整数乘法-表格法
  • 猴子数据域名防封接口降低小说被封的风险
  • 前端自动化解决方案
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 云大使推广中的常见热门问题
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • #if 1...#endif
  • $(selector).each()和$.each()的区别
  • (1)Nginx简介和安装教程
  • (2)(2.10) LTM telemetry
  • (23)Linux的软硬连接
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (三) diretfbrc详解
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .gitignore
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .NET 常见的偏门问题
  • .NET多线程执行函数
  • .net和jar包windows服务部署
  • .NET命令行(CLI)常用命令
  • .net实现头像缩放截取功能 -----转载自accp教程网
  • .NET项目中存在多个web.config文件时的加载顺序
  • @取消转义
  • [ CTF ] WriteUp-2022年春秋杯网络安全联赛-冬季赛
  • [ 渗透工具篇 ] 一篇文章让你掌握神奇的shuize -- 信息收集自动化工具
  • [ 云计算 | AWS ] AI 编程助手新势力 Amazon CodeWhisperer:优势功能及实用技巧