扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

i.MX6ULL UART2/UART7/UART8 使能实操:设备树配置与硬件冲突解决

12小时前
213
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

i.MX6ULL 内置 8 路 UART 接口,均支持2 线(无硬件流控,仅 TX/RX)4 线(带硬件流控,TX/RX/CTS/RTS) 工作模式,由 Linux 统一驱动管理。其中 UART1 为默认调试口,UART2 默认适配蓝牙模块(4 线模式),UART7/UART8 因与 ENET、LCD 引脚复用存在硬件冲突,使能方式与前 6 路不同。本文详细讲解 i.MX6ULL 上UART2 转为普通串口UART7/UART8 正常使能的完整步骤,包含设备树修改、内核编译、硬件冲突规避,基于 Linux 6.1.1_1.0.0 BSP,适配 EVK 开发板

资料获取:在i.MX6ULL 上使能UART2以及UART7和UART8

1. i.MX6ULL UART 核心特性与引脚复用说明

1.1 UART 工作模式区别

  • 2 线模式:仅使用 TX(发送)、RX(接收)引脚,无硬件流控,需软件实现数据流控制,适用于常规串口通信(如外接传感器、串口屏);
  • 4 线模式:在 2 线基础上增加 CTS(清送)、RTS(请求发送)硬件流控引脚,实现硬件 “握手”,适用于大数据量、高可靠性通信(如蓝牙、4G 模块)。

1.2 关键 UART 引脚复用冲突

i.MX6ULL 的 UART 引脚与 ENET、LCD 等外设复用,是使能的核心难点:

  • UART2:默认复用为蓝牙 4 线模式,CTS/RTS 引脚与 UART3 部分引脚复用;
  • UART7/UART8:核心冲突为RTS 引脚与 ENET TX_CLK 引脚复用,RX/TX 引脚与 LCD_DATA 引脚复用,若不做配置,ENET 时钟会干扰 UART 通信,LCD 使能时会占用 UART 引脚。

1.3 设备节点命名规则

Linux 系统中,i.MX6ULL 的 UART 设备节点统一命名为/dev/ttymxcXX 为 UART 编号 - 1,即:
UART1→ttymxc0、UART2→ttymxc1、UART7→ttymxc6、UART8→ttymxc7。

2. UART2 使能:从蓝牙 4 线模式转为普通串口

i.MX6ULL EVK 板中 UART2 默认配置为蓝牙 4 线模式(带 uart-has-rtscts 流控),并绑定蓝牙设备树节点,需通过修改设备树剥离蓝牙配置,转为普通 2 线 / 4 线串口,步骤简单且无硬件冲突。

2.1 核心修改:设备树文件imx6ul-14x14-evk.dtsi

设备树路径:arch/arm/boot/dts/imx6ul-14x14-evk.dtsi,找到 UART2 节点&uart2,按需求修改为2 线普通串口(推荐)或自定义 4 线串口

(1)转为 2 线普通串口(主流用法)

注释蓝牙节点、硬件流控配置,保留基础 TX/RX 引脚配置,修改后代码:

&uart2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart2>;
    /* 注释硬件流控,关闭4线模式 */
    // uart-has-rtscts;
    /* 注释DTE模式配置(默认DCE模式,无需修改) */
    // fsl,dte-mode;
    // pinctrl-0 = <&pinctrl_uart2dte>;
    status = "okay";
    /* 注释蓝牙设备节点,剥离蓝牙绑定 */
    // bluetooth {
    //     compatible = "nxp,88w8987-bt";
    // };
};

/* 保留原有pinctrl_uart2引脚配置(仅TX/RX生效,CTS/RTS自动失效) */
pinctrl_uart2: uart2grp {
    fsl,pins = <
        MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x1b0b1
        MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS 0x1b0b1
        MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x1b0b1
        MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS 0x1b0b1
    >;
};
  • 引脚配置值0x1b0b1:为 i.MX6ULL UART 引脚标准配置(拉偏、速度、驱动能力),无需修改;
  • 若需彻底删除无用的 CTS/RTS 引脚,可直接从fsl,pins中移除对应行。

(2)自定义为 4 线普通串口

若需保留 4 线硬件流控,仅剥离蓝牙绑定,删除bluetooth节点即可,保留uart-has-rtscts;配置。

2.2 重新编译内核与设备树

修改设备树后,需编译内核并部署镜像,使用 Yocto/bitbake 编译命令(适配 NXP 官方 BSP):

# 重新编译Linux内核
bitbake -c compile -f linux-imx
# 部署内核镜像
bitbake -c deploy linux-imx
# 重新编译根文件系统(可选,若仅修改设备树可省略)
bitbake core-image-base

2.3 烧写与验证

使用 NXP UUU 工具将编译后的镜像烧写到 EVK 板,启动后通过以下命令验证 UART2 使能:

