Skip to content

Commit 9009c88

Browse files
committed
Add generic wolfHAL Ethernet port with STM32H563ZI Nucleo board support
1 parent 56a6b60 commit 9009c88

15 files changed

Lines changed: 1392 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
@@ -145,6 +145,8 @@ CPPCHECK_FLAGS=--enable=warning,performance,portability,missingInclude \
145145
--suppress=comparePointers:src/port/lpc54s018/syscalls.c \
146146
--suppress=comparePointers:src/port/stm32f439/startup.c \
147147
--suppress=comparePointers:src/port/stm32f439/syscalls.c \
148+
--suppress=comparePointers:src/port/wolfHAL/boards/stm32h563zi_nucleo/startup.c \
149+
--suppress=comparePointers:src/port/wolfHAL/boards/stm32h563zi_nucleo/syscalls.c \
148150
--disable=style \
149151
--std=c99 --language=c \
150152
--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: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
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+
### syscalls.c
117+
118+
Must provide:
119+
- Standard libc stubs: `_write`, `_read`, `_sbrk`, `_close`, `_fstat`,
120+
`_isatty`, `_lseek`, `_exit`, `_kill`, `_getpid`
121+
- `_write` should route to `whal_Uart_Send(&g_whalUart, ...)` so that
122+
`printf` outputs to UART
123+
- `uint32_t wolfIP_getrandom(void)` is provided by `main.c` using
124+
`whal_Rng_Generate(&g_whalRng, ...)`
125+
126+
### startup.c, ivt.c, linker.ld
127+
128+
Standard bare-metal files for your target architecture. See the
129+
`stm32h563zi_nucleo` board for a reference implementation.
130+
131+
## Port API
132+
133+
The port exposes a single function:
134+
135+
```c
136+
#include "wolfhal_eth.h"
137+
138+
struct wolfhal_eth_ctx ctx = {
139+
.eth = &g_whalEth,
140+
.phy = &g_whalEthPhy,
141+
};
142+
143+
int ret = wolfhal_eth_init(wolfIP_getdev(ipstack), &ctx);
144+
```
145+
146+
`wolfhal_eth_init` will:
147+
1. Poll `whal_EthPhy_GetLinkState` until link comes up (5s timeout,
148+
configurable via `WOLFHAL_ETH_LINK_TIMEOUT_MS`)
149+
2. Start the MAC with negotiated speed/duplex
150+
3. Copy `eth->macAddr` to the wolfIP device
151+
4. Register poll/send callbacks that bridge to `whal_Eth_Recv`/`whal_Eth_Send`
152+
153+
## Naming Conventions
154+
155+
- All port functions and variables use `snake_case`
156+
- Board functions use `board_` prefix: `board_init`, `board_get_tick`
157+
- Port functions use `wolfhal_` prefix: `wolfhal_eth_init`
158+
- wolfHAL API calls retain their own naming (`whal_Eth_Init`, etc.)
159+
- Global device instances use `g_whal` prefix: `g_whalEth`, `g_whalEthPhy`, `g_whalUart`, `g_whalRng`
160+
- Macros use `UPPER_SNAKE_CASE`

0 commit comments

Comments
 (0)