嵌入式系统内存使用情况评估方法探究

嵌入式系统内存使用情况评估方法探究

Daniel 2016-7-22

      

        有一段时间没有写过博客了,这段时间抽空做做记录。总结和记录是对知识最好的回忆与升华。

       这段时间遇到MCU程序总是莫名奇妙的跑飞,插上仿真器这样的现象又不会出现,多次怀疑与内存大小有关,但如何才能知道运行中的程序内存的占用情况呢?是不是堆栈使用太多超出了设定的范围?

       所有的疑问最终都定位到malloc函数上,有时候运行malloc就会死机,但有时候又不会。后来又做了一个实验,把这个工程移植到了最新的编译器上就没问题了,还真是奇怪,是不是老编译器的bug导致?

       为了一探究竟,做了以下实验:

         1. 在老的编译器仿真看malloc的执行结果:

       申请18个字节,malloc实际申请为20个字节

       申请34个字节,malloc实际申请为36个字节

         70个字节以下都是正常的。

       在分配72个字节时候, malloc头发生错误,显示分配了0x3FE8个字节即16360个,上下指针也不对

      原来在老编译器对malloc的实现是,Malloc的管理头为16个字节,第一个为实际分配的size大小

      {

      Uint32_t size;

      Uint32_t *pNext;

      Uint32_t  flag;

      Uint32_t *pPre;

     }16个字节

      2. 使用新编译器的测试

     在测试malloc函数时,发现在新老编译器上执行的结果不同:

     新编译器malloc头结构为

     {

      Uint32_t size;

      Uint32_t *pNext;

     },共8个字节

    申请18个字节,malloc实际申请了32个字节

    申请34个字节,malloc实际申请了44个字节

      申请72个字节,malloc实际申请了80个字节

      通过对比问题就显而易见了,老编译器感觉确实有问题,使用新编译器问题也得到了解决。

      那么系统到底使用了多少内存呢?

       我们知道嵌入式系统一般在初始化的时候吧内存分为了“internal ram““head”“stack”。内存排列情况如下图所示:

 

         internal ram主要用于数据段、BSS段;heap中主要存储程序员手动分配的变量,主要是用malloc分配的;stack中存储了临时变量、返回地址、函数参数、中断环境等。

       其实程序在编译完后,程序所占用的flashinternal ram的大小就确定了,可以用memory map中计算得出,而堆栈使用情况就需要计算得出了。

       计算堆剩余空间大小

       结合开始部分对malloc的分析,可以使用malloc分配内存头中的记录来计算使用的大小,当调用free的时候根据内存头中的记录计算释放的大小。

      在系统分配释放内存的函数中添加统计代码:

void * system_alloc(void *allocator_data,  uint32_t size)//size_t

{  

    p=malloc(size);

    if(p)

    {

     malloc_size = (*(unsigned int*)((unsigned char*)p - 8)) + 8; 

    }

    return p;

}

Void system_free(void *allocator_data, void *data)

{

    if(data)

    {

     //根据指针的位置找到分配内存的大小

      free_size = (*(unsigned int*)((unsigned char*)data - 8)) + 8;

    }

       free(data);

}

       统计malloc_size以及free_size就可以了。

     堆的剩余空间为

       Heap_len - (total_malloc_size - total_free_size)

     计算栈空间剩余大小:

    栈空间,在周期中断中定义一个局部变量,分配在栈顶上

uint32_t Stack_sp = 0;

void PIT0_ISR(void)

{   uint8_t test = 0;

    Stack_sp = (uint32_t *)&test;

    PIT.CH[0].TFLG.B.TIF = 1;

}

栈的剩余空间大致为 stack_len-stack_org - Stack_sp

Internal RAM剩余空间大小(数据段、BSS段等)

internal_ram_len – (internal_ram_org - internal_ram_sp)

internal_ram_sp:在MAP文件中可以计算得到

剩余的总RAM = 剩余heap+剩余stack+剩余Internal RAM

剩余的总flash = flash_size – 使用的flashMAP中可以计算得到)

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值