Skip to content

Commit 70ac819

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

File tree

15 files changed

+1370
-0
lines changed

15 files changed

+1370
-0
lines changed
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+
arm-none-eabi-size $<
46+
47+
-include $(DEPENDS)
48+
49+
endif

src/port/wolfHAL/README.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
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/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.) and wolfIP_getrandom
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 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+
## Adding a New Board
55+
56+
Create a new directory under `boards/` with the following files:
57+
58+
### board.h
59+
60+
Must declare the following:
61+
62+
#### Required Device Externs
63+
64+
| Variable | Type | Description |
65+
|----------|------|-------------|
66+
| `g_whalEth` | `whal_Eth` | Initialized Ethernet MAC device |
67+
| `g_whalEthPhy` | `whal_EthPhy` | Initialized Ethernet PHY device |
68+
| `g_whalUart` | `whal_Uart` | Initialized UART device (used by `_write` syscall for printf) |
69+
70+
These names are required — `main.c`, `wolfhal_eth.c`, and `syscalls.c`
71+
reference them directly.
72+
73+
#### Required Functions
74+
75+
| Function | Signature | Description |
76+
|----------|-----------|-------------|
77+
| `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. |
78+
| `board_deinit` | `whal_Error board_deinit(void)` | Tear down board hardware in reverse order. |
79+
| `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. |
80+
81+
### board.c
82+
83+
Implements the functions above. Typical `board_init` sequence:
84+
85+
1. Initialize clocks (PLL, peripheral clocks)
86+
2. Initialize GPIO (UART pins, Ethernet pins)
87+
3. Initialize UART (`whal_Uart_Init`)
88+
4. Initialize Ethernet MAC (`whal_Eth_Init`)
89+
5. Initialize Ethernet PHY (`whal_EthPhy_Init`)
90+
6. Initialize and start system timer
91+
92+
The `whal_Eth` device must have its `macAddr` field set — this is
93+
where wolfIP reads the interface MAC address from.
94+
95+
### board.mk
96+
97+
Provides build configuration. Must set:
98+
99+
| Variable | Description |
100+
|----------|-------------|
101+
| `WOLFHAL_ROOT` | Path to wolfHAL (use `?=` so it's overridable) |
102+
| `GCC` | Cross-compiler path (e.g. `arm-none-eabi-gcc`) |
103+
| `OBJCOPY` | Objcopy tool |
104+
| `CFLAGS` | Compiler flags (architecture, warnings, includes) |
105+
| `LDFLAGS` | Linker flags |
106+
| `LDLIBS` | Libraries to link (libc, libgcc, etc.) |
107+
| `LINKER_SCRIPT` | Path to the board's linker script |
108+
| `BOARD_SOURCE` | List of board + wolfHAL driver source files |
109+
110+
`BOARD_SOURCE` must include at minimum:
111+
- `startup.c`, `ivt.c`, `board.c`, `syscalls.c` from the board directory
112+
- wolfHAL drivers: `eth/eth.c`, `eth/<platform>_eth.c`,
113+
`eth_phy/eth_phy.c`, `eth_phy/<phy>.c`, `clock/clock.c`,
114+
`clock/<platform>_rcc.c`, `gpio/gpio.c`, `gpio/<platform>_gpio.c`,
115+
`timer/timer.c`, `timer/systick.c`, `uart/uart.c`,
116+
`uart/<platform>_uart.c`
117+
118+
### syscalls.c
119+
120+
Must provide:
121+
- Standard libc stubs: `_write`, `_read`, `_sbrk`, `_close`, `_fstat`,
122+
`_isatty`, `_lseek`, `_exit`, `_kill`, `_getpid`
123+
- `_write` should route to `whal_Uart_Send(&g_whalUart, ...)` so that
124+
`printf` outputs to UART
125+
- `uint32_t wolfIP_getrandom(void)` — wolfIP's random number hook
126+
127+
### startup.c, ivt.c, linker.ld
128+
129+
Standard bare-metal files for your target architecture. See the
130+
`stm32h563zi_nucleo` board for a reference implementation.
131+
132+
## Port API
133+
134+
The port exposes a single function:
135+
136+
```c
137+
#include "wolfhal_eth.h"
138+
139+
struct wolfhal_eth_ctx ctx = {
140+
.eth = &g_whalEth,
141+
.phy = &g_whalEthPhy,
142+
};
143+
144+
int ret = wolfhal_eth_init(wolfIP_getdev(ipstack), &ctx);
145+
```
146+
147+
`wolfhal_eth_init` will:
148+
1. Poll `whal_EthPhy_GetLinkState` until link comes up (5s timeout,
149+
configurable via `WOLFHAL_ETH_LINK_TIMEOUT_MS`)
150+
2. Start the MAC with negotiated speed/duplex
151+
3. Copy `eth->macAddr` to the wolfIP device
152+
4. Register poll/send callbacks that bridge to `whal_Eth_Recv`/`whal_Eth_Send`
153+
154+
## Naming Conventions
155+
156+
- All port functions and variables use `snake_case`
157+
- Board functions use `board_` prefix: `board_init`, `board_get_tick`
158+
- Port functions use `wolfhal_` prefix: `wolfhal_eth_init`
159+
- wolfHAL API calls retain their own naming (`whal_Eth_Init`, etc.)
160+
- Global device instances use `g_whal` prefix: `g_whalEth`, `g_whalEthPhy`, `g_whalUart`
161+
- Macros use `UPPER_SNAKE_CASE`

0 commit comments

Comments
 (0)