FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [November 2016 Threads]
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 = USARTFetchChar();
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...
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.
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!
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.