|
| 1 | +# Porting wolfIP to a new STM32 |
| 2 | + |
| 3 | +This tree is layered so a new STM32 wolfIP port is a small set of per-chip |
| 4 | +files plus shared infrastructure. Existing ports: `stm32c5a3` (M33, TLS 1.3 + |
| 5 | +DHUK), `stm32h753` (M7, TLS + HTTPS), `stm32h563` (M33, TLS + SSH + MQTT + |
| 6 | +dot1x + FreeRTOS), `stm32f439` (M4, network only), `stm32n6` (M55, network |
| 7 | +only). |
| 8 | + |
| 9 | +## Shared -- reuse as-is |
| 10 | + |
| 11 | +| File | What it gives you | |
| 12 | +|------|-------------------| |
| 13 | +| `src/port/stm32/stm32_eth.c` / `.h` | Synopsys DWC GMAC MAC+DMA+PHY driver for H5/H7/N6 (and C5, via a one-line `STM32C5 -> STM32H5` alias). ETH1 at `0x40028000` on H5/C5. | |
| 14 | +| `src/port/stm32/wolfssl.mk` | `WOLFSSL_ROOT`/`WOLFMQTT_ROOT` defaults, the `WOLFSSL_SRCS` TLS-1.3 source list, the optional `WOLFSSL_LOG_SRCS` (logging/error/wc_encrypt) group, and the `$(WOLFSSL_ROOT)/%.o` relaxed-warning rule. `include` it from a port Makefile. | |
| 15 | +| `src/port/wolfssl_io.c` | wolfIP <-> wolfSSL I/O callbacks (EAGAIN -> WANT_READ/WRITE, `-1` -> CONN_CLOSE). | |
| 16 | +| `src/port/certs.h` | Embedded test certificates (for the HTTPS/server ports). | |
| 17 | +| `src/wolfip.c` | The stack itself. | |
| 18 | + |
| 19 | +## Per-chip -- supply these |
| 20 | + |
| 21 | +| File | Notes | |
| 22 | +|------|-------| |
| 23 | +| `startup.c` (+ `ivt.c`) | Vendor vector table + reset. Genuinely per-silicon (different peripheral IRQ set). C5A3 folds the full M33 vector table into `startup.c` (no separate `ivt.c`). | |
| 24 | +| `target.ld` | Memory map (flash/RAM addresses + sizes). Add an `.eth_buffers` output section in RAM for the GMAC descriptors + RX/TX buffers. | |
| 25 | +| `main.c` | The per-chip register sequences: `clock_init`, `uart_init`, `eth_gpio_init` (RMII pinmux + SYSCFG/SBS PHY-interface select + RCC ETH gates), `rng_init`. Plus the wolfIP init + poll loop (mostly copyable between ports). | |
| 26 | +| `config.h` | wolfIP sizing (sockets, buffers, static IP). | |
| 27 | +| `user_settings.h` | wolfSSL config: the shared TLS-1.3 base + a per-chip HW-crypto arm (`STM32_HASH` / `STM32_CRYPTO` / `WOLFSSL_STM32_PKA` / RNG, gated on the chip define). | |
| 28 | +| `Makefile` | Thin: CPU flags, device `-D`, includes, `include ../stm32/wolfssl.mk`, board sources, feature source lists, flash command. | |
| 29 | + |
| 30 | +## Makefile pattern |
| 31 | + |
| 32 | +```make |
| 33 | +CFLAGS := -mcpu=cortex-mXX ... -D<CHIP> |
| 34 | +CFLAGS_WOLFSSL := $(filter-out -Werror,$(CFLAGS)) -Wno-unused-variable -Wno-unused-function |
| 35 | +include $(ROOT)/src/port/stm32/wolfssl.mk # WOLFSSL_SRCS + %.o rule + defaults |
| 36 | +... |
| 37 | +ifeq ($(ENABLE_TLS),1) |
| 38 | + WOLFSSL_SRCS += $(WOLFSSL_LOG_SRCS) # unless you strip logging/error to save flash |
| 39 | + SRCS += $(WOLFSSL_SRCS) |
| 40 | +endif |
| 41 | +``` |
| 42 | + |
| 43 | +- A port that needs feature defines on the wolfSSL objects (e.g. SSH/dot1x) sets `WOLFSSL_EXTRA_DEFS` -- the shared `%.o` rule appends it (see `stm32h563/Makefile`). |
| 44 | +- Keep `all:`/`clean:`/`size:`/`flash:` in the port; `wolfssl.mk` intentionally defines only variables and the `%.o` pattern rule so it never hijacks the default goal. |
| 45 | + |
| 46 | +## New-port checklist (things that bite) |
| 47 | + |
| 48 | +- **`_sbrk` must use the linker `.heap` region**, not `_ebss.._estack`. On a port whose linker places `.eth_buffers` after `.bss`, an `_ebss`-based heap hands out malloc memory that overlaps the Ethernet DMA buffers, and packet DMA silently corrupts heap objects (seen on C5A3: garbage `WOLFSSL_CTX->method` -> bus fault deep in TLS). |
| 49 | +- **Add the port to the root `Makefile` cppcheck suppression list** (`comparePointers` for `startup.c`/`syscalls.c`, and `unknownMacro` for a CMSIS vendor `startup.c`). A cleaner alternative for new code: cast the `_sbrk` bounds compare to `uintptr_t` so no `comparePointers` suppression is needed. |
| 50 | +- **RMII alternate-function numbers are not uniform** -- check each pin against the CubeMX/HAL board example (on C5A3, RXD0/RXD1 are AF12/AF13 while the rest are AF10). A wrong AF on an RX pin leaves the link up (MDIO works) but drops all RX. |
| 51 | +- **DMA buffers must be in DMA-reachable RAM** (not DTCM on H7); place them via the `.eth_buffers` section. |
| 52 | +- **Wire MSPLIM** to the linker's real stack-limit symbol (`PROVIDE(__STACK_LIMIT = __StackLimit)` if the CMSIS startup uses `__STACK_LIMIT`) so a stack overflow faults cleanly instead of corrupting the heap. |
| 53 | +- The `../wolfssl` object tree is shared: ports at different FP ABIs (hard vs soft float) clobber each other's `.o` files. `make clean` (or delete `$(WOLFSSL_ROOT)/**/*.o`) between such builds. |
| 54 | + |
| 55 | +## Known de-duplication opportunity (not yet done) |
| 56 | + |
| 57 | +`tls_client.c` is currently a per-port file. The three TLS ports share a common |
| 58 | +handshake state machine, but they diverge in real behavior -- `stm32c5a3` does |
| 59 | +mutual auth with a client certificate + the DHUK PK sign callback, while |
| 60 | +`stm32h753`/`stm32h563` are plain one-way clients with no client cert. A shared |
| 61 | +`src/port/tls_client.c` would need config guards for cert-loading / DHUK / SNI / |
| 62 | +debug; worthwhile as a focused follow-up (with an on-hardware re-test of each |
| 63 | +board), but deliberately left per-port for now to avoid an unverifiable change. |
0 commit comments