源文件CortexM_StackCheck.c代码如下:
#include "CortexM_StackCheck.h"
#include "myassert.h"
extern void Stack_Mem(void);
extern uint32 __get_MSP(void);
#define CheckKey1 (0x12345678)
#define CheckKey2 (0x89abcdef)
int CortexM_StackCheck( void )
{
static int IsFirstCheck = 1;
int temp = 0;
if(0 != IsFirstCheck)
//第一次执行此函数.
//检查此时此刻是否栈溢出,并在栈底设定检查标志.
{
if(__get_MSP() <= (uint32)Stack_Mem + 8)
//需要使用8字节的检查空间,如果现在就不够了肿么办..
{
return 1;
}
else
//有足够的空间用于填入检查用的数据.
{
//填入数据
*((int32*)Stack_Mem + 0) = CheckKey1;
*((int32*)Stack_Mem + 1) = CheckKey2;
//标记已经填入了数据,以后就不来这里玩了.
IsFirstCheck = 0;
//OK
return 0;
}
}
else
//前面已经埋下了好东西,看看还在不在...
{
if(CheckKey1 != *((int32*)Stack_Mem + 0)
|| CheckKey2 != *((int32*)Stack_Mem + 1))
//好东西不在了...
{
return 1;
}
else
//东西还在哈哈哈..
{
return 0;
}
}
}
头文件CortexM_StackCheck.h代码如下:
#ifndef _CortexM_StackCheck_h_
#define _CortexM_StackCheck_h_
#include "type.h"
#ifdef __cplusplus
extern "C"{
#endif
#if 0
在startup_stmxxxxxxxx.s里增加下面的语句,把栈起始地址搞出来
EXPORT Stack_Mem
#endif
//初始化栈底,栈底空间作为测试空间.
//需要导出Stack_Mem.
//Stack_Mem是栈底.
//需要吃 8 bytes的空间,分配栈时要注意这个值.
//栈太小时,调用这个函数的时候已经过了爆栈,并且不回到原位置,
//检查是无效的,因为栈指针已经在后面捣乱了.
//检查栈底是否被改写,改写了就1.
//检查正确返回0.
int CortexM_StackCheck(void);
#ifdef __cplusplus
}
#endif
#endif
使用时,需要把栈底地址搞出来,比如STM32的官方启动代码里,在汇编里加入
EXPORT Stack_Mem
即可.
代码里偶尔检查检查,可以知道是否出现栈溢出。