今天有个程序要定义两个大数组,一个32k,一个16k。直接编译的话发现通不过,大概是提示空间不够。因为两个数组就占了48k,可是我的STM32L431CB有64k的RAM,怎么会不够呢?查了资料发现这个芯片的SRAM分为两块,一个48k,一个16k,这个从keil软件上也能看出来:
这样我直接定义两个大数组的话,都分配在SRAM1里面,就会提示内存不够。
库函数有个功能可以指定某个变量的存放地址,这里就用到了这个功能,我将16k的数组直接定义到SRAM2的起始地址去,这样不就可以了吗?代码如下:
float Mag[ADC_SAMPLES_NUMBERS/2] __attribute__((section(".ARM.__at_0x10000000")));
//编译后提示
TS.axf: Error: L6220E: Execution region RW_IRAM2 size (17688 bytes) exceeds limit (16384 bytes). Region contains 4 bytes of padding and 0 bytes of veneers (total 4 bytes of linker generated content).
明明数组只有16k,但是编译后显示有17k多点的内容,这样SRAM2又放不下了。打开map文件查看编译后各变量的地址:
可以看到Mag数组确实是从SDRAM2的起始地址开始了,并占用了16k的大小。但是后面又有一堆的变量也编译到SDRAM2后面的地址,这样就编译出错了。
我们只需要在keil里面将RAM2勾掉,这样keil在编译的时候默认将变量都分配在RAM1里面,遇到__attribute__((section(".ARM.__at_0x10000000")))时,再将这个变量分配到RAM1去。
这样就编译通过了。