专业的JAVA编程教程与资源

网站首页 > java教程 正文

linux内核中私有变量的设置与获取

temp10 2025-10-02 07:45:25 java教程 1 ℃ 0 评论

[TOC]

问题描述:

在驱动程序中,有很多时候都需要设置私有变量和获取变量,通常都会使用下面的函数:
可以从源码中看出,项目的函数是等价的
dev_set_drvdata == platform_set_drvdata
dev_get_drvdata == platform_get_drvdata

日志

添加打印日志信息

分析步骤

第1步:
第2步:
...

代码片段

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/slab.h>

// 定义设备私有数据结构体
struct platform_demo_dev {
    int id;
    char name[32];
    int value;
    // 可以添加更多设备相关的私有数据
};

// 定义驱动私有数据结构体
struct platform_demo_drv {
    int driver_version;
    char driver_name[32];
    // 可以添加更多驱动相关的私有数据
};

// 探针函数 - 设备与驱动匹配时调用
static int platform_demo_probe(struct platform_device *pdev)
{
    struct platform_demo_dev *dev_data;
    struct platform_demo_drv *drv_data;
    const char *name;
    int ret;

    printk(KERN_INFO "platform_demo_probe: Device matched\n");

    // 1. 从设备树获取属性
    ret = of_property_read_string(pdev->dev.of_node, "demo-name", &name);
    if (ret) {
        printk(KERN_ERR "Failed to read demo-name property\n");
        return ret;
    }

    // 2. 分配并初始化设备私有数据
    dev_data = devm_kzalloc(&pdev->dev, sizeof(struct platform_demo_dev), GFP_KERNEL);
    if (!dev_data) {
        return -ENOMEM;
    }

    // 从设备树获取其他属性
    of_property_read_u32(pdev->dev.of_node, "demo-id", &dev_data->id);
    of_property_read_u32(pdev->dev.of_node, "demo-value", &dev_data->value);
    strncpy(dev_data->name, name, sizeof(dev_data->name) - 1);

    // 3. 设置平台设备的私有数据 (使用dev_set_drvdata)
    /*
        static inline void dev_set_drvdata(struct device *dev, void *data)
        {
                dev->driver_data = data;
        }
    */
    dev_set_drvdata(&pdev->dev, dev_data);
    printk(KERN_INFO "Set device private data: id=%d, name=%s, value=%d\n",
           dev_data->id, dev_data->name, dev_data->value);

               // 获取设备私有数据
    struct platform_demo_dev *retrieved_dev_data = dev_get_drvdata(&pdev->dev);
    if (retrieved_dev_data) {
        printk(KERN_INFO "Retrieved device data: id=%d, name=%s, value=%d\n",
               retrieved_dev_data->id, retrieved_dev_data->name, retrieved_dev_data->value);
    }

    // 4. 分配并初始化驱动私有数据
    drv_data = kzalloc(sizeof(struct platform_demo_drv), GFP_KERNEL);
    if (!drv_data) {
        return -ENOMEM;
    }

    drv_data->driver_version = 1;
    strncpy(drv_data->driver_name, "platform_demo_driver", sizeof(drv_data->driver_name) - 1);

    // 5. 设置平台驱动的私有数据 (使用platform_set_drvdata)
    /*
        static inline void platform_set_drvdata(struct platform_device *pdev,
                                        void *data)
        {
                dev_set_drvdata(&pdev->dev, data);
        }
    */
    platform_set_drvdata(pdev, drv_data);
    printk(KERN_INFO "Set driver private data: name=%s, version=%d\n",
           drv_data->driver_name, drv_data->driver_version);
        
    // 获取驱动私有数据
    struct platform_demo_drv *retrieved_drv_data = platform_get_drvdata(pdev);
    if (retrieved_drv_data) {
        printk(KERN_INFO "Retrieved driver data: name=%s, version=%d\n",
               retrieved_drv_data->driver_name, retrieved_drv_data->driver_version);
    }

    return 0;
}

// 移除函数 - 设备与驱动分离时调用
static int platform_demo_remove(struct platform_device *pdev)
{
    // 获取并释放驱动私有数据
    struct platform_demo_drv *drv_data = platform_get_drvdata(pdev);
    if (drv_data) {
        printk(KERN_INFO "Removing driver private data: %s\n", drv_data->driver_name);
        kfree(drv_data);
    }

    // 设备私有数据使用devm分配,会自动释放
    printk(KERN_INFO "platform_demo_remove: Device removed\n");
    return 0;
}

// 设备树匹配表
static const struct of_device_id platform_demo_of_match[] = {
    { .compatible = "demo,platform-private-data" },
    { /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, platform_demo_of_match);

// 平台驱动结构体
static struct platform_driver platform_demo_driver = {
    .probe = platform_demo_probe,
    .remove = platform_demo_remove,
    .driver = {
        .name = "platform_demo",
        .of_match_table = platform_demo_of_match,
    },
};
module_platform_driver(platform_demo_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Platform driver demo with private data and device tree");
MODULE_VERSION("1.0");

图片

结论

输出结论

待查资料问题

  • 问题 1:?
  • 问题 2:?

参考链接

  • 官方文档

linux内核中私有变量的设置与获取

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表