Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ build/*
test/unit/unit
tags
cppcheck_results.xml
src/port/stm32h563/app.elf
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ CPPCHECK_FLAGS=--enable=warning,performance,portability,missingInclude \
--suppress=constParameterCallback \
--suppress=toomanyconfigs \
--suppress=unmatchedSuppression --inconclusive \
--suppress=comparePointers:src/port/stm32h563/startup.c \
--suppress=comparePointers:src/port/stm32h563/syscalls.c \
--disable=style \
--std=c99 --language=c \
--platform=unix64 \
Expand Down
43 changes: 43 additions & 0 deletions src/port/stm32h563/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
CC=arm-none-eabi-gcc
OBJCOPY ?= arm-none-eabi-objcopy

ROOT := ../../..

# TrustZone support: set TZEN=1 for TrustZone enabled builds
# Default is TZEN=0 (TrustZone disabled)
TZEN ?= 0

CFLAGS := -mcpu=cortex-m33 -mthumb -mcmse -Os -ffreestanding -fdata-sections -ffunction-sections
CFLAGS += -g -ggdb -Wall -Wextra -Werror -Wdeclaration-after-statement
CFLAGS += -I. -I$(ROOT) -I$(ROOT)/src

# Select linker script based on TZEN setting
ifeq ($(TZEN),1)
LDSCRIPT := target_tzen.ld
CFLAGS += -DTZEN_ENABLED=1
else
LDSCRIPT := target.ld
CFLAGS += -DTZEN_ENABLED=0
endif

LDFLAGS := -nostdlib -T $(LDSCRIPT) -Wl,-gc-sections

SRCS := startup.c ivt.c syscalls.c main.c stm32h5_eth.c $(ROOT)/src/wolfip.c
OBJS := $(patsubst %.c,%.o,$(SRCS))

all: app.bin
@echo "Built with TZEN=$(TZEN) using $(LDSCRIPT)"

app.elf: $(OBJS) $(LDSCRIPT)
$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -Wl,--start-group -lc -lm -lgcc -lnosys -Wl,--end-group -o $@

app.bin: app.elf
$(OBJCOPY) -O binary $< $@

%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@

clean:
rm -f $(OBJS) app.elf app.bin

.PHONY: all clean
207 changes: 207 additions & 0 deletions src/port/stm32h563/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
# wolfIP STM32H563 Port

This directory contains a bare-metal port of wolfIP for the STM32H563 microcontroller, featuring an Ethernet driver and TCP/IP echo server example.

## Hardware Requirements

- STM32H563 development board (e.g., NUCLEO-H563ZI)
- Ethernet connection (RMII interface)
- ST-LINK debugger (built-in on NUCLEO boards)
- USB cable for serial output

## Software Requirements

- ARM GCC toolchain (`arm-none-eabi-gcc`)
- OpenOCD (STMicroelectronics fork recommended)
- Serial terminal (e.g., minicom, screen, or picocom)

### Installing Dependencies (Ubuntu/Debian)

```bash
sudo apt install gcc-arm-none-eabi openocd
```

## Building

### Default Build (TrustZone Disabled - Recommended)

```bash
cd src/port/stm32h563
make TZEN=0
```

This produces `app.elf` and `app.bin` for use with TZEN=0 (TrustZone disabled).

### TrustZone Enabled Build (Experimental)

```bash
make TZEN=1
```

> **Note:** TZEN=1 support is experimental. The Ethernet driver currently has issues receiving packets when TrustZone is enabled.

## Disabling TrustZone (Option Bytes)

If your board has TrustZone enabled, you must disable it via option bytes before using the TZEN=0 build. Use STM32CubeProgrammer or OpenOCD:

### Using STM32CubeProgrammer (Recommended)

1. Open STM32CubeProgrammer
2. Connect to the target
3. Go to **Option Bytes** tab
4. Find **TZEN** under "User Configuration"
5. Set TZEN to **0xC3** (disabled)
6. Click **Apply**

### Using OpenOCD

```bash
openocd -f interface/stlink-dap.cfg -f target/stm32h5x.cfg -c "init" -c "halt" -c "stm32h5x option_write 0 0x5200201C 0xC3B6" -c "reset" -c "exit"
```

> **Warning:** Modifying option bytes can lock the device. Ensure you understand the process before proceeding.

### Verifying TrustZone Status

When flashing, OpenOCD will report TrustZone status:

```
Info : TZEN = 0xC3 : TrustZone disabled by option bytes # Good for TZEN=0
Info : TZEN = 0xB4 : TrustZone enabled by option bytes # Requires TZEN=1 build
```

## Flashing

```bash
openocd -f interface/stlink-dap.cfg -f target/stm32h5x.cfg \
-c "program app.elf verify reset exit"
```

## Serial Console

Connect to the USB serial port (typically `/dev/ttyACM0`) at 115200 baud:

```bash
# Using screen
screen /dev/ttyACM0 115200

# Using minicom
minicom -D /dev/ttyACM0 -b 115200

# Using picocom
picocom -b 115200 /dev/ttyACM0
```

## Example Output

When the firmware boots successfully, you should see output similar to:

```
=== wolfIP STM32H563 Echo Server ===
Initializing wolfIP stack...
Configuring GPIO for RMII...
Enabling Ethernet clocks...
Resetting Ethernet MAC...
Initializing Ethernet MAC...
PHY link: UP, PHY addr: 0x00000000
Setting IP configuration:
IP: 192.168.12.11
Mask: 255.255.255.0
GW: 192.168.12.1
Creating TCP socket on port 7...
Entering main loop. Ready for connections!
Loop starting...
```

The "PHY link: UP" message indicates the Ethernet PHY has established a link with the network.

## Network Configuration

The example configures the following static IP:

| Setting | Value |
|---------|-------|
| IP Address | 192.168.12.11 |
| Subnet Mask | 255.255.255.0 |
| Gateway | 192.168.12.1 |

Configure your host PC's Ethernet interface to be on the same subnet:

```bash
sudo ip addr add 192.168.12.1/24 dev <interface>
sudo ip link set <interface> up
```

Replace `<interface>` with your Ethernet interface name (e.g., `eth0`, `enp5s0`).

## Testing

Once running, the echo server listens on TCP port 7:

```bash
# Test with netcat
echo "Hello wolfIP!" | nc 192.168.12.11 7

# Test with ping
ping 192.168.12.11
```

## Files

| File | Description |
|------|-------------|
| `main.c` | Application entry point, wolfIP initialization, echo server |
| `stm32h5_eth.c` | Ethernet MAC/DMA driver for STM32H5 |
| `stm32h5_eth.h` | Ethernet driver header |
| `startup.c` | Startup code and data initialization |
| `ivt.c` | Interrupt vector table |
| `syscalls.c` | Newlib syscall stubs |
| `target.ld` | Linker script for TZEN=0 |
| `target_tzen.ld` | Linker script for TZEN=1 |
| `config.h` | Build configuration |
| `Makefile` | Build system |

## TrustZone Support (TZEN=1) - Experimental

The TZEN=1 build adds TrustZone support:

- **SAU Configuration:** Marks memory regions for non-secure DMA access
- **GTZC/MPCBB:** Configures SRAM3 blocks for Ethernet DMA
- **Secure Aliases:** Uses secure peripheral addresses (0x5xxxxxxx)
- **Separate ETHMEM:** Places Ethernet buffers in dedicated non-secure SRAM

### Current Limitations

The TZEN=1 build compiles and runs, but the Ethernet driver experiences RBU (Receive Buffer Unavailable) errors. This appears to be a DMA access issue that requires further investigation.

## Troubleshooting

### No Serial Output

- Check USB connection and correct serial port
- Verify baud rate is 115200
- Try resetting the board

### OpenOCD Connection Fails

- Ensure ST-LINK drivers are installed
- Try `sudo` if permission denied
- Check that no other debugger is connected

### Ethernet Not Responding

- Verify physical Ethernet connection
- Check that host PC is on same subnet (192.168.12.x)
- Confirm PHY link is up (check serial output for "link" status)

### TrustZone Errors

If you see `stm32h5x.cpu in Secure state` but built with TZEN=0:
- The board has TrustZone enabled
- Either rebuild with `make TZEN=1` or disable TrustZone via option bytes

## License

This code is part of wolfIP and is licensed under GPLv3. See the LICENSE file in the repository root for details.

Copyright (C) 2026 wolfSSL Inc.
56 changes: 56 additions & 0 deletions src/port/stm32h563/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* config.h
*
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfIP TCP/IP stack.
*
* wolfIP is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfIP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef WOLF_CONFIG_H
#define WOLF_CONFIG_H

#ifndef CONFIG_IPFILTER
#define CONFIG_IPFILTER 0
#endif

#define ETHERNET
#define LINK_MTU 1536

#define MAX_TCPSOCKETS 4
#define MAX_UDPSOCKETS 2
#define MAX_ICMPSOCKETS 2
#define RXBUF_SIZE (LINK_MTU * 16)
#define TXBUF_SIZE (LINK_MTU * 16)

#define MAX_NEIGHBORS 16

#ifndef WOLFIP_MAX_INTERFACES
#define WOLFIP_MAX_INTERFACES 1
#endif

#ifndef WOLFIP_ENABLE_FORWARDING
#define WOLFIP_ENABLE_FORWARDING 0
#endif

#ifndef WOLFIP_ENABLE_LOOPBACK
#define WOLFIP_ENABLE_LOOPBACK 0
#endif

#define WOLFIP_IP "192.168.12.11"
#define WOLFIP_NETMASK "255.255.255.0"
#define WOLFIP_GW "192.168.12.1"
#define WOLFIP_STATIC_DNS_IP "9.9.9.9"

#endif
57 changes: 57 additions & 0 deletions src/port/stm32h563/ivt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* ivt.c
*
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfIP TCP/IP stack.
*
* wolfIP is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfIP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <stdint.h>

extern void Reset_Handler(void);
extern unsigned long _estack;

static void default_handler(void)
{
while (1) { }
}

void NMI_Handler(void) __attribute__((weak, alias("default_handler")));
void HardFault_Handler(void) __attribute__((weak, alias("default_handler")));
void MemManage_Handler(void) __attribute__((weak, alias("default_handler")));
void BusFault_Handler(void) __attribute__((weak, alias("default_handler")));
void UsageFault_Handler(void)__attribute__((weak, alias("default_handler")));
void SVC_Handler(void) __attribute__((weak, alias("default_handler")));
void DebugMon_Handler(void) __attribute__((weak, alias("default_handler")));
void PendSV_Handler(void) __attribute__((weak, alias("default_handler")));
void SysTick_Handler(void) __attribute__((weak, alias("default_handler")));

__attribute__((section(".isr_vector")))
const uint32_t vector_table[16 + 96] = {
[0] = (uint32_t)&_estack,
[1] = (uint32_t)&Reset_Handler,
[2] = (uint32_t)&NMI_Handler,
[3] = (uint32_t)&HardFault_Handler,
[4] = (uint32_t)&MemManage_Handler,
[5] = (uint32_t)&BusFault_Handler,
[6] = (uint32_t)&UsageFault_Handler,
[7] = 0, [8] = 0, [9] = 0, [10] = 0,
[11] = (uint32_t)&SVC_Handler,
[12] = (uint32_t)&DebugMon_Handler,
[13] = 0,
[14] = (uint32_t)&PendSV_Handler,
[15] = (uint32_t)&SysTick_Handler,
[16 ... 111] = (uint32_t)&default_handler
};
Loading