第五十三讲 获取设备树属性 |
您所在的位置:网站首页 › 查看设备节点信息的软件叫什么 › 第五十三讲 获取设备树属性 |
第五十三讲 获取设备树属性
文章目录
第五十三讲 获取设备树属性一、获取设备树属性信息1、查看属性所在节点device_node 结构体
2、如何查找结点节点路径节点类型(不推荐使用)节点名字(不推荐使用)节点属性
3、查找节点属性值property 结构体
4、如何查找节点属性值of_find_propertyof_property_read_u32of_property_read_u32_arrayof_property_read_string
二、设备树属性获取实验1、实验代码getDTSproperty.cMakefile
2、实验步骤3、实验结果
参考资料
一、获取设备树属性信息
1、查看属性所在节点
前面讲到我们所编写的设备树源码文件是后缀为.dts的文件。dts文件经过编译生成dtb文件,通过复制dtb文件到开发板的指定位置才能被uboot识别然后加载到指定位置。当内核启动的时候会去指定位置来找到dtb文件,然后对dtb文件进行解析。已经知道dtb文件中的节点与属性信息会被解析填充到kernel的device_node和property结构体中;在start_kernel的后续初始化过程中,device_node还会进一步和各种device进行绑定,有虚拟的platform bus下的platform_device,也有spi、i2c等物理bus下的从设备(client)。 kernel会为设备树root节点下所有带’compatible’ 属性的节点都分配并注册一个platform_device;另外,如果某节点的’compatible’ 符合某些matches条件,则会为该节点下所有带’compatible’ 属性的子节点(child)也分配并注册一个platform_device。 device_node 结构体路径:ebf_linux_kernel-ebf_4.19.35_imx6ul\include\linux\of.h 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; #if defined(CONFIG_OF_KOBJ) struct kobject kobj; #endif 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 }; #define MAX_PHANDLE_ARGS 16 struct of_phandle_args { struct device_node *np; int args_count; uint32_t args[MAX_PHANDLE_ARGS]; }; 2、如何查找结点通过上面的介绍,我们就可以知道如何查找设备树节点了-节点路径、节点类型、节点名字、节点属性。 节点路径 函数原型参数返回值of_find_node_by_pathstruct device_node *of_find_node_by_path(const char *path)path:带节点名的路径成功:device_node节点失败:NULL 节点类型(不推荐使用) 函数原型参数返回值of_find_node_by_typestruct device_node *of_find_node_by_type(struct device_node *from,const char *type)from:开始搜索的节点,NULL 开始搜索整个设备树。 不会搜索你传递的节点,只会搜索下一个节点; 通常,您传递上一个调用返回的内容。 of_node_put() 将为您调用。type:要匹配的类型字符串返回一个引用计数递增的节点指针,完成后使用 of_node_put() 。 节点名字(不推荐使用) 函数原型参数返回值of_find_node_by_namestruct device_node *of_find_node_by_name(struct device_node *from,const char *name)from: The node to start searching from or NULL; the nodename: The name string to match againstReturns a node pointer with refcount incremented, use of_node_put() on it when done. 节点属性 函数原型参数返回值of_find_compatible_nodestruct device_node *of_find_compatible_node(struct device_node *from,const char *type, const char *compatible)from:The node to start searching from or NULL, the node you pass will not be searched, only the next one will; typically, you pass what the previous call returned. of_node_put() will be called on ittype: The type string to match “device_type” or NULL to ignorecompatible: The string to match to one of the tokens in the device “compatible” list.of_node_put() on it when done.Returns a node pointer with refcount incremented, use 3、查找节点属性值 property 结构体这个结构体存放着节点的属性 路径:ebf_linux_kernel-ebf_4.19.35_imx6ul\include\linux\of.h struct property { char *name; int length; void *value; struct property *next; #if defined(CONFIG_OF_DYNAMIC) || defined(CONFIG_SPARC) unsigned long _flags; #endif #if defined(CONFIG_OF_PROMTREE) unsigned int unique_id; #endif #if defined(CONFIG_OF_KOBJ) struct bin_attribute attr; #endif }; 4、如何查找节点属性值 of_find_property 函数原型参数返回值of_find_propertystruct property *of_find_property(const struct device_node *np,const char *name,int *lenp)np:device_node表示的节点name:查找属性的名字lenp:属性值的字节数成功:property属性值失败:NULL of_property_read_u32 函数原型参数返回值of_property_read_u32int of_property_read_u32(const struct device_node *np,const char *propname,u32 *out_value)np:device node from which the property value is to be read.propname:name of the property to be searched.out_values:pointer to return value, modified only if return value is 0.0:成功负值:失败 of_property_read_u32_array 函数原型参数返回值of_property_read_u32_arrayint of_property_read_u32_array(const struct device_node *np,const char *propname,u32 *out_values, size_t sz)np:device node from which the property value is to be read.propname:name of the property to be searched.out_values:pointer to return value, modified only if return value is 0.sz:number of array elements to readReturns 0 on success,-EINVAL if the property does not exist,-ENODATA if property does not have a value-EOVERFLOW if the property data isn’t large enough of_property_read_string 函数原型参数返回值of_property_read_stringint of_property_read_string(const struct device_node *np,const char *propname,const char **out_string)np:device_node表示的节点proname:查找属性的名字out_string:读取到的字符串值0:成功负值:失败 二、设备树属性获取实验写在前面,由于本节仅演示获取设备树属性,所以并没有按照视频内的方法来写程序,前面有介绍过在加载模块的时候,会自动调用init函数。所以本实验是利用这个直接演示获取其他的设备树属性。并没有注册一个设备。 1、实验代码 getDTSproperty.c /* * @LastEditors: 夜雨 * @Date: 2022-03-10 21:52:21 * @LastEditTime: 2022-03-16 22:11:36 * @FilePath: \code\kernel\012getDTSproperty\getDTSproperty.c */ #include #include #include #define DEVICE_TREE_PATH "/74hc595" struct device_node *dts_device_node; static __init int dtsPropertyInit(void) { printk(" DTS property init!\n"); /*通过路径寻找设备树节点*/ dts_device_node = of_find_node_by_path(DEVICE_TREE_PATH); if(dts_device_node == NULL) { printk(" get "DEVICE_TREE_PATH" DTS property failed!\n"); return -1; } printk(" "DEVICE_TREE_PATH" node name is %s\n", dts_device_node->name); printk(" "DEVICE_TREE_PATH" node type is %s\n", dts_device_node->type); } static __exit void dtsPropertyExit(void) { printk(" DTS property exit!\n"); } module_init(dtsPropertyInit); module_exit(dtsPropertyExit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Yeyu"); MODULE_DESCRIPTION("dts module!"); MODULE_ALIAS("dts_module"); Makefile KERNEL_DIR=../../ebf_linux_kernel/build_image/build/ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- export ARCH CROSS_COMPILE obj-m := getDTSproperty.o all: $(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules .PHONE:clean copy clean: $(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean copy: sudo cp *.ko /home/dragon/nfsshare 2、实验步骤编译代码 make 将代码复制到共享文件夹 ‘make copy’ 打开登陆开发板 连接共享文件夹 sudo mount -t nfs 192.168.3.41:/home/xxx/nfsshare /mnt 加载模块 sudo insmod /mnt/getDTSproperty.ko 3、实验结果 [ 3483.270178] getDTSproperty: loading out-of-tree module taints kernel. [ 3483.286299] DTS property init! [ 3483.289760] /74hc595 node name is 74hc595 [ 3483.294123] /74hc595 node type is [ 3483.306374] do_init_module: 'getDTSproperty'->init suspiciously returned 32, it should follow 0/-E convention [ 3483.306374] do_init_module: loading module anyway... [ 3483.323163] CPU: 0 PID: 582 Comm: insmod Tainted: G O 4.19.35-imx6 #1stable [ 3483.331450] Hardware name: Freescale i.MX6 UltraLite (Device Tree) [ 3483.337669] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 3483.345434] [] (show_stack) from [] (dump_stack+0x78/0x8c) [ 3483.352675] [] (dump_stack) from [] (do_init_module+0x8c/0x200) [ 3483.360349] [] (do_init_module) from [] (load_module+0x2174/0x257c) [ 3483.368367] [] (load_module) from [] (sys_finit_module+0xc4/0x110) [ 3483.376298] [] (sys_finit_module) from [] (ret_fast_syscall+0x0/0x54) [ 3483.384481] Exception stack(0x86061fa8 to 0x86061ff0) [ 3483.389544] 1fa0: baddb300 00000000 00000003 0045f7e0 00000000 7ef15c48 [ 3483.397732] 1fc0: baddb300 00000000 00000000 0000017b 01f26230 00000000 7ef15dc8 00000000 [ 3483.405917] 1fe0: 7ef15bf8 7ef15be8 00457e41 76d61d92可以看到,获取到了设备树的属性,感兴趣的朋友也试试其他函数呀!!! [ 3483.286299] DTS property init! [ 3483.289760] /74hc595 node name is 74hc595 [ 3483.294123] /74hc595 node type is写在最后,细心的小伙伴可能发现了实验结果有报错呀,这个怎么解决呢?很简单,在init函数最后加上 return 0即可。哈哈哈,我的问题!!! 参考资料设备树(二):device_node与device绑定 |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |