esp32s2芯片内部有320KB SRAM空间。
一、为何编译app后统计的静态分配空间+heap空间远小于320K?
例如当我们编译完hello world例程后,用idf.py size命令计算出来的static+heap空间总量可能只有188KB左右,比320KB少很多,这是为什么呢?执行idf.py size 命令后输出如下:
Total sizes:
Used stat D/IRAM: 53315 bytes ( 135101 remain, 28.3% used)
.data size: 7224 bytes
.bss size: 2136 bytes
.text size: 42928 bytes
.vectors size: 1027 bytes
Used Flash size : 100795 bytes
.text : 73135 bytes
.rodata : 27404 bytes
Total image size: 151974 bytes (.bin may be padded larger)
从上面的输出可以看出
53315(静态分配空间)+135101(可用heap空间)=大概180KB,剩下的140KB跑哪了?
这是因为在boot阶段,mcu内部的rom程序以及bootloader都会占用大量的ram,可以理解成最多会占用140KB。所以我们在编译app时只会看到180KB左右。
二、难道我们只能在app中用180KB空间?
并不是的。先说结论:实际上在App中,编译静态分配空间50KB左右,Heap可用空间会有250KB。解释如下:
app在启动之后会回收之前在Boot阶段rom程序以及bootloader都会占用大量的ram(约140KB),并将回收的空间加入到heap空间中。所以在app进入app_main()后,调用esp_get_minimum_free_heap_size()函数可以看到可用的heap空间竟能够达到250KB,并不是在编译时统计所得的135101字节。
至于上面为什么不是270KB而是250KB,是因为进入app_main()前初始化Freertos的statck空间以及其他事项也会从270KB Heap空间中瓜分掉20KB左右的空间,故还剩250KB。
三、建议:程序中大空间的数组分配最好通过malloc从Heap中分配,不要通过编译静态分配
这是因为ESP32S2官方文档中给出如下说明:
Due to a technical limitation, the maximum statically allocated DRAM usage is 160KB. The remaining 160KB (for a total of 320KB of DRAM) can only be allocated at runtime as heap.
所以当我们需要在程序中申请一个全局变量的大数组时,最好用如下方法:
uint8_t *array;
array = (uint8_t *)malloc(90*1024);