This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM5708: UART callback模式发送和接收无法进Callback

Part Number: AM5708

在使用AM5708配置UART1时,无法正常进入UART的发送和接收callBack

UART配置如下:

调用UART_write可以正常发送(发送完成之后也不会进writeCallback),无法接收数据

  • 检查一下代码逻辑或者硬件连接是否有问题吧,或是用调试工具调试一下,看看中断是否正常触发

  • 调试了,进不了中断。  阻塞模式发送和接收都正常

  • 看看中断是否配置正确和优先级有没有比UART高的

  • DSP核我只配了一个中断,帮忙看下这样配置是否有问题

  • 麻烦别用图片,重新用代码形式发一下吧

  • static void drv_uart_HwiInit(UART_HwAttrs *pHwAttrs)
    {
        Hwi_Params hwi_params;
        Error_Block eb;
        Error_init(&eb);
        Hwi_Params_init(&hwi_params);
    
        CSL_xbarIrqConfigure(CSL_XBAR_IRQ_CPU_ID_DSP1, CSL_XBAR_INST_DSP1_IRQ_44, CSL_XBAR_UART1_IRQ);
    
        hwi_params.eventId = pHwAttrs->eventId;
        hwi_params.arg = NULL;
        hwi_params.priority = 0x20;
        hwi_params.maskSetting = Hwi_MaskingOption_SELF;
        hwi_uart = Hwi_create(4, drv_uart_ISRHandle, &hwi_params, &eb);
        if(NULL == hwi_uart)
        {
            M_TraceL("HWI Uart Create Failed");
        }
    }

  • 这段代码看起来是没问题的,只用一个中断来处理UART

  • 清除一下中断状态试试

  • 用到共享资源了吗

  • ARM核上面跑的Linux,我是直接用的烧录器直接对DSP进行烧录的

  • 好像没用,我把整个工程代码帖出来,帮忙看看有什么问题没,创建了一个Task循环判断,目的是通过串口中断实现自发自收

    #include "drv_uart.h"
    #include "drv_debug.h"
    #include <string.h>
    
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/hal/Hwi.h>
    #include <ti/sysbios/knl/Task.h>
    
    #include <ti/board/board.h>
    
    #define UART_INSTANCE                       (0)
    #define TASK_UART_PRIORITY                  (8)
    #define TASK_UART_STACK_SIZE                (2048)
    
    #define UART_BUFFER_SIZE                    (128 - 1)
    
    typedef struct
    {
        uint8_t  size;
        uint8_t  buffer[UART_BUFFER_SIZE];
    }TS_UART_MESSAGE;
    
    typedef struct
    {
        TS_UART_MESSAGE write;
        TS_UART_MESSAGE read;
    }TS_UART_DATA;
    
    static UART_Handle uart_handle;
    static Hwi_Handle hwi_uart;
    static TS_UART_DATA uartData;
    
    static Task_Handle task_uart_handle;
    static uint8_t stack_task_uart[TASK_UART_STACK_SIZE];
    
    TS_UART_DATA *drv_uart_GetUartData(void)
    {
        return &uartData;
    }
    
    static void drv_uart_GpioInit(void)
    {
        /*Pad configurations */
        HW_WR_REG32(CSL_DSP_CORE_PAD_IO_REGISTERS_REGS + CSL_CONTROL_CORE_PAD_IO_PAD_UART1_RXD, 0x00040000);
        HW_WR_REG32(CSL_DSP_CORE_PAD_IO_REGISTERS_REGS + CSL_CONTROL_CORE_PAD_IO_PAD_UART1_TXD, 0x00000000);
    }
    
    static void drv_uart_ISRHandle(uint32_t arg)
    {
        HwiP_clearInterrupt(4);
    }
    
    static void drv_uart_HwiInit(UART_HwAttrs *pHwAttrs)
    {
        Hwi_Params hwi_params;
        Error_Block eb;
        Error_init(&eb);
        HwiP_Params_init(&hwi_params);
    
        CSL_xbarDspIrqConfigure(1, CSL_XBAR_INST_DSP1_IRQ_44, CSL_XBAR_UART1_IRQ);
    
        HwiP_clearInterrupt(4);
    
        hwi_params.eventId = pHwAttrs->eventId;
        hwi_params.arg = NULL;
        hwi_params.priority = 10;
        hwi_params.maskSetting = Hwi_MaskingOption_SELF;
        hwi_uart = Hwi_create(4, drv_uart_ISRHandle, &hwi_params, &eb);
        if(NULL == hwi_uart)
        {
            M_TraceL("HWI Uart Create Failed");
        }
    }
    
    static void drv_uart_ConfigInit(void)
    {
        UART_HwAttrs uart_cfg;
        UART_socGetInitCfg(UART_INSTANCE, &uart_cfg);
        uart_cfg.edmaHandle = NULL;
        uart_cfg.dmaMode    = FALSE;
        uart_cfg.loopback   = FALSE;
        UART_socSetInitCfg(UART_INSTANCE, &uart_cfg);
        uart_handle->hwAttrs = &uart_cfg;
        drv_uart_HwiInit(&uart_cfg);
    }
    
    void drv_uart_WriteCallback(UART_Handle handle, void *buf, size_t count)
    {
        // 发送成功
        // M_TraceL("UART1 Send Complete");
    }
    
    void drv_uart_ReadCallback(UART_Handle handle, void *buf, size_t count)
    {
        uartData.read.size = count;
        memcpy(uartData.read.buffer, buf, uartData.read.size);
        // 发送事件
    }
    
    void drv_uart_Init(void)
    {
        UART_Params uart_params;
    
        drv_uart_GpioInit();
        drv_uart_ConfigInit();
    
        UART_Params_init(&uart_params);
        uart_params.writeDataMode = UART_DATA_BINARY;
        uart_params.writeMode = UART_MODE_CALLBACK;
        uart_params.writeCallback = drv_uart_WriteCallback;
    
        uart_params.readDataMode = UART_DATA_BINARY;
        uart_params.readMode = UART_MODE_CALLBACK;
        uart_params.readCallback = drv_uart_ReadCallback;
    
        uart_params.baudRate = 115200;
        uart_params.dataLength = UART_LEN_8;
        uart_params.parityType = UART_PAR_NONE;
        uart_params.stopBits = UART_STOP_ONE;
        uart_handle = UART_open(UART_INSTANCE, &uart_params);
        if(uart_handle == NULL)
        {
            M_TraceL("Uart%d Open Failed", UART_INSTANCE + 1);
        }
    
        UART_read(uart_handle, uart_read.buffer, sizeof(uart_read.buffer));
    }
    
    void drv_uart_Write(uint8_t *data, uint16_t size)
    {
        if(uart_handle != NULL)
        {
            UART_write(uart_handle, data, size);
        }
    }
    
    int32_t drv_uart_Read(uint8_t *buffer, uint16_t size)
    {
        return UART_read(uart_handle, buffer, size);
    }
    
    static void app_uart_TaskCallBack(UArg a0, UArg a1)
    {
        TS_UART_DATA *pData = drv_uart_GetUartData();
        while(1)
        {
            if(pData->read.size != 0)
            {
                drv_uart_Write(pData->read.buffer, pData->read.size);
                pData->read.size = 0;
            }
            Task_sleep(1000);
        }
    }
    
    static void drv_uart_TaskInit(void)
    {
        Error_Block eb;
        Task_Params task_params;
        Error_init(&eb);
        Task_Params_init(&task_params);
        task_params.priority = TASK_UART_PRIORITY;
        task_params.stackSize = TASK_UART_STACK_SIZE;
        task_params.stack = stack_task_uart;
        task_uart_handle = Task_create(app_uart_TaskCallBack, &task_params, &eb);
        if(task_uart_handle == NULL)
        {
            M_TraceL("Task UART Create Failed");
            BIOS_exit(0);
        }
    }
    
    void app_uart_Init(void)
    {
        drv_uart_Init();
        drv_uart_TaskInit();
    }
    
    static void Device_Init(void)
    {
        Board_initCfg boardCfg;
    
        boardCfg = BOARD_INIT_PINMUX_CONFIG |
                    BOARD_INIT_MODULE_CLOCK |
                    BOARD_INIT_UART_STDIO;
        Board_init(boardCfg);
    }
    
    /*
     *  ======== main ========
     */
    int main()
    {
        Device_Init();
        drv_uart_Init();
        BIOS_start();    /* does not return */
        return(0);
    }

  • 已经可以进发送CallBack了,接收CallBack也能进,  但是是数据满了才进,怎么设置空闲中断?

  • 我写了个中断函数示例,加上去试试

    // 启用空闲中断的宏定义
    
    #define ENABLE_IDLE_INTERRUPT() // 设置寄存器、配置
    
    // 空闲中断处理函数
    void IdleInterruptHandler(void) {
    // 执行一些低优先级的任务或系统监控
    }
    
    int main() {
    // 初始化系统和硬件
    
    // 启用空闲中断
    ENABLE_IDLE_INTERRUPT();
    
    // 设置空闲中断阈值(每秒触发一次)
    SetIdleInterruptThreshold(/* 阈值设置 */);
    
    while (1) {
    // 主循环,处理其他高优先级的任务
    // ...
    }
    
    return 0;
    }

  • 不好意思,ENABLE_IDLE_INTERRUPT这部分应该怎么配置,5708的UART寄存器里面没有找到有空闲中断的相关配置

  • ENABLE_IDLE_INTERRUPT这部分应该怎么配置

    不是配置项,就是个假设性的示例标识,可能是为了强调需要启用空闲中断的情况

  • 可以用超时计数器或直接用DMA

  • 我用了DMA,DMA接收也是定长数据,DMA可以接收不定长数据吗?

  • void drv_uart_Read(void)
    {
        if(uart_handle != NULL)
        {
    #ifdef UART_DMA_ENABLE
            CacheP_wbInv((void *)uartRead.buffer, (int32_t)sizeof(uartRead.buffer));
            // 此处写的接收长度为1,假设长度设置为10,必须接收满10个字节才能触发中断
            UART_read(uart_handle, uartRead.buffer, 1);
    #else
            UART_read(uart_handle, uartRead.buffer, 1);
    #endif
        }
    }

  • 所以怎么设置接收非定长数据,UART_Read中有一个参数是接收长度,假设我将接受缓存设置为128Bytes, 如何1个字节、10个字节、100个字节都能触发中断呢?

  • 您好,

    我看你设置接收长度为1,也就是每次只接收一个字节的数据。如果你要能够触发中断来处理不同长度的数据,要修改一下

    比如:1.使用中断服务函数处理接收到数据,而不是在drv_uart_Read函数中进行处理。

    2.在中断服务函数中,根据接收到数据长度来判断是否达到预期的长度,如果达到预期长度进行处理。

  • 我将您的代码修改了一下

    void UART_ISR() {
    // 检查接收中断标志
    if (UART_GetInterruptStatus(UART0, UART_INT_RX)) {
    // 读取接收数据
    uint8_t received_data = UART_Read(UART0);
    
    // 将数据存入接收缓存
    rx_buffer[received_length] = received_data;
    received_length++;
    
    // 检查是否达到预期长度
    if (received_length >= 10) {
    // 处理接收到的数据
    // ...
    
    // 重置接收长度
    received_length = 0;
    }
    }
    }
    
    void drv_uart_Read(void)
    {
    if(uart_handle != NULL)
    {
    #ifdef UART_DMA_ENABLE
    CacheP_wbInv((void *)uartRead.buffer, (int32_t)sizeof(uartRead.buffer));
    // 设置FIFO中断触发阈值为1个字节
    UART_SetFIFOInterruptLevel(uart_handle, UART_FIFO_RX1);
    #else
    // 设置FIFO中断触发阈值为10个字节
    UART_SetFIFOInterruptLevel(uart_handle, UART_FIFO_RX10);
    #endif
    // 注册UART中断服务函数
    UART_SetInterruptHandler(uart_handle, UART_ISR);
    
    // 启用UART接收中断
    UART_EnableInterrupts(uart_handle, UART_INT_RX);
    }
    }