成都企业网站设计制作,公众号开发者模式,个人电脑做网站,修改wordpress域名参考文献
参考视频 开发板及程序 原子mini 设备树官方文档
设备树的基本概念
DT:Device Tree //设备树 FDT: Flattened Device Tree //开放设备树#xff0c;起源于OpenFirmware (所以后续会见到很多OF开头函数) dts: device tree source的缩写 //设备树源码 dtsi: device …参考文献
参考视频 开发板及程序 原子mini 设备树官方文档
设备树的基本概念
DT:Device Tree //设备树 FDT: Flattened Device Tree //开放设备树起源于OpenFirmware (所以后续会见到很多OF开头函数) dts: device tree source的缩写 //设备树源码 dtsi: device tree source include的缩写 //通用的设备树源码5dtb: device tree blob的缩写//编译设备树源码得到的文件 dtc: device tree compiler的缩写 //设备树编译器
设备树编译
dis和dtsi文件通过dtc编译器生成dtb设备树二进制文件。 DTC编译器在内核源码
alientekubuntu16:~/linux/linux-imx-4.1.15-2.1.0-g3dc0a4b-v2.7$ find -name dtc.c./drivers/scsi/dtc.c
./scripts/dtc/dtc.c
alientekubuntu16:~/linux/linux-imx-4.1.15-2.1.0-g3dc0a4b-v2.7$ cd ./scripts/dtc/dtc.c
bash: cd: ./scripts/dtc/dtc.c: Not a directory
alientekubuntu16:~/linux/linux-imx-4.1.15-2.1.0-g3dc0a4b-v2.7$ cd ./scripts/dtcalientekubuntu16:~/linux/linux-imx-4.1.15-2.1.0-g3dc0a4b-v2.7/scripts/dtc$ ls
checks.c dtc-parser.tab.h Makefile
checks.o dtc-parser.tab.h_shipped Makefile.dtc
data.c dtc-parser.tab.o modules.order
data.o dtc-parser.y srcpos.c
dtc fdtdump.c srcpos.h
dtc.c fdtget.c srcpos.o
dtc.h fdtput.c treesource.c
dtc-lexer.l flattree.c treesource.o
dtc-lexer.lex.c flattree.o update-dtc-source.sh
dtc-lexer.lex.c_shipped fstree.c util.c
dtc-lexer.lex.o fstree.o util.h
dtc.o libfdt util.o
dtc-parser.tab.c livetree.c version_gen.h
dtc-parser.tab.c_shipped livetree.o
编译内核时候会同步编译dtc。 指令格式 dtc [-I input-format] [-O output-format][-o output-filename] [-V output_version] input_filename 编译设备树dtc -I dts -O dtb -o xxx.dtb xxx.dts 反编译设备树dtc -I dtb -O dts -o xxx.dts xxx.dtb 简单写一个dts
/dts-v1/;
/ {};编译与反编译 在Linux根目录下用make dtbs 可以编译所有设备树。 arch/arm/boot/dts/Makefile通过比配置控制编译那些设备树
dtb-$(CONFIG_SOC_IMX6UL) \imx6ul-14x14-ddr3-arm2.dtb \imx6ul-14x14-ddr3-arm2-emmc.dtb \
.........imx6ul-9x9-evk-csi.dtb \imx6ul-9x9-evk-ldo.dtb
语法
头文件
和 C 语言一样设备树也支持头文件设备树的头文件扩展名为.dtsi也可以引用 C 语言中的.h 文件甚至也可以引用.dts 文件例如
#include dt-bindings/input/input.h
#include xxxxx.dtsi一般.dtsi 描述板级信息(也就是开发板上有哪些 IIC 设备、SPI 设备等由芯片厂提供).dts 描述 SOC 级信息(各个外设控制器信息、那个iic上挂哪个传感器等)这样写的好处是将芯片平台与下游odm分开通过dts拓展原始基础dtsi。
节点
根节点是设备树必须要包含的节点。根节点的名字是/。 子节点格式为
[label:]node-name[unit-address]{[properties definitions][child nodes]
};
举例
node1{//子节点节点名称为node1node1_child{//子子节点节点名称为node1_child}
}同级节点下节点名称不能相同不通级节点名称可以相同。 label 标签引入 label 的目的就是为了方便访问节点可以直接通过label 来访问这个节点。 node-name名称必须要有。 unit-address设备地址这里的设备地址没有实际用处只是为了代码可读性的要求。
特殊节点
aliases 特殊节点aliases用来定义别名。定义别名的目的就是为了方便引用节点。当然除了使用aliases来命名别用也可以在对节点命名的适合添加标签来命名别名。
举例:
aliases(mmc0 sdmmc0mmc1 sdmmc1:mmc2 sdhci:serial0/simplefe000000/serialllc500”
}choosen chosen节点用来uboot给内核传递参数。重点是bootargs参数。chosen节点必须是根节点的子节点。举例:
chosen{bootargs root/dev/nfs rw nfsroot192.168.1.1 consolettyS0,115200
}属性
compatible“兼容性”属性该属性的值是一个字符串列表compatible属性用于将设备和驱动绑定起来属性的值格式“manufacturer,model” 其中manufacturer 表示厂商model 一般是模块对应的驱动名字如果该属性为字符串列表则先使用第一个兼容值在 Linux 内核里面查找没找到的话再使用第二个兼容值查找 |model描述设备模块信息一般为名字例如model “wm8960-audio”;status字符串设备的状态信息包括“okay”、“disabled”、“fail”、“fail-xxx”各种错误信息#addresscells 和#size-cells无符号 32 位整型用于描述子节点的地址信息#address-cells决定了子节点 reg 属性中地址信息所占用的字长#size-cells决定了长度信息所占用的字长。reg寄存器信息 例如父节点#address-cells值为1#size-cells值为1则子节点中reg的值就是一个首地址加一个地址长度为一个单元子节点可以reg0x100000000 0x0100 0x200000000 0x0100父节点#address-cells值为1#size-cells值为0则子节点中reg的值就是一个首地址加一个地址长度为一个单元子节点可以reg0x100000000 0x200000000ranges 属性是一个地址映射/转换表它可以为空即“ranges”为空值说明子地址空间和父地址空间完全相同不需要进行地址转换。 不为空时格式child-bus-address,parent-bus-address,length child-bus-address子总线地址空间的物理地址由父节点的#address-cells 确定此物理地址所占用的字长。 parent-bus-address 父总线地址空间的物理地址同样由父节点的#address-cells 确定此物理地址所占用的字长。 length 子地址空间的长度由父节点的#size-cells 确定此地址长度所占用的字长。device_type在某些设备树文件中可以看到device_type属性device_type属性的值是字符串只用于cpu节点或者memory节点进行描述。自定义自由发挥
节点含义
如果包含gpio-controller该节点就是gpio控制器 如果包含interrupt-controller该节点就是gpio控制器
引用
interrunt-parentgpio0;追加内容
向节点追加内容相当于硬件上在soc厂商的基础上添加字节的硬件。比如要在iic总线上挂载一个六轴设备soc厂商可能给一个例程也可能不给就要自己修改和添加。 比如dtsi中
i2c1: i2c021a0000 {#address-cells 1;#size-cells 0;compatible fsl,imx6ul-i2c, fsl,imx21-i2c;reg 0x021a0000 0x4000;interrupts GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH;clocks clks IMX6UL_CLK_I2C1;status disabled;
};可以直接在dtsi中加但是代码复用性就降低了。在dts中追加
i2c1 {clock-frequency 100000;pinctrl-names default;pinctrl-0 pinctrl_i2c1;status okay;mag31100e {compatible fsl,mag3110;reg 0x0e;position 2;};ap3216c1e {compatible ap3216c;reg 0x1e;};
};这里就追加了几个属性和两个子节点。 其中status属性进行了改写属性名形同时追加的值会覆盖原有的值。
实例分析
中断
在中断控制器中必须有一个属性#interrupt-cells表示其他节点如果使用这个中断控制器需要几个cell来表示使用哪一个中断。 在中断控制器中必须有一个属性interrupt-controller表示他是中断控制器。 在设备树中使用中断需要使用属性interrupt-parentXXXX表是中断信号链接的是哪个中断控制器。接着使用interrupts属性来表示中断引脚和触发方式。 注: interrupt里有几个cell是由interrupt-parent对应的中断控制器里面的#interrupt-cells属性决定。
//原厂BSP工程师编写
gpio1: gpio209c000{compatible fsl,imx6ul-gpiofsl,imx35-gpio;reg 0x0209c000 0x4000;interrupts GIC_SPI 66 IROTYPE LEVEL HIGH,GIC SPI 67 IRO TYPE LEVEL HIGH;gpio-controller;//该节点可以是gpio控制器#gpio-cells 2;interrupt-controller;//该节点也可以是中断控制器#interrupt-cells 2;//引用该节点的节点中interrupt-controller属性中数据的个数
}//开发人员编写
edt-ft5x06g38{compatible edt,edt-ft5x06”edt,edt-ft5406edtedt-ft5306pinctrl-names default;pinctrl-0 ts_int_pin,ats_reset_pin;reg 0X38;interrupt-parent gpio1;interrupts 9 0;reset-gpios gpio5 9 GPIO ACTIVE_LOW;//低电平触发irq-gpios gpio1 9 GPIO ACTIVE LOW;status disabled;
}设备树信息读取of函数
设备树被内核解析以后可以在/proc/device-tree/目录中查看。 设备树机制是源于IEEE 1275 Open Firmware standard规范相关的代码都是继承下来的因此内核中设备树相关的函数都是以of开头的。 位置include/linux/of.h Linux设备树常用的OF函数总结