ARM Cortex-M3因--使用FreeRTOS'造成的"帧"指针而崩溃;s定时器任务

ARM Cortex-M3因--使用FreeRTOS'造成的"帧"指针而崩溃;s定时器任务,arm,embedded,stm32,cortex-m3,freertos,Arm,Embedded,Stm32,Cortex M3,Freertos,我们当前的项目包括FreeRTOS,我添加了--使用Keil uVision的ARMGCC编译器选项的\u frame\u指针。但在将固件加载到STM32F104芯片并运行之后,它崩溃了。如果没有--使用\u frame\u指针,一切都正常。 硬故障处理程序显示faultStackAddress为0x40FFFFDC,它指向保留区域。有人知道这个错误吗?非常感谢 #if defined(__CC_ARM) __asm void HardFault_Handler(void) { TST l

我们当前的项目包括FreeRTOS,我添加了--使用Keil uVision的ARMGCC编译器选项的\u frame\u指针。但在将固件加载到STM32F104芯片并运行之后,它崩溃了。如果没有--使用\u frame\u指针,一切都正常。 硬故障处理程序显示faultStackAddress为0x40FFFFDC,它指向保留区域。有人知道这个错误吗?非常感谢

#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)
{

}
我进入每一行代码,在调用vTaskDelete(NULL)后,FreeRTOS的port.c中的follow函数发生了崩溃

但这似乎不是根本原因,因为当我删除vTaskDelete(NULL)时,崩溃仍然发生

[1月8日更新]示例代码

#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)
{
}
#包括“FreeRTOSConfig.h”
#包括“FreeRTOS.h”
#包括“task.h”
#包括
void崩溃任务(void*param)
{
无符号整数i=0;
/*停止硬件*/
而(1)
{
i+=1;
}
vTaskDelete(空);
}
void testCrashTask()
{
xTaskCreate(crashTask,(常量符号字符*)“crashTask”,配置最小堆栈大小,NULL,1,NULL);
}
无效硬错误处理程序(无符号整数*faultStackAddress);
/*故障处理程序实现调用名为Hard\u fault\u handler()的函数*/
#如果已定义(uuu CC_uarm)
__asm void硬故障处理程序(void)
{
尖沙咀轻铁#4
ITE均衡器
MRSEQ r0,MSP
MRSNE r0,PSP
B\u\u cpp(硬故障处理程序)
}
#否则
无效硬故障处理程序(无效)
{
__asm(“TST lr,#4”);
__asm(“ITE EQ”);
__asm(“MRSEQ r0,MSP”);
__asm(“MRSNE r0,PSP”);
__asm(“B硬故障处理程序”);
}
#恩迪夫
无效硬错误处理程序(无符号int*faultStackAddress)
{
int i=0;
而(1)
{
i+=1;
}
}
无效nvicInit(无效)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
#ifdef矢量选项卡RAM
NVIC_可设置可更改(NVIC_可设置内存,0x0);
#否则
NVIC_设置可更改(NVIC_VectLab_闪存,0x0);
#恩迪夫
}
int main()
{
nvicInit();
testCrashTask();
vTaskStartScheduler();
}
/*目前,空闲的堆栈深度还剩下88。如果要在此处添加func,
你应该增加它*/
void vapplicationdlehook(void)
{/*注意:此处调用的所有函数都不能被阻止*/
//工作服();
}
void debugSendTraceInfo(未签名的int taskNbr)
{
}
当崩溃发生时,在HardFault_处理程序中,Keil MDK IDE报告以下故障信息。我查看了STKERR错误,这主要意味着堆栈指针已损坏。但我真的不知道它为什么会被破坏。如果没有--使用\u frame\u指针,一切正常

[1月13日更新]
我做了进一步的调查。看起来崩溃是由FreeRTOS的默认TimerTask造成的。如果在vTaskStartScheduler()函数(tasks.c)中注释掉xTimerCreateTimerTask(),则不会发生崩溃
另一件奇怪的事情是,如果我调试它并进入TimerTask的portYIELD_in_API()函数调用,然后恢复应用程序。它不会崩溃。所以我猜这可能是由于特定的时间顺序。但我找不到它的根本原因。

有什么想法吗?谢谢。

我在项目中遇到了类似的问题。看来
armcc--use\u frame\u pointer
倾向于生成中断的函数尾声。生成的代码示例如下:

; function prologue
stmdb   sp!, {r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
add.w   r11, sp, #36

; ... actual function code ...

; function epilogue
mov     sp, r11
        ; <--- imagine an interrupt happening here
sub     sp, #36
ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, r10, r11, pc}
;函数序言
stmdb sp!,{r3,r4,r5,r6,r7,r8,r9,r10,r11,lr}
add.w r11,sp,#36
; ... 实际功能代码。。。
; 功能结语
mov sp,r11

; 您是否有明确使用R11的汇编代码?如果我没有调用FreeRTOS某些函数,例如创建任务,那么就没有硬错误。所以我认为r11不应该是根本原因。实际上,我还尝试了另一个没有使用R11的项目,它也崩溃了。我不确定这是否是由于某些编译兼容性问题。我还试图增加FreeRTOS的任务堆栈大小,但仍然崩溃。R7通常是Thumb ABI中的帧指针,不过在这种情况下,我也会怀疑堆栈损坏-一些保存的FP被破坏,然后最终在通过该帧返回时加载回SP,导致不相关的东西崩溃;如果没有帧指针,堆栈布局会略有不同,恶意写入会遇到一些不太重要的问题,如填充字节或使用局部变量完成。@不一样:在Cortex-M上使用的Thumb-2上,它是R11而不是R7。
; function prologue
stmdb   sp!, {r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
add.w   r11, sp, #36

; ... actual function code ...

; function epilogue
mov     sp, r11
        ; <--- imagine an interrupt happening here
sub     sp, #36
ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, r10, r11, pc}