⑴ 如何在linux-3.x内核编译设备树
可以让设备树文件和内核一起编译,单独编译的化,可以参考下面的文档:
http://blog.csdn.net/woshigaoyuan/article/details/13996277
⑵ 如何使用dtc编译设备树 devicetree
DTS (device tree source)
.dts文件是一种ASCII 文本格式的Device
Tree描述,此文本格式非常人性化,适合人类的阅读习惯。基本上,在ARM
Linux在,一个.dts文件对应一个ARM的machine,一般放置在内核的arch/arm/boot/dts/目录。由于一个SoC可能对应多个machine(一个SoC可以对应多个产品和电路板),势必这些.dts文件需包含许多共同的部分,Linux内核为了简化,把SoC公用的部分或者多个machine共同的部分一般提炼为.dtsi,类似于C语言的头文件。其他的machine对应的.dts就include这个.dtsi。譬如,对于VEXPRESS而言,vexpress-v2m.dtsi就被vexpress-v2p-ca9.dts所引用,
vexpress-v2p-ca9.dts有如下一行:
/include/
"vexpress-v2m.dtsi"
当然,和C语言的头文件类似,.dtsi也可以include其他的.dtsi,譬如几乎所有的ARM
SoC的.dtsi都引用了skeleton.dtsi。
.dts(或者其include的.dtsi)基本元素即为前文所述的结点和属性:
[plain] view
plainprint?
/ {
node1 {
a-string-property = "A string";
a-string-list-property = "first string", "second string";
a-byte-data-property = [0x01 0x23 0x34 0x56];
child-node1 {
first-child-property;
second-child-property = <1>;
a-string-property = "Hello, world";
};
child-node2 {
};
};
node2 {
an-empty-property;
a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
child-node1 {
};
};
};
/ {
node1 {
a-string-property = "A string";
a-string-list-property = "first string", "second string";
a-byte-data-property = [0x01 0x23 0x34 0x56];
child-node1 {
first-child-property;
second-child-property = <1>;
a-string-property = "Hello, world";
};
child-node2 {
};
};
node2 {
an-empty-property;
a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
child-node1 {
};
};
};
上述.dts文件并没有什么真实的用途,但它基本表征了一个Device
Tree源文件的结构:
1个root结点"/";
root结点下面含一系列子结点,本例中为"node1" 和
"node2";
结点"node1"下又含有一系列子结点,本例中为"child-node1" 和
"child-node2";
各结点都有一系列属性。这些属性可能为空,如"
an-empty-property";可能为字符串,如"a-string-property";可能为字符串数组,如"a-string-list-property";可能为Cells(由u32整数组成),如"second-child-property",可能为二进制数,如"a-byte-data-property"。
下面以一个最简单的machine为例来看如何写一个.dts文件。假设此machine的配置如下:
1个双核ARM
Cortex-A9 32位处理器;
ARM的local bus上的内存映射区域分布了2个串口(分别位于0x101F1000 和
0x101F2000)、GPIO控制器(位于0x101F3000)、SPI控制器(位于0x10170000)、中断控制器(位于0x10140000)和一个external
bus桥;
External bus桥上又连接了SMC SMC91111
Ethernet(位于0x10100000)、I2C控制器(位于0x10160000)、64MB NOR
Flash(位于0x30000000);
External bus桥上连接的I2C控制器所对应的I2C总线上又连接了Maxim
DS1338实时钟(I2C地址为0x58)。
其对应的.dts文件为:
[plain] view
plainprint?
/ {
compatible = "acme,coyotes-revenge";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = "arm,cortex-a9";
reg = <0>;
};
cpu@1 {
compatible = "arm,cortex-a9";
reg = <1>;
};
};serial@101f0000 {
compatible = "arm,pl011";
reg = <0x101f0000 0x1000 >;
interrupts = < 1 0 >;
};serial@101f2000 {
compatible = "arm,pl011";
reg = <0x101f2000 0x1000 >;
interrupts = < 2 0 >;
};gpio@101f3000 {
compatible = "arm,pl061";
reg = <0x101f3000 0x1000
0x101f4000 0x0010>;
interrupts = < 3 0 >;
};intc: interrupt-controller@10140000 {
compatible = "arm,pl190";
reg = <0x10140000 0x1000 >;
interrupt-controller;
#interrupt-cells = <2>;
};spi@10115000 {
compatible = "arm,pl022";
reg = <0x10115000 0x1000 >;
interrupts = < 4 0 >;
};external-bus {
#address-cells = <2>
#size-cells = <1>;
ranges = <0 0 0x10100000 0x10000 // Chipselect 1, Ethernet
1 0 0x10160000 0x10000 // Chipselect 2, i2c controller
2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flashethernet@0,0 {
compatible = "smc,smc91c111";
reg = <0 0 0x1000>;
interrupts = < 5 2 >;
};i2c@1,0 {
compatible = "acme,a1234-i2c-bus";
#address-cells = <1>;
#size-cells = <0>;
reg = <1 0 0x1000>;
interrupts = < 6 2 >;
rtc@58 {
compatible = "maxim,ds1338";
reg = <58>;
interrupts = < 7 3 >;
};
};flash@2,0 {
compatible = "samsung,k8f1315ebm", "cfi-flash";
reg = <2 0 0x4000000>;
};
};
};
/ {
compatible = "acme,coyotes-revenge";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = "arm,cortex-a9";
reg = <0>;
};
cpu@1 {
compatible = "arm,cortex-a9";
reg = <1>;
};
};
serial@101f0000 {
compatible = "arm,pl011";
reg = <0x101f0000 0x1000 >;
interrupts = < 1 0 >;
};
serial@101f2000 {
compatible = "arm,pl011";
reg = <0x101f2000 0x1000 >;
interrupts = < 2 0 >;
};
gpio@101f3000 {
compatible = "arm,pl061";
reg = <0x101f3000 0x1000
0x101f4000 0x0010>;
interrupts = < 3 0 >;
};
intc: interrupt-controller@10140000 {
compatible = "arm,pl190";
reg = <0x10140000 0x1000 >;
interrupt-controller;
#interrupt-cells = <2>;
};
spi@10115000 {
compatible = "arm,pl022";
reg = <0x10115000 0x1000 >;
interrupts = < 4 0 >;
};
external-bus {
#address-cells = <2>
#size-cells = <1>;
ranges = <0 0 0x10100000 0x10000 // Chipselect 1, Ethernet
1 0 0x10160000 0x10000 // Chipselect 2, i2c controller
2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flash
ethernet@0,0 {
compatible = "smc,smc91c111";
reg = <0 0 0x1000>;
interrupts = < 5 2 >;
};
i2c@1,0 {
compatible = "acme,a1234-i2c-bus";
#address-cells = <1>;
#size-cells = <0>;
reg = <1 0 0x1000>;
interrupts = < 6 2 >;
rtc@58 {
compatible = "maxim,ds1338";
reg = <58>;
interrupts = < 7 3 >;
};
};
flash@2,0 {
compatible = "samsung,k8f1315ebm", "cfi-flash";
reg = <2 0 0x4000000>;
};
};
};
上述.dts文件中,root结点"/"的compatible 属性compatible =
"acme,coyotes-revenge";定义了系统的名称,它的组织形式为:<manufacturer>,<model>。Linux内核透过root结点"/"的compatible
属性即可判断它启动的是什么machine。
在.dts文件的每个设备,都有一个compatible
属性,compatible属性用户驱动和设备的绑定。compatible
属性是一个字符串的列表,列表中的第一个字符串表征了结点代表的确切设备,形式为"<manufacturer>,<model>",其后的字符串表征可兼容的其他设备。可以说前面的是特指,后面的则涵盖更广的范围。如在arch/arm/boot/dts/vexpress-v2m.dtsi中的Flash结点:
[plain] view
plainprint?
flash@0,00000000 {
compatible = "arm,vexpress-flash", "cfi-flash";
reg = <0 0x00000000 0x04000000>,
<1 0x00000000 0x04000000>;
bank-width = <4>;
};
flash@0,00000000 {
compatible = "arm,vexpress-flash", "cfi-flash";
reg = <0 0x00000000 0x04000000>,
<1 0x00000000 0x04000000>;
bank-width = <4>;
};
compatible属性的第2个字符串"cfi-flash"明显比第1个字符串"arm,vexpress-flash"涵盖的范围更广。
再比如,Freescale
MPC8349 SoC含一个串口设备,它实现了国家半导体(National Semiconctor)的ns16550
寄存器接口。则MPC8349串口设备的compatible属性为compatible = "fsl,mpc8349-uart",
"ns16550"。其中,fsl,mpc8349-uart指代了确切的设备, ns16550代表该设备与National Semiconctor
的16550
UART保持了寄存器兼容。
接下来root结点"/"的cpus子结点下面又包含2个cpu子结点,描述了此machine上的2个CPU,并且二者的compatible
属性为"arm,cortex-a9"。
注意cpus和cpus的2个cpu子结点的命名,它们遵循的组织形式为:<name>[@<unit-address>],<>中的内容是必选项,[]中的则为可选项。name是一个ASCII字符串,用于描述结点对应的设备类型,如3com
Ethernet适配器对应的结点name宜为ethernet,而不是3com509。如果一个结点描述的设备有地址,则应该给出@unit-address。多个相同类型设备结点的name可以一样,只要unit-address不同即可,如本例中含有cpu@0、cpu@1以及serial@101f0000与serial@101f2000这样的同名结点。设备的unit-address地址也经常在其对应结点的reg属性中给出。ePAPR标准给出了结点命名的规范。
⑶ Linux SPI通过设备树文件添加设备
如上DTS文件片段,SPI Device 节点必须定义在 SPI Master 节点下,其中 compatible 属性和 reg 属性,以上 compatible 属性用于匹配对应的 Driver 程序,reg 属性用于指定使用的 SPI Master 的编号,SPI 相关设备树文件识别见下文讲解。
匹配设备树文件在SPI子系统中有两个地方:在 spi_register_master() 中匹配和在 device register 时通过内核的通知链(notifier_block)来调用设备树匹配相关程序。
在 device register 时,需配置 CONFIG_OF_DYNAMIC 宏以开启动态匹配才能够使用设备树添加设备,该宏在 menuconfig/Device Drivers/Device Tree and Open Firmware support 中开启,如下图:
⑷ Jetson Nano 配置40引脚扩展接头
https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fhw_setup_jetson_io.html%23
每个Jetson开发套件均包含40针扩展插头。许多引脚可以用作GPIO或“特殊功能IO口(SFIO)”,例如I2C,I2S等。40引脚接头连接器使您可以将Jetson开发人员工具包连接到现成的Raspberry Pi HAT(Hardware Attached on Top),例如Seeed Grove模块,SparkFun Qwiic产品等。
烧录系统时,Jetson开发套件上所有I / O的默认配置写入设备中。要更改L4T 32.3之前的40引脚扩展插头的引脚配置,您必须使用Pinmux电子表格为相应的平台更新引脚配置,然后将新配置烧录到开发者套件中。尽管这可能是更新生产系统的适当方法,但开发时仍需要一种更方便的方法来测试不同的引脚配置。
从L4T 32.3版开始,NVIDIA提供了Jetson-IO工具来简化40针扩展插头的I / O配置。 Jetson‑IO 是基于Python的工具,可在开发人员工具包上运行并修改Device Tree Blob(DTB)固件,以便开发套件重新启动后使40针插头新配置生效。
要启动Jetson-IO,请在开发人员工具包上输入以下命令:
启动Jetson‑IO时,将显示以下屏幕。此时主屏幕显示40针接头当前的配置,并为您提供两个用于配置I / O的选项:
当您选择“配置兼容硬件(configure for compatible hardware)”选项时,Jetson‑IO将显示一些硬件模块的配置列表。
当前有两个硬件模块可供配置:
选择配置后,Jetson-IO返回主屏幕,主屏幕显示为针对该配置更新后的40针扩展接头的图。
您可以选择以下操作:
请注意,在更新配置文件之后,您仍然可以将开发人员工具包引导至先前的配置,因为Jetson ‑IO 通过为新配置添加新条目来更新extlinux.conf。先前的配置仍在文件中。引导目标时,引导加载程序使您可以选择配置(或文件中定义的任何其他配置)。
当您在主屏幕上选择“配置40针扩展头”选项时,Jetson-IO将显示40针头I / O支持的特殊功能列表。它在括号中显示了与功能相关的引脚。
例如,在NVIDIA ®杰特森™纳米开发工具包,杰特森-IO显示的功能列表如下。
有关支持的功能的更多详细信息,请参阅开发人员套件中的Jetson SoC 技术参考手册。
您可以根据需要选择或取消选择功能。
要接受所选的功能集,请选择“返回”选项。Jetson‑IO返回主屏幕。它会重新显示在“ 兼容硬件屏幕 ”之后显示的主 屏幕 ,并附加一个条目:
如果您希望从命令行而不是从菜单配置40针扩展头,NVIDIA提供了一组命令行工具,它们提供相同的功能。以下各节介绍了这些实用程序。
例子
显示可用硬件模块配置的列表。
例子
您可以通过为硬件模块创建设备树覆盖(Device Tree overlay)来使用Jetson‑IO支持自定义硬件模块。以下各节描述了此过程。
要添加对自定义硬件的支持到Jetson‑IO,您必须了解Jetson‑IO如何管理附加硬件。对硬件模块的支持由设备树覆盖文件(.dtbo文件)处理。
硬件模块的设备树覆盖必须定义:
该叠加名称属性必须是唯一的名称,从别人的覆盖区别。该兼容属性必须有一个或多个以下的,这取决于Jetson平台的支持。
用户可以通过输入以下命令来获取适用于其Jetson平台的正确兼容字符串。如果您有Jetson Nano开发人员工具包,此命令还将标识PCB版本。
例如,请考虑FE-PI Audio Z V2模块。目标的/ boot目录中是名称与模式匹配的覆盖文件:
您可以使用fdtmp实用工具检查覆盖文件的内容,并查看覆盖名称( overlay-name )和兼容属性( compatible )。例如,在Jetson Nano开发人员工具包上,您可以通过输入以下命令来显示这些属性:
要创建简单的设备树覆盖图以为Jetson Nano(带有A02载板和A02模块)开发人员工具包添加新的自定义属性,请在目标平台上创建一个名为my-overlay.dts的文件,内容如下:
输入以下命令以将DTS源文件编译为覆盖文件:
将新的覆盖文件复制到/ boot目录之后,Jetson‑IO会找到该覆盖文件并允许您应用它:
如果要为连接到40针扩展接头连接器的自定义硬件模块创建覆盖文件,则最简单的方法是使用Jetson-IO根据需要配置40针接头连接器并将配置导出为覆盖。您可以使用面向菜单的Jetson-IO脚本或关联的·config-by -...·命令行工具来执行此操作。
例如,要为启用I2S接口的Jetson Nano(A02)创建覆盖,请输入以下命令:
然后,您可以通过输入此命令将覆盖图转换为设备树源文件。
您可以根据需要为定制硬件修改生成的设备树源,并添加硬件模块所需的任何其他节点和/或属性。然后,您可以重新编译设备树源并将其放置在/ boot /目录中,以供Jetson‑IO使用:
⑸ 编译linux内核设备树文件使用什么命令
Linux源码的arch/powerpc/boot/dts/目录下存放了很多dts文件,可以作为参考文件。另外dtc编译器在内核专源码2.6.25版本之后已经被属包含进去。在2.6.26版本之后,生成blob的简单规则已经加入makefile,如下命令:
$ make ARCH=powerpc canyonlands.dtb
也可以根据自己的硬件修改好dts文件后,用下面类似命令生成dtb文件。
$ dtc -f -I dts -O dtb -R 8 -S 0x3000 test.dts > mpc836x_mds.dtb
$ mkimage -A ppc -O Linux -T flat_dt -C none -a 0x300000 -e 0 -d mpc836x_mds.dtb mpc836x_mds.dtu
⑹ 怎么把设备树烧录到flash
可以通过硕思闪客把设备树烧录到flash。
在硕思闪客菜单中,你可以将下拉菜单应用到程序中,并产生一个闪客菜单,下拉菜单的属性将会包含在新的闪客菜单中,例如文本、内容、文本类型、链接、对象、状态和提示文本。此外,你可以将树状菜单导入到程序中,产生一个闪客菜单,菜单生成器也是如此。
导入魔法菜单,只要点击界面中的文件:导入魔法菜单文件,就能将魔法菜单导入到闪客菜单中。