]> granicus.if.org Git - esp-idf/commitdiff
freertos: check that mutex is released by owner task
authorIvan Grokhotkov <ivan@espressif.com>
Fri, 21 Dec 2018 04:49:33 +0000 (12:49 +0800)
committerbot <bot@espressif.com>
Mon, 11 Mar 2019 14:40:54 +0000 (14:40 +0000)
Mutex type semaphores should be acquired and released by the same task.
Add a check to xQueueGenericSend for this condition.

components/freertos/Kconfig
components/freertos/include/freertos/FreeRTOSConfig.h
components/freertos/queue.c
components/freertos/test/test_freertos_mutex.c [new file with mode: 0644]

index 8ec085e1404955df4e61c9f3381020aa6858c475..8063c266bc9ad01d96be65b5710837d4ab85a4c8 100644 (file)
@@ -419,4 +419,11 @@ menu "FreeRTOS"
             abort the application. This option is also required for GDB backtraces and C++
             exceptions to work correctly inside top-level task functions.
 
+    config FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER
+        bool "Check that mutex semaphore is given by owner task"
+        default y
+        help
+            If enabled, assert that when a mutex semaphore is given, the task giving the
+            semaphore is the task which is currently holding the mutex.
+
 endmenu
index 80185f9e0458df179a2bcc73701c7bdf0d3c4a77..cc6cdad90b9f789b43bc8899f0e299717d09060e 100644 (file)
@@ -314,5 +314,11 @@ extern void vPortCleanUpTCB ( void *pxTCB );
 #endif /* def __ASSEMBLER__ */
 #endif
 
+#if CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER
+#define configCHECK_MUTEX_GIVEN_BY_OWNER    1
+#else
+#define configCHECK_MUTEX_GIVEN_BY_OWNER    0
+#endif
+
 #endif /* FREERTOS_CONFIG_H */
 
index f6b63de5e6b4dcc4afd8ed02ce1bececda7cf58f..eccd1a016a407c6c48a2b26277aa872e8ef1bdf3 100644 (file)
@@ -724,6 +724,12 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
                configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
        }
        #endif
+       #if ( configUSE_MUTEXES == 1 && configCHECK_MUTEX_GIVEN_BY_OWNER == 1)
+       {
+               configASSERT(pxQueue->uxQueueType != queueQUEUE_IS_MUTEX || pxQueue->pxMutexHolder == NULL || xTaskGetCurrentTaskHandle() == pxQueue->pxMutexHolder);
+       }
+       #endif
+
 
 
        /* This function relaxes the coding standard somewhat to allow return
diff --git a/components/freertos/test/test_freertos_mutex.c b/components/freertos/test/test_freertos_mutex.c
new file mode 100644 (file)
index 0000000..5169798
--- /dev/null
@@ -0,0 +1,21 @@
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/semphr.h"
+#include "unity.h"
+#include "esp_ipc.h"
+#include "test_utils.h"
+
+static void mutex_release_task(void* arg)
+{
+    SemaphoreHandle_t mutex = (SemaphoreHandle_t) arg;
+    xSemaphoreGive(mutex);
+    TEST_FAIL_MESSAGE("should not be reached");
+}
+
+TEST_CASE("mutex released not by owner causes an assert", "[freertos][reset=abort,SW_CPU_RESET]")
+{
+    SemaphoreHandle_t mutex = xSemaphoreCreateMutex();
+    xSemaphoreTake(mutex, portMAX_DELAY);
+    xTaskCreate(&mutex_release_task, "mutex_release", 2048, mutex, UNITY_FREERTOS_PRIORITY + 1, NULL);
+    vTaskDelay(1);
+}