Преглед изворни кода

Merge pull request #2 from GuEe-GUI/main

add enum node api and add examples doc
Bernard Xiong пре 4 година
родитељ
комит
3d4bc19375
7 измењених фајлова са 146 додато и 4 уклоњено
  1. 2 2
      README.md
  2. 1 0
      docs/README.md
  3. 40 1
      docs/api.md
  4. 81 0
      docs/examples.md
  5. 1 1
      docs/version.md
  6. 1 0
      inc/fdt.h
  7. 20 0
      src/fdt_get.c

+ 2 - 2
README.md

@@ -23,7 +23,7 @@ fdt package 遵循 GPL-3.0 许可,详见 LICENSE 文件。
 ```
 RT-Thread online packages
     tools packages --->
-        [*] FDT package
+        [*] Device Tree package in RT-Thread
 ```
 
 ## 3、使用 fdt
@@ -38,4 +38,4 @@ RT-Thread online packages
 ## 5、联系方式
 
 * 维护:GuEe-GUI
-* 主页:https://gitee.com/GuEe_GUI/fdt
+* 主页:https://github.com/GuEe-GUI/fdt

+ 1 - 0
docs/README.md

@@ -8,5 +8,6 @@
 
 |文件名                             |描述|
 |:-----                             |:----|
+|[examples.md](examples.md)         |示例程序|
 |[version.md](version.md)           |版本信息|
 |[api.md](api.md)                   |API 说明|

+ 40 - 1
docs/api.md

@@ -127,7 +127,7 @@ void fdt_free_dtb_list(struct dtb_node *dtb_node_head)
 | **返回** | **描述** |
 |无返回值 | 无描述 |
 
-示例
+示例:加载设备树
 
 ```c
 #include <rtthread.h>
@@ -166,6 +166,43 @@ void fdt_get_dts_dump(struct dtb_node *dtb_node_head)
 | **返回** | **描述** |
 |无返回值 | 无描述 |
 
+## 遍历设备节点树并使用程序定义的回调函数
+```c
+void fdt_get_enum_dtb_node(struct dtb_node *dtb_node_head, void (*callback(struct dtb_node *dtb_node)))
+```
+
+| 参数 | 描述 |
+|:------------------|:------------------------------------|
+|dtb_node_head | 设备节点树头节点 |
+|callback | 程序定义的回调函数 |
+| **返回** | **描述** |
+|无返回值 | 无描述 |
+
+示例:遍历设备树节点,并打印每个节点名称
+
+```c
+#include <rtthread.h>
+#include <fdt.h>
+
+void callback(struct dtb_node *node)
+{
+    rt_kprintf("this node's name is %s\n", node->name);
+}
+
+int main()
+{
+    /* loaded dtb_node */
+    extern struct dtb_node *dtb_node_list;
+
+    if (dtb_node_list != RT_NULL)
+    {
+        fdt_get_enum_dtb_node(dtb_node_list, callback);
+    }
+
+    return 0;
+}
+```
+
 ## 通过节点名称查找节点
 ```c
 struct dtb_node *fdt_get_dtb_node_by_name_DFS(struct dtb_node *dtb_node, const char *nodename)
