Hi all,
I’m a beginner to Freertos, and I want to write a function API_get_uart_data() designed as part of a library.
The basic idea is to introduce an abtraction layer architecture in my firmware project.
Summarizing : API_get_uart_data() returns NULL if no data is present on UART port
If a data is present in the queue, **API_get_uart_data() ** returns a pointer to data.
I have already implemented the task HAL_UART_task() which stores in a DATA queue the incoming messages from serial port.
This is a simple usecase:
my_application_task()
{
while (1)
{
if (API_get_uart_data() != NULL )
{
/*do something with the data … */
}
}
}
Now my question:
my_application_task() should be in [SUSPENDED] state until API_get_uart_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:
//
/HAL_UART_task() 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.
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 API_get_uart_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.
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 API_get_uart_data() is called by my_application_task()
A query is sent to AL_UART_task() , providing a pointer for the response
my_application_task() is [SUSPENDED] by API_get_uart_data()
when AL_UART_task() intercepts the query, it updates the provided response pointer and resumes my_application_task()
updated response is returned by API_get_uart_data()
Is this a common architecture design in FreeRTOS?
What could be considered the most reasonable options in order to implement my idea?
Hi Richard, thank you for your suggestion.
I changed my strategy, implementing *API_set_callback_uart_data( void ) instead of API_get_uart_data().
Briefly:
**API_set_callback_uart_data (*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.