Linux 设备树: of_property_match_string 的用法与工作原理

前言

  • 当前新版本的 Linux 内核 设备驱动框架,与设备树(Device Tree)结合密切,整体 设备树的设备驱动框架,比较的庞大,但又非常的经典。

  • 一个个的 设备树解析函数,都是前人【智慧】的结晶,了解 设备树的实现,了解设备树的解析,对Linux 设备驱动开发非常有利,并且可以大大提高开发编码能力

  • 虽然Linux 内核庞大、开源,但是Linux 内核各个模块的实现都是经典,非常适合学习深造

设备树节点与设备树属性

  • 通过 include\linux\of.h 可以获取 设备树节点 struct device_node 与设备树节点属性 struct property 的定义

  • 这里需要特别了解 设备树节点属性:属性name = 属性value,属性value 可能是一个字符串的列表,比如

	i2c1: i2c@fea90000 {compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";reg = <0x0 0xfea90000 0x0 0x1000>;clocks = <&cru CLK_I2C1>, <&cru PCLK_I2C1>;clock-names = "i2c", "pclk";interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;pinctrl-names = "default";pinctrl-0 = <&i2c1m0_xfer>;resets = <&cru SRST_I2C1>, <&cru SRST_P_I2C1>;reset-names = "i2c", "apb";#address-cells = <1>;#size-cells = <0>;status = "disabled";};
  • 这里 compatibleclock-names reset-names 都有两个 属性值,比如 reset-names = "i2c", "apb";

  • 这里需要确认 reset-names = "i2c", "apb"; 这种 多个属性值的具体 内存储存方式,用于理解如何解析这样的设备树属性,比如分别获取其中的属性,也就是 "i2c", "apb" ,分别得到 "i2c""apb"

property 的 dtb 存储方式

  • 可能大家认为 reset-names = "i2c", "apb"; 在 dtb 中就是 这样的字符串存储,其实 dtb 的生成,有 dtc 的一套复杂的规则决定,这里 属性 name 可能只是一个索引,作为公用的字符串,而属性值如果是 字符串列表(多个字符串),比如 "i2c", "apb",引号不需要,并且 中间的分隔符是 \0,而不是 逗号 ,

  • 这样拆解字符串列表,就不再是以 逗号分隔,而是 字符串结束符 \0 进行分隔,这就需要获取整个字符串的长度【字节数】,这个 设备树属性 的 长度是 struct property 中的 int length; 成员

struct property {char	*name;int	length;   /* 属性 value 的长度(字节数) */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
};

在这里插入图片描述

在这里插入图片描述

of_property_match_string 解析

  • 明白了设备树 属性值(property -> value)字符串列表的储存方式后,解析起来就明白多了,这里有个字符串列表 【index】索引的概念,比如第一个,第二个字符串

  • Linux 内核 drivers\of\property.cof_property_match_string 的实现代码如下

/*** of_property_match_string() - Find string in a list and return index* @np: pointer to node containing string list property* @propname: string list property name* @string: pointer to string to search for in string list** This function searches a string list property and returns the index* of a specific string value.*/
int of_property_match_string(const struct device_node *np, const char *propname,const char *string)
{const struct property *prop = of_find_property(np, propname, NULL);size_t l;int i;const char *p, *end;if (!prop)return -EINVAL;if (!prop->value)return -ENODATA;p = prop->value;end = p + prop->length;for (i = 0; p < end; i++, p += l) {l = strnlen(p, end - p) + 1;if (p + l > end)return -EILSEQ;pr_debug("comparing %s with %s\n", string, p);if (strcmp(string, p) == 0)return i; /* Found it; return index */}return -ENODATA;
}
  • 这里入参: 设备树节点,设备树属性 name,就可以查找这个设备树属性 property。

  • 查找到设备树属性 property不是目的,目的就是 查找 设备树属性值 是否匹配,给定一个字符串,是否存在于 字符串列表中,返回字符串列表的索引 index

  • 举个例子: reset-names = "i2c", "apb";,这里查找 "apb" 是否存在,这里存在,就是返回了 index,比如是 1(索引以 0 作为起始)

  • 这里有个经典的字符串列表匹配的算法,就是 通过 总长度,获取整个字符串列表的结束地址,

  • prop->length 就是这个设备树属性 value,也就是 字符串列表的总长度(字节数)

	p = prop->value;end = p + prop->length;
  • 利用了 字符串操作函数都是以 NULL(\0) 作为结束,因此通过获取 单个字符串的 长度,利用指针的加减法(地址加减),就可以逐个判断分隔出来的 单个字符是否匹配

  • 这里 strnlen 用的比较的经典,获取到的其实就是第一次 遇到 字符串结束符 NULL(\0)之前的长度。

小结

  • 这个 of_property_match_string 实现原理比较的经典,当然与 设备树节点属性值的存储有关系,也就是 属性值是字符串列表时,字符串列表的分隔符是 【NULL 或者 \0】,这用于字符串列表的拆解

  • 有些设备树属性确实有多个属性值,有的是数值型的,有的是字符串列表型的,需要解析匹配并获取 匹配值的 索引值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/773900.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DC电源模块与其他电源模块有着明显的区别与优势

DC电源模块与其他电源模块有着明显的区别与优势 BOSHIDA DC电源模块&#xff08;Direct Current Power Supply Module&#xff09;是一种将交流电转换为直流电的设备&#xff0c;常用于电子设备和工业控制系统中。与其他电源模块相比&#xff0c;DC电源模块有一些明显的区别和…

R语言ggplot2 | 热图+随机森林重要性!升级版~

&#x1f4cb;文章目录 原图复现定义ggrf_ggcor_plot()函数加载数据集一键出图函数优点 今天推出一个升级版&#xff1a; ggrf_ggcor_plot的函数。只需要输入 响应变量的矩阵和 解释变量的矩阵&#xff0c;就能轻松一键生成随机森林重要性相关性热图。 原图 所需复现的随机森…

推荐5款测试数据生成工具!

一个成功、有效的测试策略由下面几个基本部分组成&#xff1a;完整的测试覆盖率、最小化的环境影响和健壮的测试数据。 其中测试数据尤其重要&#xff0c;其质量直接关系到测试的有效性。可以把测试数据看作是保持测试引擎运行的燃料——高质量的测试数据有助于确保测试执行的…

极速体验DolphinScheduler 3.2.1 Standalone 版[一]

文章目录 极速体验DolphinScheduler 3.2.1 Standalone 版前置准备工作启动 DolphinScheduler Standalone Server解压并启动 DolphinScheduler登录 DolphinScheduler 启停服务配置数据库 极速体验DolphinScheduler 3.2.1 Standalone 版 Standalone 仅适用于 DolphinScheduler 的…

【go从入门到精通】函数详解

作者简介&#xff1a; 高科&#xff0c;先后在 IBM PlatformComputing从事网格计算&#xff0c;淘米网&#xff0c;网易从事游戏服务器开发&#xff0c;拥有丰富的C&#xff0c;go等语言开发经验&#xff0c;mysql&#xff0c;mongo&#xff0c;redis等数据库&#xff0c;设计模…

【蓝桥杯】tarjan算法

一.概述 Tarjan 算法是基于DFS的算法&#xff0c;用于求解图的连通性问题。 Tarjan 算法可以在线性时间内求出&#xff1a; 无向图&#xff1a; 割点与桥双连通分量 有向图&#xff1a; 强连通分量必经点与必经边 1.割点&#xff1a; 若从图中删除节点 x 以及所有与 x 关联的…

Intel AIPC发布会:开启AI终端应用的新纪元

2024年3月27日下午&#xff0c;Intel在北京市朝阳区凤凰中心举办了AIPC发布会开启了AI终端应用的新征程。 整场发布会围绕着‘让不可想象&#xff0c;变为寻常’主线进行。在本次发布会上&#xff0c;众多PC端的AI应用得到了展示&#xff0c;包括&#xff1a;智谱AI&#xff…

第十一届蓝桥杯大赛第二场省赛试题 CC++ 研究生组-寻找2020

数据很恶心&#xff0c;但是考点挺友好~ 把测试数据黏贴到记事本中&#xff0c;知测试数据的行列数 然后根据规则判断2020是否出现&#xff0c;并累计其次数即可。 判断可能需要注意超出下标&#xff0c;可以索性把数组定大些。 #include<stdio.h> const int N 310; ch…

哈曼卡顿音箱解决关闭自动休眠 + 自用车载音乐分享制作

一&#xff1a;哈曼卡顿音箱解决关闭自动休眠 1. 背景&#xff1a;每天做最多的事情就是开音箱电源。问了客服&#xff0c;说只有玻璃4才能关闭休眠。搞得我都想买新音箱了。 2. 解决办法&#xff1a;电脑开机启动一个阻止功放休眠.exe&#xff0c;可以设置自动启动&#x…

Redis入门到实战-第十九弹

Redis实战热身Count-min-sketch篇 完整命令参考官网 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://redis.io/Redis概述 Redis是一个开源的&#xff08;采用BSD许可证&#xff09;&#xff0c;用作数据库、缓存、…

Android Studio 无法下载 gradle-7.3.3-bin.zip

下载新的Android Studio&#xff0c;然后创建新的工程时&#xff0c;出现报错&#xff1a;Could not install Gradle distribution from https://services.gradle.org/distributions/gradle-7.3.3-bin.zip 或者超时&#xff0c;我们可以复制&#xff1a;https://services.grad…

IntellIJ Idea 内存不足时怎么设置

文章目录 前言背景一、 内存显示二、 在IDEA中设置内存三 、在IDEA中打开内存的设置文件四、 JetBrains ToolBox 中安装 IntellIJ Idea配置文件位置总结 前言 请各大网友尊重本人原创知识分享&#xff0c;谨记本人博客&#xff1a;南国以南i、 提示&#xff1a;以下是本篇文章…

【React】react 使用 lazy 懒加载模式的组件写法,外面需要套一层 Loading 的提示加载组件

react 组件按需加载问题解决 1 错误信息2 解决方案 1 错误信息 react 项目在创建 router 路由时&#xff0c;使用 lazy 懒加载时&#xff0c;导致以下报错&#xff1a; The above error occurred in the <Route.Provider> component:Uncaught Error: A component suspe…

计算机基础系列 —— CPU

“Make everything as simple as possible, but no simpler.” – Albert Einstein 文中提到的所有实现都可以参考&#xff1a;nand2tetris_sol&#xff0c;但是最好还是自己学习课程实现一遍&#xff0c;理解更深刻。 之前的文章里我们介绍了 Register、PC、RAM 和 ALU&#…

【Linux实践室】Linux用户管理实战指南:用户密码管理操作详解

&#x1f308;个人主页&#xff1a;聆风吟_ &#x1f525;系列专栏&#xff1a;Linux实践室、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️任务描述二. ⛳️相关知识2.1 &#x1f514;用户密码存放地及方式2.2 &#x1f514;使用…

游戏本续航@控制中心的省电模式效果如何

文章目录 节能模式长续航模式&#x1f47a;相关工具 节能模式长续航模式&#x1f47a; 蓝天模具Control Center中的模式 根据我的试验,以及软件的提示,可以发现 Power Saving是最省电的,儿Quiet模式并不省电,它会启用独立显卡,只不过风扇的转速不像娱乐模式和性能模式那么积极而…

UE5学习日记——蓝图节点前缀关键字整理

一、起因 节点如海&#xff0c;中英文翻译的时候还是有差别的&#xff0c;比如&#xff1a; 同一个中文&#xff0c;可能在英文里完全不同&#xff0c;连出现位置可能都不一样 附加 Attach Actor To Component&#xff08;将Actor附加到组件&#xff09;Append Array&#xf…

数据分析和机器学习库Pandas的使用

Pandas 库是一个免费、开源的第三方 Python 库&#xff0c;是 Python 数据分析和机器学习的工具之一。Pandas 提供了两种数据结构&#xff0c;分别是 Series&#xff08;一维数组结构&#xff09;与 DataFrame&#xff08;二维数组结构&#xff09;&#xff0c;极大地增强的了 …

Web API —— DOM 学习(四)(完结)

目录 一、日期对象 &#xff08;一&#xff09;实例化 &#xff08;二&#xff09;日期对象方法 1.时间戳介绍 2.获得时间戳的方式 getTime()方法 new Date()方法 Date.now()方法 二、节点操作 &#xff08;一&#xff09;DOM 节点 1.节点类型 元素节点 &#xff08…

1+x中级题目练习复盘(20220625 1+X 中级理论考试)

Override 用于标注重写方法 函数式接口是指有且只有一个抽象方法的接口&#xff1b;