jorick23 wrote on Monday, April 23, 2007:
I have a project I’m developing that currently has only one task, a command processor that reads commands from the serial port, acts on them, and sends a response back out the serial port.
I’ve been having problems with transmitting the response back. It appeared that the transmit FIFO was overflowing and I was losing characters, even though I was blocking when the transmit FIFO became full (I used the STR912F demo for IAR as the template). Debugging showed that the task would correctly block when taking a semaphore when the FIFO filled and then wait for the semaphore to be given back by the UART ISR when the FIFO became free. But when running full bore, the FIFO overflowed as if the semaphore weren’t there.
I then had an idea that maybe the task was blocking on the semaphore and then immediately awakening again because it was the only task in the system and the scheduler had to wake somebody after the lone task went to sleep. This occurred to me once before with the uCOS RTOS, and I was wondering if it was happening in FreeRTOS as well.
Here’s the code in the Send Character function I use to block on, which doesn’t work:
___if (UART_GetFlagStatus (mkapsUARTBase [ziUART], UART_FLAG_TxFIFOFull)) {
______xSemaphoreTake (mapsTxSemaphore [ziUART], portMAX_DELAY);
___}
But when I make it a loop to force it to go back to sleep if the FIFO is still full, it works very well:
while (UART_GetFlagStatus (mkapsUARTBase [ziUART], UART_FLAG_TxFIFOFull)) {
xSemaphoreTake (mapsTxSemaphore [ziUART], portMAX_DELAY);
}
Is this what could be happening? Why doesn’t the Idle Task run while waiting for the FIFO to become free?