设备树of函数及示例
2025-11-18
9
0
of函数分为以下几类:
查找节点的函数
- of_find_node_by_name:节点名字查找指定的节点
- of_find_node_by_type:通过 device_type 属性查找指定的节点
- of_find_compatible_node:据 device_type 和 compatible 这两个属性查找指定的节点
- of_find_matching_node_and_match:通过 of_device_id 匹配表来查找指定的节点
- of_find_node_by_path :通过路径来查找指定的节点
查找父子节点的函数
- of_get_parent:获取指定节点的父节点
- of_get_next_child :用迭代的方式查找子节点
提取属性值的 OF 函数
- of_find_property :用于获取指定的属性
- f_property_read_string:读取属性中字符串值
- of_property_count_elems_of_size:获取属性中元素的数量
- of_property_read_u32_index:从属性中获取指定标号的 u32 类型数据值
- 读取属性中 u8、 u16、 u32 和 u64 类型的数组数据,比如大多数的 reg 属性都是数组数据,可以使用这 4 个函数一次读取出 reg 属性中的所有数据
- of_property_read_u8_array 函数
- of_property_read_u16_array 函数
- of_property_read_u32_array 函数
- of_property_read_u64_array 函数
- 属性只有一个整形值,这四个函数就是用于读取这种只有一个整形值的属性,分别用于读取 u8、 u16、 u32 和 u64 类型属性值
- of_property_read_u8 函数
- of_property_read_u16 函数
- of_property_read_u32 函数
- of_property_read_u64 函数
- of_n_addr_cells : 获取#address-cells 属性值
- of_n_size_cells:获取#size-cells 属性值
其他常用的 OF 函数
- of_device_is_compatible:查看节点的 compatible 属性是否有包含 compat 指定的字符串,也就是检查设备节点的兼容性
- of_get_address:获取地址相关属性,主要是“reg”或者“assigned-addresses”属性值
- of_translate_address:从设备树读取到的地址转换为物理地址
- of_address_to_resource:IIC、 SPI、 GPIO 等这些外设都有对应的寄存器,这些寄存器其实就是一组内存空间, Linux
内核使用 resource 结构体来描述一段内存空间 - of_iomap:直接内存映射
使用示例
设备树内容如下:
/{
pcieeled {
#address-cells = <1>;
#size-cells = <1>;
compatible = "pciee-led";
status = "okay";
reg = < 0X020C406C 0X04 /* CCM_CCGR1_BASE */
0X020E0068 0X04 /* SW_MUX_GPIO1_IO03_BASE */
0X020E02F4 0X04 /* SW_PAD_GPIO1_IO03_BASE */
0X0209C000 0X04 /* GPIO1_DR_BASE */
0X0209C004 0X04 >; /* GPIO1_GDIR_BASE */
};
};
驱动代码如下:
struct property *proper;
/* 获取设备树中的属性数据 */
/* 1、获取设备节点:alphaled */
dtsled.nd = of_find_node_by_path("/pcieeled");
if(dtsled.nd == NULL) {
printk("alphaled node nost find!\r\n");
return -EINVAL;
} else {
printk("alphaled node find!\r\n");
}
/* 2、获取compatible属性内容 */
proper = of_find_property(dtsled.nd, "compatible", NULL);
if(proper == NULL) {
printk("compatible property find failed\r\n");
} else {
printk("compatible = %s\r\n", (char*)proper->value);
}
/* 3、获取status属性内容 */
ret = of_property_read_string(dtsled.nd, "status", &str);
if(ret < 0){
printk("status read failed!\r\n");
} else {
printk("status = %s\r\n",str);
}
/* 4、获取reg属性内容 */
ret = of_property_read_u32_array(dtsled.nd, "reg", regdata, 10);
if(ret < 0) {
printk("reg property read failed!\r\n");
} else {
u8 i = 0;
printk("reg data:\r\n");
for(i = 0; i < 10; i++)
printk("%#X ", regdata[i]);
printk("\r\n");
}
//取消映射使用iounmap
#if 0
/* 1、寄存器地址映射 */
IMX6U_CCM_CCGR1 = ioremap(regdata[0], regdata[1]);
SW_MUX_GPIO1_IO03 = ioremap(regdata[2], regdata[3]);
SW_PAD_GPIO1_IO03 = ioremap(regdata[4], regdata[5]);
GPIO1_DR = ioremap(regdata[6], regdata[7]);
GPIO1_GDIR = ioremap(regdata[8], regdata[9]);
#else
IMX6U_CCM_CCGR1 = of_iomap(dtsled.nd, 0);
SW_MUX_GPIO1_IO03 = of_iomap(dtsled.nd, 1);
SW_PAD_GPIO1_IO03 = of_iomap(dtsled.nd, 2);
GPIO1_DR = of_iomap(dtsled.nd, 3);
GPIO1_GDIR = of_iomap(dtsled.nd, 4);
#endif
ARM&Linux基础





