During the last dozen or so posts, we have been discussing how to use the real-time operating system ThreadX® within the Renesas Synergy™ Platform. The basics on how to setup a task, synchronize tasks and even common issues have been discussed. In today’s final post on transitioning to ThreadX, we are going to look at an advanced technique known as event chaining that is only available in ThreadX.
Event chaining provides a developer with a technique for easily handling threads that rely upon multiple objects in order to continue execution. There are several advantages that a developer can gain from using event chaining such as:
Setting up an event chain is a multistep process but it isn’t really all that complicated. We will look at an example shortly but first let’s examine the general process that a developer should follow. There are three steps that are required in the process.
Let’s look at a simple example where a queue is event chained.
The first step for the developer is to create the objects that will be used in the event. For a queue event chain, a developer would create a queue and semaphore using the Synergy Configurator. To review how this can be done, see Transitioning to ThreadX: Semaphores and Transitioning to ThreadX: Message Queues. Once this has been done, a developer can look through their generated thread source and find that they have declared objects according to the name they provided such as:
TX_SEMAPHORE g_gatekeeper;
TX_QUEUE g_eventQueue;
The developer will need to go into their thread_entry.c module for their desired thread and create a variable to hold the g_eventQueue message and also the callback function. For example, a developer could write the following variable and prototype code:
ULONG my_message[4];
void queue_notify(TX_QUEUE *my_queue);
Don’t forget that the callback function needs to be registered! In the thread initialization code, a developer will need to call queue_notify and provide it with the desired queue. For example, the following code would be added to the initialization:
tx_queue_send_notify(&g_eventQueue, queue_notify);
The above code is telling ThreadX that when a message is placed into g_eventQueue then immediately the queue_notify function will called. At this point; however, we have not filled in the details for queue_notify which is the second step in the process. In this example, the notification function would look similar to the following:
void queue_notify(TX_QUEUE *my_queue)
{
tx_semaphore_put(&gatekeeper);
}
Now when the queue receives a message, queue_notify will immediately be called through the callback function and the gatekeeper semaphore will signal the desired thread. This brings us to the final and third step, making sure that our thread waits on the gatekeeper semaphore. This can be done by adding the following code to our thread:
tx_semaphore_get(&gatekeeper, TX_WAIT_FOREVER);
Now when a message is placed into eventQueue, the callback function queue_notify will be immediately called which will signal any threads waiting for the gatekeeper semaphore that the message has been received and the scheduler can act accordingly.
Event chaining is an advanced technique developers can use to reduce the number of threads and resources needed in their application. Once again it is only useful when there are threads waiting for multiple objects or even multiple threads waiting on a single object that require automatic notification.
I hope that you have enjoyed our series on transitioning to ThreadX. In the next post, we’ll be examining the finer details on how to get the most from the Synergy Platform.
Until next time,
Live long and profit!
Professor_IoT
Hot Tip of the Week
One of the quickest ways to get started with advanced networking applications with NetX is to use the Getting Started with NetX application projects available on the Synergy Tools and Kits Sample Code tab. New ones are being added all the time, so check out the Sample Code page often! Below are the links for the associated application projects.