aple0807 发表于 2021-11-3 13:49

ARM MCU检测堆栈用量的方法

分享一个测试工程项目堆栈使用量的方法。
通常由于担心堆栈溢出,我们会给系统配置一个很大的堆栈空间,这样往往会挤占APP部分RAM用量,造成资源浪费,这种情况在小容量MCU中特别明显。如果堆栈实际用量已知,我们可以留一定裕量即可,也无需再担心分配的堆栈是否足够。

下面介绍具体的方法
==================================================================================================================================
首先定义中断向量表位置和堆栈大小。
向量表位置一般是ROM区首地址,实际项目有变动应保持一直。堆栈大小和启动文件中的stack_size值应相同。
/*******************************************************************************
* stack infomation
*******************************************************************************/
#define VECT_ADDR                              0x8000000
#define STACK_SIZE                              0x400


初始化:必须在main()函数内的首行调用。用于给堆栈内存添加水印。
/*******************************************************************************
* mem_clr define
* \param none
* \retval: none
*******************************************************************************/
#define mem_clr(base, size, val)    \
    pdata = (uint32_t*)(base);      \
    Len = (size)/4;               \
    while(Len--)                  \
    {                               \
      *pdata++ = val;             \
    }                               \

#define inpw(port)                (*((volatile unsigned long *)(port)))

/*******************************************************************************
* stack init, keil 进入mian时,SP=Vect
* \param none
* \retval: none
*******************************************************************************/
void stack_init(void)
{
         volatileuint32_t * pdata;
      register uint32_t Len;
      register uint32_t addr;
      
      // stack
      addr = inpw(VECT_ADDR) - STACK_SIZE;
      mem_clr(addr, STACK_SIZE - 0x20, 0xEFEFEFEF);
}



检测已用STACK。原理是检测堆栈初始化时的水印是否被破坏,以此来判定STACK最大使用量。
返回一个千分数。
可以在任意位置调用查看。
/*******************************************************************************
* stack_used
* \param none
* \retval:千分数
*******************************************************************************/
uint16_t stack_used(void)
{
      uint32_t unused = 0;
      uint32_t * pdata;
      register uint32_t ofsset;
      register uint32_t addr;
      
      addr = inpw(VECT_ADDR) - STACK_SIZE;
      pdata = (uint32_t *)addr;
               
      for(ofsset =0; ofsset < STACK_SIZE; ofsset+=4)
      {
                if(0xEFEFEFEF == *pdata++)
                {
                        unused += 4;
                }
                else
                {
                        break;
                }
      }
      
      return         (1000 - unused * 1000 / STACK_SIZE);
}





页: [1]
查看完整版本: ARM MCU检测堆栈用量的方法