How to suspend the task execution , waiting for a response from another task

Hi all, I’m a beginner to Freertos, and I want to write a function APIgetuart_data() designed as part of a library. The basic idea is to introduce an abtraction layer architecture in my firmware project. Summarizing : APIgetuart_data() returns NULL if no data is present on UART port If a data is present in the queue, **APIgetuart_data() ** returns a pointer to data. I have already implemented the task HALUARTtask() which stores in a DATA queue the incoming messages from serial port. This is a simple usecase: myapplicationtask() { while (1) { if (APIgetuart_data() != NULL ) { /*do something with the data … */ } } } Now my question: myapplicationtask() should be in [SUSPENDED] state until APIgetuart_data() returns a valid result What could be the best way to implement this mechanism? In other words, this is my current idea of a possible implementation: UARTmessage* API_get_UART_data(void) { UARTmessage* tempmessage = NULL; currenttask _handler = xTaskGetCurrentTaskHandle(); /* send message to HAL_UART queue ** with ( tempmessage , currenttask _handler )*/ ** vTaskSuspend( current_task _handler); /****************************/ /* HALUARTtask() will ceck for a message in the DATA queue , changing temp_message if necessary. /* now HAL_UART_task() resumes using vTaskResume( current_task _handler); */ /****************************/
return tempmessage;
} any advice and suggestions will be greatly appreciated. Thanks. Giorgio.

How to suspend the task execution , waiting for a response from another task

You have defined your API badly for this task, as your API doesn’t block, so it must be polled, forcing the application to work around this limitation. Redefine your APIgetuart_data to have a parameter for how long to wait for data, and if the timeout expires, return the null, and if not return the pointer to the data. Then the consumer can make the blocking call and wait for the data. This timeout value can then be passed to the queue fetch operation that the UART task has put the data in. Personallly, I tend to have the UART ISR do most of the packing work of assembly the low level message and putting it onto a FreeRTOS queue, and then the application level UART task takes that data, with no intermediate ‘uart driver’ task in the middle. The receive side API is basically a simple call wrapper for that queue receive operation.

How to suspend the task execution , waiting for a response from another task

Hi Richard, thank you for the reply. I agree with you about my not clever API definition, but at this moment I’m focusing on the possibilities provided by FreeRTOS in order to Suspend/Resume a desired task. Maybe a dedicated semaphore could be considered as a valid alternative. In any case, trying to explain better my expectations: when APIgetuart_data() is called by myapplicationtask() 1) A query is sent to ALUARTtask() , providing a pointer for the response 2) myapplicationtask() is [SUSPENDED] by APIgetuart_data() 3) when ALUARTtask() intercepts the query, it updates the provided response pointer and resumes myapplicationtask() 4) updated response is returned by APIgetuart_data() Is this a common architecture design in FreeRTOS? What could be considered the most reasonable options in order to implement my idea? Thanks. Best Regards. Giorgio.

How to suspend the task execution , waiting for a response from another task

I would not use suspend/resume here as there is a fundamental data race. I would have APIgetuart_data() block on something, either a semaphore, queue or direct to task notification for the answer to be ready

How to suspend the task execution , waiting for a response from another task

Hi Richard, thank you for your suggestion. I changed my strategy, implementing APIsetcallbackuartdata( *void ) instead of APIgetuart_data(). Briefly: APIsetcallbackuartdata (*function_ptr) ** starts a dedicated task , which is triggered by UART_DATA and calls **function_ptr() . This approach seems more efficient to me. Regards. Giorgio.