ESP32: почему malloc может выделять только 126888 байт с кучей 402540 байт?

Мне нужен буфер размером 153600 байт в моем проекте ESP32, но я не смог создать статический буфер в коде и не могу malloc буфера.

Сам ESP32 сообщает:

  ESP.getHeapSize()  // = 402540
  ESP.getFreeHeap()  // = 376980
  ESP.getPsramSize() // = 0
  ESP.getFreePsram() // = 0

malloc(153600) возвращает NULL; я написал небольшой цикл, который уменьшается на единицу и повторяет попытку malloc. В первый раз он работает с malloc(126888), так что, похоже, это максимальный буфер, который я могу получить.

(Я пробовал это с разными платами; одна от eBay и одна от подлинного дистрибьютора - никаких различий.)

Очевидно, что размер кучи достаточно велик. Итак, я думаю, что оперативная память, возможно, разделена на разные блоки, и ни один из них не является достаточно большим для моего буфера?

Существует ли какая-либо документация, объясняющая это поведение?

, 👍0

Обсуждение

Выделяете ли вы память и в других местах? Может быть, вы уже фрагментировали память, прежде чем попробовать?, @PMF


1 ответ


Лучший ответ:

1

Да, память ESP32 разделена на несколько различных блоков. Все эти фрагменты объединяются диспетчером памяти, чтобы выглядеть как единая куча, но на самом деле они разделены.

Как упоминается в документации ESP-IDF:

При запуске все приложения ESP-IDF регистрируют сводку всех адресов кучи (и размеров) на уровне Информация:

I (252) heap_init: Initializing. RAM available for dynamic allocation:
I (259) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (265) heap_init: At 3FFB2EC8 len 0002D138 (180 KiB): DRAM
I (272) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (278) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (284) heap_init: At 4008944C len 00016BB4 (90 KiB): IRAM

И, конечно, у вас есть некоторая фрагментация кучи от других потоков, выделяющих и освобождающих память, поэтому самый большой непрерывный блок памяти, который вы можете выделить, будет меньше самой большой области.

Для дополнительной иллюстрации я нашел эту удобную карту памяти на форумах Arduino:

Там вы можете ясно видеть, что SRAM разделен на разные части. Основная причина этого заключается в том, чтобы лучше обеспечить одновременный доступ к двум ядрам в двухъядерных вариантах чипа.

,