I am experiencing an issue where UART data is lost when a FreeRTOS task dispatch overlaps with a UART DMA interrupt.
・Problem:
When a FreeRTOS task is dispatched while waiting for UART data, several hundred bytes of data are lost.
The UART DMA interrupt callback function is not triggered during this time.
・Suspected Cause:
I suspect that the FreeRTOS task dispatch has a higher priority than the UART DMA interrupt, which prevents the callback function from being executed.
I would appreciate your advice on this.
・Question:
How can I ensure that the UART DMA interrupt callback is always triggered, even when a FreeRTOS task is dispatched?
Are there specific priority settings or configurations I should adjust to prevent data loss?
・Current Configuration:
- UART DMA interrupt priority: Set using adi_sec_SetPriority().
- FreeRTOS task priority: Set using xTaskCreateStatic().
・Environment:
- Processor: ADSP-SC594 Core0 (Arm Cortex-A5)
- IDE: CrossCore Embedded Studio 3.0.1.0
- FreeRTOS Version: V10.5.1 (installed via add-in)
・Sample Code:
#include <sys/platform.h>
#include <sys/adi_core.h>
#include <services/spu/adi_spu.h>
#include <services/int/adi_sec.h>
#include <drivers/uart/adi_uart.h>
#include "FreeRTOSConfig.h"
#include "FreeRTOS.h"
#include "task.h"
ADI_SPU_HANDLE Handle_Spu;
uint8_t Wk_Mem_Spu[ADI_SPU_MEMORY_SIZE];
ADI_UART_HANDLE Handle_Uart;
uint8_t Wk_Mem_Uart[ADI_UART_BIDIR_MEMORY_SIZE];
char RecvBuf_Uart_Rx[1024];
char *RecvBuf_Uart_Rx_Curr = RecvBuf_Uart_Rx;
ADI_PDMA_DESC_LIST DescList_Uart_Rx[2] __attribute__((section (".l2_uncached_data"))) __attribute__((aligned(4U)));
uint8_t Dma_RecvBuf_Uart_Rx[2] __attribute__((section (".l2_uncached_data"))) __attribute__((aligned(4U)));
TaskHandle_t Handle_Task_A;
TaskHandle_t Handle_Task_B;
StackType_t Stack_Task_A[1024];
StackType_t Stack_Task_B[1024];
StaticTask_t StaticTask_Task_A;
StaticTask_t StaticTask_Task_B;
---------------------------
void callback_uart_rx(void *param, uint32_t event, void *arg)
{
switch (event)
{
case ADI_UART_EVENT_RX_PROCESSED:
*RecvBuf_Uart_Rx_Curr++ = *(char *)arg;
if (RecvBuf_Uart_Rx_Curr >= &RecvBuf_Uart_Rx[1024]) RecvBuf_Uart_Rx_Curr = RecvBuf_Uart_Rx;
break;
default:
break;
}
}
---------------------------
void task_a(void *param)
{
while (true)
{
for (volatile size_t cycle_cnt = 1000000UL; _cycle_cnt; _cycle_cnt--) __asm volatile("NOP");
vTaskDelay((TickType_t)100 / portTICK_PERIOD_MS); /* dispatch */
}
}
---------------------------
void task_b(void *param)
{
while (true)
{
vTaskDelay((TickType_t)100 / portTICK_PERIOD_MS); /* dispatch */
for (volatile size_t cycle_cnt = 1000000UL; _cycle_cnt; _cycle_cnt--) __asm volatile("NOP");
}
}
---------------------------
/* Initialize SPU */
adi_spu_Init(0u, Wk_Mem_Spu, NULL, NULL, &Handle_Spu);
adi_spu_EnableMasterSecure(Handle_Spu, 29, true); /* UART0 */
adi_spu_EnableMasterSecure(Handle_Spu, 79, true); /* UART0 Rx DMA */
/* Initialize SEC */
adi_sec_SetPriority(SEC_UART0_RXDMA, 100); /* Set Priority to UART0 Rx DMA */
/* Set Descriptor List */
DescList_Uart_Rx[0].pNxtDscp = &DescList_Uart_Rx[1];
DescList_Uart_Rx[0].pStartAddr = &Dma_RecvBuf_Uart_Rx[0];
DescList_Uart_Rx[0].Config = ENUM_DMA_CFG_XCNT_INT;
DescList_Uart_Rx[0].XCount = 1;
DescList_Uart_Rx[0].XModify = 1;
DescList_Uart_Rx[0].YCount = 0;
DescList_Uart_Rx[0].YModify = 0;
DescList_Uart_Rx[1].pNxtDscp = &DescList_Uart_Rx[0];
DescList_Uart_Rx[1].pStartAddr = &Dma_RecvBuf_Uart_Rx[1];
DescList_Uart_Rx[1].Config = ENUM_DMA_CFG_XCNT_INT;
DescList_Uart_Rx[1].XCount = 1;
DescList_Uart_Rx[1].XModify = 1;
DescList_Uart_Rx[1].YCount = 0;
DescList_Uart_Rx[1].YModify = 0;
/* Initialize UART */
adi_uart_Open(ADI_UART_0, ADI_UART_DIR_BIDIRECTION, Wk_Mem_Uart, ADI_UART_BIDIR_MEMORY_SIZE, &Handle_Uart);
adi_uart_ConfigBaudRate(Handle_Uart, 1, 135);
adi_uart_SetWordLen(Handle_Uart, ADI_UART_WORDLEN_8BITS);
adi_uart_EnableParity(Handle_Uart, false);
adi_uart_RegisterCallback(Handle_Uart, callback_uart_rx, NULL);
adi_uart_DMARead(Handle_Uart, DescList_Uart_Rx, 2, ADI_PDMA_DESCRIPTOR_LIST);
/* Create Task */
Handle_Task_A = xTaskCreateStatic(task_a, "task_a", 1024, NULL, tskIDLE_PRIORITY + 3, Stack_Task_A, &StaticTask_Task_A);
Handle_Task_B = xTaskCreateStatic(task_b, "task_b", 1024, NULL, tskIDLE_PRIORITY + 2, Stack_Task_B, &StaticTask_Task_B);
Edit Notes
The question is the same but the writing style has been adjusted.[edited by: MrKK at 7:08 AM (GMT -4) on 23 Apr 2025]

