第五十三讲 获取设备树属性

文章目录

  • 第五十三讲 获取设备树属性
    • 一、获取设备树属性信息
      • 1、查看属性所在节点
        • device_node 结构体
      • 2、如何查找结点
        • 节点路径
        • 节点类型(不推荐使用)
        • 节点名字(不推荐使用)
        • 节点属性
      • 3、查找节点属性值
        • property 结构体
      • 4、如何查找节点属性值
        • of_find_property
        • of_property_read_u32
        • of_property_read_u32_array
        • of_property_read_string
    • 二、设备树属性获取实验
      • 1、实验代码
        • getDTSproperty.c
        • Makefile
      • 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;
#endifunsigned 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_path struct device_node *of_find_node_by_path(const char *path) path:带节点名的路径 成功:device_node节点
失败:NULL

节点类型(不推荐使用)

函数 原型 参数 返回值
of_find_node_by_type struct 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_name struct device_node *of_find_node_by_name(struct device_node *from,const char *name) from: The node to start searching from or NULL; the node
name: The name string to match against
Returns a node pointer with refcount incremented, use of_node_put() on it when done.

节点属性

函数 原型 参数 返回值
of_find_compatible_node struct 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 it
type: The type string to match “device_type” or NULL to ignore
compatible: 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_property struct 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_u32 int 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_array int 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 read
Returns 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_string int 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 <linux/kernel.h>
#include <linux/module.h>#include <linux/of.h>#define DEVICE_TREE_PATH        "/74hc595"struct device_node    *dts_device_node;static __init int dtsPropertyInit(void)
{printk("<3> DTS property init!\n");/*通过路径寻找设备树节点*/dts_device_node = of_find_node_by_path(DEVICE_TREE_PATH);if(dts_device_node == NULL){printk("<3> get "DEVICE_TREE_PATH" DTS property failed!\n");return -1;}printk("<3> "DEVICE_TREE_PATH" node name is %s\n", dts_device_node->name);printk("<3> "DEVICE_TREE_PATH" node type is %s\n", dts_device_node->type);
}
static __exit void dtsPropertyExit(void)
{printk("<3> 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_COMPILEobj-m := getDTSproperty.oall:$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules.PHONE:clean copyclean:$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean    copy:sudo  cp  *.ko  /home/dragon/nfsshare

2、实验步骤

  1. 编译代码

    make

  2. 将代码复制到共享文件夹

    ‘make copy’

  3. 打开登陆开发板

  4. 连接共享文件夹

    sudo mount -t nfs 192.168.3.41:/home/xxx/nfsshare /mnt

  5. 加载模块

    sudo insmod /mnt/getDTSproperty.ko

3、实验结果

[ 3483.270178] getDTSproperty: loading out-of-tree module taints kernel.
[ 3483.286299] <3> DTS property init!
[ 3483.289760] <3> /74hc595 node name is 74hc595
[ 3483.294123] <3> /74hc595 node type is <NULL>
[ 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] [<801106d4>] (unwind_backtrace) from [<8010c5c8>] (show_stack+0x10/0x14)
[ 3483.345434] [<8010c5c8>] (show_stack) from [<80d5e370>] (dump_stack+0x78/0x8c)
[ 3483.352675] [<80d5e370>] (dump_stack) from [<801ae490>] (do_init_module+0x8c/0x200)
[ 3483.360349] [<801ae490>] (do_init_module) from [<801ad38c>] (load_module+0x2174/0x257c)
[ 3483.368367] [<801ad38c>] (load_module) from [<801ada18>] (sys_finit_module+0xc4/0x110)
[ 3483.376298] [<801ada18>] (sys_finit_module) from [<80101000>] (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] <3> DTS property init!
[ 3483.289760] <3> /74hc595 node name is 74hc595
[ 3483.294123] <3> /74hc595 node type is <NULL>

写在最后,细心的小伙伴可能发现了实验结果有报错呀,这个怎么解决呢?很简单,在init函数最后加上 return 0即可。哈哈哈,我的问题!!!

参考资料

设备树(二):device_node与device绑定

第五十三讲 获取设备树属性相关推荐

  1. 第五十五讲 插件设备树

    第五十五讲 插件设备树 文章目录 第五十五讲 插件设备树 一.概述 1.概述 2.使用前提 3.编译工具 二.插件设备树实验 1.环境准备 2.实验 3.验证实验 附录 驱动代码 led.c led. ...

  2. 第五十四讲 设备树实现RGB驱动

    第五十四讲 设备树实现RGB驱动 文章目录 第五十四讲 设备树实现RGB驱动 一.基础知识 1.GPIO Write Mode 2.硬件连接 3.重要寄存器(参考IMXULL用户手册) RGB_R R ...

  3. 【正点原子Linux连载】第四十四章 设备树下的LED驱动实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  4. 【正点原子MP157连载】第二十四章 设备树下的LED驱动实验-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7

    1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...

  5. Linux 获取设备树源文件(DTS)里描述的资源

    Linux 获取设备树源文件(DTS)里的资源 韩大卫@吉林师范大学 在linux使用platform_driver_register() 注册 platform_driver 时, 需要在 plat ...

  6. 韦东山 IMX6ULL和正点原子_「正点原子Linux连载」第四十四章设备树下的LED驱动实验...

    1)实验平台:正点原子Linux开发板 2)摘自<正点原子I.MX6U嵌入式Linux驱动开发指南> 关注官方微信号公众号,获取更多资料:正点原子 上一章我们详细的讲解了设备树语法以及在驱 ...

  7. linux 获取设备树源文件(dts)里描述的资源,Linux 获取设备树源文件(DTS)里描述的资源...

    在linux使用platform_driver_register() 注册  platform_driver 时, 需要在 platform_driver 的probe() 里面知道设备的中断号, 内 ...

  8. 线性代数学习笔记——第五十三讲——齐次方程组求解实例

    1. 给定一个齐次线性方程组,求其通解 (写出系数矩阵 -> 行初等变换为行简化矩阵 -> 求基础解系 -> 写出通解) 2. 示例2 (只有零解的情况) 3. 与基础解系等价的线性 ...

  9. 设备树下字符设备驱动

    设备树下字符设备驱动 一.在设备树里添加自己的节点 二.驱动代码 三.makefile 四.应用层代码 运行测试 总结 一.在设备树里添加自己的节点 alphaled { 2 #address-cel ...

最新文章

  1. 《Beginning Linux Programming》读书笔记(二)
  2. oracle siplugincol表,ORACLE 经常使用的命令工具-第三章:表
  3. .bash_profile和.bashrc的区别
  4. 我的.net程序在linux上运行起啦
  5. behavior php,behavior.php
  6. linux将光驱挂载到目录下,Linux操作系统下关于光驱的挂载
  7. html的音频播放,HTML5 音频播放 audio
  8. sonar不支持mysql_sonar-iOS的实践
  9. requests 获取百度推广信息
  10. 实现子元素在父元素中水平垂直都居中笔记
  11. 网课答案免费搜题入口
  12. Jupyter关联规则挖掘-莫名其妙的问题
  13. Mybase7延长试用期
  14. Make a mark of Gates
  15. 前沿分享|数澜科技联合创始人副总裁 江敏:基于云原生数据仓库AnalyticDB PostgreSQL的最佳实践
  16. 英语会话必须掌握的五种基本结构[转]
  17. 利用二维数组实现一个矩阵类:Matrix
  18. 华为麦芒6支持鸿蒙吗,华为麦芒6支持电信吗_华为麦芒6支持电信卡吗-太平洋IT百科...
  19. JavaScript读书笔记四
  20. SQL Server 2005的100范例程序及数据库下载

热门文章

  1. 淘宝运营 影响ROI的因素 优化直通车ROI 的方法
  2. oracle数据库时钟,oracle11g巡检RAC数据库
  3. 电动牙刷头品牌新产品上市软文宣传的策略和技巧,助力产品宣传引导消费者关注和购买
  4. QXmpp源码 GuiClient
  5. 笔记本装win10和ubuntu双系统
  6. 1012: 求绝对值
  7. 招聘工作第一步:和业务部门沟通招聘需求关键谈的内容是什么?
  8. Nao机器人实现语音识别
  9. QT5.8.0+VS2015+OpenCV4.1.2 配置Windows 32位和64位平台
  10. Navicat创建数据库模型