就我们测试的ESP32芯片,可用动态内存有限,设计有520K,可以分配320K,实际可用280K左右(Arduino会占用一部分),但WROVER系列带有SPIRAM的,看我们测试芯片的状态数据:
========================== STATE ==============================
总堆大小: 279912 Byte
可用堆大小: 191080 Byte
启动以来最低可用堆大小: 176448 Byte
可以一次分配的最大堆块: 113792 Byte
SPI RAM总堆大小: 4194252 Byte
SPI RAM可用堆大小: 4194252 Byte
SPI RAM系统启动以来最低可用堆大小: 4194252 Byte
SPI RAM可以可以一次分配的最大堆块: 4194252 Byte
查询到SPI可用内存有4M,正常可以用官方提供的heap_caps_malloc(size, MALLOC_CAP_SPIRAM) 和 heap_caps_free() 的方法来使用这一块RAM,但如果用 DynamicJsonDocument 怎么来分配呢:
正常使用ArduinoJson的时候它包括两个实现类:
- DynamicJsonDocument,内存分配在heap区,无固定大小,可以自动增长所需空间,方法调用完自动回收,建议内存大小大于1KB使用;
StaticJsonDocument<256> doc;
- StaticJsonDocument,内存分配在stack区,有固定大小,大小值由开发者定义,方法调用完自动回收,建议内存大小小于1KB使用;
DynamicJsonDocument doc(2048);
但是我们怎么来使用SPIRAM来动态存储大量数据呢?
您可以JsonDocument通过定义自定义分配器类(作为模板参数传递给BasicJsonDocument的基类)来创建这种新类型DynamicJsonDocument。
自定义的分配器必须实现两个公有成员函数,allocate()并且deallocate(),用相同的签名,malloc()和free()。
struct SpiRamAllocator {
void* allocate(size_t size) {
return heap_caps_malloc(size, MALLOC_CAP_SPIRAM);
}
void deallocate(void* pointer) {
heap_caps_free(pointer);
}
};
using SpiRamJsonDocument = BasicJsonDocument<SpiRamAllocator>;
这些代码段定义SpiRamJsonDocument了您可以像使用其他代码一样使用JsonDocument:
SpiRamJsonDocument doc(1048576);
deserializeJson(doc, input);
然后痛快的用就行了~