I have been developing control software based on FreeRTOS operating system. From the timing point of view the software can be divided into two loops.
The first execution loop (fast loop (FL)) is invoked with period 100 us at the end of analogue-digital conversion. The second execution loop (slow loop (SL)) is invoked after each fourth execution of fast loop. So the timing of the control software can be described by following timing diagram
I need to ensure consistency of data shared between fast and slow loop. The slow loop has to use during its whole execution time the data values valid at the end of fourth execution of the fast loop.
I have been thinking about how to ensure the above mentioned consistency of data. My first idea is to use some global variable (let´s say mutex
)
typedef enum
{
SLOW_LOOP_RUNNING,
SLOW_LOOP_WAITING
}MutexState
MutexState mutex;
which will be used in atomic manner. For example in case the slow loop starts its calculation it at first executes
mutex = SLOW_LOOP_RUNNING;
At the end of slow loop execution it executes
mutex = SLOW_LOOP_WAITING;
The fast loop monitors always the status of the mutex
variable and in case it finds out that the mutex contains SLOW_LOOP_RUNNING
value it doesn´t overwrite the shared variables. I think that this could work but I don´t like the global variable. Does anybody have better idea how to resolve that? Thanks in advance for any suggestions.
If the data is small, I'd just send/copy it. Especially if you're already using fork()
, you can use pipes (ex). Where your fast loop, on every 4th cycle, can write(buf)
the data to the pipe fd, and the slow loop then read(buf)
from it. Even better, if you only want to run the slow loop cycle after you've received data from the 4th fast loop cycle, you can select()
to only run the slow loop function when there is data to read from the pipe. This approach, vs mutexes, should be cleaner & less error prone, avoiding the data race entirely; allowing you to treat the slow loop task as a purely functional task.