@@ -241,6 +278,8 @@ void *fdt_get_dtb_node_property(struct dtb_node *dtb_node, const char *property_
 |void * | 无描述 |
 |RT_NULL | 该设备树没有该属性 |
 
+读取的值为在设备树中存储的值,CPU小端模式下可能需要使用其他API进行转换才是正确的值
+
 ## 读取预留内存信息
 ```c
 struct dtb_memreserve *fdt_get_dtb_memreserve(struct dtb_node *dtb_node, int *memreserve_size)

+ 81 - 0
docs/examples.md

@@ -0,0 +1,81 @@
+# fdt示例 #
+
+在`examples`文件夹中存放`bcm2711-rpi-4-b.dtb`和`vexpress-v2p-ca9.dtb`可供测试,如果系统可以从bootloader或其他方式获取到bsp本身的dtb,也可以通过修改示例程序进行测试
+
+## fdt_dump
+```bash
+fdt_dump vexpress-v2p-ca9.dtb
+```
+
+####  示例结果 ####
+```bash
+/dts-v1/;
+
+/ {
+        model = "V2P-CA9";
+        arm,hbi = <0x191>;
+        arm,vexpress,site = <0xf>;
+        compatible = "arm,vexpress,v2p-ca9", "arm,vexpress";
+        interrupt-parent = <0x1>;
+        #address-cells = <0x1>;
+        #size-cells = <0x1>;
+
+        chosen {
+        };
+
+        aliases {
+                serial0 = "/smb@4000000/motherboard/iofpga@7,00000000/uart@9000";
+                serial1 = "/smb@4000000/motherboard/iofpga@7,00000000/uart@a000";
+                serial2 = "/smb@4000000/motherboard/iofpga@7,00000000/uart@b000";
+                serial3 = "/smb@4000000/motherboard/iofpga@7,00000000/uart@c000";
+                i2c0 = "/smb@4000000/motherboard/iofpga@7,00000000/i2c@16000";
+                i2c1 = "/smb@4000000/motherboard/iofpga@7,00000000/i2c@2000";
+        };
+
+...... 省略
+
+        hsb@e0000000 {
+                compatible = "simple-bus";
+                #address-cells = <0x1>;
+                #size-cells = <0x1>;
+                ranges = <0x0 0xe0000000 0x20000000>;
+                #interrupt-cells = <0x1>;
+                interrupt-map-mask = <0x0 0x3>;
+                interrupt-map = <0x0 0x0 0x1 0x0 0x24 0x4 0x0 0x1 0x1 0x0 0x25 0x4 0x0 0x2 0x1 0x0 0x26 0x4 0x0 0x3 0x1 0x0 0x27 0x4>;
+        };
+};
+```
+
+## fdt_test
+```bash
+fdt_test
+```
+
+####  示例结果 ####
+```bash
+name = uart@9000
+reg = <0x9000,0x1000>;
+compatible = "arm,pl011","arm,primecell";
+
+name = cpus
+path = /cpus/cpu@0/
+path = /cpus/cpu@1/
+path = /cpus/cpu@2/
+path = /cpus/cpu@3/
+
+name = user1, lable = v2m:green:user1
+name = user2, lable = v2m:green:user2
+name = user3, lable = v2m:green:user3
+name = user4, lable = v2m:green:user4
+name = user5, lable = v2m:green:user5
+name = user6, lable = v2m:green:user6
+name = user7, lable = v2m:green:user7
+name = user8, lable = v2m:green:user8
+
+/memreserve/    0x0000000000000000 0x0000000000001000;
+
+phandle = <0x9>
+name = bt_pins
+path = /soc/gpio@7e200000/bt_pins/
+brcm,pins = [2d 00]
+```

+ 1 - 1
docs/version.md

@@ -4,4 +4,4 @@
 | --------   | :-----:   | :----      | :---- |
 | 2021-9-1   | v0.0.1    | GuEe-GUI   | 初始版本 |
 | 2021-11-11   | v1.0.0    | GuEe-GUI   | API确定版本 |
-|            |           |            | |
+|            |           |            | |

+ 1 - 0
inc/fdt.h

@@ -71,6 +71,7 @@ rt_err_t fdt_get_exec_status();
 struct dtb_node *fdt_get_dtb_list(void *fdt);
 void fdt_free_dtb_list(struct dtb_node *dtb_node_head);
 void fdt_get_dts_dump(struct dtb_node *dtb_node_head);
+void fdt_get_enum_dtb_node(struct dtb_node *dtb_node_head, void (callback(struct dtb_node *dtb_node)));
 
 struct dtb_node *fdt_get_dtb_node_by_name_DFS(struct dtb_node *dtb_node, const char *nodename);
 struct dtb_node *fdt_get_dtb_node_by_name_BFS(struct dtb_node *dtb_node, const char *nodename);

+ 20 - 0
src/fdt_get.c

@@ -463,6 +463,26 @@ void fdt_get_dts_dump(struct dtb_node *dtb_node_head)
     }
 }
 
+static void _fdt_get_enum_dtb_node(struct dtb_node *dtb_node, void (callback(struct dtb_node *dtb_node)))
+{
+    while (dtb_node != RT_NULL)
+    {
+        callback(dtb_node);
+        _fdt_get_enum_dtb_node(dtb_node->child, callback);
+        dtb_node = dtb_node->sibling;
+    }
+}
+
+void fdt_get_enum_dtb_node(struct dtb_node *dtb_node_head, void (callback(struct dtb_node *dtb_node)))
+{
+    if (dtb_node_head == RT_NULL || callback == RT_NULL)
+    {
+        return;
+    }
+
+    _fdt_get_enum_dtb_node(dtb_node_head, callback);
+}
+
 struct dtb_node *fdt_get_dtb_node_by_name_DFS(struct dtb_node *dtb_node, const char *nodename)
 {
     struct dtb_node *dtb_node_child;