| Keil编译项目,如果使用微库MicroLIB,就可以使用malloc。微库内部位置一个堆管理模块。 芯片的RAM大小是固定了的,前面分为全局变量,后面分给堆和栈,这是一般开发方式。
 但是我们在开发项目的过程中,市场遇到各种各样问题,栈穿透到堆里面,或者堆不够大,相当烦人!
 有时候就在想,何不让全局变量以外的所有RAM给堆栈共用?
 因为堆从低到高分配,而栈从高到低分配,理论上是可行的!
 
 但是堆的分配由__heap_base和__heap_limit两个标签决定,不是变量又不能改!
 
 因为我们使用很多种芯片,每一种芯片的RAM大小都有可能不同。
 而SmartOS追求跨平台,不想为不同芯片做太多设置。
 之前我们已经实现了通过修改MSP把栈顶移到RAM最高处,这样子栈可以得到最大利用!
 但是堆还是不好搞!
 
 今晚再次遇到堆不够用的情况,__heap_limit如果分配过大,在小容量芯片就会出错。
 忍无可忍,决定分析一下微库是怎么管理堆的。
 
 首先打开项目编译后生成的链接地址映射文件Linker Address Map,我们这里是SmartOSF0_Debug.map
 找到符号表段Global Symbols
 __heap_base                              0x200005a0   Data           0  startup_stm32f0xx.o(HEAP)
 __heap_limit                             0x200005a0   Data           0  startup_stm32f0xx.o(HEAP)
 __initial_sp                             0x200005c0   Data           0  startup_stm32f0xx.o(STACK)
 从这里可以看出,堆栈已经分配好了。
 
 
 堆分配使用的是malloc函数,上图找到它位于Keil库文件mc_p.l中
 我的目录是D:\Keil\ARM\ARMCC\lib\armlib
 
 轮到法宝IDA上阵,选择malloc.o,太简单了,只有malloc/free两个函数
 汇编图形界面如下:
 
 
 手头的IDA没有ARM插件,否则一个F5就可以得到malloc的C源代码。
 好好工作赚钱卖ARM插件吧。。。
 
 没有工具辅助,那就自己来写吧!
 
 
 上面是手工写的C代码,被注释的是最原始的汇编写法,然后逐步精简优化。
 大概摸清楚了malloc的机制,关键点在于初始化那里,用到了__heap_limit
 而__heap_limit作为常量被编译到Flash里面去了,内存里面无法动态修改。
 实在没办法,只好字节写代码来接替它初始化整个堆了。
 
 
 |