【背景】
以下本地 S32K146 的代码,本地使用了malloc 动态申请2KB的内存空间,运行过程中输出了申请内存失败的log,所以才有了该帖子来记录问题的调查过程。
void eeprom_dump(void) { uint8_t * buff = malloc(2048); if(buff != NULL) { /* read data from eeprom */ at24cxxx_eeprom_read(0x00,buff,2048); trace_byte_stream(buff,2048,0); free(buff); } else { LOG_E("Alloc memory failed."); } }
运行该函数会输出对应申请内存失败的log
【调查过程】
申请内存失败,本能反应是堆空间大小不够,造成申请失败2KB的申请也算是大单交易了,本地使用的IAR 环境heap 空间大小在link file(*.icf)里设置,本地查看icf 文件heap 配置大小为1KB,修改icf 配置为4KB
修改后本以为这下应该不会报错了,运行后依然是申请失败,这就有点出乎意料了代码中没事其他地方使用malloc 修改为4KB后理论上空间是足够了,查看链接脚本如果定义了__heap_size__ 符号就会使用定义的size ,所以猜测是不是工程中配置了该符号造成我们修改的配置无效使用的其他的配置。
针对该想法,为了验证上述猜测,我们打开工程文件.ewp 搜索__heap_size__ 符号,果然在工程中有对应的配置
发现使用的工程内部果然配置了该参数,发现在IAR 的link 配置中定义了该符号为0x100,所以造成修改link file 的大小配置是无效的。
有了该结论后,我们查看IAR的编译选项中,也会发现上述的配置
编译的时候会添加 --config_def __heap_size__=0x100,该编译选项IAR 文档中描述如下。
【修改验证】
根据上述调查结论,我们可以修改IDE中 __heap_size__ =0x1000,修改配置后问题得到解决,成功申请到了内存资源不会打印之前的报错信息了。