嵌入式开发记录-day41 在驱动中获取设备树中的节点属性

1、Linux引入设备树,把硬件分到设备树文件中,驱动中仍然需要硬件信息。所以必须将设备树中的硬件信息传到驱动中

2、当驱动与设备信息匹配时,进入到probe函数中,在probe的参数列表中,传递的结构体中包含有相关的硬件信息;

  传递硬件信息用到的结构体、以及设备树属性获取函数头文件:include/linux/of.h

  节点信息包含在结构体property中,但是需要用结构体device_node找到它;

  device_node定义

struct device_node {
        const char *name;        //节点名称
        const char *type;        //设备类型
        phandle phandle;
        const char *full_name;    //全路径节点
        struct fwnode_handle fwnode;

        struct  property *properties;    // 需要大部分硬件信息都在这里
        struct  property *deadprops;    /* removed properties */
        struct  device_node *parent;        //父节点指针
        struct  device_node *child;            //子节点指针
        struct  device_node *sibling;
        struct  kobject kobj;
        unsigned long _flags;
        void    *data;
#if defined(CONFIG_SPARC)
        const char *path_component_name;
        unsigned int unique_id;
        struct of_irq_controller *irq_trans;
#endif
};
  property 定义
struct property {
        char    *name;
        int     length;
        void    *value;
        struct property *next;
        unsigned long _flags;
        unsigned int unique_id;
        struct bin_attribute attr;
};

  需要使用函数来调用该结构体

// 根据属性名称,提取属性值
struct property *of_find_property(const struct device_node *np, const char *name, int *lenp);
/** 
* of_find_property - 提取指定属性的值
* @np - 设备树节点指针
* @name - 属性名称
* @lenp - 属性值的字节数
* 返回值:成功,属性值的首地址;失败:NULL
*/

 获取设备树上节点信息

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>         // 获取设备树节点信息的头文件
#include <linux/of_gpio.h>

#define DRIVER_NAME "leds_test"     

static int leds_probe(struct platform_device * pdev)
{
    // 获取设备树上节点的信息
    struct device_node *node = pdev->dev.of_node;   // 获取设备节点的地址
    printk("node name is %s!\n",node->name);        // 打印设备节点的名称 leds_test
    printk("node fullname is %s!\n",node->full_name); // 包含有路径的设备节点名称
    
    struct property *comprop = NULL; 
    comprop = of_find_property(node,"compatible",NULL);  // 根据节点的属性名查找
    printk("comprop name is %s!\n",comprop->name);        // 获取属性名 ---> compatible
    printk("comprop value is %s!\n",comprop->value);    // 对应的值compatible对应的值 leds_test
    
    comprop = of_find_property(node,"status",NULL);
    printk("comprop name is %s!\n",comprop->name);        // status
    printk("comprop value is %s!\n",comprop->value);    // status对应的值 -->okay  // 能进probe肯定是okay
    
    printk(KERN_ALERT "probe init\n");
    
    return 0;
}

static int leds_remove(struct platform_device * pdev)
{
    printk(KERN_ALERT "Goodbye, curel world, this is remove\n");
    return 0;
}

static const struct of_device_id of_leds_dt_match[] = {
    {.compatible = DRIVER_NAME},   // 根据compatible定位到哪一个节点 定位到leds_test
    {},
};

MODULE_DEVICE_TABLE(of,of_leds_dt_match);

static struct platform_driver leds_driver = {
    .probe     = leds_probe,
    .remove = leds_remove,
    .driver = {
        .name = DRIVER_NAME,
        .owner = THIS_MODULE,
        .of_match_table = of_leds_dt_match,
        },
};

static int leds_init(void)
{
    printk(KERN_ALERT "Hello, world\n");
    return platform_driver_register(&leds_driver);
    return 0;
}

static void leds_exit(void)
{
    printk(KERN_ALERT "Goodbye, curel world\n");
    platform_driver_unregister(&leds_driver);
}

module_init(leds_init);
module_exit(leds_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("rty");
MODULE_DESCRIPTION("topeet4412_regiter_dev_drv");

 

posted @ 2020-09-07 21:39  笑不出花的旦旦  阅读(351)  评论(0)    收藏  举报