Unit Test Strategy

The mutex wrapper isn’t secret at all :slight_smile: I use this wrapper almost without exceptions. The only exceptions are like in a timer callback, where I don’t want to stall the timer task waiting for a mutex. Then I return immediately if the mutex could not be taken.


/**
 * Class for locking and unlocking mutex. Simply add an instance of CicMutex
 * in a function to lock a semaphore, and it will be automatically unlocked by
 * CicMutex's destructor.
 */

class CicMutex
{
    public:
        /**
         * Constructor which locks a mutex.
         *
         * @param[in]   mutex   Mutex to lock and unlock
         */
        explicit CicMutex(SemaphoreHandle_t mutex) : m_mutex(mutex)
        {
            CIC_ASSERT(mutex != nullptr);
            xSemaphoreTake(mutex, portMAX_DELAY);
        }
        /**
         * Destructor, which unlocks the semaphore given in the constructor.
         */
        ~CicMutex()
        {
            xSemaphoreGive(m_mutex);
        }
    private:
        /**
         * Mutex to be unlocked by destructor.
         */
        SemaphoreHandle_t m_mutex;
};

The mutex is created in CicSettings::init() and this is how it is used:



void CicSettings::config()
{
    CicMutex settings_list_mutex = CicMutex(m_os.settings_list_mutex);
    bool is_image_ok = read_settings_image();
    if (is_image_ok)
    {
        read_settings();
    }
    else
    {
        PRINT_ERROR("[%s:%d] CIC Settings image invalid\r\n", __file__, __LINE__);
    }
}