Linux 设备树

一.介绍

1. 基础知识

DTS 即 Device Tree Source 设备树源码,Device Tree 是一种描述硬件的数据结构。

1. dts(device tree source)文件对应一个开发板,一般放置在内核的"arch/arm/boot/dts/"目录下:

2. dtsi:一些相同的 dts 配置可以抽象到 dtsi 文件中,这个 dtsi 文件其实就类似于 C 语言当中的.h 头文件,用法:

3. dtc: device-tree-compiler,就是设备树文件.dts 的编译器。

        dtc 工具在 Linux 内核的 scripts/dtc 目录下。

4. dtb:.dts 文件编译成二进制数据之后得到的文件

2. 编译 make dtbs

2.1 编译流程:

  执行”make all” 或者是”make dtbs” 命令的时候, arch/arm/boot/dts/Makefile文件中对应的那些 dts 文件就会被编译成 dtb(二进制文件) 文件。

2.2 编译指定的dts

 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- system-top.dtb    

二. dts语法

1 设备树基础结构体:

/{    //根节点
    node1{   //node1节点
        property1=value1; //node1节点属性
    };

    node2{   //node2节点
        propertyx=valuex; //node2节点属性
        ...
        node3{   //node2的子节点node3节点
            property3=value3; //node3节点属性
        };
    };
};

2 节点和属性

节点:

 label 标签:方便在 dts文件中被其他的节点引用;

node-name :节点名字;

unit-address:一般表示设备的地址或寄存基地址,如果某个节点没有地址或者寄存器的话“         unit-address”可以不要,比如“ cpu@0”、“ interrupt-controller@00a01000”。

示例:

 

 特殊节点:

1. aliases 节点,示例:

        

2.chosen节点:

        一般会有两个属性, “ bootargs”和“ stdout-path”

        

        stdout-path = “ serial0:115200n8” ,表示标准输出设备使用串口 serial0
        bootargs:启动参数

3. momory节点:

        

        memory 节点描述了系统内存的基地址以及系统内存大小。

 属性:

1.字符串 " "   示例: compatible = "arm,cortex-a9";
2.整型数据< > 示例: clock-latency = <1000>; reg = <0x00000000 0x00500000>;

3.二进制数据 [ ]  示例:local-mac-address = [00 0a 35 00 1e 53];

4.字符串数组 " "," " 示例:compatible = "n25q512a","micron,m25p80";

5.混合值 都用   示例:mixed-property = "a string", [0x01 0x23 0x45 0x67], <0x12345678>;
6.节点引用:& ,示例:clocks = <&clkc 3>;
7.注释:// 或  /* */

属性解释:

1.compatible 属性:一般使用” <制造商>,<型号>”命名。用于将设备和驱动绑定起来。

2.model属性:字符串描述信息, 它指定制造商的设备型号, model 属性一般定义
        在根节点下,一般就是对板子的描述信息,没啥实质性的作用。

3.status属性:设备状态。

        注意如果节点中没有添加 status 属性,那么它默认就是“ status = okay”。

4.#address-cells 和#size-cells 属性:用于描述子节点的地址信息。
        ➢ #address-cells,用来描述子节点"reg"属性的地址表中首地址 cell 的数量;
        ➢ #size-cells,用来描述子节点"reg"属性的地址表中地址长度 cell 的数量

        reg = <address1 length1 address2 length2 address3 length3……>


5.reg属性:

        reg 属性的值一般是(address, length)对。 reg 属性一般用于描述设备地址空间资源信息,一般都是描述某个外设的寄存器地址范围信息、 flash 设备的分区信息等,

         示例:

        

6.ranges属性:地址转换表

        ranges 属性值可以为空或者(child-bus-address,parent-bus-address,length)

7.device_type 属性:表示节点的类型
        此属性在设备树当中用的比较少,一般用于 cpu 节点或者 memory 节点

 2.向节点追加或修改内容

向i2c0总线添加24c64和rtc,举例:

&i2c0{
    clock-frequency = <100000>;
    status = "okey";
    
    24c64@50{
        compatible = "atmel,24c64";
        reg = <0x50>;
        pagesize = <32>;
    };

    rtc@51{
        compatible = "nxp,pcf8563";
        reg = <0x51>;
    };
};

帮助文档路径:Linux 源码目录/Documentation/devicetree/bindings

