Proecting Calls for UART Access

Hello: I have 3 tasks running that all require access to a common UART function to send message strings to a touch screen. I have tried putting a mutex around the call to the “sendString” function, but the screen is still hanging on occassion. This is on an STM32F4, using FreeRTOS 9.0. Perhaps I am using the call incorrectly? if( xSemaphoreTake( xMutexUARTAccess, ( TickTypet ) 5 ) == pdTRUE )
{
sendString( buffer ); //calls another function to send it out of UART… ///poll for response while(1) { rxCode = USART
FetchChar();
if( rxCode == RCVDPROMPT ) //one more for 0xD rxCode = USARTFetchChar();
break; }
xSemaphoreGive( xMutexUARTAccess );
}
else { printf(“Had to leave…couldn’t wait for pokey the UART.n”); } Based on this, I have 2 questions: 1 – Is there a better mechanism in FreeRTOS than what I am using (assuming I am using the mutex correctly) 2 – Is there any way to determine if the poll response is hanging? For example, if I set the 2nd parameter as shown to 25ms, the message will print for about 20 times, then stop, then the watchdog reboots it. If I set it to 5 or 10ms, it seems to work OK. However, what I don’t understand is whether or not the mutex will tell me anything about the poll and response. To check the poll response, I have set a volatile variable at the top of the function, and then change it in the while(1) loop. It seems to always get reset in the while loop OK, but not certain if this really determines much. I should also mention that the tasks calling this function are doing so through a queue. The various tasks send the single queue the pointer to the (queue) data structure, and it then calls this function from there. So I am hoping I’ve covered all the bases to safeguard wild access, but something must be missing. Any suggestions on what could be wrong, or how I could implement this in a better way? Thanks…

Proecting Calls for UART Access

I have tried putting a mutex around the call to the “sendString” function, but the screen is still hanging
Are you sure the screen hanging is related to the mutex? What if you hammer the send screen function in an application that is not using FreeRTOS, or just from a single task so mutual exclusion is not a problem?
if( xSemaphoreTake( xMutexUARTAccess, ( TickTypet ) 5 ) == pdTRUE ) { sendString( buffer ); //calls another function to send it out of UART… ///poll for response while(1) { rxCode = USARTFetchChar(); if( rxCode == RCVDPROMPT ) //one more for 0xD rxCode = USARTFetchChar(); break; } xSemaphoreGive( xMutexUARTAccess );
I can’t see anything wrong here, but polling the UART while you hold the mutex might cause performance issues. It would be better to have the task enter the Blocked state to wait for the UART send to complete, and so not use any processing time while it has nothing to do (allowing other tasks to execute). The example code on this page shows one way of doing this: http://www.freertos.org/vTaskNotifyGiveFromISR.html Is a timeout of ‘5’ long enough if the UART is slow?
1 – Is there a better mechanism in FreeRTOS than what I am using (assuming I am using the mutex correctly)
Personally I would have the tasks write their messages to a circular RAM buffer, rather than directly to the UART, then have the characters transmitted by an ISR. If the buffer was previously empty when you wrote a message to it you would have to kick off the transmission, then the ISR would continue transmitting until the buffer was empty again, at which point it would stop.
2 – Is there any way to determine if the poll response is hanging? For example, if I set the 2nd parameter as shown to 25ms, the message will print for about 20 times, then stop, then the watchdog reboots it.
Sorry, I don’t understand. Your poll loop has no time out, so I presume it can hang there. If you want to know if that is what has happened then you will have to add diagnostic code, or simply use the debugger.
I should also mention that the tasks calling this function are doing so through a queue. The various tasks send the single queue the pointer to the (queue) data structure, and it then calls this function from there.
Are you saying that tasks don’t write to the UART directly, but send messages to a queue, and whatever drains the queue writes to the UART? If that is the case then only one task is actually using the UART and you don’t need a mutex at all.

Proecting Calls for UART Access

Thank you. What you said is correct – I use a queue to write to the function. However, after inspecting through the code, I may have found that I am writing directly to the function as well, which might be colliding with the task call. Once I refactor the code, I will test again. Although I do like the suggestion of using a circular buffer and ISR, as it offloads the task to HW that’s otherwise not being used. Thanks again!