Then, follow through with the interactive lab assignment below.
SESSION 17: LAB ASSIGNMENT
In this lab a mutex will be used to protect the logging that we added in the lab for session 13 on memory services. If you followed through the lab for session 13 you will recall that the Health Task was logging information into Health Records and then copying them onto a queue. When commanded to do so by the user, the UI Task would traverse the queue to read all of the Health Records and print them out. However, a corruption can occur during the time that the UI task is accessing the queue to retrieve and remove the Health Records if, at the same time, the Health Task is trying to add to the queue.The operation of mutexes is quite straight forward as you saw in the video, and given that we don't need to flesh out any more of our application at this stage this is a fairly short lab.
The objective of this lab is to see the operation of a mutex to protect access to a resource, and to see how simple they are to implement.
DECLARING AND INITIALIZING THE MUTEX
Since mutexes are an optional component of MQX you'll need to add the mutex.h include file to main.h.
We'll need global access to our mutex so declare an external variable 'log_mutex' of type MUTEX_STRUCT in main.c where the other global structures are declared, and make this an extern in main.h.
The mutex needs to be initialized which can be done in the Health Task at the same time the queue is initialized (with the _queue_init() function) using the _mutex_init() function. We'll just use the default values so you can use NULL as the mutex attribute struct.
UPDATING THE HEALTH TASK
In the while(1) loop of the Health Task where the LOG_TICK_MESSAGE message types are processed is where the Health Records are added to the queue using the _queue_enqueue() function. Since the job of the mutex is to prevent simultaneous access to the mutex, just before the record is logged is where we want to lock the mutex. And immediately after the Health Record has been added to the queue is where the mutex should be unlocked since we're done accessing the queue for now. Use the _mutex_lock() and _mutex_unlock() functions for this.
UPDATING THE UI TASK
The UI Task traverses the list of Health Records in the queue when the user requests that the logs be printed. This is done in the Shell_log() function. Use the _mutex_lock() and the _mutex_unlock() functions to protect the queue for the entire time that the list is being traversed.
Compile and run your code. You first may want to comment out any periodic print statements. Use the 'log' function in the shell to see a print out of logged Health Records and ensure that a new record was being made every second.
Need more help? The full source code for this lab can be found in the 'Lab Source Code' folder here.