三. 设备树常用of操作函数

        设备都是以节点的形式“挂”到设备树上的,因此要想获取这个设备的属性信息,必须先
获取到这个设备的节点。

       路径:(include/linux/of.h)
        device_node 结构体来描述一个节点,如下:

        

1.节点查找(5个函数)

 a.根据名字查找:of_find_node_by_name 

struct device_node *of_find_node_by_name(struct device_node *from,
                const char *name);

b.根据device_type属性查找:of_find_node_by_type

struct device_node *of_find_node_by_type(struct device_node *from, const char *type)

c.根据 device_type 和 compatible 这两个属性查找:of_find_compatible_node

struct device_node *of_find_compatible_node(struct device_node *from,
            const char *type,const char *compatible)

d.根据 of_device_id 匹配表来查找:of_find_matching_node_and_match
 

struct device_node *of_find_matching_node_and_match(struct device_node *from,
    const struct of_device_id *matches,const struct of_device_id **match)

e.根据节点路径查找:of_find_node_by_path

inline struct device_node *of_find_node_by_path(const char *path)

2.父/子节点查找

a.获取指定节点的父节点

struct device_node *of_get_parent(const struct device_node *node)

b.迭代的查找子节点

struct device_node *of_get_next_child(const struct device_node *node,
                            struct device_node *prev)

3.提取属性值

        

 a.查找指定的属性

property *of_find_property(const struct device_node *np,
                const char *name,int *lenp)

b.获取属性中元素的数量

int of_property_count_elems_of_size(const struct device_node *np,
                const char *propname,int elem_size)

c.从属性中获取指定下标

int of_property_read_u32_index(const struct device_node *np,
                const char *propname,u32 index,u32 *out_value)

d.读取属性中 u8、 u16、 u32 和 u64 类型的数组数据

int of_property_read_u8_array(const struct device_node *np,
            const char *propname,u8 *out_values,size_t sz)
int of_property_read_u16_array(const struct device_node *np,
            const char *propname,u16 *out_values,size_t sz)
int of_property_read_u32_array(const struct device_node *np,
            const char *propname,u32 *out_values,size_t sz)
int of_property_read_u64_array(const struct device_node *np,
            const char *propname,u64 *out_values,size_t sz)

e.读取只有一个整形值的属性

int of_property_read_u8(const struct device_node *np,
                const char *propname,u8 *out_value)
int of_property_read_u16(const struct device_node *np,
                const char *propname,u16 *out_value)
int of_property_read_u32(const struct device_node *np,
                const char *propname,u32 *out_value)
int of_property_read_u64(const struct device_node *np,
                const char *propname,u64 *out_value)

f.读取属性中字符串值

int of_property_read_string(struct device_node *np,
        const char *propname,const char **out_string)

g.获取#address-cells 和#size-cells属性值

int of_n_addr_cells(struct device_node *np)
int of_n_size_cells(struct device_node *np)

4.其他常用函数

a.检查设备节点的兼容性

int of_device_is_compatible(const struct device_node *device,const char *compat)

b.获取地址相关属性,主要是“ reg”或者“ assigned-addresses”属性值

const __be32 *of_get_address(struct device_node *dev,
                int index,u64 *size,unsigned int *flags)

c.从设备树读取到的地址转换为物理地址

u64 of_translate_address(struct device_node *dev, const __be32 *in_addr)

d.从设备树里面提取资源值,本质:将 reg 属性值转换为 resource 结构体类型:

int of_address_to_resource(struct device_node *dev, int index,struct resource *r)

e.内存映射

void __iomem *of_iomap(struct device_node *np,int index)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设备树(Device Tree)是一种描述嵌入式系统硬件设备的文件格式,用于在Linux内核中动态配置和管理硬件。设备树采用树形结构,描述了开发板上的各种设备信息,比如CPU数量、内存基地址、接口上连接的设备等。设备树文件的扩展名为.dts,编译后得到.dtb文件。在引导Linux内核时,Bootloader会将.dtb文件的地址传递给内核,内核会根据设备树文件中描述的信息创建和注册相关设备。通过设备树开发者可以在不修改内核源代码的情况下配置和管理硬件设备。在编译Linux源码时,可以使用"make dtbs"命令来单独编译设备树文件,而不是编译整个源码。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Linux 设备树](https://blog.csdn.net/m0_69211839/article/details/130601344)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [linux设备树](https://blog.csdn.net/qq_27094347/article/details/121012569)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值