In my application, I am receiving bunch of data via UART port. I am using ARM A5 core. I am facing data loss issue while using vTaskDelay() inside the task. I provided 100ms as a delay period. Suppose if I comment this API or increase the delay period from 100 to 10000, I could see all data in my rxbuffer. I registered a callback after reception of each character.
Welcome to the FreeRTOS forum.
There is not enough information in your post to analyze the problem you’re having. ARM Cortex-A5 tells us the CPU architecture (ARMv7-A), and the fact that you’re posting the question to the FreeRTOS community (plus the API function name you included) tell us that it’s a FreeRTOS application, but without information about the target hardware, the drivers that are being used, etc.
Please include a bit more information, and perhaps somebody here can help you diagnose and fix the problem you’re having.
Also - the Community Media is not the best place for this question. Try the kernel forum.
Hi Daniel,
Apologies for not giving target details in the earlier mail. I am using SC594 Evaluation kit as a target. It contains Cortex-A5 and Sharc core. I have configured UART0 using driver APIs. I have configured descriptor in a chained manner. If I send a single character at a time via tera term, I could see that data in Rxbuffer. But if I copy set of character and send via teraterm using ALT+v option, I could see one or two characters only. If I comment out vTaskDelay() API inside task handler or increase the delay period from 100 to 10000, I could receive all the data in the Rxbuffer. With vTaskDelay() API, I could receive one or two data in the rxbuffer with the delay period of 100ms. But same application works fine in Sharc core as well as ARM55 core in SC598 eval kit. I suspect that the problem is related to port specific files. Could you please share your comments.
It is not clear from your description where are you calling vTaskDelay. Please share relevant code snippets.
Hi,
Please find the code snippet here.
void Task_1(void *param)
{
Uart_Init();
int i=0;
while (true)
{
for (volatile size_t _cycle_cnt = 1000000UL; _cycle_cnt; _cycle_cnt--) __asm volatile("NOP");
vTaskDelay((TickType_t)100/ portTICK_PERIOD_MS); /* dispatch */
}
}
int main()
{
adi_initComponents();
xReturned_1 = xTaskCreate(Task_1, "Task1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+3, &xHandle_Task_1);
if( xReturned_1 != pdPASS )
abort();
/* Start the scheduler. */
vTaskStartScheduler();
}
Another observation is, we just commented vTaskDelay() API and placing portYIELD_WITHIN_API(); in the task handler function also creating the same issue. So we suspect that the problem is due to this port specific macro implementation
#define portYIELD() __asm volatile ( "SWI 0" ::: "memory" ); in ARM cortex A5 core.
void Task_1(void *param)
{
Uart_Init();
int i=0;
while (true)
{
// for (volatile size_t _cycle_cnt = 1000000UL; _cycle_cnt; _cycle_cnt--) __asm volatile("NOP");
// vTaskDelay((TickType_t)100/ portTICK_PERIOD_MS); /* dispatch */
portYIELD_WITHIN_API();
}
}
Please share your comments.
well, the busy loop will hog the CPU. If your eco system implicitly creates worker tasks at lower priority than your task to process the input, that worker thread may get starved.
What if you only do a small computation in your task?
Hi,
We are doing only a simple operation inside the task handler. UART0 has been configured to receive the data. The requirement is whenever we are sending a bunch of data it has to be received by the UART. UART callback will be triggered for every character. But we could see one or two bytes in the Rx buffer while using vTaskDelay() call inside the handler function. UART Rx Interrupt ID is 171 for ARM core. We suspect that the ISR is not getting serviced for all data if the vTaskDelay() API is used or portYIELD_WITHIN_API() is used inside the Task
void Task_1(void *param)
{
Uart_Init();
while (true)
{
vTaskDelay((TickType_t)100/ portTICK_PERIOD_MS);
//portYIELD_WITHIN_API();
}
}
Are you using an interrupt for the UART? How large is the memory buffer for the UART (not the internal Rx FIFO)?
I’m not allowed to post code snippets (not the website, my employer) so I cannot provide an example of something that I know works for me with FreeRTOS on ARM Cortex-M in STM32 microcontrollers and Microchip SmartFusion SoC FPGAs, and ARM Cortex-A53 in the PS of a Xilinx (AMD) MPSoC FPGA.
I also don’t know the SoC, and importantly, the vendor provided drivers. Interrupts should happen asynchronously to your loops unless you’re using blocking read calls. On the STM32, I typically use DMA with a circular buffer and register callbacks with the driver for buffer half-full and I/O complete. Depending on whether you have a dedicated task waiting for the next characters (blocking read with timeout) or the task polls the input buffer status periodically also affects things.
I have used FreeRTOS in a number of embedded applications, one of which had 3 UARTs connected to different types of navigation receivers accepting and parsing NEMA data along a 4th (BLE) for remote control, and a USB 2.0 High Speed connection to a host device. 8 foreground tasks in total (not counting the FreeRTOS timer task and the Idle task), no character loss.
you need to understand the control flow in your vendor provided device driver. In what context is your callback executed?
What is the point of having this task? Did you share the trimmed down version? Can you share the code which receives UART data and processes it?