System thread

Synchronizing access to shared system resources

With system threading enabled, the system thread and the application thread run in parallel. When both attempt to use the same resource, such as writing a message to Serial, there is no guaranteed order - the message printed by the system and the message printed by the application are arbitrarily interleaved as the RTOS rapidly switches between running a small part of the system code and then the application code. This results in both messages being intermixed.

This can be avoided by acquiring exclusive access to a resource. To get exclusive access to a resource, we can use locks. A lock ensures that only the thread owning the lock can access the resource. Any other thread that tries to use the resource via the lock will not be granted access until the first thread eventually unlocks the resource when it is done.

At present there is only one shared resource that is used by the system and the application - Serial. The system makes use of Serial during listening mode. If the application also makes use of serial during listening mode, then it should be locked before use.

WITH_LOCK

void print_status()
{
    WITH_LOCK(Serial) {
        Serial.print("Current status is:");
            Serial.println(status);
    }
}

The primary difference compared to using Serial without a lock is the WITH_LOCK declaration. This does several things:

  • attempts to acquire the lock for Serial. If the lock isn't available, the thread blocks indefinitely until it is available.

  • once Serial has been locked, the code in the following block is executed.

  • when the block has finished executing, the lock is released, allowing other threads to use the resource.

It's also possible to attempt to lock a resource, but not block when the resource isn't available.

TRY_LOCK

TRY_LOCK(Serial) {
    // this code is only run when no other thread is using Serial
}

The TRY_LOCK() statement functions similarly to WITH_LOCK() but it does not block the current thread if the lock isn't available. Instead, the entire block is skipped over.