Our current project includes FreeRTOS, and I added --use_frame_pointer to Keil uVision's ARMGCC compiler option. But after loading firmware into STM32F104 chip, then runs it, it crashed. Without --use_frame_pointer, everything is OK. The hard fault handler shows that faultStackAddress is 0x40FFFFDC, which points to a reserved area. Does anyone has any idea of this error? Thanks a lot.
#if defined(__CC_ARM)
__asm void HardFault_Handler(void)
{
TST lr, #4
ITE EQ
MRSEQ r0, MSP
MRSNE r0, PSP
B __cpp(Hard_Fault_Handler)
}
#else
void HardFault_Handler(void)
{
__asm("TST lr, #4");
__asm("ITE EQ");
__asm("MRSEQ r0, MSP");
__asm("MRSNE r0, PSP");
__asm("B Hard_Fault_Handler");
}
#endif
void Hard_Fault_Handler(uint32_t *faultStackAddress)
{
}
I stepped into each line of code, and the crash happened in below function in FreeRTOS's port.c after I called vTaskDelete(NULL);
void vPortYieldFromISR( void )
{
/* Set a PendSV to request a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
But seems like this is not the root cause, because when I deleted vTaskDelete(NULL), crash still happened.
[update on Jan 8] sample code
#include "FreeRTOSConfig.h"
#include "FreeRTOS.h"
#include "task.h"
#include <stm32f10x.h>
void crashTask(void *param)
{
unsigned int i = 0;
/* halt the hardware. */
while(1)
{
i += 1;
}
vTaskDelete(NULL);
}
void testCrashTask()
{
xTaskCreate(crashTask, (const signed char *)"crashTask", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
}
void Hard_Fault_Handler(unsigned int *faultStackAddress);
/* The fault handler implementation calls a function called Hard_Fault_Handler(). */
#if defined(__CC_ARM)
__asm void HardFault_Handler(void)
{
TST lr, #4
ITE EQ
MRSEQ r0, MSP
MRSNE r0, PSP
B __cpp(Hard_Fault_Handler)
}
#else
void HardFault_Handler(void)
{
__asm("TST lr, #4");
__asm("ITE EQ");
__asm("MRSEQ r0, MSP");
__asm("MRSNE r0, PSP");
__asm("B Hard_Fault_Handler");
}
#endif
void Hard_Fault_Handler(unsigned int *faultStackAddress)
{
int i = 0;
while(1)
{
i += 1;
}
}
void nvicInit(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
#ifdef VECT_TAB_RAM
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
}
int main()
{
nvicInit();
testCrashTask();
vTaskStartScheduler();
}
/* For now, the stack depth of IDLE has 88 left. if want add func to here,
you should increase it. */
void vApplicationIdleHook(void)
{ /* ATTENTION: all funcs called within here, must not be blocked */
//workerProbe();
}
void debugSendTraceInfo(unsigned int taskNbr)
{
}
When crash happened, in HardFault_Handler, Keil MDK IDE reports below fault information. I looked the STKERR error, which mainly means that stack pointer is corrupted. But I really have no idea why it is corrupted. Without --use_frame_pointer, everything works OK.
[update on Jan 13]
I did further investigation. Seems like the crash is caused by FreeRTOS's default TimerTask. If I comment out the xTimerCreateTimerTask() in vTaskStartScheduler() function(tasks.c), the crash does not happen.
Another odd thing is that if I debug it and step into the TimerTask's portYIELD_WITHIN_API() function call, then resume the application. It does not crash. So my guess is that this might due to certain time sequence. But I could not find the root cause of it.
Any thoughts? Thanks.