فهرست منبع

Mutex static create. Handle rt_mutex_create failure. Add mutex static test.

tangzz98 3 سال پیش
والد
کامیت
05342a97f4
5فایلهای تغییر یافته به همراه148 افزوده شده و 24 حذف شده
  1. 9 4
      FreeRTOS/include/FreeRTOS.h
  2. 1 1
      FreeRTOS/include/semphr.h
  3. 22 16
      FreeRTOS/queue.c
  4. 2 3
      test/test_mutex_dynamic.c
  5. 114 0
      test/test_mutex_static.c

+ 9 - 4
FreeRTOS/include/FreeRTOS.h

@@ -1114,14 +1114,19 @@
 
 typedef struct
 {
+    struct rt_ipc_object *rt_ipc;
+    struct rt_mailbox ipc_obj;
+} StaticQueue_t;
+
+typedef struct
+{
+    struct rt_ipc_object *rt_ipc;
     union
     {
-        struct rt_mailbox mailbox;
         struct rt_semaphore semaphore;
         struct rt_mutex mutex;
-    } u;
-} StaticQueue_t;
-typedef StaticQueue_t StaticSemaphore_t;
+    } ipc_obj;
+} StaticSemaphore_t;
 
 /* *INDENT-OFF* */
 #ifdef __cplusplus

+ 1 - 1
FreeRTOS/include/semphr.h

@@ -363,7 +363,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
  * \ingroup Semaphores
  */
 #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
-    #define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore )    xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore )
+    #define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore )    xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, ( StaticQueue_t * )pxStaticSemaphore )
 #endif /* configSUPPORT_STATIC_ALLOCATION */
 
 /**

+ 22 - 16
FreeRTOS/queue.c

@@ -47,8 +47,7 @@ static volatile rt_uint8_t mutex_index = 0;
 
 /*-----------------------------------------------------------*/
 
-#if 0
-//#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
 
     QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength,
                                              const UBaseType_t uxItemSize,
@@ -67,16 +66,17 @@ static volatile rt_uint8_t mutex_index = 0;
             ( !( ( pucQueueStorage != NULL ) && ( uxItemSize == 0 ) ) ) &&
             ( !( ( pucQueueStorage == NULL ) && ( uxItemSize != 0 ) ) ) )
         {
-            /* The address of a statically allocated queue was passed in, use it.
-             * The address of a statically allocated storage area was also passed in
-             * but is already set. */
-            pxNewQueue = ( Queue_t * ) pxStaticQueue; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
-
             if ( ( ucQueueType == queueQUEUE_TYPE_RECURSIVE_MUTEX ) )
             {
                 rt_snprintf( name, RT_NAME_MAX - 1, "mutex%02d", mutex_index++ );
-                rt_mutex_init( ( rt_mutex_t ) &pxNewQueue->u.mutex, name, RT_IPC_FLAG_PRIO );
+                rt_mutex_init( ( rt_mutex_t ) &( ( StaticSemaphore_t * ) pxStaticQueue )->ipc_obj.mutex, name, RT_IPC_FLAG_PRIO );
+            }
+            else
+            {
+                return pxNewQueue;
             }
+            pxStaticQueue->rt_ipc = ( struct rt_ipc_object * ) &pxStaticQueue->ipc_obj;
+            pxNewQueue = ( QueueHandle_t ) pxStaticQueue;
         }
 
         return pxNewQueue;
@@ -93,6 +93,7 @@ static volatile rt_uint8_t mutex_index = 0;
     {
         Queue_t * pxNewQueue = NULL;
         char name[RT_NAME_MAX] = {0};
+        struct rt_ipc_object * pipc = RT_NULL;
 
         if( ( uxQueueLength > ( UBaseType_t ) 0 ) &&
             /* Check for multiplication overflow. */
@@ -100,16 +101,22 @@ static volatile rt_uint8_t mutex_index = 0;
             /* Check for addition overflow. */
             ( ( SIZE_MAX - sizeof( Queue_t ) ) >= ( uxQueueLength * uxItemSize ) ) )
         {
+            pxNewQueue = ( Queue_t * ) RT_KERNEL_MALLOC( sizeof( Queue_t ) );
+            if ( pxNewQueue == NULL )
+            {
+                return ( QueueHandle_t ) pxNewQueue;
+            }
             if ( ucQueueType == queueQUEUE_TYPE_RECURSIVE_MUTEX )
             {
                 rt_snprintf( name, RT_NAME_MAX - 1, "mutex%02d", mutex_index++ );
-                pxNewQueue = (Queue_t *) RT_KERNEL_MALLOC( sizeof( Queue_t ) );
-                if ( pxNewQueue == NULL)
-                {
-                    return ( QueueHandle_t ) pxNewQueue;
-                }
-                pxNewQueue->rt_ipc = ( struct rt_ipc_object * ) rt_mutex_create( name, RT_IPC_FLAG_PRIO );
+                pipc = ( struct rt_ipc_object * ) rt_mutex_create( name, RT_IPC_FLAG_PRIO );
+            }
+            if ( pipc == RT_NULL )
+            {
+                RT_KERNEL_FREE( pxNewQueue );
+                return NULL;
             }
+            pxNewQueue->rt_ipc = pipc;
         }
 
         return ( QueueHandle_t ) pxNewQueue;
@@ -132,8 +139,7 @@ static volatile rt_uint8_t mutex_index = 0;
 #endif /* configUSE_MUTEXES */
 /*-----------------------------------------------------------*/
 
-#if 0
-//#if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
+#if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
 
     QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType,
                                            StaticQueue_t * pxStaticQueue )

