Skip to content

Commit fc3675e

Browse files
committed
Add generic wolfHAL Ethernet port with STM32H563ZI Nucleo board support
1 parent d6fe35e commit fc3675e

15 files changed

Lines changed: 1377 additions & 0 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: wolfHAL STM32H563ZI Nucleo Build
2+
3+
on:
4+
push:
5+
branches: [ 'master', 'main', 'release/**' ]
6+
pull_request:
7+
branches: [ '*' ]
8+
9+
jobs:
10+
wolfhal_stm32h563zi_nucleo_build:
11+
runs-on: ubuntu-latest
12+
timeout-minutes: 10
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Install ARM toolchain
18+
run: |
19+
set -euo pipefail
20+
sudo apt-get update
21+
sudo apt-get install -y gcc-arm-none-eabi
22+
23+
- name: Clone wolfHAL
24+
run: |
25+
set -euo pipefail
26+
git clone --depth 1 https://github.com/wolfSSL/wolfHAL.git ../wolfHAL
27+
28+
- name: Build wolfHAL port
29+
run: |
30+
set -euo pipefail
31+
make -C src/port/wolfHAL BOARD=stm32h563zi_nucleo
32+
33+
- name: Verify binary
34+
run: |
35+
set -euo pipefail
36+
test -f src/port/wolfHAL/build/stm32h563zi_nucleo/app.bin
37+
arm-none-eabi-size src/port/wolfHAL/build/stm32h563zi_nucleo/app.elf

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ CPPCHECK_FLAGS=--enable=warning,performance,portability,missingInclude \
123123
--suppress=comparePointers:src/port/stm32n6/syscalls.c \
124124
--suppress=comparePointers:src/port/va416xx/startup.c \
125125
--suppress=comparePointers:src/port/va416xx/syscalls.c \
126+
--suppress=comparePointers:src/port/wolfHAL/boards/stm32h563zi_nucleo/startup.c \
127+
--suppress=comparePointers:src/port/wolfHAL/boards/stm32h563zi_nucleo/syscalls.c \
126128
--disable=style \
127129
--std=c99 --language=c \
128130
--platform=unix64 \

src/port/wolfHAL/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/

src/port/wolfHAL/Makefile

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
ROOT = $(CURDIR)/../../..
2+
PORT_DIR = $(ROOT)/src/port/wolfHAL
3+
4+
BOARD_DIR = $(PORT_DIR)/boards/$(BOARD)
5+
6+
ifeq ($(BOARD),)
7+
ifeq ($(MAKECMDGOALS),clean)
8+
clean:
9+
rm -rf build
10+
.PHONY: clean
11+
else
12+
$(error BOARD is required. Usage: make BOARD=stm32h563zi_nucleo)
13+
endif
14+
else
15+
include $(BOARD_DIR)/board.mk
16+
17+
SOURCE = $(PORT_DIR)/main.c
18+
SOURCE += $(PORT_DIR)/wolfhal_eth.c
19+
SOURCE += $(ROOT)/src/wolfip.c
20+
SOURCE += $(BOARD_SOURCE)
21+
22+
BUILD_DIR = build/$(BOARD)
23+
OBJECTS = $(patsubst %.c,$(BUILD_DIR)/%.o,$(SOURCE))
24+
DEPENDS = $(OBJECTS:.o=.d)
25+
26+
all: $(BUILD_DIR)/app.bin
27+
28+
$(BUILD_DIR)/%.o: %.c Makefile
29+
@mkdir -p $(dir $@)
30+
$(GCC) $(CFLAGS) -c -o $@ $<
31+
32+
.SECONDARY:
33+
$(BUILD_DIR)/%.elf: $(OBJECTS) $(LINKER_SCRIPT)
34+
@mkdir -p $(dir $@)
35+
$(GCC) $(CFLAGS) $(LDFLAGS) -T $(LINKER_SCRIPT) -o $@ $(OBJECTS) $(LDLIBS)
36+
37+
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf
38+
$(OBJCOPY) $^ -O binary $@
39+
40+
.PHONY: clean size
41+
clean:
42+
rm -rf build
43+
44+
size: $(BUILD_DIR)/app.elf
45+
$(GCC_PATH)arm-none-eabi-size $<
46+
47+
-include $(DEPENDS)
48+
49+
endif

