oprs wrote on Saturday, September 26, 2015:
Hi,
The following code causes FreeRTOS 8.2.2 to crash (Hard Fault observed on STM32):
#include <FreeRTOS.h>
#include <task.h>
static void task( void *x )
{
(void)x;
for( ;; )
vTaskDelay( 1000 / portTICK_RATE_MS );
}
int main( void )
{
TaskHandle_t t1, t2;
(void)xTaskCreate( task, "task1", 128, NULL, 1, &t1 );
(void)xTaskCreate( task, "task2", 128, NULL, 1, &t2 );
vTaskSuspend( t1 );
vTaskResume( t1 ); // <- crash
vTaskStartScheduler();
for( ;; );
}
(This is only a minimal, complete / verifiable example; basically I need to create a bunch of suspended tasks ready to be resumed later on, depending on the state my application finds itself in).
I’ve traced the problem down to vTaskResume(), specifically around line 1443 in tasks.c
/* We may have just resumed a higher priority task. */
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
{
/* This yield may not cause the task just resumed to run,
but will leave the lists in the correct state for the
next yield. */
taskYIELD_IF_USING_PREEMPTION();
}
In my use case above, taskYIELD_IF_USING_PREEMPTION() gets called, eventually leading to a context switch before the scheduler is started which, in turn, leads to…
*** HARD FAULT HANDLER ***
R0: 0x00000000
R1: 0x20006f00
R2: 0x20001ce8
R3: 0x20001ce8
R12: 0xa5a5a5a5
LR: 0x00000000
PC: 0x00000000
PSR: 0x4000000e
BFAR: 0xe000ed38
CFSR: 0x00020000
HFSR: 0x40000000
DFSR: 0x00000009
AFSR: 0x00000000
note: the fact that both PC and LR show as NULL here sure didn’t help tracking down the problem. I didn’t bother investingating much further though, as I’m not familiar enough with FreeRTOS internals to appreciate the possible ramifications of a context switch occuring outside the supervision of the scheduler.
Anyway, the following patch seems to fix the issue for vTaskResume(), but then again I guess other functions (xTaskResumeAll(), and possibly xTaskResumeFromISR()) should be fixed as well.
diff --git a/sat/sys/FreeRTOS/tasks.c b/sat/sys/FreeRTOS/tasks.c
index 2fb4c2f..1534855 100644
--- a/sat/sys/FreeRTOS/tasks.c
+++ b/sat/sys/FreeRTOS/tasks.c
@@ -1439,7 +1439,7 @@ StackType_t *pxTopOfStack;
prvAddTaskToReadyList( pxTCB );
/* We may have just resumed a higher priority task. */
- if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
+ if( ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) && ( xSchedulerRunning != pdFALSE ) )
{
/* This yield may not cause the task just resumed to run,
but will leave the lists in the correct state for the
Does this workaround look reasonable to you guys ? Should I create a ticket about this issue ?
Cheers,
-Olivier.