Ver código fonte

fix:queue使用的时候需要注意避开OS挂起的状态

alienwalker 3 anos atrás
pai
commit
c13ab8f2b9

+ 1 - 0
bsp/common/include/bsp_common.h

@@ -300,6 +300,7 @@ void OS_MutexRelease(HANDLE Sem);
 void OS_MutexDelete(HANDLE Sem);
 void OS_SuspendTask(HANDLE taskHandle);
 void OS_ResumeTask(HANDLE taskHandle);
+uint8_t OS_IsSchedulerRun(void);
 #endif
 uint32_t OS_EnterCritical(void);
 void OS_ExitCritical(uint32_t Critical);

+ 25 - 2
bsp/common/src/bsp_common.c

@@ -322,13 +322,31 @@ HANDLE OS_MutexCreateUnlock(void)
 
 void OS_MutexLock(HANDLE Sem)
 {
+	uint8_t suspend = !OS_IsSchedulerRun();
+	if (suspend)
+	{
+		xTaskResumeAll();
+	}
 	xSemaphoreTake(Sem, portMAX_DELAY);
-
+	if (suspend)
+	{
+		vTaskSuspendAll();
+	}
 }
 
 int32_t OS_MutexLockWtihTime(HANDLE Sem, uint32_t TimeoutMs)
 {
-	if (pdTRUE != xSemaphoreTake(Sem, TimeoutMs))
+	uint8_t suspend = !OS_IsSchedulerRun();
+	if (suspend)
+	{
+		xTaskResumeAll();
+	}
+	int result = xSemaphoreTake(Sem, TimeoutMs);
+	if (suspend)
+	{
+		vTaskSuspendAll();
+	}
+	if (pdTRUE != result)
 	{
 		return -ERROR_OPERATION_FAILED;
 	}
@@ -361,6 +379,11 @@ void OS_MutexDelete(HANDLE Sem)
 	vSemaphoreDelete(Sem);
 }
 
+uint8_t OS_IsSchedulerRun(void)
+{
+	return (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING);
+}
+
 void OS_SuspendTask(HANDLE taskHandle)
 {
 	if (taskHandle)

+ 8 - 2
os/FreeRTOS_v10/src/tasks.c

@@ -5064,7 +5064,7 @@ TickType_t uxTaskResetEventItemValue( void )
 
             /* If the task is in the blocked state specifically to wait for a
              * notification then unblock it now. */
-            if( ucOriginalNotifyState == taskWAITING_NOTIFICATION )
+            if( (ucOriginalNotifyState == taskWAITING_NOTIFICATION)  && (listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL))
             {
                 /* The task should not have been on an event list. */
                 configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );
@@ -5155,7 +5155,7 @@ TickType_t uxTaskResetEventItemValue( void )
 
             /* If the task is in the blocked state specifically to wait for a
              * notification then unblock it now. */
-            if( ucOriginalNotifyState == taskWAITING_NOTIFICATION )
+            if( (ucOriginalNotifyState == taskWAITING_NOTIFICATION)  && (listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL))
             {
                 /* The task should not have been on an event list. */
                 configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );
@@ -5471,3 +5471,9 @@ void *vTaskGetCurrent(void)
 {
 	return pxCurrentTCB;
 }
+
+uint8_t vTaskIsEventListItemEmpty(TaskHandle_t xHandle)
+{
+	TCB_t * pxTCB = prvGetTCBFromHandle( xHandle );
+	return (listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL);
+}