mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
fix(freertos): Fixed assert failure in vTaskDeleteWithCaps
This commit fixes an assert failure in vTaskDeleteWithCaps() when multiple un-pinned tasks are created with stack in the external memory and such tasks delete themselves. Closes https://github.com/espressif/esp-idf/issues/14222
This commit is contained in:
parent
02cd0253a1
commit
c36674eaa8
@ -81,15 +81,44 @@ err:
|
|||||||
|
|
||||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
|
||||||
|
static void prvTaskDeleteWithCaps( TaskHandle_t xTaskToDelete )
|
||||||
|
{
|
||||||
|
/* Return value unused if asserts are disabled */
|
||||||
|
BaseType_t __attribute__( ( unused ) ) xResult;
|
||||||
|
StaticTask_t * pxTaskBuffer;
|
||||||
|
StackType_t * puxStackBuffer;
|
||||||
|
|
||||||
|
/* The task to be deleted must not be running.
|
||||||
|
* So we suspend the task before deleting it. */
|
||||||
|
vTaskSuspend( xTaskToDelete );
|
||||||
|
|
||||||
|
/* Wait for the task to be suspended */
|
||||||
|
while( eRunning == eTaskGetState( xTaskToDelete ) )
|
||||||
|
{
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
|
||||||
|
configASSERT( eRunning != eTaskGetState( xTaskToDelete ) );
|
||||||
|
|
||||||
|
xResult = xTaskGetStaticBuffers( xTaskToDelete, &puxStackBuffer, &pxTaskBuffer );
|
||||||
|
configASSERT( xResult == pdTRUE );
|
||||||
|
configASSERT( puxStackBuffer != NULL );
|
||||||
|
configASSERT( pxTaskBuffer != NULL );
|
||||||
|
|
||||||
|
/* We can delete the task and free the memory buffers. */
|
||||||
|
vTaskDelete( xTaskToDelete );
|
||||||
|
|
||||||
|
/* Free the memory buffers */
|
||||||
|
heap_caps_free( puxStackBuffer );
|
||||||
|
vPortFree( pxTaskBuffer );
|
||||||
|
}
|
||||||
|
|
||||||
static void prvTaskDeleteWithCapsTask( void * pvParameters )
|
static void prvTaskDeleteWithCapsTask( void * pvParameters )
|
||||||
{
|
{
|
||||||
TaskHandle_t xTaskToDelete = ( TaskHandle_t ) pvParameters;
|
TaskHandle_t xTaskToDelete = ( TaskHandle_t ) pvParameters;
|
||||||
|
|
||||||
/* The task to be deleted must not be running */
|
|
||||||
configASSERT( eRunning != eTaskGetState( xTaskToDelete ) );
|
|
||||||
|
|
||||||
/* Delete the WithCaps task */
|
/* Delete the WithCaps task */
|
||||||
vTaskDeleteWithCaps( xTaskToDelete );
|
prvTaskDeleteWithCaps( xTaskToDelete );
|
||||||
|
|
||||||
/* Delete the temporary clean up task */
|
/* Delete the temporary clean up task */
|
||||||
vTaskDelete( NULL );
|
vTaskDelete( NULL );
|
||||||
@ -98,7 +127,7 @@ err:
|
|||||||
void vTaskDeleteWithCaps( TaskHandle_t xTaskToDelete )
|
void vTaskDeleteWithCaps( TaskHandle_t xTaskToDelete )
|
||||||
{
|
{
|
||||||
/* THIS FUNCTION SHOULD NOT BE CALLED FROM AN INTERRUPT CONTEXT. */
|
/* THIS FUNCTION SHOULD NOT BE CALLED FROM AN INTERRUPT CONTEXT. */
|
||||||
/*TODO: Update it to use portASSERT_IF_IN_ISR() instead. (IDF-10540) */
|
/* TODO: Update it to use portASSERT_IF_IN_ISR() instead. (IDF-10540) */
|
||||||
vPortAssertIfInISR();
|
vPortAssertIfInISR();
|
||||||
|
|
||||||
TaskHandle_t xCurrentTaskHandle = xTaskGetCurrentTaskHandle();
|
TaskHandle_t xCurrentTaskHandle = xTaskGetCurrentTaskHandle();
|
||||||
@ -151,60 +180,8 @@ err:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ( configNUM_CORES > 1 )
|
/* Delete the WithCaps task */
|
||||||
else if( eRunning == eTaskGetState( xTaskToDelete ) )
|
prvTaskDeleteWithCaps( xTaskToDelete );
|
||||||
{
|
|
||||||
/* The WithCaps task is running on another core.
|
|
||||||
* We suspend the task first and then delete it. */
|
|
||||||
vTaskSuspend( xTaskToDelete );
|
|
||||||
|
|
||||||
/* Wait for the task to be suspended */
|
|
||||||
while( eRunning == eTaskGetState( xTaskToDelete ) )
|
|
||||||
{
|
|
||||||
portYIELD_WITHIN_API();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return value unused if asserts are disabled
|
|
||||||
BaseType_t __attribute__((unused)) xResult;
|
|
||||||
StaticTask_t * pxTaskBuffer;
|
|
||||||
StackType_t * puxStackBuffer;
|
|
||||||
|
|
||||||
xResult = xTaskGetStaticBuffers( xTaskToDelete, &puxStackBuffer, &pxTaskBuffer );
|
|
||||||
configASSERT( xResult == pdTRUE );
|
|
||||||
configASSERT( puxStackBuffer != NULL );
|
|
||||||
configASSERT( pxTaskBuffer != NULL );
|
|
||||||
|
|
||||||
/* Delete the task */
|
|
||||||
vTaskDelete( xTaskToDelete );
|
|
||||||
|
|
||||||
/* Free the memory buffers */
|
|
||||||
heap_caps_free( puxStackBuffer );
|
|
||||||
vPortFree( pxTaskBuffer );
|
|
||||||
}
|
|
||||||
#endif /* if ( configNUM_CORES > 1 ) */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* The WithCaps task is not running and is being deleted
|
|
||||||
* from another task's context. */
|
|
||||||
configASSERT( eRunning != eTaskGetState( xTaskToDelete ) );
|
|
||||||
|
|
||||||
// Return value unused if asserts are disabled
|
|
||||||
BaseType_t __attribute__((unused)) xResult;
|
|
||||||
StaticTask_t * pxTaskBuffer;
|
|
||||||
StackType_t * puxStackBuffer;
|
|
||||||
|
|
||||||
xResult = xTaskGetStaticBuffers( xTaskToDelete, &puxStackBuffer, &pxTaskBuffer );
|
|
||||||
configASSERT( xResult == pdTRUE );
|
|
||||||
configASSERT( puxStackBuffer != NULL );
|
|
||||||
configASSERT( pxTaskBuffer != NULL );
|
|
||||||
|
|
||||||
/* We can delete the task and free the memory buffers. */
|
|
||||||
vTaskDelete( xTaskToDelete );
|
|
||||||
|
|
||||||
/* Free the memory buffers */
|
|
||||||
heap_caps_free( puxStackBuffer );
|
|
||||||
vPortFree( pxTaskBuffer );
|
|
||||||
} /* if( ( xTaskToDelete == NULL ) || ( xTaskToDelete == xCurrentTaskHandle ) ) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
|
#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
|
||||||
@ -262,8 +239,8 @@ err:
|
|||||||
|
|
||||||
void vQueueDeleteWithCaps( QueueHandle_t xQueue )
|
void vQueueDeleteWithCaps( QueueHandle_t xQueue )
|
||||||
{
|
{
|
||||||
// Return value unused if asserts are disabled
|
/* Return value unused if asserts are disabled */
|
||||||
BaseType_t __attribute__((unused)) xResult;
|
BaseType_t __attribute__( ( unused ) ) xResult;
|
||||||
StaticQueue_t * pxQueueBuffer;
|
StaticQueue_t * pxQueueBuffer;
|
||||||
uint8_t * pucQueueStorageBuffer;
|
uint8_t * pucQueueStorageBuffer;
|
||||||
|
|
||||||
@ -335,8 +312,8 @@ err:
|
|||||||
|
|
||||||
void vSemaphoreDeleteWithCaps( SemaphoreHandle_t xSemaphore )
|
void vSemaphoreDeleteWithCaps( SemaphoreHandle_t xSemaphore )
|
||||||
{
|
{
|
||||||
// Return value unused if asserts are disabled
|
/* Return value unused if asserts are disabled */
|
||||||
BaseType_t __attribute__((unused)) xResult;
|
BaseType_t __attribute__( ( unused ) ) xResult;
|
||||||
StaticSemaphore_t * pxSemaphoreBuffer;
|
StaticSemaphore_t * pxSemaphoreBuffer;
|
||||||
|
|
||||||
/* Retrieve the buffer used to create the semaphore before deleting it
|
/* Retrieve the buffer used to create the semaphore before deleting it
|
||||||
@ -408,8 +385,8 @@ err:
|
|||||||
void vStreamBufferGenericDeleteWithCaps( StreamBufferHandle_t xStreamBuffer,
|
void vStreamBufferGenericDeleteWithCaps( StreamBufferHandle_t xStreamBuffer,
|
||||||
BaseType_t xIsMessageBuffer )
|
BaseType_t xIsMessageBuffer )
|
||||||
{
|
{
|
||||||
// Return value unused if asserts are disabled
|
/* Return value unused if asserts are disabled */
|
||||||
BaseType_t __attribute__((unused)) xResult;
|
BaseType_t __attribute__( ( unused ) ) xResult;
|
||||||
StaticStreamBuffer_t * pxStaticStreamBuffer;
|
StaticStreamBuffer_t * pxStaticStreamBuffer;
|
||||||
uint8_t * pucStreamBufferStorageArea;
|
uint8_t * pucStreamBufferStorageArea;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user