设备树学习

设备树简介

设备树是用来描述硬件的分层数据结构,Zephyr操作系统使用设备树来描述器支持的板子上可以使用的硬件设备,以及硬件的初始配置。

分为两种类型的设备输入文件:设备树源和设备树绑定。其中设备树源文件包含设备树本身,绑定描述了它的内容,包括数据类型。构建系统使用设备树源和绑定来生成C头文件,这个生成头文件的内容被include\devicetree.h API抽象,可以用它获取设备树的信息。

设备树文件的拓展名为:.dts

设备树文件的“头”文件(通用文件):.dtsi,类似于C语言的头文件,.dtsi文件描述了 Zephyr 运行的 CPU 或片上系统,可能包括其他 .dtsi文件。它们还可以描述多个板共享的其他常见硬件功能,到时候直接引用该.dtsi文件即可。

设备树举例说明

我的开发板是stm32g071rb系列的,因此以该硬件的设备树为例,对设备树语法进行分析学习。

boards\arm\nucleo_g071rb\nucleo_g071rb.dts

/dts-v1/;
#include <st/g0/stm32g071Xb.dtsi>
#include <st/g0/stm32g071r(6-8-b)tx-pinctrl.dtsi>
#include "arduino_r3_connector.dtsi"

/ {
	model = "STMicroelectronics STM32G071RB-NUCLEO board";
	compatible = "st,stm32g071rb-nucleo";

	chosen {
		zephyr,console = &usart2;
		zephyr,shell-uart = &usart2;
		zephyr,sram = &sram0;
		zephyr,flash = &flash0;
	};

	power-states {
		stop0: state0 {
			compatible = "zephyr,power-state";
			power-state-name = "suspend-to-idle";
			substate-id = <1>;
			min-residency-us = <20>;
		};
		stop1: state1 {
			compatible = "zephyr,power-state";
			power-state-name = "suspend-to-idle";
			substate-id = <2>;
			min-residency-us = <100>;
		};
	};

	leds {
		compatible = "gpio-leds";
		green_led_1: led_4 {
			gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>;
			label = "User LD4";
		};
	};

	gpio_keys {
		compatible = "gpio-keys";
		user_button: button {
			label = "User";
			gpios = <&gpioc 13 GPIO_ACTIVE_LOW>;
		};
	};

	aliases {
		led0 = &green_led_1;
		sw0 = &user_button;
	};
};

&clk_hsi {
	status = "okay";
};
...
&usart1 {
	pinctrl-0 = <&usart1_tx_pc4 &usart1_rx_pc5>;
	pinctrl-names = "default";
	current-speed = <115200>;
	status = "okay";
};

};

        /dts-v1/

                表示该设备树文件,DTS语法版本是V1;

        三个include:引用其它通用设备树文件;

        /

                表示根节点;

        model

                :其属性用来描述设备模块信息,属性值一般是字符串形式;这里描述了“意法半导体硬件型号”

        compatible

                :兼容性属性 ,值为字符串,用于将设备与驱动绑定起来;字符串序列用于选择设备要使用的驱动程序;可以有多个值。

        chosen

                chosen节点位于根节点,其不代表实际的硬件,用于给内核传递参数;

        子节点

power-states、leds、gpio_keys...都是根节点下的子节点。

        其中像power-states节点中又包括了两个子节点。

        label

         :标签,用于代表节点,方便访问节点,可以通过&label访问该节点。

        aliases

        :给节点起别名,目的也是为了方便访问节点;

	aliases {
		led0 = &green_led_1; #给节点green_led_1起个别名为led0
		sw0 = &user_button;
	};

        &节点名

:用于对已有的节点进行追加内容,或者修改内容。

        以&clk_hsi为例:

在通用文件:dts\arm\st\g0\stm32g0.dtsi中:

clk_hsi: clk-hsi {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <DT_FREQ_M(16)>;
status = "disabled";
};

在boards\arm\nucleo_g071rb\nucleo_g071rb.dts中,将禁止状态修改为使能状态

&clk_hsi {
	status = "okay";
};

下面看一下nucleo_g071rb.dts引用的通用文件stm32g071Xb.dtsi

#include <mem.h>
#include <st/g0/stm32g071.dtsi>

/ {
	sram0: memory@20000000 {
		reg = <0x20000000 DT_SIZE_K(36)>;
	};

	soc {
		flash-controller@40022000 {
			flash0: flash@8000000 {
				reg = <0x08000000 DT_SIZE_K(128)>;
			};
		};
	};
};

在这个文件中只有很少的内容,在根节点下面有两个子节点

以sram0为例。它是描述静态随机存储器的硬件信息。

memory@20000000 指的就是stm32g071xb芯片上的SRAM起始地址0x20000000

#define DT_SIZE_K(x) ((x) * 1024)  

 DT_SIZE_K(36) 即36KB,

也就是说设置SRAM的内存大小为36KB。

我们可以对照一下参考手册的Memory map 各寄存器地址分布

再看一下stm32g071Xb.dtsi引用的通用文件

#include <st/g0/stm32g071.dtsi>,其部分内容如下:

/ {
	soc {
		usart3: serial@40004800 {
			compatible = "st,stm32-usart", "st,stm32-uart";
			reg = <0x40004800 0x400>;
			clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00040000>;
			interrupts = <29 0>;
			status = "disabled";
			label = "UART_3";
		};

		usart4: serial@40004c00 {
			compatible = "st,stm32-usart", "st,stm32-uart";
			reg = <0x40004c00 0x400>;
			clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00080000>;
			interrupts = <29 0>;
			status = "disabled";
			label = "UART_4";
		};
}

我们可以看到soc节点下的usart节点:

        其中usart3寄存器的起始地址为0x40004800

        其中usart4寄存器的起始地址为0x40004c00

对照一下参考手册的Memory map 各寄存器地址分布

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值