在Linux驱动开发中,设备树(Device Tree)是描述硬件配置的核心机制。以下是对of_property_read_string
、of_property_count_elems_of_size
和of_property_read_u32_array
三个函数的详解,结合内核源码与实际场景分析:
1. of_property_read_string
- 作用:从设备树属性中读取单字符串值(如
compatible
、model
属性)。 - 函数原型:
int of_property_read_string(struct device_node *np, const char *propname, const char **out_string);
- 参数:
np
:设备节点指针(如struct device_node *node
)。propname
:属性名(如"compatible"
)。out_string
:输出参数,指向存储读取结果的指针。
- 返回值:
- 成功返回
0
,失败返回负值错误码:-EINVAL
:属性不存在或参数无效。-ENODATA
:属性无值。-EILSEQ
:字符串未正确终止(非空结尾)。
- 成功返回
- 典型场景:
- 读取
compatible
属性匹配驱动:const char *compat; of_property_read_string(np, "compatible", &compat);
- 获取设备型号信息(如
model
属性)。
- 读取
- 注意事项:仅适用于单字符串属性,多字符串需用
of_property_read_string_array
。
2. of_property_count_elems_of_size
- 作用:统计设备树属性中指定大小的元素数量(如数组长度)。
- 函数原型:
int of_property_count_elems_of_size(const struct device_node *np, const char *propname, int elem_size);
- 参数:
np
:设备节点指针。propname
:属性名(如"reg"
、"interrupts"
)。elem_size
:元素大小(如4
表示u32数组,1
表示u8数组)。
- 返回值:
- 成功返回元素数量,失败返回负值错误码(同上)。
- 典型场景:
- 确定
reg
属性中寄存器地址数组的长度:int count = of_property_count_elems_of_size(np, "reg", 4);
- 校验中断数组的合法性(如
interrupts
属性)。
- 确定
- 注意事项:需确保
elem_size
与属性数据类型匹配,否则返回-EINVAL
。
3. of_property_read_u32_array
- 作用:从设备树属性中读取u32类型数组(如寄存器列表、中断号数组)。
- 函数原型:
int of_property_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values, size_t sz);
- 参数:
np
:设备节点指针。propname
:属性名。out_values
:存储读取结果的u32数组指针。sz
:期望读取的元素数量。
- 返回值:
- 成功返回实际读取的元素数量,失败返回负值错误码:
-EOVERFLOW
:属性数据长度不足或超出范围。
- 成功返回实际读取的元素数量,失败返回负值错误码:
- 典型场景:
- 读取寄存器地址数组:
u32 reg_values[4]; of_property_read_u32_array(np, "reg", reg_values, ARRAY_SIZE(reg_values));
- 解析中断号列表(如
interrupts
属性)。
- 读取寄存器地址数组:
- 注意事项:
- 需预先通过
of_property_count_elems_of_size
确定数组长度。 - 确保
out_values
缓冲区足够大,避免缓冲区溢出。
- 需预先通过
函数关联与最佳实践
- 协同使用:通常结合使用,例如:
- 用
of_property_count_elems_of_size
确定数组长度。 - 用
of_property_read_u32_array
读取数组数据。
- 用
- 错误处理:必须检查返回值,避免空指针或无效数据导致系统崩溃。
- 内核版本兼容性:函数行为可能随内核版本微调,需参考对应版本的内核源码(如
drivers/of/property.c
)。
这些函数是Linux驱动与设备树交互的基石,正确使用它们可确保驱动兼容不同硬件配置,提升代码可移植性与健壮性。