# 查看UART设备节点,存在ttymxc1即表示成功
ls /dev/ttymxc*
# 测试串口发送(需外接串口模块,接UART2的TX/RX引脚)
echo "test uart2" > /dev/ttymxc1

3. UART7/UART8 使能:核心解决硬件冲突问题

UART7/UART8 的使能是重点与难点,核心需解决两个硬件冲突RTS 与 ENET TX_CLK 冲突RX/TX 与 LCD_DATA 引脚冲突,且根据ENET/LCD 是否启用,配置方式不同,本文以EVK 板 UART7 使能为例(UART8 方法完全一致),讲解最通用场景ENET 启用、LCD 禁用、UART7 为 2 线模式(无 RTS/CTS)。

3.1 使能前提:明确硬件配置场景

i.MX6ULL 官方手册规定,UART7/UART8 的使能需根据 ENET 和 RTS/CTS 是否启用分场景处理,核心规则

场景 ENET 状态 UART7/8 RTS/CTS 配置要点
1 禁用 任意 无需特殊操作,直接配置设备树引脚即可
2 启用 启用(4 线) 设备树配置 RTS/CTS 引脚,内核自动配置冲突寄存器,无需手动修改
3 启用 禁用(2 线) 手动修改内核代码配置冲突寄存器,设备树配置 TX/RX 引脚并禁用 LCD

本文讲解场景 3(最通用):ENET 启用(保留网口功能)、UART7 为 2 线模式(常规串口)、禁用 LCD(释放引脚)。

3.2 步骤 1:设备树修改(禁用 LCD + 配置 UART7 引脚)

需修改两个设备树文件:imx6ul-14x14-evk.dtsiimx6ul-14x14-evk.dts核心操作:禁用 LCDIF 控制器 + 添加 UART7 引脚与节点配置

(1)禁用 LCDIF 控制器(释放 LCD_DATA 引脚)

imx6ul-14x14-evk.dts中找到 LCDIF 节点&lcdif,设置status = "disabled";,彻底禁用 LCD,释放与 UART7 复用的 LCD_DATA16/LCD_DATA17 引脚:

&lcdif {
    status = "disabled"; // 禁用LCDIF,释放引脚
    // 原有LCD配置全部保留,仅修改status即可
};

(2)添加 UART7 节点与引脚配置

imx6ul-14x14-evk.dtsi中添加&uart7节点,并在&iomuxc中配置引脚(TX→LCD_DATA16,RX→LCD_DATA17):

// 1. 添加UART7设备节点
&uart7 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart7>; // 绑定引脚配置
    status = "okay"; // 使能UART7
    // 无uart-has-rtscts,为2线模式
};

// 2. 在&iomuxc中添加UART7引脚配置
&iomuxc {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_hog_1>;
    // 原有其他配置保留,添加以下uart7grp节点
    pinctrl_uart7: uart7grp {
        fsl,pins = <
            // UART7 TX → LCD_DATA16,标准配置0x1b0b1
            MX6UL_PAD_LCD_DATA16__UART7_DCE_TX 0x1b0b1
            // UART7 RX → LCD_DATA17,标准配置0x1b0b1
            MX6UL_PAD_LCD_DATA17__UART7_DCE_RX 0x1b0b1
        >;
    };
};
  • UART8 引脚配置参考:TX→LCD_DATA20,RX→LCD_DATA21,节点为&uart8,引脚配置节点为pinctrl_uart8

3.3 步骤 2:内核代码修改(解决 RTS 与 ENET TX_CLK 冲突)

ENET 启用且 UART7/8 为 2 线模式时,内核不会自动配置冲突寄存器,需手动修改 mach-imx6ul.c,设置 IOMUXC 寄存器,规避 ENET TX_CLK 对 UART RTS 引脚的干扰。

(1)修改内核文件mach-imx6ul.c

文件路径:arch/arm/mach-imx/mach-imx6ul.c,找到板级初始化函数imx6ul_init_machine(void),添加寄存器映射与值写入代码,配置 UART7 RTS 冲突寄存器:

static void __init imx6ul_init_machine(void)
{
    struct device *parent;
    void __iomem *iomux; // 定义IOMUXC寄存器虚拟地址指针
    struct device_node *np; // 设备树节点指针
    .........
    imx6ul_pm_init();
    
    // 新增代码开始:配置UART7 RTS与ENET TX_CLK冲突寄存器
    // 找到iomuxc设备树节点
    np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-iomuxc");
    // 将iomuxc物理地址映射为内核虚拟地址
    iomux = of_iomap(np, 0);
    // 向UART7 RTS选择寄存器写入0x2,规避ENET TX_CLK冲突
    // 寄存器偏移地址0x650为i.MX6ULL UART7 RTS_B_SELECT_INPUT
    writel_relaxed(0x2, iomux + 0x650);
    // 新增代码结束
    
    .........
}

