是什么
flatten device tree
https://elinux.org/Device_Tree_Usage
数据结构及查找算法
深度优先DFS算法
怎么用
工具类
libfdt
dtc工具
dts, dtsi <–> dtb
dtc-tools
常用函数:
如何用好
查找节点的绝对路径:
#define MAX_LEVEL 30
static int of_find_node_by_name(const void *blob, const char *name) {
// fdt_path_offset_namelen(const void *fdt, const char *path, int namelen)
int nextoffset; /* next node offset from libfdt */
uint32_t tag; /* current tag */
int level = 0; /* keep track of nesting level */
const char *pathp;
int depth = 1; /* the assumed depth of this node */
int node = 0;
int ret = -1;
char buf[300];
char name_cur[100];
while (level >= 0) {
tag = fdt_next_tag(blob, node, &nextoffset);
switch (tag) {
case FDT_BEGIN_NODE:
pathp = fdt_get_name(blob, node, NULL);
if (level <= depth) {
if (pathp == NULL)
pathp = "/* NULL pointer error */";
if (*pathp == '\0')
pathp = "/"; /* root is nameless */
}
level++;
if (level >= MAX_LEVEL) {
goto err;
}
break;
case FDT_END_NODE:
level--;
if (level == 0)
level = -1; /* exit the loop */
break;
case FDT_END:
return 1;
case FDT_PROP:
break;
default:
if (level <= depth)
return 1;
}
// printf("name: %s\n", name);
// printf("pathp: %s\n", pathp);
if (!strcmp(pathp, name)) {
ret = 1;
fdt_get_path(blob, node, buf, 300);
printf("of_find_node_by_name name:%s, path: %s\n", name, buf);
goto exit;
}
node = nextoffset;
}
exit:
ret = node;
err:
return ret;
}
int get_alias_nth_reg_value(void *fdt, char *alias, uint *value, int idx) {
const char *real_path;
uint offset;
const uint32_t *prop;
int len;
const fdt32_t *reg;
int ret = 0;
real_path = fdt_get_alias(fdt, alias);
offset = fdt_path_offset(fdt, real_path);
prop = fdt_getprop(fdt, offset, "reg", &len);
if (!prop || len < idx) {
// printf("Error: Couldn't find reg property\n");
ret = -1;
} else {
*value = fdt32_to_cpu(prop[idx]);
}
return ret;
}