打印
[MCU]

ARM MCU检测堆栈用量的方法

[复制链接]
860|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
aple0807|  楼主 | 2021-11-3 13:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
分享一个测试工程项目堆栈使用量的方法。
通常由于担心堆栈溢出,我们会给系统配置一个很大的堆栈空间,这样往往会挤占APP部分RAM用量,造成资源浪费,这种情况在小容量MCU中特别明显。如果堆栈实际用量已知,我们可以留一定裕量即可,也无需再担心分配的堆栈是否足够。

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


初始化:必须在main()函数内的首行调用。用于给堆栈内存添加水印。
/*******************************************************************************
* mem_clr define
* \param[in] 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[0]
* \param[in] none
* \retval: none
*******************************************************************************/
void stack_init(void)
{
         volatile  uint32_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[in] 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);
}





  

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

328

帖子

2

粉丝