我解决了!!!!也许是微不足道的事情,但对我来说真的很难,我学到了很多东西。关于如何在 Pandaboard 中执行此操作的信息不多,仅适用于 Beagleboards。所以首先,Device Tree Overlay
它仅在启动时加载的文件,我们不能像使用 Beagleboard 那样动态加载它,因为我们没有bone_capemgr
. 编译后的.dtb
文件位于/boot/dtbs
(至少在 Arch Linux 中),那里有很多.dtb
文件,但根据板子的不同,只有一个在启动时加载,您可以在启动时看到哪个文件被加载,例如,在我的情况下是:
U-Boot 2015.04 (Jun 07 2015 - 19:26:06) Arch Linux ARM
CPU : OMAP4460 ES1.1
Board: OMAP4 Panda
I2C: ready
DRAM: 1 GiB
MMC: OMAP SD/MMC: 0
** Unable to use mmc 0:1 for loading the env **
Using default environment
Net: No ethernet found.
Hit any key to stop autoboot: 0
starting USB...
USB0: USB EHCI 1.00
scanning bus 0 for devices... 3 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found
scanning usb for ethernet devices... 1 Ethernet Device(s) found
switch to partitions #0, OK
mmc0 is current device
mmc found on device 0
Checking for: /boot/uEnv.txt ...
74 bytes read in 13 ms (4.9 KiB/s)
Loaded environment from /boot/uEnv.txt
Checking if uenvcmd is set ...
4984312 bytes read in 244 ms (19.5 MiB/s)
loading /boot/dtbs/omap4-panda-es.dtb ...
100695 bytes read in 380 ms (257.8 KiB/s)
** File not found /boot/initramfs-linux.img **
Kernel image @ 0x82000000 [ 0x000000 - 0x4c0df8 ]
## Flattened Device Tree blob at 88000000
Booting using the fdt blob at 0x88000000
Loading Device Tree to 8ffe4000, end 8ffff956 ... OK
Starting kernel ...
我有一个 Pandaboard ES,所以加载的文件是/boot/dtbs/omap4-panda-es.dtb
. dtc -I dtb -O dts omap4-panda-es.dtb > omap4-panda-es.dts
我反编译了该文件,因此我可以使用(取自此处)添加 UART4 MUX 设置。所以现在我们有了一个omap4-panda-es.dts
完整的设备树覆盖,可以设置所有内容,我只需要添加 UART4 MUX 设置。我们必须使用该pinctrl-single,pins
属性。这是一个非常好的解释pinctrl-single,pins
:
pinctrl-single 的引脚配置节点使用 pinctrl-single,pins 指定为 pinctrl 寄存器偏移和值对。仅更新 pinctrl-single,function-mask 中指定的位。例如,可以通过以下方式为设备设置引脚: pinctrl-single,pins = <0xdc 0x118>; 其中 0xdc 是设备 pinctrl 寄存器的 pinctrl 寄存器基地址的偏移量,0x118 包含 pinctrl 寄存器的所需值。
这是我一开始就误解了,我虽然pinctrl
地址是绝对的,但它是相对于树中的基地址的。例如,在我的情况下,有很多pinmux_tfp410_pins
, pinmux_dss_hdmi_pins
,pinmux_i2c1_pins
等。所有这些都在pinmux_*
一个父节点下,这pinmux@40
意味着指定的地址pinctrl
是相对于里面的地址是相对于节点的基地址的,即所有这些地址的总和,也就是说,基地址也是,所有指定的地址都是相对的。因此,根据表 18-5040x40
pinmux@40
scm@100000
l4@4a000000
pinmux@40
0x4a000000 + 0x100000 + 0x40 = 0x4a100040
0xa100040
pinctrl
0xa100040
OMAP4 Technical Reference Manual
(可在此处下载)控制 MUX 和其他一些东西的 UART4 控制寄存器的地址是0x4A10015C
。pinctrl 的基地址是,0x4a100040
所以我们必须指定的地址pinctrl
是0x11c
因为0x4a100040 + 0x11c = 0x4A10015C
. 我在其他支持 Pandaboard 的 Linux 发行版中发现的所有设备树覆盖都使用相同的基地址0x4a100040
(例如此处)。所以我在节点下添加了pinmux@40
这个:
// Set the UART4 MUX, it doesn't come by default so I had to add it
// "linux,phandle" has the same value aas "phandle", it's just a reference number, just make sure
// it is not being used in another part of the tree (it will refuse to compile if you do it wrong)
// The phandle is used for reference in "serial@4806e000" at "pinctrl-0"
pinmux_uart4_pins {
pinctrl-single,pins = <
0x11c 0x100 // uart4_rx.uart4_rx INPUT | MODE0
0x11e 0 // uart4_tx.uart4_tx OUTPUT | MODE0
>;
linux,phandle = <0xfff>;
phandle = <0xfff>;
};
我从这里获取了这个设置,但只是更改了0x100
并且0
会更改寄存器中的设置。就我而言,我还必须添加:
linux,phandle = <0xfff>;
phandle = <0xfff>;
例如,我在 Ubuntu 中看不到这一点(https://github.com/Canonical-kernel/Ubuntu-kernel/blob/master/arch/arm/boot/dts/omap4.dtsi)但我不知道为什么或者这样做的目的是什么phandle
,我所知道的是否将它们用作参考,我需要将参考放在设备树中的其他位置,只要确保它是唯一的,它可以是任何 32 位值,但必须在树内是唯一的。就我而言,还有另一个节点引用 UART4:
serial@4806e000 {
compatible = "ti,omap4-uart";
reg = <0x4806e000 0x100>;
interrupts = <0x0 0x46 0x4>;
ti,hwmods = "uart4";
clock-frequency = <0x2dc6c00>;
interrupts-extended = <0x1 0x0 0x46 0x4 0x82 0x11c>;
linux,phandle = <0x121>;
phandle = <0x121>;
};
所以我不得不使用,phandle
否则不会应用 MUX 设置:
serial@4806e000 {
compatible = "ti,omap4-uart";
reg = <0x4806e000 0x100>;
interrupts = <0x0 0x46 0x4>;
ti,hwmods = "uart4";
pinctrl-names = "default";
pinctrl-0 = <0xfff>;
clock-frequency = <0x2dc6c00>;
interrupts-extended = <0x1 0x0 0x46 0x4 0x82 0x11c>;
linux,phandle = <0x121>;
phandle = <0x121>;
};
最后,在文件的末尾有很多定义,每个节点一个,例如
i2c1_pins = "/ocp/l4@4a000000/scm@100000/pinmux@40/pinmux_i2c1_pins";
i2c2_pins = "/ocp/l4@4a000000/scm@100000/pinmux@40/pinmux_i2c2_pins";
i2c3_pins = "/ocp/l4@4a000000/scm@100000/pinmux@40/pinmux_i2c3_pins";
i2c4_pins = "/ocp/l4@4a000000/scm@100000/pinmux@40/pinmux_i2c4_pins";
wl12xx_gpio = "/ocp/l4@4a000000/scm@100000/pinmux@40/pinmux_wl12xx_gpio";
wl12xx_pins = "/ocp/l4@4a000000/scm@100000/pinmux@40/pinmux_wl12xx_pins";
twl6030_pins = "/ocp/l4@4a000000/scm@100000/pinmux@40/pinmux_twl6030_pins";
它们只是描述了每个节点所在的位置,这里我们可以清楚地看到基地址是什么。所以在这里我只是添加了这个:
uart4_pins = "/ocp/l4@4a000000/scm@100000/pinmux@40/pinmux_uart4_pins";
现在我们有了一个完整的.dts
文件,它应该可以让 UART4 正常工作。我们必须使用 编译它dtc -O dtb -o omap4-panda-es.dtb -b O -@ omap4-panda-es.dts
,这将生成一个.dtb
替换 中的文件/boot/dtbs
,所以替换它并重新启动!重新启动 run 后cat /sys/kernel/debug/pinctrl/4a100040.pinmux/pinmux-functions
,它应该显示如下内容:
function: pinmux_dss_dpi_pins, groups = [ pinmux_dss_dpi_pins ]
function: pinmux_tfp410_pins, groups = [ pinmux_tfp410_pins ]
function: pinmux_dss_hdmi_pins, groups = [ pinmux_dss_hdmi_pins ]
function: pinmux_tpd12s015_pins, groups = [ pinmux_tpd12s015_pins ]
function: pinmux_hsusbb1_pins, groups = [ pinmux_hsusbb1_pins ]
function: pinmux_uart4_pins, groups = [ pinmux_uart4_pins ]
function: pinmux_wl12xx_pins, groups = [ pinmux_wl12xx_pins ]
function: gpio_led_pmx, groups = [ gpio_led_pmx ]
function: pinmux_wl12xx_gpio, groups = [ pinmux_wl12xx_gpio ]
function: pinmux_i2c1_pins, groups = [ pinmux_i2c1_pins ]
function: pinmux_twl6030_pins, groups = [ pinmux_twl6030_pins ]
function: pinmux_twl6040_pins, groups = [ pinmux_twl6040_pins ]
function: pinmux_i2c2_pins, groups = [ pinmux_i2c2_pins ]
function: pinmux_i2c3_pins, groups = [ pinmux_i2c3_pins ]
function: pinmux_i2c4_pins, groups = [ pinmux_i2c4_pins ]
function: pinmux_wl12xx_pins, groups = [ pinmux_wl12xx_pins ]
function: pinmux_mcpdm_pins, groups = [ pinmux_mcpdm_pins ]
function: pinmux_mcbsp1_pins, groups = [ pinmux_mcbsp1_pins ]
如果我们看到uart4
一切都很好,它应该可以工作!否则.dts
文件中有问题。例如,我们可以通过运行来测试 uart 是否正常工作echo -e "AT" > /dev/ttyO3
,记住/dev/ttyO3
是UART4
。我希望这对某人有用!
此处仅供参考,是带有工作 UART4的完整.dts
编译文件: https ://gist.github.com/dragondgold/1aaabf93279006b703f3.dtb