UART4 与 Pandaboard 和 Arch Linux
UART4 with Pandaboard and Arch Linux
我正在尝试在我的带有 Arch Linux 的 Pandaboard 中使用 UART4
。我使用的是最新的内核 (4.2.0-2-ARCH),所以我无法使用 omap_mux
以旧方式配置 MUX,我必须使用设备树覆盖来完成。这对我来说是新的,所以很难,我以前从未做过。我一直在阅读一些 post 关于如何在 this and this. So I downloaded the OMAP4 Technical Reference Manual (download here 等网站的 Beaglebone 板上使用它们的文章。 Table 18-504表示UART4
控制寄存器。基于此和上面的 url,我创建并编译了以下设备树覆盖,用 0 填充寄存器,这应该为 UART4
功能设置 MUX:
// Util: http://lxr.free-electrons.com/source/arch/arm/boot/dts/omap4-panda-es.dts
// http://www.valvers.com/embedded-linux/beaglebone-black/step04-gpio/
/dts-v1/;
/plugin/;
/ {
model = "TI OMAP4 PandaBoard-ES";
compatible = "ti,omap4-panda-es", "ti,omap4460";
part-number = "ANDRES-IO";
fragment@0 {
target = <&am33xx_pinmux>;
__overlay__ {
uart4_pins: pinmux_uart4_pins {
pinctrl-single,pins = <
0x15C 0x00 // kernel pin 142 (uart4 tx y rx - address 0x4A10 015C)
>;
};
};
};
fragment@1 {
target = <&ocp>;
__overlay__ {
uart4_pins_helper {
compatible = "panda-pinmux-helper";
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins>;
status = "okay";
};
};
};
};
我将编译后的文件复制到/lib/firmware/,但之后我不知道如何使用或启用它。 Beaglebone 板有 bone_capemgr 但我在 Pandaboard 中看不到这样的东西。
其他 OS 如 Ubuntu 已配置 UART4
,我尝试寻找他们使用的设备树覆盖,但找不到任何东西。
我解决了!!!!!也许是微不足道的事情,但对我来说真的很难,我学到了很多东西。没有太多关于如何在 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 设置(取自 here). So now we have a omap4-panda-es.dts
which is the complete Device Tree Overlays that sets everything up, I just need to add the UART4 MUX settings. We have to use the pinctrl-single,pins
property. Here 是关于 pinctrl-single,pins
:
的一个很好的解释
The pin configuration nodes for pinctrl-single are specified as
pinctrl register offset and value pairs using pinctrl-single,pins.
Only the bits specified in pinctrl-single,function-mask are updated.
For example, setting a pin for a device could be done with:
pinctrl-single,pins = <0xdc 0x118>; Where 0xdc is the offset from the
pinctrl register base address for the device pinctrl register, and
0x118 contains the desired value of the pinctrl register.
这是我一开始的误解,我虽然 pinctrl
地址是绝对地址,但它是相对于树中的基地址的。例如,在我的例子中,有很多 pinmux_tfp410_pins
、pinmux_dss_hdmi_pins
、pinmux_i2c1_pins
等。所有这些 pinmux_*
都在名为 pinmux@40
的父项下,这意味着pinctrl
中指定的地址是相对于 0x40
的,但是这个 pinmux@40
在另一个名为 scm@100000
的节点下,该节点位于另一个名为 l4@4a000000
的节点内,所以pinmux@40
里面的地址是相对于所有这些地址之和的结点的基地址,即0x4a000000 + 0x100000 + 0x40 = 0x4a100040
,所以0xa100040
是基地址,所有在[中指定的地址=28=] 相对于 0xa100040
。所以,根据Table18-504中的OMAP4 Technical Reference Manual
(下载可用here) the address for the UART4 control register that control the MUX and some other things is 0x4A10015C
. The base address of pinctrl is 0x4a100040
so the address we must specify in pinctrl
is 0x11c
because 0x4a100040 + 0x11c = 0x4A10015C
. All the Device Tree Overlays I found of other linux distros that support Pandaboard use the same base address 0x4a100040
(here为例)。所以我在节点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>;
};
我从 here 中获取了此设置,但只需更改 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
中的文件,所以替换它并重新启动!重新启动 运行 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
文件有问题。我们可以通过 运行ning 测试 uart 是否工作,例如 echo -e "AT" > /dev/ttyO3
,记住 /dev/ttyO3
是 UART4
。我希望这对某人有用!
仅供参考,这里是完整的 .dts
和已编译的 .dtb
文件,带有工作的 UART4:https://gist.github.com/dragondgold/1aaabf93279006b703f3
我正在尝试在我的带有 Arch Linux 的 Pandaboard 中使用 UART4
。我使用的是最新的内核 (4.2.0-2-ARCH),所以我无法使用 omap_mux
以旧方式配置 MUX,我必须使用设备树覆盖来完成。这对我来说是新的,所以很难,我以前从未做过。我一直在阅读一些 post 关于如何在 this and this. So I downloaded the OMAP4 Technical Reference Manual (download here 等网站的 Beaglebone 板上使用它们的文章。 Table 18-504表示UART4
控制寄存器。基于此和上面的 url,我创建并编译了以下设备树覆盖,用 0 填充寄存器,这应该为 UART4
功能设置 MUX:
// Util: http://lxr.free-electrons.com/source/arch/arm/boot/dts/omap4-panda-es.dts
// http://www.valvers.com/embedded-linux/beaglebone-black/step04-gpio/
/dts-v1/;
/plugin/;
/ {
model = "TI OMAP4 PandaBoard-ES";
compatible = "ti,omap4-panda-es", "ti,omap4460";
part-number = "ANDRES-IO";
fragment@0 {
target = <&am33xx_pinmux>;
__overlay__ {
uart4_pins: pinmux_uart4_pins {
pinctrl-single,pins = <
0x15C 0x00 // kernel pin 142 (uart4 tx y rx - address 0x4A10 015C)
>;
};
};
};
fragment@1 {
target = <&ocp>;
__overlay__ {
uart4_pins_helper {
compatible = "panda-pinmux-helper";
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins>;
status = "okay";
};
};
};
};
我将编译后的文件复制到/lib/firmware/,但之后我不知道如何使用或启用它。 Beaglebone 板有 bone_capemgr 但我在 Pandaboard 中看不到这样的东西。
其他 OS 如 Ubuntu 已配置 UART4
,我尝试寻找他们使用的设备树覆盖,但找不到任何东西。
我解决了!!!!!也许是微不足道的事情,但对我来说真的很难,我学到了很多东西。没有太多关于如何在 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 设置(取自 here). So now we have a omap4-panda-es.dts
which is the complete Device Tree Overlays that sets everything up, I just need to add the UART4 MUX settings. We have to use the pinctrl-single,pins
property. Here 是关于 pinctrl-single,pins
:
The pin configuration nodes for pinctrl-single are specified as pinctrl register offset and value pairs using pinctrl-single,pins. Only the bits specified in pinctrl-single,function-mask are updated. For example, setting a pin for a device could be done with: pinctrl-single,pins = <0xdc 0x118>; Where 0xdc is the offset from the pinctrl register base address for the device pinctrl register, and 0x118 contains the desired value of the pinctrl register.
这是我一开始的误解,我虽然 pinctrl
地址是绝对地址,但它是相对于树中的基地址的。例如,在我的例子中,有很多 pinmux_tfp410_pins
、pinmux_dss_hdmi_pins
、pinmux_i2c1_pins
等。所有这些 pinmux_*
都在名为 pinmux@40
的父项下,这意味着pinctrl
中指定的地址是相对于 0x40
的,但是这个 pinmux@40
在另一个名为 scm@100000
的节点下,该节点位于另一个名为 l4@4a000000
的节点内,所以pinmux@40
里面的地址是相对于所有这些地址之和的结点的基地址,即0x4a000000 + 0x100000 + 0x40 = 0x4a100040
,所以0xa100040
是基地址,所有在[中指定的地址=28=] 相对于 0xa100040
。所以,根据Table18-504中的OMAP4 Technical Reference Manual
(下载可用here) the address for the UART4 control register that control the MUX and some other things is 0x4A10015C
. The base address of pinctrl is 0x4a100040
so the address we must specify in pinctrl
is 0x11c
because 0x4a100040 + 0x11c = 0x4A10015C
. All the Device Tree Overlays I found of other linux distros that support Pandaboard use the same base address 0x4a100040
(here为例)。所以我在节点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>;
};
我从 here 中获取了此设置,但只需更改 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
中的文件,所以替换它并重新启动!重新启动 运行 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
文件有问题。我们可以通过 运行ning 测试 uart 是否工作,例如 echo -e "AT" > /dev/ttyO3
,记住 /dev/ttyO3
是 UART4
。我希望这对某人有用!
仅供参考,这里是完整的 .dts
和已编译的 .dtb
文件,带有工作的 UART4:https://gist.github.com/dragondgold/1aaabf93279006b703f3