Skip to content

Commit c36674e

Browse files
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 #14222
1 parent 02cd025 commit c36674e

File tree

1 file changed

+42
-65
lines changed

1 file changed

+42
-65
lines changed

components/freertos/esp_additions/idf_additions.c

Lines changed: 42 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,44 @@
8181

8282
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
8383

84-
static void prvTaskDeleteWithCapsTask( void * pvParameters )
84+
static void prvTaskDeleteWithCaps( TaskHandle_t xTaskToDelete )
8585
{
86-
TaskHandle_t xTaskToDelete = ( TaskHandle_t ) pvParameters;
86+
/* Return value unused if asserts are disabled */
87+
BaseType_t __attribute__( ( unused ) ) xResult;
88+
StaticTask_t * pxTaskBuffer;
89+
StackType_t * puxStackBuffer;
90+
91+
/* The task to be deleted must not be running.
92+
* So we suspend the task before deleting it. */
93+
vTaskSuspend( xTaskToDelete );
94+
95+
/* Wait for the task to be suspended */
96+
while( eRunning == eTaskGetState( xTaskToDelete ) )
97+
{
98+
taskYIELD();
99+
}
87100

88-
/* The task to be deleted must not be running */
89101
configASSERT( eRunning != eTaskGetState( xTaskToDelete ) );
90102

103+
xResult = xTaskGetStaticBuffers( xTaskToDelete, &puxStackBuffer, &pxTaskBuffer );
104+
configASSERT( xResult == pdTRUE );
105+
configASSERT( puxStackBuffer != NULL );
106+
configASSERT( pxTaskBuffer != NULL );
107+
108+
/* We can delete the task and free the memory buffers. */
109+
vTaskDelete( xTaskToDelete );
110+
111+
/* Free the memory buffers */
112+
heap_caps_free( puxStackBuffer );
113+
vPortFree( pxTaskBuffer );
114+
}
115+
116+
static void prvTaskDeleteWithCapsTask( void * pvParameters )
117+
{
118+
TaskHandle_t xTaskToDelete = ( TaskHandle_t ) pvParameters;
119+
91120
/* Delete the WithCaps task */
92-
vTaskDeleteWithCaps( xTaskToDelete );
121+
prvTaskDeleteWithCaps( xTaskToDelete );
93122

94123
/* Delete the temporary clean up task */
95124
vTaskDelete( NULL );
@@ -98,7 +127,7 @@
98127
void vTaskDeleteWithCaps( TaskHandle_t xTaskToDelete )
99128
{
100129
/* THIS FUNCTION SHOULD NOT BE CALLED FROM AN INTERRUPT CONTEXT. */
101-
/*TODO: Update it to use portASSERT_IF_IN_ISR() instead. (IDF-10540) */
130+
/* TODO: Update it to use portASSERT_IF_IN_ISR() instead. (IDF-10540) */
102131
vPortAssertIfInISR();
103132

104133
TaskHandle_t xCurrentTaskHandle = xTaskGetCurrentTaskHandle();
@@ -151,60 +180,8 @@
151180
}
152181
}
153182

154-
#if ( configNUM_CORES > 1 )
155-
else if( eRunning == eTaskGetState( xTaskToDelete ) )
156-
{
157-
/* The WithCaps task is running on another core.
158-
* We suspend the task first and then delete it. */
159-
vTaskSuspend( xTaskToDelete );
160-
161-
/* Wait for the task to be suspended */
162-
while( eRunning == eTaskGetState( xTaskToDelete ) )
163-
{
164-
portYIELD_WITHIN_API();
165-
}
166-
167-
// Return value unused if asserts are disabled
168-
BaseType_t __attribute__((unused)) xResult;
169-
StaticTask_t * pxTaskBuffer;
170-
StackType_t * puxStackBuffer;
171-
172-
xResult = xTaskGetStaticBuffers( xTaskToDelete, &puxStackBuffer, &pxTaskBuffer );
173-
configASSERT( xResult == pdTRUE );
174-
configASSERT( puxStackBuffer != NULL );
175-
configASSERT( pxTaskBuffer != NULL );
176-
177-
/* Delete the task */
178-
vTaskDelete( xTaskToDelete );
179-
180-
/* Free the memory buffers */
181-
heap_caps_free( puxStackBuffer );
182-
vPortFree( pxTaskBuffer );
183-
}
184-
#endif /* if ( configNUM_CORES > 1 ) */
185-
else
186-
{
187-
/* The WithCaps task is not running and is being deleted
188-
* from another task's context. */
189-
configASSERT( eRunning != eTaskGetState( xTaskToDelete ) );
190-
191-
// Return value unused if asserts are disabled
192-
BaseType_t __attribute__((unused)) xResult;
193-
StaticTask_t * pxTaskBuffer;
194-
StackType_t * puxStackBuffer;
195-
196-
xResult = xTaskGetStaticBuffers( xTaskToDelete, &puxStackBuffer, &pxTaskBuffer );
197-
configASSERT( xResult == pdTRUE );
198-
configASSERT( puxStackBuffer != NULL );
199-
configASSERT( pxTaskBuffer != NULL );
200-
201-
/* We can delete the task and free the memory buffers. */
202-
vTaskDelete( xTaskToDelete );
203-
204-
/* Free the memory buffers */
205-
heap_caps_free( puxStackBuffer );
206-
vPortFree( pxTaskBuffer );
207-
} /* if( ( xTaskToDelete == NULL ) || ( xTaskToDelete == xCurrentTaskHandle ) ) */
183+
/* Delete the WithCaps task */
184+
prvTaskDeleteWithCaps( xTaskToDelete );
208185
}
209186

210187
#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
@@ -262,8 +239,8 @@
262239

263240
void vQueueDeleteWithCaps( QueueHandle_t xQueue )
264241
{
265-
// Return value unused if asserts are disabled
266-
BaseType_t __attribute__((unused)) xResult;
242+
/* Return value unused if asserts are disabled */
243+
BaseType_t __attribute__( ( unused ) ) xResult;
267244
StaticQueue_t * pxQueueBuffer;
268245
uint8_t * pucQueueStorageBuffer;
269246

@@ -335,8 +312,8 @@
335312

336313
void vSemaphoreDeleteWithCaps( SemaphoreHandle_t xSemaphore )
337314
{
338-
// Return value unused if asserts are disabled
339-
BaseType_t __attribute__((unused)) xResult;
315+
/* Return value unused if asserts are disabled */
316+
BaseType_t __attribute__( ( unused ) ) xResult;
340317
StaticSemaphore_t * pxSemaphoreBuffer;
341318

342319
/* Retrieve the buffer used to create the semaphore before deleting it
@@ -408,8 +385,8 @@
408385
void vStreamBufferGenericDeleteWithCaps( StreamBufferHandle_t xStreamBuffer,
409386
BaseType_t xIsMessageBuffer )
410387
{
411-
// Return value unused if asserts are disabled
412-
BaseType_t __attribute__((unused)) xResult;
388+
/* Return value unused if asserts are disabled */
389+
BaseType_t __attribute__( ( unused ) ) xResult;
413390
StaticStreamBuffer_t * pxStaticStreamBuffer;
414391
uint8_t * pucStreamBufferStorageArea;
415392

0 commit comments

Comments
 (0)