0

0

Linux设备驱动之platform:一种描述和管理嵌入式设备的简便方法

WBOY

WBOY

发布时间:2024-02-11 19:18:15

|

929人浏览过

|

来源于良许Linux教程网

转载

你是否想过如何在linux系统中为你的嵌入式设备编写驱动程序?你是否想过如何在linux系统中让你的驱动程序适应不同的硬件平台和架构?你是否想过如何在linux系统中让你的驱动程序实现一些高级的功能,比如热插拔、电源管理、设备共享等?如果你对这些问题感兴趣,那么本文将为你介绍一种实现这些目标的有效方法——linux设备驱动之platform。platform是一种用于描述嵌入式设备的数据结构,它可以让你用一种简单而统一的方式,将嵌入式设备的信息和属性传递给内核,从而实现设备的识别和驱动。platform也是一种用于实现硬件无关性的机制,它可以让你用一种灵活而可移植的方式,将嵌入式设备的配置和管理从驱动程序代码中分离出来,从而实现多平台的支持。platform还是一种用于实现高级功能的框架,它可以让你用一种标准而通用的方式,定义和使用各种嵌入式设备的接口和协议,从而实现热插拔、电源管理、设备共享等功能。本文将从platform的基本概念、语法规则、编写方法、注册过程、匹配方式等方面,为你详细地介绍platform在linux设备驱动中的应用和作用,帮助你掌握这种有用而强大的方法。

根据Linux设备模型可知,一个现实的Linux设备和驱动通常都需要挂接在一种总线上,对于本身依附于PCI、USB等的设备而言,这自然不是问题,但是在嵌入式系统里面,SoC系统中集成的独立的外设控制器、挂接在 SoC 内存空间的外设等却不依附于此类总线。基于这一背景,Linux设计了一种虚拟的总线,称为platform总线,相应的设备称为platform_device,而驱动称为platform_driver。


设计目的

  • 兼容设备模型

    使得设备被挂接在一个总线上,因此,符合 Linux 2.6 的设备模型。其结果是,配套的
    
    sysfs结点、设备电源管理都成为可能。
    
  • BSP和驱动隔离

    在BSP中定义platform设备和设备使用的资源、设备的具体配置信息。而在驱动中,只需要通
    
    过通用API去获取资源和数据,做到了板相关代码和驱动代码的分离,使得驱动具有更好的可
    
    扩展性和跨平台性。
    

软件架构

内核中Platform设备有关的实现位于include/linux/platform_device.h和drivers/base/platform.c两个文件中,它的软件架构如下:
Linux设备驱动之platform:一种描述和管理嵌入式设备的简便方法

由图片可知,Platform设备在内核中的实现主要包括三个部分:

  • Platform Bus,基于底层bus模块,抽象出一个虚拟的Platform bus,用于挂载Platform设备;
  • Platform Device,基于底层device模块,抽象出Platform Device,用于表示Platform设备;
  • Platform Driver,基于底层device_driver模块,抽象出Platform Driver,用于驱动Platform设备。

platform_device

注意,所谓的platform_device并不是与字符设备、块设备和网络设备并列的概念,而是Linux系统提供的一种附加手段,例如,在S3C2440处理器中,把内部集成的I2C、RTC、SPI、LCD、看门狗等控制器都归纳为platform_device,而它们本身就是字符设备。

LongShot
LongShot

LongShot 是一款 AI 写作助手,可帮助您生成针对搜索引擎优化的内容博客。

下载
/* defined in  */
struct platform_device {
    const char * name; / * 设备名 */
    u32 id; /* 用于标识该设备的ID */
    struct device dev; /* 真正的设备(Platform设备只是一个特殊的设备,
因此其核心逻辑还是由底层的模块实现)*/
    u32 num_resources; / * 设备所使用各类资源数量 */
    struct resource * resource; / * 资源 */
};

/* defined in  */
struct resource {
    resource_size_t start; /* 资源起始 */
    resource_size_t end; /* 结束 */
    const char *name;
    unsigned long flags; /* 类型 */
    struct resource *parent, *sibling, *child;
};
/* 设备驱动获取BSP定义的resource */
struct resource *platform_get_resource(struct platform_device *, unsigned int flags, 
unsigned int num);

#include 
int platform_device_register(struct platform_device *);   
void platform_device_unregister(struct platform_device *);

Tip: 和板级紧密相关的资源描述放在dev.paltform_data中。

paltform_driver

platform_driver这个结构体中包含probe()、remove()、shutdown()、suspend()、resume()函数,通常也需要由驱动实现:

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 (*suspend_late)(struct platform_device *, pm_message_t state);
    int (*resume_early)(struct platform_device *);
    int (*resume)(struct platform_device *);
    struct device_driver driver;
};

#include 
int platform_driver_register(struct platform_driver *);   
void platform_driver_unregister(struct platform_driver *);

platform_bus

系统中为platform总线定义了一个bus_type的实例platform_bus_type:

struct bus_type platform_bus_type = {
    .name = "platform",
    .dev_attrs = platform_dev_attrs,
    .match = platform_match,
    .uevent = platform_uevent,
    .pm = PLATFORM_PM_OPS_PTR,
};
EXPORT_SYMBOL_GPL(platform_bus_type);

这里要重点关注其 match()成员函数,正是此成员函数确定了 platform_device 和 platform_driver之间如何匹配:

static int platform_match(struct device *dev, struct device_driver *drv)
{
    struct platform_device *pdev;
    pdev = container_of(dev, struct platform_device, dev);
    return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);
}

通过本文,我们了解了platform在Linux设备驱动中的应用和作用,学习了如何编写、注册、匹配、修改和调试platform。我们发现,platform是一种非常适合嵌入式系统开发的方法,它可以让我们方便地描述和管理嵌入式设备,实现硬件无关性和高级功能。当然,platform也有一些注意事项和限制,比如需要遵循语法规范、需要注意兼容性问题、需要注意内存占用和性能影响等。因此,在使用platform时,我们需要有一定的硬件知识和经验,以及良好的编程习惯和调试技巧。希望本文能够为你提供一个入门级的指导,让你对platform有一个初步的认识和理解。如果你想深入学习platform,建议你参考更多的资料和示例,以及自己动手实践和探索。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

240

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

192

2025.07.04

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

539

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

21

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

28

2026.01.06

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1133

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

213

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1811

2025.12.29

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 8万人学习

Git 教程
Git 教程

共21课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号