独立编译设备树的方法 多文件 多dts依赖

通常将设备树源码(dts/dtsi)编译成设备树二进制文件(dtb)可以使用DTC(Device Tree Compiler)工具编译。

  • 单文件编译

对于单文件的dts,可以采用下面的命令:

# dtc命令使用方法见文末
dtc -O dtb -b 0 -o [dest_dtb_file] [src_dts_file]

src_dts_file编译成dest_dtb_file设备树二进制文件。

  • 多文件编译

对于有#include包含关系、宏定义的dts文件,直接采用以上的方法将会出现#include相关的语法错误
DTC本身不支持#include语法,其正确语法为/include/。

如将以下dts(没有宏定义)

#include "child_file.dtsi"
#include "child_file_common.dtsi"

改为

/include/ "child_file.dtsi"
/include/ "child_file_common.dtsi"

即可通过编译。

对于以下稍微复杂一点(包含#include,宏,*.h等)的设备树,以上的方法不免有些笨拙。

复杂设备树

由于“#include”“宏”等都是C的特征,因此可以使用CPP(C Preprocessor)命令对dts源文件进行处理,完成文件包含与宏置换的工作。

# cpp的使用方法较长就不列出来了,可以自己man一下。
cpp -nostdinc -I. -undef -x assembler-with-cpp [src_dts_file] > [tmp_dts_file]
# -nostdinc 不搜索标准目录
# -I. 搜索当前目录
# -undef 不预定义系统和gcc特定的宏
# -x assembler-with-cpp 指定语言c c++ objective-c assembler-with-cpp

使用以上命令将所有的*.dts、*.dtsi、*.h转换至临时*.dts中,然后再使用单文件编译的方法编译临时*.dts,生成最终的dtb。

将上面的操作写成脚本(dts2dtb.sh)如下:

#/bin/bash
#set -vx
device="your_device_name"
src_dts=$device.dts
tmp_dts=$device.tmp.dts
dst_dtb=$device.dtb

cpp -nostdinc -I. -undef -x assembler-with-cpp $src_dts > $tmp_dts
dtc -O dtb -b 0 -o $dst_dtb $tmp_dts
rm $tmp_dts

使用:

修改your_device_name为你要编译的设备树名称,拷贝所有相关的设备树源文件至脚本所在目录,运行。

dtc使用方法:

NAME
       dtc - Device Tree Compiler

SYNOPSIS
       /usr/bin/dtc [options] <input file>

DESCRIPTION
       Device  Tree  Compiler,  dtc,  takes  as input a device-tree in a given format and outputs a
       device-tree in another format for booting kernels on embedded systems.  Typically, the input
       format  is  "dts",  a human readable source format, and creates a "dtb", or binary format as
       output.

OPTIONS
       -h     Display help text.

       -q     Quiet:

              -q - Suppress warnings.
              -qq - Suppress errors.
              -qqq - Suppress all.

       -I <input format>

              Input formats are:

              dts - device tree source text
              dtb - device tree blob
              fs - /proc/device-tree style directory

       -o <output file>

              Dump the result into a file, instead of stdout.

       -O <output format>

              Output formats are:

              dts - device tree source text
              dtb - device tree blob
              asm - assembler source

       -V <output version>

              Blob version to produce. The default is 17 (only relevant for dtb and asm output).

       -d <output dependency file>

       -R <number>

              Make space for <number> reserve map entries (only relevant for dtb and asm output).

       -S <bytes>

              Make the blob at least <bytes> long (extra space).

       -p <bytes>

              Add padding to the blob of <bytes> long (extra space)

       -b <number>

              Set the physical boot CPU.

       -f

              Force - try to produce output even if the input tree has errors.

       -s

              Sort nodes and properties before outputting (only useful for comparing trees)

       -v     Print DTC version and exit.

       -H <phandle format>

              phandle formats are:

              legacy - "linux,phandle" properties only
              epapr - "phandle" properties only
              both - Both "linux,phandle" and "phandle" properties
<think>嗯,用户想在现有的SPI设备树节点中添加一个控制引脚res_control_pin。我需要先仔细看看用户提供的代码结构。首先,用户给出的代码中有两个主要部分:spi3节点和pinctrl节点。 在spi_oled@0子节点里,已经有一个dc_control_pin的定义,使用的是gpio3 RK_PA7。用户现在要添加的是res_control_pin,应该需要类似的语法。首先,我需要确定这个res引脚对应的GPIO组和引脚号,比如假设用户想用gpio3 RK_PB0,或者其他可用的GPIO。这里用户可能需要根据硬件实际情况调整,但代码示例需要保持正确性。 接下来,在设备树节点中添加res_control_pin属性,应该是在spi_oled@0里面,和dc_control_pin并列。例如: res_control_pin = <&gpioX RK_PXx GPIO_ACTIVE_HIGH>; 这里的X和x需要替换成具体的GPIO信息。同时,用户可能需要注意GPIO的激活电平是否正确,比如是GPIO_ACTIVE_HIGH还是LOW。 然后,还需要在pinctrl节点中添加对应的引脚控制配置。原来的spi_oled_pin已经配置了gpio3 PA7,现在需要为res引脚添加一个新的pinctrl条目。比如在&pinctrl下的spi_oled部分添加新的子节点: spi_oled_res_pin: spi_oled_res_pin { rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; }; 然后,在spi_oled@0中,pinctrl-0可能需要引用这个新的引脚配置,或者如果已经有个pinctrl条目,可能需要调整pinctrl-names和对应的pinctrl-序号。不过原代码中pinctrl-names是"default",所以可能只需要将新的引脚配置合并到同一个pinctrl-0中,或者创建新的pinctrl名称,如"res_pin",但需要确保驱动支持个pinctrl状态。 不过,可能更简单的做法是将新的res引脚添加到现有的pinctrl-0里。例如,修改原来的spi_oled_pin,或者新增一个条目。但根据Rockchip的惯例,可能需要分开配置。因此,正确的做法应该是: 在&pinctrl的spi_oled节点内,添加新的子节点定义res引脚,然后在spi_oled@0的pinctrl-0中同时引用这两个引脚。例如: pinctrl-0 = <&spi_oled_pin &spi_oled_res_pin>; 不过,这需要确保pinctrl驱动可以处理个引脚的配置。或者,用户可能需要将两个引脚的配置合并到一个pinctrl条目中。例如,将两个rockchip,pins写在一起: rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>, <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; 但原来的代码中spi_oled_pin是单独定义的,所以可能更清晰的方式是分开定义,然后在pinctrl-0中引用两个引脚。不过需要检查设备树语法是否允许在pinctrl-0中列出个句柄,通常是可以的,用逗号分隔。 总结步骤应该是: 1. 在spi_oled@0节点中添加res_control_pin属性,指定GPIO。 2. 在pinctrl节点中定义对应的GPIO引脚配置。 3. 更新pinctrl-0以包含新的引脚配置。 需要注意的是,GPIO的编号和组别是否正确,比如使用正确的GPIO控制器(如gpio3),以及引脚号是否正确。另外,激活电平是否需要根据硬件设计调整,比如RESET引脚通常是低电平有效,所以可能使用GPIO_ACTIVE_LOW。 最后,用户可能需要检查驱动程序是否支持这个新的res_control_pin,并在驱动中正确处理该GPIO,比如在初始化时设置电平,或者在操作时控制复位信号。</think>根据设备树语法规范,添加控制引脚需要分两个部分修改:设备节点定义和pinctrl引脚控制。以下是具体步骤: 一、在spi_oled设备节点中添加: ```diff 20 spi_oled@0 { 21 status = "okay"; 22 compatible = "fire,spi_oled"; 23 reg = <0>; 24 spi-max-frequency = <24000000>; 25 dc_control_pin = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>; +26 res_control_pin = <&gpioX RK_PXx GPIO_ACTIVE_HIGH>; // 替换X和x为实际GPIO编号 26 pinctrl-names = "default"; 27 pinctrl-0 = <&spi_oled_pin>; 28 }; ``` 二、在pinctrl节点中添加引脚控制: ```diff 32 spi_oled { 33 spi_oled_pin: spi_oled_pin { 34 rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; +35 // 添加新的复位引脚配置 +36 spi_oled_res_pin: spi_oled_res_pin { +37 rockchip,pins = <X RK_PXx RK_FUNC_GPIO &pcfg_pull_none>; // 与实际GPIO对齐 +38 }; 35 }; 36 }; ``` 三、关联pinctrl配置: ```diff 26 pinctrl-names = "default"; -27 pinctrl-0 = <&spi_oled_pin>; +27 pinctrl-0 = <&spi_oled_pin &spi_oled_res_pin>; ``` 注意事项: 1. GPIO编号需要根据具体硬件确定,例如: - RK3568的GPIO4_C6对应 `<&gpio4 RK_PC6 ...>` - 引脚编号可通过公式计算:`RK_P[组][引脚号]`,如PC5对应 `RK_PC5` 2. 推荐保持GPIO控制策略一致: - 引脚功能选择 `RK_FUNC_GPIO` 表示作为普通GPIO使用 - 上拉配置根据硬件需求选择: - `&pcfg_pull_up` 内部上拉 - `&pcfg_pull_down` 内部下拉 - `&pcfg_pull_none` 无上下拉 3. 驱动适配:需在驱动代码中通过`gpiod_get()`获取该引脚,并使用`gpiod_direction_output()`进行控制 验证方法: 1. 编译dtb后,通过`fdtdump`命令查看节点是否包含新添加的引脚属性 2. 在/sys/kernel/debug/pinctrl/pinctrl-handles中查看引脚状态 3. 使用示波器测量实际引脚电平变化 建议参考同一SoC的官方设备树文件(如rk3568.dtsi)中的GPIO定义,确保引脚未被其他外设复用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值