3. Jacinto U-Boot编译与SPL启动镜像生成

Jacinto U-Boot编译与SPL启动镜像生成 学习卡片

任务说明

在TI Jacinto平台(如DRA829/TDA4VM)的BSP环境中,实现UART驱动的最小可复现闭环:完成串口控制器初始化、引脚mux配置、中断方式收发,最终通过串口助手发送数据并观察原样返回,验证回显功能。

环境与依赖

  • SDK:TI Processor SDK Linux / RTOS(本文以RTOS + PDK为例)
  • 硬件:Jacinto EVM板载UART(如WKUP_UART0,调试串口)
  • 依赖头文件:ti/drv/uart/UART.h、ti/drv/uart/UART_soc.h(PDK驱动库)
  • 引脚配置:需在board配置中确认UART0 TX/RX对应的引脚mux模式(本文直接使用PDK默认的board init,实际项目中通过DTS或board.c配置)

核心实现

以下代码基于PDK的UART驱动,完成初始化、注册回调、使能接收中断,并在回调中将收到的字节立即写回(回显)。使用信号量同步主循环等待数据,便于验证。

#include <ti/drv/uart/UART.h>
#include <ti/drv/uart/UART_soc.h>
#include <ti/osal/osal.h>

#define UART_INSTANCE    0          /* WKUP_UART0 */
#define ECHO_BUFFER_SIZE 256

static volatile uint8_t g_rx_char;
static volatile bool    g_rx_done = false;
static SemaphoreP_Handle g_rx_sem;

/* 接收回调:读取一个字节,立即写回(回显),并释放信号量 */
static void UART_echoCallback(UART_Handle handle, void *buffer, size_t count, void *userArg)
{
    uint8_t *rxBuf = (uint8_t *)buffer;
    if (count > 0) {
        g_rx_char = rxBuf[0];
        /* 回显:将收到的字节发送出去 */
        UART_write(handle, &g_rx_char, 1, NULL);
        g_rx_done = true;
        SemaphoreP_post(g_rx_sem);
    }
}

void UART_echoTask(void *args)
{
    UART_Params uartParams;
    UART_Handle uartHandle;
    UART_BoardCfg boardCfg;
    uint8_t rxBuf[1];
    int32_t status;

    /* 1. 获取该实例的board配置(含引脚mux、时钟、基址) */
    status = UART_socGetBoardCfg(UART_INSTANCE, &boardCfg);
    if (status != SystemP_SUCCESS) {
        /* 实际工程中此处应记录错误并返回 */
        return;
    }

    /* 2. 初始化UART外设(引脚mux、时钟使能、控制器复位) */
    status = UART_socSetBoardCfg(&boardCfg);
    if (status != SystemP_SUCCESS) {
        return;
    }

    /* 3. 配置UART参数:默认115200-8-N-1,开启接收中断 */
    UART_Params_init(&uartParams);
    uartParams.baudRate = 115200;
    uartParams.dataLength = UART_DATA_LEN_8;
    uartParams.stopBits = UART_STOP_BITS_1;
    uartParams.parityType = UART_PAR_NONE;
    uartParams.readMode = UART_MODE_CALLBACK;
    uartParams.readCallback = UART_echoCallback;
    uartParams.readUserArg = NULL;
    uartParams.writeMode = UART_MODE_BLOCKING;   /* 回显写操作用阻塞模式,简单可靠 */

    /* 4. 打开UART */
    uartHandle = UART_open(UART_INSTANCE, &uartParams);
    if (uartHandle == NULL) {
        return;
    }

    /* 5. 创建信号量用于同步 */
    g_rx_sem = SemaphoreP_create(0, NULL);
    if (g_rx_sem == NULL) {
        UART_close(uartHandle);
        return;
    }

    /* 6. 启动一次接收,等待1字节触发回调 */
    UART_read(uartHandle, rxBuf, 1, NULL);

    /* 7. 主循环:等待回显完成,打印状态 */
    while (1) {
        SemaphoreP_pend(g_rx_sem, SystemP_WAIT_FOREVER);
        if (g_rx_done) {
            /* 回显已由回调完成,此处仅作状态指示 */
            g_rx_done = false;
            /* 重新启动下一次接收 */
            UART_read(uartHandle, rxBuf, 1, NULL);
        }
    }
}

编译与运行

  1. 将上述代码放入PDK RTOS工程(如pdk/packages/ti/drv/uart/example/下新建uart_echo目录),添加对应makefile或使用CCS导入。
  2. 编译命令(以PDK makefile为例):
make -C pdk/packages/ti/drv/uart example_echo BOARD=j721e_evm SOC=j721e
  1. 将生成的.xer5f(或.out)通过CCS加载到MCU1_0核心运行。
  2. 使用串口助手连接WKUP_UART0(默认使用板载USB转串口,波特率115200),打开串口。

验证方法

  • 在串口助手中发送任意ASCII字符(如A或Hello),观察接收区是否原样返回相同内容。
  • 判定通过条件:发送单个字符或短字符串,串口助手能逐字节收到完全一致的回显,且无乱码、无丢失。
  • 若需验证中断路径:在回调中设置断点,发送数据时确认能触发断点,证明接收由中断驱动而非轮询。

常见问题

  • 无回显:检查UART_socGetBoardCfg返回的实例号是否正确(WKUP_UART0通常为0);确认EVM板串口跳线/开关选择正确。
  • 乱码:核对波特率是否与串口助手一致;检查板级时钟配置中UART输入时钟频率是否与PDK默认值匹配。
  • 回调未触发:确认readMode已设为UART_MODE_CALLBACK,且UART_read已调用——PDK的UART驱动在回调模式下必须显式调用read才会使能接收中断。