嵌入式开发记录-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");

浙公网安备 33010602011771号