Verdin iMX8MP 调试串口更改
简介
Verdin iMX8M Plus 具有四个串口,其中 UART3 是用于 A53 核心上的系统如 Linux 的默认调试串口,出于设计需要可能需要将调试口换到其他串口,文章将介绍如何使用 UART1 作调试串口。
硬件介绍
Verdin iMX8M Plus 的四个串口 UART1 ~UART4 中,UART3 为默认的 A53 调试串口,UART4 为 M7 调试串口,其余两个作为通用 UART 使用。Verdin 系列的模块均使用 1.8V TTL 电平,在连接外部设备时请先检查电压。本次测试使用的是 Dahlia 底板,在 X20 扩展接口 Pin12 和 Pin13 分别将模块的 UART1_RXD和 UART1_TXD 引出。四个串口的物理地址如下:
UART | 起始地址 | 结束地址 |
UART1 | 0x3086_0000 | 0x3086_FFFF |
UART2 | 0x3089_0000 | 0x3089_FFFF |
UART3 | 0x3088_0000 | 0x3088_FFFF |
UART4 | 0x30A6_0000 | 0x30A6_FFFF |
软件修改
调试串口更改的软件涉及到三个部分,ATF、U-Boot 和 Linux。ATF 会和 U-Boot 等其他文件如 DDR 固件一起打包成用于 NXP i.MX 8M Plus 处理器的启动文件。这些文件的下载和编译请参考该网页。文章使用到的完整补丁请从这里下载。
ATF
ATF 代码的 imx8mp_bl31_setup.c 中,把 RDC_PDAP_UART1 划分到 A53 所在的 D0 域。
---------------------------
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c +++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c @@ -53,7 +53,7 @@ static const struct imx_rdc_cfg rdc[] = { RDC_MDAn(RDC_MDA_M7, DID1), /* peripherals domain permission */ -RDC_PDAPn(RDC_PDAP_UART2, D0R | D0W), +RDC_PDAPn(RDC_PDAP_UART1, D0R | D0W),
--- a/plat/imx/imx8m/imx8mq/include/platform_def.h +++ b/plat/imx/imx8m/imx8mq/include/platform_def.h @@ -60,6 +60,7 @@ #define HAB_RVT_BASEU(0x00000880) /* HAB_RVT for i.MX8MQ */ +#define IMX_BOOT_UART_BASEU(0x30860000)
---------------------------
platform_def.h 中指定 IMX_BOOT_UART_BASE 为 UART1 的物理地址 0×30860000。如果不在这里定义,在编译的时候添加 IMX_BOOT_UART_BASE=0×30860000 参数也可。
make PLAT=imx8mp IMX_BOOT_UART_BASE=0x30860000 bl31
编译成功后在 build/imx8mp/release/ 目录下生成 bl32.bin 文件。
U-Boot
Linux BSP v6 中对应 toradex_imx_lf_v2022.04 分支 U-Boot 在修改外设接口配置时也使用了 device tree。例如在 imx8mp-verdin-u-boot.dtsi 中配置 UART1 对应的 pinctrl_uart1,并删除原来的 pinctrl_uart1。
---------------------------
--- a/arch/arm/dts/imx8mp-verdin-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-verdin-u-boot.dtsi @@ -134,7 +134,7 @@ u-boot,off-on-delay-us = <20000>; };
-&pinctrl_uart3 { +&pinctrl_uart1 { u-boot,dm-spl; };
@@ -174,7 +174,7 @@ u-boot,dm-spl; };
-&uart3 { +&uart1 { u-boot,dm-spl; };
---------------------------
在 imx8mp-verdin.dts 中修改 stdout-path 的启动参数以及 UART1 所使用的引脚配置。earlycon 可用于 SPL 的调试输出。
--- a/arch/arm/dts/imx8mp-verdin.dts +++ b/arch/arm/dts/imx8mp-verdin.dts chosen { - bootargs = "console=ttymxc2,115200 earlycon"; - stdout-path = &uart3; + bootargs = "console=ttymxc0,115200 \ + earlycon=ec_imx6q,0x30860000,115200"; + stdout-path = &uart1; };
-/* Verdin UART3 */ -&uart3 { +/* Verdin UART1 */ +&uart1 { /* console */ pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart3>; + pinctrl-0 = <&pinctrl_uart1>; status = "okay"; };
- pinctrl_uart3: uart3grp { + pinctrl_uart1: uart1grp { fsl,pins = < - MX8MP_IOMUXC_UART3_RXD__UART3_DCE_RX 0x49 - MX8MP_IOMUXC_UART3_TXD__UART3_DCE_TX 0x49 + MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x49 + MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x49
---------------------------
verdin-imx8mp.c 中需要初始化 UART1 的时钟。
---------------------------
--- a/board/toradex/verdin-imx8mp/verdin-imx8mp.c +++ b/board/toradex/verdin-imx8mp/verdin-imx8mp.c /* Verdin UART_3, Console/Debug UART */ static const iomux_v3_cfg_t uart_pads[] = { - MX8MP_PAD_UART3_RXD__UART3_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), - MX8MP_PAD_UART3_TXD__UART3_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL), + MX8MP_PAD_UART1_RXD__UART1_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + MX8MP_PAD_UART1_TXD__UART1_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL), };
imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
- init_uart_clk(2); + init_uart_clk(0);
return 0; }
---------------------------
在 include/configs/verdin-imx8mp.h 将 CONFIG_MXC_UART_BASE 的地址也设置为 UART1。同时修改 console。
---------------------------
--- a/include/configs/verdin-imx8mp.h +++ b/include/configs/verdin-imx8mp.h "boot_script_dhcp=" BOOT_SCRIPT "\0" \ - "console=ttymxc2\0" \ + "console=ttymxc0\0" \ "fdt_board=dev\0" \
@@ -111,7 +111,7 @@ #define PHYS_SDRAM_2_SIZE (SZ_4G + SZ_1G)
/* UART */ -#define CONFIG_MXC_UART_BASE UART3_BASE_ADDR +#define CONFIG_MXC_UART_BASE UART1_BASE_ADDR
/* Monitor Command Prompt */ #define CONFIG_SYS_CBSIZE SZ_2K
---------------------------
Linux
Linux 的 device tree 同样也需要做修改。在 freescale/imx8mp-verdin-dev.dtsi 中取消 UART1 默认配置下的 RS485 功能。
---------------------------
--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi /* Verdin UART_1, connector X50 through RS485 transceiver */ &uart1 { + /* linux,rs485-enabled-at-boot-time; rs485-rts-active-low; rs485-rx-during-tx; + */ status = "okay"; };
---------------------------
imx8mp-verdin.dtsi 中更改 stdout-path 调试串口输出至 UART1,并删除 RTS 和 CTS 功能引脚。
---------------------------
--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi @@ -8,7 +8,7 @@
/ { chosen { - stdout-path = &uart3; + stdout-path = &uart1; };
aliases { @@ -891,7 +891,7 @@ &snvs_pwrkey { &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; - uart-has-rtscts; + /* uart-has-rtscts; */ };
/* Verdin UART_2 */ @@ -1331,8 +1331,8 @@ pinctrl_sai3: sai3grp {
pinctrl_uart1: uart1grp { fsl,pins = -
---------------------------
修改完毕上述文件后重新编译 flash.bin(imx-boot)和 device tree 文件,并将其放入支持 Toradex Easy Installer 烧录的镜像文件中。同时也需要修改镜像文件中的 u-boot-initial-env-sd,将 console 改为 console=ttymxc0。该文件会在烧录系统时配置 U-Boot 环境变量。安装完镜像后,在 UART1 即可看到启动日志。
总结
通过上述几个文件的修改,可以切换 A53 调试串口。对于 Linux 系统通常建议保留一个调试串口,这将有利于调试和后期其他问题排查。
提交
Verdin AM62 LVGL 移植
基于 NXP iMX8MM 测试 Secure Boot 功能
隆重推出 Aquila - 新一代 Toradex 计算机模块
NXP iMX8MM Cortex-M4 核心 GPT Capture 测试
嵌入式Linux下使用 Plymouth 实现开机画面示例