higher priority task affects reception process over UART in a lower priority task (STM32f429 Discovery)

thyanger wrote on Wednesday, July 29, 2015:

Hi everybody,

I am facing a problem with a reception process: I have an stm32f429
discovery connected to a gsm/gps module held on an evaluation board. The
communication between the discovery and the module take place via UART. I am
using STM32Cube_FW_F4_V1.5.0 along with FreeRTOS V8.1.2 and everything is
developped on Eclipse Mars.

In my application I need to access to the Internet via gsm, then login to a
remote server and send some info to it. Therefore, I arranged everithing as
follow:
there are two tasks, say A (the low level task) and B (the application
task). Basicly, task A must ensure to task B that the module is powered on,
the SIM PIN is inserted, the AP is configured and the module is connected to
the Internet. On the other hand, task B waits for task A to notify that the
module is ready in the meaning I just explained.

Both task A and B implements two corresponding finite state machines. So, at
the beginning task A goes to the UNKNOWN state while task B goes to the IDLE
state.

Then, task A send some AT commands to the module and waits for the responses
in order understand which is the module state. Then based on this knowledge,
it performs some actions to bring the module fully operative for task B. The
transmission/reception is obtained by means of the HALs functions
HAL_UART_Transmit_IT/HAL_UART_Receive, and the first is non-blocking while
the second is blocking with a timeout. The transmission is non-blocking
since the module replies very rapidly.

In the beginning the reception was puzzling. In the reception buffer I was
always finding odd chars, like due to something that was interrupting the
reception many times. Debugging (with the STATEViewer plugin) I came up with
the idea that that could be related to the fact that task A and B had the
same priority and then I tried to assign a higher priority (wrt task B) to
task A and everything worked fine. Based on this, I put some
osThreadSetPriority(), which is provided by ST within STM32Cube/cmsis_os.c,
in task A and B: when task A ends its job and notify to task B that it can
leave the IDLE state, then task B start performing some
HAL_UART_Transmit_IT/HAL_UART_Receive calls and therefore it needs to have
its priority higher than that of task A.

My question is: is this solution correct? Is really the reception process
integrity related with the task priority? There are many other tasks in my
application, and I started developping by assigning equal priority to
everyone leaving the “tuning” in the end because of the lack of time. But
now it seems that this approach could bring to a bad behavior. What if two
tasks must perform transmission/reception via different peripherals?

Thank you for the advice and regards.

heinbali01 wrote on Wednesday, July 29, 2015:

Hi Valerio,

I’m not sure what osThreadSetPriority() does, I’d normally use the FreeRTOS equivalents: setting the priority parameter in xTaskCreate() or calling vTaskPrioritySet().

Do you really have two task that must work continuously? That is quiet rare.
If you want a task to respond quickly, you might see if it can be woken up with an interrupt, or else have it sleep for short periods of time (use e.g. vTaskDelay()).

The following would be a simple IRQ handler that sets a semaphore to wake up a task:

    void Some_IRQHandler(void)
    {
    BaseType_t xHigherPriorityTaskWoken = 0;

        if( xSemaphore != NULL )
        {
            xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
        }
        portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    }

It is possible to have two or more tasks work continuously by giving them the same FreeRTOS priority. But remember that tasks with a lower priority will probably never get attention.

The correctness of the receiving task should not depend on its priority. Is it polling for data? Interrupt driven?
How does it forward the received data to the application?
Can you show some source code?

Regards.

thyanger wrote on Wednesday, July 29, 2015:

Hi Hein,

thank you for the response. Firstly, it looks that this https://sourceforge.net/p/freertos/discussion/382005/thread/845cdccf/ answer to my questions.

Saying that, the transmission is achieved in nonblocking mode with interrupts, but the reception is achieved in blocking mode with polling. I chose polling for reception because it was the fastest way to me to achieve what I wanted to do. osThreadSetPriority() simply wraps vTaskPrioritySet() to comply with the ST API style and it is provided by ST within STM32Cube which is a set of libraries to “simplify” developers’ life.

So, basicly, the solution I implemented is what you use to do, if I well understood.

In the case I mentioned, you’re right task A and B do not need to continuously work, at least in the implementation I described. Indeed, by means of dynamicly assigning priorities to tasks, I ensure the task A is working continuously at the startup, when task B, and neither A, does not know which is the module state (is the module powered on? is the module connected to the internet?). When task A has determined the module state, then its priority is decreased whilst that of task B is increased. However, in a more refined implementation, which I still have to think about it, it is very likely task A and B should run continuously, but I am not sure.

Furthermore, the complete application shall have some tasks running real-time. These tasks will be basicly handling I/O with other peripherals and they will have the same priority. And one of them shall do critical computations.

Since I am a newbie of embedded programming and realtime questions, I’d like to have an insight in order to do correct things in the future development.

Sorry, I did not understand how to properly post the code (this is my first post) by reading “Formatting Help”, maybe you can give me some hints :).