src/port/wolfHAL/README.md

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# wolfHAL Port for wolfIP
2+
3+
Generic wolfIP port that uses the wolfHAL Ethernet API (`whal_Eth` /
4+
`whal_EthPhy`). Users create a wolfHAL board and the port handles the
5+
rest — bridging wolfHAL's Ethernet MAC/PHY drivers to wolfIP's
6+
link-layer device interface.
7+
8+
## Supported Boards
9+
10+
| Board | MCU | PHY | Directory |
11+
|-------|-----|-----|-----------|
12+
| NUCLEO-H563ZI | STM32H563ZI | LAN8742A | `boards/stm32h563zi_nucleo` |
13+
14+
## Directory Structure
15+
16+
```
17+
src/port/wolfHAL/
18+
├── Makefile # Top-level build: make BOARD=<board_name>
19+
├── main.c # Generic main: board_init -> wolfhal_eth_init -> wolfIP_poll loop
20+
├── wolfhal_eth.h # Port API and wolfhal_eth_ctx struct
21+
├── wolfhal_eth.c # Bridges wolfIP_ll_dev poll/send to whal_Eth_Recv/whal_Eth_Send
22+
└── boards/
23+
└── <board_name>/
24+
├── board.mk # Toolchain, CFLAGS, wolfHAL driver sources
25+
├── board.h # Board API declarations and device externs
26+
├── board.c # Clock, GPIO, Ethernet, PHY, UART, timer setup
27+
├── startup.c # Reset_Handler: copies .data, zeros .bss, calls main()
28+
├── ivt.c # Interrupt vector table
29+
├── syscalls.c # libc stubs (_write, _sbrk, etc.)
30+
└── linker.ld # Memory layout (FLASH/RAM regions)
31+
```
32+
33+
## Building
34+
35+
```
36+
cd src/port/wolfHAL
37+
make BOARD=stm32h563zi_nucleo
38+
```
39+
40+
Override the wolfHAL location (defaults to `../../../wolfHAL` relative to
41+
the wolfip root, i.e. a sibling directory):
42+
43+
```
44+
make BOARD=stm32h563zi_nucleo WOLFHAL_ROOT=/path/to/wolfHAL
45+
```
46+
47+
Override IP configuration or MAC address at build time:
48+
49+
```
50+
make BOARD=stm32h563zi_nucleo \
51+
CFLAGS+='-DWOLFIP_IP=\"10.0.0.2\" -DWOLFIP_NETMASK=\"255.255.255.0\" -DWOLFIP_GW=\"10.0.0.1\"'
52+
```
53+
54+
```
55+
make BOARD=stm32h563zi_nucleo \
56+
CFLAGS+='-DBOARD_MAC_ADDR={0x02,0xAA,0xBB,0xCC,0xDD,0xEE}'
57+
```
58+
59+
## Adding a New Board
60+
61+
Create a new directory under `boards/` with the following files:
62+
63+
### board.h
64+
65+
Must declare the following:
66+
67+
#### Required Device Externs
68+
69+
| Variable | Type | Description |
70+
|----------|------|-------------|
71+
| `g_whalEth` | `whal_Eth` | Initialized Ethernet MAC device |
72+
| `g_whalEthPhy` | `whal_EthPhy` | Initialized Ethernet PHY device |
73+
| `g_whalUart` | `whal_Uart` | Initialized UART device (used by `_write` syscall for printf) |
74+
| `g_whalRng` | `whal_Rng` | Initialized RNG device (used by `wolfIP_getrandom`) |
75+
76+
These names are required — `main.c`, `wolfhal_eth.c`, and `syscalls.c`
77+
reference them directly.
78+
79+
#### Required Functions
80+
81+
| Function | Signature | Description |
82+
|----------|-----------|-------------|
83+
| `board_init` | `whal_Error board_init(void)` | Initialize all board hardware. Must call `whal_Eth_Init`, `whal_EthPhy_Init`, `whal_Uart_Init`, and start the system timer before returning. Returns `WHAL_SUCCESS` on success. |
84+
| `board_deinit` | `whal_Error board_deinit(void)` | Tear down board hardware in reverse order. |
85+
| `board_get_tick` | `uint32_t board_get_tick(void)` | Return a millisecond tick counter. Used by `wolfhal_eth_init` for link timeout and by `wolfIP_poll` for stack timing. |
86+
87+
### board.c
88+
89+
Implements the functions above. Typical `board_init` sequence:
90+
91+
1. Initialize clocks (PLL, peripheral clocks)
92+
2. Initialize GPIO (UART pins, Ethernet pins)
93+
3. Initialize UART (`whal_Uart_Init`)
94+
4. Initialize Ethernet MAC (`whal_Eth_Init`)
95+
5. Initialize Ethernet PHY (`whal_EthPhy_Init`)
96+
6. Initialize and start system timer
97+
98+
The `whal_Eth` device must have its `macAddr` field set — this is
99+
where wolfIP reads the interface MAC address from.
100+
101+
### board.mk
102+
103+
Provides build configuration. Must set:
104+
105+
| Variable | Description |
106+
|----------|-------------|
107+
| `WOLFHAL_ROOT` | Path to wolfHAL (use `?=` so it's overridable) |
108+
| `GCC` | Cross-compiler path (e.g. `arm-none-eabi-gcc`) |
109+
| `OBJCOPY` | Objcopy tool |
110+
| `CFLAGS` | Compiler flags (architecture, warnings, includes) |
111+
| `LDFLAGS` | Linker flags |
112+
| `LDLIBS` | Libraries to link (libc, libgcc, etc.) |
113+
| `LINKER_SCRIPT` | Path to the board's linker script |
114+
| `BOARD_SOURCE` | List of board + wolfHAL driver source files |
115+
116+
`BOARD_SOURCE` must include at minimum:
117+
- `startup.c`, `ivt.c`, `board.c`, `syscalls.c` from the board directory
118+
- wolfHAL drivers: `eth/eth.c`, `eth/<platform>_eth.c`,
119+
`eth_phy/eth_phy.c`, `eth_phy/<phy>.c`, `clock/clock.c`,
120+
`clock/<platform>_rcc.c`, `gpio/gpio.c`, `gpio/<platform>_gpio.c`,
121+
`timer/timer.c`, `timer/systick.c`, `uart/uart.c`,
122+
`uart/<platform>_uart.c`, `rng/rng.c`,
123+
`rng/<platform>_rng.c`
124+
125+
### syscalls.c
126+
127+
Must provide:
128+
- Standard libc stubs: `_write`, `_read`, `_sbrk`, `_close`, `_fstat`,
129+
`_isatty`, `_lseek`, `_exit`, `_kill`, `_getpid`
130+
- `_write` should route to `whal_Uart_Send(&g_whalUart, ...)` so that
131+
`printf` outputs to UART
132+
- `uint32_t wolfIP_getrandom(void)` is provided by `main.c` using
133+
`whal_Rng_Generate(&g_whalRng, ...)`
134+
135+
### startup.c, ivt.c, linker.ld
136+
137+
Standard bare-metal files for your target architecture. See the
138+
`stm32h563zi_nucleo` board for a reference implementation.
139+
140+
## Port API
141+
142+
The port exposes a single function:
143+
144+
```c
145+
#include "wolfhal_eth.h"
146+
147+
struct wolfhal_eth_ctx ctx = {
148+
.eth = &g_whalEth,
149+
.phy = &g_whalEthPhy,
150+
};
151+
152+
int ret = wolfhal_eth_init(wolfIP_getdev(ipstack), &ctx);
153+
```
154+
155+
`wolfhal_eth_init` will:
156+
1. Poll `whal_EthPhy_GetLinkState` until link comes up (5s timeout,
157+
configurable via `WOLFHAL_ETH_LINK_TIMEOUT_MS`)
158+
2. Start the MAC with negotiated speed/duplex
159+
3. Copy `eth->macAddr` to the wolfIP device
160+
4. Register poll/send callbacks that bridge to `whal_Eth_Recv`/`whal_Eth_Send`
161+
162+
## Naming Conventions
163+
164+
- All port functions and variables use `snake_case`
165+
- Board functions use `board_` prefix: `board_init`, `board_get_tick`
166+
- Port functions use `wolfhal_` prefix: `wolfhal_eth_init`
167+
- wolfHAL API calls retain their own naming (`whal_Eth_Init`, etc.)
168+
- Global device instances use `g_whal` prefix: `g_whalEth`, `g_whalEthPhy`, `g_whalUart`, `g_whalRng`
169+
- Macros use `UPPER_SNAKE_CASE`

0 commit comments

Comments
 (0)