Вопрос с управлением памятью скрыт за многочисленными макросами. К тому же в LWIP существует не один вариант работы с выделением памяти. Но разобраться в этом надо , так как памяти SRAM 128K контроллеру скорее всего не будет хватать и надо будет что-то разумно урезать , чем-то пожертвовать.
Самая большая проблема в работе не с выделением памяти (выделить ее совсем не сложно), а с очиской ее после использования.
Где резервируется память в LWIP ? Оттуда начинаем изучать исходники.
Есть два подхода к управлению памятью : стандартный MEM_LIBC_MALLOC и через самописный диспетчер памяти MEM_USE_POOLS.
MEM_LIBC_MALLOC это стандартный набор с бибилиотек malloc/free. Его нельзя использовать в многопоточных приложениях от слова совсем.
MEM_USE_POOLS создает пулы (регионы) в памяти для использования под конкретные задачи с добавлением блоков с разной полезной информацией.
memp_std.h
Для начала озадачиваемся наличием трех типов пулов памяти.
Мы имеем три варианта пулов памяти :
1) LWIP_MEMPOOL
2) LWIP_MALLOC_MEMPOOL // pbuf_alloc | pbuf_free [PBUF_RAM]
3) LWIP_PBUF_MEMPOOL - // pbuf_alloc | pbuf_free [PBUF_POOL]
LWIP_MALLOC_MEMPOOL использует pbuf_alloc ( вариант PBUF_RAM) и далее фукцию mem_malloc (см. файл mem.c).
LWIP_PBUF_MEMPOOL вариант использует pbuf_alloc ( вариант PBUF_POOL) и далее фукцию memp_malloc (см. файл memp.c).
Но на самом деле все варианты в итоге используют шаблон LWIP_MEMPOOL.
Одновременно использовать два способа управления памятью MEMP_MEM_MALLOC и MEM_USE_POOLS нельзя!
Если их выставить в 1 оба , то получаем при компиляции #error "MEMP_MEM_MALLOC and MEM_USE_POOLS cannot be enabled at the same time". Это срабатывает защита на уровне компиляции в файле init.c .
По видимому , все области памяти , которые нам будут нужны прописаны в файле memp_std.h . В этом файле видим , что для каждого функционала выделяется отдельный регион памяти. Например для TCP так :
#if LWIP_TCP
LWIP_MEMPOOL(TCP_PCB, MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB")
LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN")
LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG")
#endif /* LWIP_TCP */
LWIP_MEMPOOL это просто шаблон, сам он ничего не делает. Используется в коде по принципу : #define LWIP_MEMPOOL blablabla... и далее #include "lwip/memp_std.h" .
Итак похоже мы поняли , что выбор использования памяти надо делать в пользу MEM_USE_POOLS .
На самом деле MEM_USE_POOLS использует в результате функцию для варианта pbuf_alloc(..,..,PBUF_RAM) mem_malloc и для варианта pbuf_alloc(..,..,PBUF_POOL) функцию memp_malloc для выделения памяти.
Для варианта MEM_USE_POOLS срабатывает напоминание , что нам надо в этом случае включить MEMP_USE_CUSTOM_POOLS.
MEMP_USE_CUSTOM_POOLS
MEMP_USE_CUSTOM_POOLS это регионы MALLOC_ХХХ , которые будет использовать pbuf_alloc (вариант PBUF_RAM). Определяются они в любом файле (у нас lwippools.h) примерно так:
//#ifndef LWIPPOOLS_H - это важно не использовать !!
//#define LWIPPOOLS_H - это важно не использовать !!
LWIP_MALLOC_MEMPOOL_START
LWIP_MALLOC_MEMPOOL(4, 256)
LWIP_MALLOC_MEMPOOL(2, 512)
LWIP_MALLOC_MEMPOOL(1, 1024)
LWIP_MALLOC_MEMPOOL_END
//#endif
Похоже есть нюанс - стандартную защиту от повторного включения хэдера *.h надо убрать.
Дефайн LWIP_MALLOC_MEMPOOL(num, size) это макрос :
LWIP_MEMPOOL(POOL_##size, num, (size + sizeof(struct memp_malloc_helper)), "MALLOC_"#size)
LWIP_MEMPOOL просто резервирует память как и для других регионов памяти.
Если прочитать всю таблицу распределения памяти , то она выглядит примерно так :
00 size x001C num 0004 next:20000728 RAW_PCB
01 size x0020 num 0004 next:200007A0 UDP_PCB
02 size x0098 num 0005 next:200009A8 TCP_PCB
03 size x001C num 0008 next:20000B80 TCP_PCB_LISTEN
04 size x0014 num 0016 next:20000CD0 TCP_SEG
05 size x0020 num 0005 next:20000D58 REASSDATA
06 size x0018 num 0015 next:20000ED0 FRAG_PBUF
07 size x0014 num 0003 next:20000F14 SYS_TIMEOUT
08 size x0010 num 0016 next:2000101C PBUF_REF/ROM
09 size x05FC num 0016 next:20006404 PBUF_POOL
10 size x0104 num 0006 next:2000740C MALLOC_256 // 10 = MEMP_POOL_HELPER_FIRST !
11 size x0204 num 0002 next:20007614 MALLOC_512
12 size x05EC num 0002 next:20007A1C MALLOC_1512 // 12 = MEMP_POOL_HELPER_LAST !
У каждого региона (к счастью) есть символьное название. Мы можем подключить сбор статистики и выводить на экран в любой момент текущее состояние расхода памяти каждого региона:
avail: 04 used: 00 max: 00 err: 00 [RAW_PCB]
avail: 04 used: 02 max: 02 err: 00 [UDP_PCB]
avail: 05 used: 00 max: 01 err: 00 [TCP_PCB]
avail: 08 used: 01 max: 01 err: 00 [TCP_PCB_LISTEN]
avail: 16 used: 00 max: 00 err: 00 [TCP_SEG]
avail: 05 used: 00 max: 00 err: 00 [REASSDATA]
avail: 15 used: 00 max: 00 err: 00 [FRAG_PBUF]
avail: 03 used: 02 max: 02 err: 00 [SYS_TIMEOUT]
avail: 16 used: 00 max: 00 err: 00 [PBUF_REF/ROM]
avail: 16 used: 01 max: 02 err: 00 [PBUF_POOL]
avail: 06 used: 00 max: 00 err: 00 [MALLOC_256]
avail: 02 used: 00 max: 00 err: 00 [MALLOC_512]
avail: 02 used: 00 max: 00 err: 00 [MALLOC_1512]
Дефайны , которые влияют на расход памяти :
TCP_MSS: TCP Maximum segment size
TCP_MSS: TCP Maximum segment size