+ 2 - 3
test/test_mutex.c → test/test_mutex_dynamic.c

@@ -27,7 +27,6 @@
 
 /* mutex handler */
 static SemaphoreHandle_t dynamic_mutex = RT_NULL;
-StaticSemaphore_t xMutexBuffer;
 static rt_uint8_t number1, number2 = 0;
 
 ALIGN(RT_ALIGN_SIZE)
@@ -80,7 +79,7 @@ static void rt_thread_entry2(void *parameter)
 }
 
 /* 互斥量示例的初始化 */
-int mutex_sample(void)
+int mutex_dynamic(void)
 {
     /* 创建一个动态互斥量 */
     dynamic_mutex = xSemaphoreCreateRecursiveMutex();
@@ -111,4 +110,4 @@ int mutex_sample(void)
 }
 
 /* 导出到 msh 命令列表中 */
-MSH_CMD_EXPORT(mutex_sample, mutex sample);
+MSH_CMD_EXPORT(mutex_dynamic, mutex sample);

+ 114 - 0
test/test_mutex_static.c

@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-08-24     yangjie      the first version
+ * 2020-10-17     Meco Man     translate to English comment
+ */
+
+/*
+ * Demo: mutex(es)
+ *
+ * This demo demonstrates how the mutex manage the shared resource.
+ *
+ * read more:
+ *    https://www.rt-thread.io/document/site/thread-sync/thread-sync/#mutex
+ */
+
+#include <rtthread.h>
+#include <FreeRTOS.h>
+#include <semphr.h>
+
+#define THREAD_PRIORITY         8
+#define THREAD_TIMESLICE        5
+
+/* mutex handler */
+static SemaphoreHandle_t static_mutex = RT_NULL;
+StaticSemaphore_t xMutexBuffer;
+static rt_uint8_t number1, number2 = 0;
+
+ALIGN(RT_ALIGN_SIZE)
+static char thread1_stack[1024];
+static struct rt_thread thread1;
+static void rt_thread_entry1(void *parameter)
+{
+    while (1)
+    {
+        /* pending the mutex */
+        xSemaphoreTakeRecursive(static_mutex, portMAX_DELAY);
+        /* protect and deal with public variables */
+        number1++;
+        rt_thread_mdelay(10);
+        number2++;
+        if (number1 != number2)
+        {
+            rt_kprintf("not protect.number1 = %d, mumber2 = %d \n", number1, number2);
+        }
+        else
+        {
+            rt_kprintf("mutex protect ,number1 = mumber2 is %d\n", number1);
+        }
+        /* release the mutex */
+        xSemaphoreGiveRecursive(static_mutex);
+
+        if (number1 >= 100)
+        {
+            vSemaphoreDelete(static_mutex);
+            return;
+        }
+    }
+}
+
+ALIGN(RT_ALIGN_SIZE)
+static char thread2_stack[1024];
+static struct rt_thread thread2;
+static void rt_thread_entry2(void *parameter)
+{
+    while (1)
+    {
+        xSemaphoreTakeRecursive(static_mutex, portMAX_DELAY);
+        number1++;
+        number2++;
+        xSemaphoreGiveRecursive(static_mutex);
+
+        if (number1 >= 50)
+            return;
+    }
+}
+
+/* 互斥量示例的初始化 */
+int mutex_static(void)
+{
+    /* 创建一个动态互斥量 */
+    static_mutex = xSemaphoreCreateRecursiveMutexStatic(&xMutexBuffer);
+    if (static_mutex == RT_NULL)
+    {
+        rt_kprintf("create dynamic mutex failed.\n");
+        return -1;
+    }
+
+    rt_thread_init(&thread1,
+                   "thread1",
+                   rt_thread_entry1,
+                   RT_NULL,
+                   &thread1_stack[0],
+                   sizeof(thread1_stack),
+                   THREAD_PRIORITY, THREAD_TIMESLICE);
+    rt_thread_startup(&thread1);
+
+    rt_thread_init(&thread2,
+                   "thread2",
+                   rt_thread_entry2,
+                   RT_NULL,
+                   &thread2_stack[0],
+                   sizeof(thread2_stack),
+                   THREAD_PRIORITY, THREAD_TIMESLICE);
+    rt_thread_startup(&thread2);
+    return 0;
+}
+
+/* 导出到 msh 命令列表中 */
+MSH_CMD_EXPORT(mutex_static, mutex sample);