(2)UART8 冲突寄存器配置

若需使能 UART8,在上述代码后添加 UART8 的寄存器配置,偏移地址为 0x654,写入值为0x3

// 新增UART8 RTS冲突寄存器配置
writel_relaxed(0x3, iomux + 0x654);
  • 寄存器值0x2(UART7)/0x3(UART8):为 i.MX6ULL 官方指定值,用于将 RTS 引脚的输入源从 ENET TX_CLK 切换为其他引脚,彻底规避冲突。

4. 步骤 3:编译内核与设备树

与 UART2 编译命令一致,使用 bitbake 编译并部署:

# 编译内核(含代码修改)
bitbake -c compile -f linux-imx
# 部署内核与设备树
bitbake -c deploy linux-imx
# 烧写镜像(UUU工具)

5. 步骤 4:UART7/UART8 验证

烧写完成后启动 EVK 板,通过以下命令验证使能结果:

# 查看UART设备节点,存在ttymxc6(UART7)/ttymxc7(UART8)即成功
ls /dev/ttymxc*
# 测试UART7发送(外接串口模块,接LCD_DATA16/TX、LCD_DATA17/RX引脚)
echo "test uart7" > /dev/ttymxc6
# 测试UART8发送(若使能)
echo "test uart8" > /dev/ttymxc7

4. UART7/UART8 4 线模式使能(ENET 启用场景)

若需将 UART7/UART8 配置为4 线模式(带 RTS/CTS)ENET 启用,无需修改内核代码,仅需在设备树中完成3 个配置,内核会自动处理 RTS 与 ENET TX_CLK 的冲突:

  1. 禁用 LCDIF 控制器,释放 TX/RX/CTS/RTS 对应的 LCD_DATA 引脚;
  2. 在 UART7/8 节点中添加uart-has-rtscts;,启用硬件流控;
  3. pinctrl_uart7/8中配置完整的 4 线引脚(TX/RX/CTS/RTS)。

设备树示例(UART7 4 线模式)

&uart7 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart7>;
    uart-has-rtscts; // 启用4线硬件流控
    status = "okay";
};

&iomuxc {
    pinctrl_uart7: uart7grp {
        fsl,pins = <
            MX6UL_PAD_LCD_DATA16__UART7_DCE_TX 0x1b0b1
            MX6UL_PAD_LCD_DATA17__UART7_DCE_RX 0x1b0b1
            MX6UL_PAD_LCD_DATA06__UART7_DCE_CTS 0x1b0b1
            MX6UL_PAD_LCD_DATA07__UART7_DCE_RTS 0x1b0b1
        >;
    };
};

5. 关键注意事项

  1. 引脚配置值统一:i.MX6ULL 的 UART 引脚配置值固定为0x1b0b1,包含上拉 / 下拉、速度等级、驱动能力,无需修改;
  2. 设备树节点与引脚对应pinctrl-0必须绑定正确的pinctrl_uartX节点,否则 UART 引脚复用失败;
  3. 寄存器偏移地址不可错:UART7 RTS 冲突寄存器偏移为0x650(值 0x2),UART8 为0x654(值 0x3),错写会导致通信异常;
  4. LCD 与 UART 互斥:UART7/8 的 RX/TX 引脚与 LCD_DATA 复用,LCD 启用时 UART 无法使用,反之亦然,需根据硬件需求取舍;
  5. 烧写验证顺序:修改后需先烧写内核镜像(含设备树与代码修改),再启动验证,仅烧写根文件系统无效;
  6. UART8 与 UART7 完全一致:所有 UART7 的配置步骤、代码、设备树修改,仅需替换为 UART8 对应的节点、引脚、寄存器,即可实现 UART8 使能。

i.MX6ULL UART2/UART7/UART8 的使能核心围绕设备树配置硬件冲突解决,不同 UART 的使能要点可概括为:

  1. UART2:无核心冲突,仅需修改设备树,注释蓝牙节点和硬件流控,即可转为普通串口;
  2. UART7/UART8:核心解决RTS 与 ENET TX_CLKRX/TX 与 LCD_DATA两大冲突,根据 ENET/LCD 是否启用分场景配置,2 线模式(ENET 启用) 需手动修改内核寄存器,4 线模式(ENET 启用) 仅需配置设备树即可。

本文所有配置均基于 NXP 官方 EVK 板与 Linux 6.1.1_1.0.0 BSP,UART8 的使能与 UART7 完全一致,仅需替换对应的节点、引脚和寄存器偏移地址,配置完成后可通过/dev/ttymxcX节点直接使用,与普通串口无差异,可外接传感器、串口屏、无线模块等外设。

相关推荐