Post Go back to editing

How to Prevent UART Data Loss When FreeRTOS Task Dispatches Overlap with Interrupts?

Category: Hardware
Product Number: ADSP-SC594

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]

Thread Notes

Parents
  • Hi,

    Thank you for your inquiry.

    We have created a RTOS project with three tasks and integrated UART stop mode code into that. This code will send the data from UART0 to UART1. We are able to see the correct data continuously in the Rxbuffer. We didn't set the priority for UART Rx DMA also.

    Did you check the behavior of the application with default priorities.

    Could you please share your complete project which simulates this observation in SC594 evaluation kit. This would be helpful for us to assist you better.

    Waiting for your reply.

    Best Regards,
    Santhakumari.V

  • I discovered that you can insert it from the menu "[Insert]->[External Content]".

    InsertMenu

    But, the company I am currently working for prohibits me from accessing these network storage for security reasons.
    However, I think you can send it as an attachment to an e-mail.

  • Hi,
    Thank you for your reply.

    We were relieved to learn that this issue is still open and has not been closed, as we were a bit concerned it might have been.
    Also, we truly appreciate your assurance that you will get back to us.
    We look forward to your response.
    Thank you very much.
    Sincerely yours,

    Best Regards,

  • Hi,

    The root cause of the issue is both semihosting I/O and vTaskDelay function uses SWI Interrupts. So the recommended way is "disabling semihosting" in CCES while debugging ARM applications.

    This can be done by,
    Connect the session and then Right click project properties->Debug Configurations ->Go to Automatic breakpoints Tab -> Uncheck "Enable semihosting" as like the below image.

    CCES uses semihosting IO mechanism which writes to console window. This is incompatible with default GCC-compiled I/O code which also uses SWI interrupts.

    After unchecking this option, we are able to get all data in the Rxbuffer. Hope this option helps to resolve the issue.

    Thank you so much for your patience.

    Best Regards,
    Santha kumari.V

  • Hi,
    Thank you for your reply.

    We have confirmed that disabling semihosting allows it to work as expected without any issues in our environment.
    We sincerely appreciate your support.
    Thank you very much.

    By the way, may I ask you a few questions about semihosting for future reference?
    We understand semihosting to be a feature that outputs debug information (such as debug logs) to the CCES console using functions such as printf when launching the debugger.
    Could you please confirm if our understanding is correct?
    Also, is it correct to understand that disabling semihosting simply means that debug information will no longer be output to the CCES console?
    In other words, when launching a ROM without going through CCES, does disabling semihosting have no other effects?

    Best Regards,
    MrKK

  • Hi,
    I apologize for asking again, but I have one more question.

    We understand that the UART issue occurred because the FreeRTOS task dispatcher (task scheduler) and the CCES semihosting function use the same interrupt (SWI interrupt), resulting in a conflict.
    In other words, if there is a conflict between the FreeRTOS task dispatcher and the CCES semihosting function, does that mean that similar issues will not only occur with UART, but also with other peripherals?
    Conversely, if there is no conflict between the FreeRTOS task dispatcher and the CCES semihosting function, does that mean that similar issues will not occur with UART, but also with other peripherals?

    Best Regards,
    MrKK

  • Hi,

    Glad to hear that your application is functioning correctly after disabling semihosting.

    Yes. Your understanding is correct. The semihosting I/O mechanism writes output to the CCES console during debug sessions, such as with printf statements. When semihosting is disabled, these outputs no longer appear in the CCES console. Instead, the stdio function calls made by the ARM core are routed through UART and must be monitored using an external serial terminal.

    In our FreeRTOS project, when semihosting is enabled, issues are observed not only with UART but also with other peripherals. We confirmed this by testing a timer project with FreeRTOS that calls vTaskDelay() inside the task, where similar problems occurred.

    If the semihosting option is disabled, the application works correctly.

    Hope this helps.

    Best Regards,
    Santha kumari.V

  • Hi,
    Thank you for your response to my question.

    We understood that these issues exist in FreeRTOS on ARM and that they can be tentative avoided by disabling the semihosting mechanism.
    We will continue development with the semihosting mechanism disabled as a workaround.

    We would like to express our gratitude for your continued support over the months.
    Also, we sincerely hope that these issues will be resolved at their root.
    Thank you very much.

    Best Regards,
    MrKK

  • Hi,

    Apologies for the delayed response.

    Yes, your understanding is correct. We are currently coordinating with our internal team to address this observation.

    Thank you very much for your patience and cooperation!

    Best Regards,
    Santhakumari.V

  • Hi,
    We truly appreciate your handling of this issue.

    P.S.
    The content of “AI GENERATED CONTENT” inserted at the beginning of this thread is incomplete.
    If possible, we would appreciate it if you could replace it with the complete content.

    Best Regards,
    MrKK

  • Hi,

    Thank you for the information. We have passed this to corresponding Internal team.

    Best Regards,
    Santhakumari.V

  • Hi,
    Please excuse me for asking again.

    We would appreciate it if you could kindly update this thread with a note and a link to the bug fix list once this issue has been resolved.

    We would also appreciate it if you could insert a "Thread Summary" by AI at the beginning of the thread.

    Best Regards,
    MrKK

Reply Children
No Data

Before You Switch


Switching languages will make ADI Explorer unavailable. Resume your session by switching back to English and reopening ADI Explorer.