当前位置:首页>Linux>放弃全局变量!这才是 Linux 内核驱动数据管理的“正确姿势”

放弃全局变量!这才是 Linux 内核驱动数据管理的“正确姿势”

  • 2026-10-23 22:49:21
放弃全局变量!这才是 Linux 内核驱动数据管理的“正确姿势”

Linux驱动入门课程已更新完结!提供一对一指导!

https://www.bilibili.com/cheese/play/ss635583370

01

前言

我们经常在驱动中看到如下代码:

staticintxxx_probe(struct platform_device *pdev){  struct my_dev *my_dev;  my_dev = devm_kzalloc(&pdev->dev, sizeof(*my_dev), GFP_KERNEL);  if (!my_dev) return -ENOMEM;  platform_set_drvdata(pdev, my_dev);}intxxx_remove(struct platform_device *pdev){  struct my_dev *key_dev = platform_get_drvdata(pdev);  .....}

上面通过platform_set_drvdata来保存数据,然后再通过platform_get_drvdata来获取数据。通常用来传递自定义的设备结构体。很多同学可能会想,干嘛不直接用个全部变量,省得在几个函数间传来传去,接下来我们来讲讲它的好处,以及为什么不用全局变量。

02

platform_set_drvdata的优势

1. 驱动程序需要支持多个相同的硬件设备

比如:系统中有两个 SPI 控制器或者两个相同的温度传感器,你不能使用一个全局变量来存储每个设备的特定数据结构(如中断号、内存基址、设备私有状态)。所有设备实例都会尝试读写同一个全局变量,导致数据混乱和竞态条件。

回到上面的例子,我们可以看到在probe()函数中会为设备分配内存,这样子每个设备实例都会创建自己的设备结构体。然后通过platform_set_drvdata保存,这样子就独立开了。

2. 更清晰的代码结构和封装

  • 面向对象思想:这种机制体现了一种松散的面向对象思想。每个 platform_device 结构体都带有自己的“私有成员数据”。代码逻辑上更贴合硬件的物理分离。

  • 全局变量的问题: 使用全局变量会导致驱动程序在逻辑上依赖于外部状态,降低模块化和可读性。为了支持多个设备,虽然可能创建全局数组,但这增加了代码的复杂性。

3.符合内核编程规范

platform_set_drvdata 是 Linux 设备驱动模型(LDDM) 推荐且标准化的做法。使用标准 API 可以让熟悉内核代码的开发者更容易理解你的驱动程序的意图和结构。

03

总结

除非你确信设备驱动永远只会加载一个实例且不需要热插拔,否则永远应该使用 platform_set_drvdata 来绑定你的私有设备数据。这是编写健壮、可维护和符合内核规范的 Linux 驱动的关键一步。

每一个总线都有类似的函数,这里只是以platform总线为例。

END

往期

RECOMMEND

推荐

·Linux驱动之RTC驱动(PCF8563)

·Linux驱动之RTC子系统

·Linux驱动之I2C控制器驱动

·Linux驱动之I2C子系统

最新文章

随机文章