如何在读取前判断设备树节点属性值的类型(u32/u64/字符串/数组)
设备树属性类型判断问题
问题背景
我有如下设备树源文件:
/dts-v1/; { node { child { property1 = "string"; // string property2 = <1>; // u32 property3 = <1 2>; //u32 array }; }; };
我通过如下方式遍历child节点的属性:
for_each_property_of_node(child, prop) { //save the property data like of_property_read_u64(child,prop->name,...); of_property_read_u32(...); }
请问是否有办法在读取属性值前,判断其类型(u32、u64、字符串或数组类型)?
解决方案
当然可以,Linux内核提供了一系列标准设备树操作函数,能直接在读取属性前完成类型校验:
- 判断字符串类型:使用
of_property_read_string()尝试读取,返回值为0则说明是合法字符串;也可以用of_property_string_match()匹配特定字符串,间接验证类型。不建议手动通过prop->value的结尾\0或长度判断,内核标准函数会处理字节序、边界等细节,更可靠。 - 判断u32/u64类型(含数组):
- 单个u32值:调用
of_property_read_u32(),返回0即为合法单u32属性; - u32数组:调用
of_property_count_u32_elems(),返回值大于0则代表是u32数组(包含单个元素的情况); - u64类型同理,对应使用
of_property_read_u64()和of_property_count_u64_elems()。
- 单个u32值:调用
- 遍历场景下的通用判断逻辑:按优先级依次尝试读取不同类型,根据函数返回值确定属性类型,示例代码如下:
for_each_property_of_node(child, prop) { const char *str; u32 val; int ret; // 先验证字符串类型 ret = of_property_read_string(child, prop->name, &str); if (!ret) { pr_info("property %s is string: %s\n", prop->name, str); continue; } // 验证单个u32 ret = of_property_read_u32(child, prop->name, &val); if (!ret) { pr_info("property %s is u32: %u\n", prop->name, val); continue; } // 验证u32数组 int count = of_property_count_u32_elems(child, prop->name); if (count > 0) { u32 arr[count]; of_property_read_u32_array(child, prop->name, arr, count); pr_info("property %s is u32 array with %d elements\n", prop->name, count); // 此处可添加数组处理逻辑 continue; } // 如需验证u64类型,参照u32的逻辑调用对应函数即可 }
注意:设备树中用<>标记的数值实际以大端序存储,内核提供的读取函数会自动处理字节序转换,无需手动操作。另外规范的设备树属性一般为单一类型,上述逻辑可覆盖绝大多数开发场景。
内容的提问来源于stack exchange,提问作者Bret Joseph
相关产品推荐
相关产品推荐

