UART4与Pandaboard和Arch Linux

时间:2015-09-22 03:18:01

标签: linux device-tree pandaboard archlinux-arm

我正在尝试在我的Pandaboard中使用UART4和Arch Linux。我正在使用最新的内核(4.2.0-2-ARCH),因此无法使用omap_mux以旧方式配置MUX,我必须使用设备树覆盖来完成。这对我来说是新的,所以很难,我以前从未这样做过。我一直在阅读一些关于如何在thisthis等网站的Beaglebone板中使用它们的帖子。所以我下载了OMAP4技术参考手册(下载here)。 表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看不到这样的东西。

像Ubuntu这样的其他操作系统已配置UART4,我尝试寻找他们使用的设备树覆盖但找不到任何东西。

1 个答案:

答案 0 :(得分:0)

我解决了!!!!!也许是微不足道的事情,但对我来说真的很难,而且我学到了很多东西。在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(取自here)添加UART4 MUX设置。所以现在我们有一个omap4-panda-es.dts,它是完整的设备树覆盖,可以设置所有内容,我只需要添加UART4 MUX设置。我们必须使用pinctrl-single,pins属性。 Here是关于pinctrl-single,pins

的非常好的解释
  

pinctrl-single的引脚配置节点指定为   pinctrl寄存器偏移和值对使用pinctrl-single引脚。   只更新pinctrl-single,function-mask中指定的位。   例如,为设备设置引脚可以通过以下方式完成:   pinctrl-single,pins =&lt; 0xdc 0x118&gt ;;其中0xdc是偏移量   pinctrl寄存器基地址为器件pinctrl寄存器,和   0x118包含pinctrl寄存器的所需值。

这是我在开始时误解的东西,虽然pinctrl地址是绝对的,但它相对于树中的基地址。在我的例子中,有很多pinmux_tfp410_pinspinmux_dss_hdmi_pinspinmux_i2c1_pins等等。所有这些pinmux_*都在名为pinmux@40的父级下,这意味着pinctrl中指定的地址与0x40相关,但此pinmux@40位于另一个名为scm@100000的节点下,该节点位于另一个名为l4@4a000000的节点内,因此pinmux@40内的地址相对于节点的基地址是所有这些地址的总和,即0x4a000000 + 0x100000 + 0x40 = 0x4a100040,因此0xa100040是基地址,pinctrl中指定的所有地址{1}}与0xa100040相关。因此,根据OMAP4 Technical Reference Manual中的表18-504 (可下载here),控制MUX的UART4控制寄存器的地址和其他一些内容是{{1 }}。 pinctrl的基址是0x4A10015C,因此我们必须在0x4a100040中指定的地址为pinctrl,因为0x11c。我发现支持Pandaboard的其他Linux发行版的所有设备树覆盖都使用相同的基址0x4a100040 + 0x11c = 0x4A10015C(例如here)。所以我在节点0x4a100040下添加了这个:

pinmux@40

我从here获取此设置,但只更改// 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

我在Ubuntu中没有看到这个例子(https://github.com/Canonical-kernel/Ubuntu-kernel/blob/master/arch/arm/boot/dts/omap4.dtsi),但我不知道为什么或linux,phandle = <0xfff>; phandle = <0xfff>; 的目的是什么,我知道如果它们被用作引用,我需要在设备树中放置其他位置的引用,只需确保它是唯一的,它可以是任何32位值,但在树中必须是唯一的。在我的例子中,有另一个节点引用UART4:

phandle

所以我不得不使用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>; }; ,否则将不会应用MUX设置:

phandle

最后,在文件的末尾有很多定义,每个节点一个,例如

 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"; 文件,可以使UART4正常工作。我们必须使用.dts对其进行编译,这将生成一个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来测试uart是否正常工作,请记住echo -e "AT" > /dev/ttyO3/dev/ttyO3。我希望这对某人有用!

仅供参考,这是完整的UART4和已编译的.dts文件,其中包含有效的UART4:https://gist.github.com/dragondgold/1aaabf93279006b703f3