How to use the usart in a task which doesn’t have the highest priority, and avoid losing data?

Hi, I’m using a SAML21 Xplained Pro A with several tasks running at the same time at different priorities, with tickless iddle sleep. The highest priority task reads and processes a sensor every 500ms (blocking with a vTaskDelay). The second most prioritary task sends messages throught GPRS (SIM900), using the USART to connect with a server, with usartreadbuffer_job (Atmel’s ASF routines). When a character is received in the serial port, the USART interrupt executes the read callback, storing the character in a circular buffer, which will be processed outside of the callback routine. Some of the messages are correctly sent and the server responses are correctly received, however, in many occassions, the GPRS task wait for the response of the server and never receives the expected characters. I have tested the GPRS system without FreeRTOS, connecting the SIM900 directly to the CPU, and it works perfectly.
This makes me wonder if some data is getting lost when a context switch occurs and the usart interrupt and callback are being preempted by other task or by a FreeRTOS interrupt (as I don’t have any other interrupts). The usart is setup to run in standby. I know that all interrupts have higher priority than any FreeRTOS tasks, so I wonder what might be causing this loss. I have read that using DMA might be a solution, could it? Also, I have found freertos.peripheral_control and FreeRTOS+IO, but it seems there is no support for the SAML21. Could this be due to an incorrect priority assignment to the usart interrupt? What’s the proper method to use the usart in a task which doesn’t have the highest priority, and avoid losing data? I would appreciate any insights on this issue. Álvaro

How to use the usart in a task which doesn’t have the highest priority, and avoid losing data?

Is you UART ISR making any FreeRTOS API calls? You say with FreeRTOS and tickless idle you have a problem, without FreeRTOS you don’t have a problem – have you tried with FreeRTOS but WITHOUT tickless idle? I suspect, without much evidence, the issue will be processing as you leave low power mode rather than anything to do with context switching.

How to use the usart in a task which doesn’t have the highest priority, and avoid losing data?

Thanks Richard, The USART ISR doesn’t use FreeRTOS API calls, just saves the received byte in a circular buffer: ~~~ void usartGPRSreadcallback(struct usartmodule *const usartmodule) { GPRSdatarx[datainGPRSRXbuffer] = *rx_bufferGPRS; data_in_GPRS_RX_buffer++; } ~~~ I am trying without tickless idle, and even without entering into sleep mode, and still some USART messages are not properly received. I have configured the GPRS task to have the same priority as the sensor task, with the same result. I am trying to find how to set up interrupt priorities, thinking that this could be the cause, does it make sense?

How to use the usart in a task which doesn’t have the highest priority, and avoid losing data?

Fixed. I post my findings in case it helps anyone with similar issues: The issue was caused by an incorrect management of the USART interrupts. I was activating the USART interrupt calling usartreadbuffer_job only at the points of the code when I was expecting to receive a message. However, this seems to be wrong, as some data may arrive a bit before the interrupt was active, therefore getting lost. Thus, we configured the interrupt to be active all the time, by executing usartreadbuffer_job at the beginning of the program, and by activating again the interrupt every time the USART callback is called: ~~~ void usartGPRSreadcallback(struct usartmodule *const usartmodule) { //store the received data in a circular buffer// GPRSdatarx[datainGPRSRXbuffer] = *rx_bufferGPRS; data_in_GPRS_RX_buffer++;
//Activate the USART interrupt to be ready for the next coming data
usart_read_buffer_job(&usartGPRS_instance, (uint8_t *)rx_bufferGPRS, MAX_RX_BUFFER_LENGTH_GPRS);
} ~~~ In this way, the USART interrupt receives all data and the systems works as expected.

How to use the usart in a task which doesn’t have the highest priority, and avoid losing data?

Thanks for taking the time to report back.