2. 案例2

任务说明

在自定义开发板上,U-Boot默认可能未启用串口控制台,或串口参数与板载硬件不匹配。本案例目标为:配置U-Boot串口驱动(以NS16550兼容UART为例),使控制台初始化代码正确执行,并在串口终端上观察到U-Boot启动日志输出。

硬件前提与依赖

  • 开发板使用NS16550兼容UART(如16550A、Zynq、i.MX等常见IP),寄存器地址已知。
  • U-Boot源码树已建立,且已创建或确认板级目录(如board/mycompany/myboard/)。
  • 本案例不涉及时钟、引脚复用等板级初始化,假设这些已在更早的板级初始化代码中完成。

实现步骤

核心修改涉及两个文件:板级头文件(定义UART基地址与时钟)和设备树或板级配置(启用串口作为控制台)。以下以include/configs/myboard.h为例,展示最小配置。

关键完整代码

// 文件:include/configs/myboard.h(片段)
#ifndef __MYBOARD_H
#define __MYBOARD_H

#include <asm/config.h>

// 串口硬件参数:NS16550寄存器基地址(按实际板卡修改)
#define CONFIG_SYS_NS16550_COM1    0xE0001000
#define CONFIG_SYS_NS16550_CLK     50000000   // 串口输入时钟,单位Hz

// 控制台选择:使用COM1作为调试串口
#define CONFIG_CONS_INDEX          1
#define CONFIG_BAUDRATE            115200

// 使能NS16550驱动与命令
#define CONFIG_SYS_NS16550
#define CONFIG_SYS_NS16550_REG_SIZE    -4   // 32位寄存器,地址步进4字节

// 标准控制台相关(必须包含)
#define CONFIG_SERIAL_MULTI         1
#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1

// 环境变量默认值(用于启动时设置串口参数)
#define CONFIG_EXTRA_ENV_SETTINGS \
    "stdin=serial\0" \
    "stdout=serial\0" \
    "stderr=serial\0"

#endif // __MYBOARD_H

若板级使用设备树(如ARMv8架构),还需在设备树&uart0节点中确认status = "okay"且clock-frequency与上述宏一致。U-Boot会优先读取设备树中的current-speed与clock-frequency属性,若存在则覆盖头文件宏。

编译与烧录

# 在U-Boot源码根目录执行(以myboard_defconfig为例)
make myboard_defconfig
make CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)

将生成的u-boot.bin烧录至开发板启动介质(SD卡、QSPI Flash等),连接串口线至COM1对应UART引脚,主机侧打开串口终端(如minicom或PuTTY),设置波特率115200、8N1、无流控。

验证方法与判定标准

  1. 开发板上电或复位后,串口终端应立即显示U-Boot启动日志,首行通常为U-Boot 20xx.xx-xxxx版本信息。
  2. 若日志正常输出且无ERROR或panic字样,说明串口驱动初始化成功。
  3. 在U-Boot命令行提示符出现后,输入help并回车,终端应回显命令列表,证明控制台输入输出双向正常。
  4. 若终端无输出,依次检查:
    • 串口基地址CONFIG_SYS_NS16550_COM1是否与硬件原理图一致;
    • 时钟频率CONFIG_SYS_NS16550_CLK是否等于UART外设输入时钟(可从芯片手册或时钟树配置获得);
    • 设备树中串口节点是否被U-Boot正确解析(可用dm tree命令在U-Boot中查看,若驱动未绑定则需检查设备树compatible属性)。

常见问题

  • 输出乱码:通常为波特率不匹配或时钟频率错误,核对CONFIG_BAUDRATE与终端设置,并确认时钟宏值。
  • 完全无输出:先确认板级串口引脚复用是否已配置(本案例未包含,需在board_init中完成);其次检查U-Boot是否真的执行了串口初始化——可在board_init_f中临时调用putc('U')定位卡死位置。
  • 设备树覆盖宏:若使用设备树,U-Boot以设备树中clock-frequency为准,需同步修改dts文件而非仅改头文件。