Search code examples
cembeddedtaskdata-synchronization

How to ensure consistency of data between two execution loops


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

enter image description here

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.


Solution

  • 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.