3. 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);
}
}
}
编译与运行
- 将上述代码放入PDK RTOS工程(如
pdk/packages/ti/drv/uart/example/下新建uart_echo目录),添加对应makefile或使用CCS导入。 - 编译命令(以PDK makefile为例):
make -C pdk/packages/ti/drv/uart example_echo BOARD=j721e_evm SOC=j721e
- 将生成的
.xer5f(或.out)通过CCS加载到MCU1_0核心运行。 - 使用串口助手连接WKUP_UART0(默认使用板载USB转串口,波特率115200),打开串口。
验证方法
- 在串口助手中发送任意ASCII字符(如
A或Hello),观察接收区是否原样返回相同内容。 - 判定通过条件:发送单个字符或短字符串,串口助手能逐字节收到完全一致的回显,且无乱码、无丢失。
- 若需验证中断路径:在回调中设置断点,发送数据时确认能触发断点,证明接收由中断驱动而非轮询。
常见问题
- 无回显:检查
UART_socGetBoardCfg返回的实例号是否正确(WKUP_UART0通常为0);确认EVM板串口跳线/开关选择正确。 - 乱码:核对波特率是否与串口助手一致;检查板级时钟配置中UART输入时钟频率是否与PDK默认值匹配。
- 回调未触发:确认
readMode已设为UART_MODE_CALLBACK,且UART_read已调用——PDK的UART驱动在回调模式下必须显式调用read才会使能接收中断。