diff --git a/.github/workflows/test-configs.yml b/.github/workflows/test-configs.yml index 296bdac64c..e546018adb 100644 --- a/.github/workflows/test-configs.yml +++ b/.github/workflows/test-configs.yml @@ -571,6 +571,12 @@ jobs: arch: arm config-file: ./config/examples/stm32wb.config + wolfhal_stm32wb_test: + uses: ./.github/workflows/test-build.yml + with: + arch: arm + config-file: ./config/examples/wolfhal_stm32wb_nucleo.config + # TODO: ti-tms570lc435.config requires F021 Flash API (Windows installer only) # ti_tms570lc435_test: # uses: ./.github/workflows/test-build-ti-hercules.yml diff --git a/.gitmodules b/.gitmodules index 6cd81662fe..13396fd2ec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "lib/wolfPSA"] path = lib/wolfPSA url = https://github.com/wolfSSL/wolfPSA.git +[submodule "lib/wolfHAL"] + path = lib/wolfHAL + url = https://github.com/wolfSSL/wolfHAL.git diff --git a/Makefile b/Makefile index c25413327f..9e82890244 100644 --- a/Makefile +++ b/Makefile @@ -522,7 +522,10 @@ $(LSCRIPT): $(LSCRIPT_IN) FORCE sed -e "s/@BOOTLOADER_START@/$(BOOTLOADER_START)/g" | \ sed -e "s/@IMAGE_HEADER_SIZE@/$(IMAGE_HEADER_SIZE)/g" | \ sed -e "s/@FSP_S_LOAD_BASE@/$(FSP_S_LOAD_BASE)/g" | \ - sed -e "s/@WOLFBOOT_L2LIM_SIZE@/$(WOLFBOOT_L2LIM_SIZE)/g" \ + sed -e "s/@WOLFBOOT_L2LIM_SIZE@/$(WOLFBOOT_L2LIM_SIZE)/g" | \ + sed -e 's/@WOLFHAL_FLASH_EXCLUDE_TEXT@/$(WOLFHAL_FLASH_EXCLUDE_TEXT)/g' | \ + sed -e 's/@WOLFHAL_FLASH_EXCLUDE_RODATA@/$(WOLFHAL_FLASH_EXCLUDE_RODATA)/g' | \ + sed -e 's/@WOLFHAL_FLASH_RAM_SECTIONS@/$(WOLFHAL_FLASH_RAM_SECTIONS)/g' \ > $@ hex: wolfboot.hex diff --git a/arch.mk b/arch.mk index 849fa0360f..06ce83b173 100644 --- a/arch.mk +++ b/arch.mk @@ -206,6 +206,11 @@ ifeq ($(ARCH),ARM) SPI_TARGET=stm32 endif + # Defaults for linker script placeholders (overridden by wolfhal target) + WOLFHAL_FLASH_EXCLUDE_TEXT?=*(.text*) + WOLFHAL_FLASH_EXCLUDE_RODATA?=*(.rodata*) + WOLFHAL_FLASH_RAM_SECTIONS?= + ifeq ($(TARGET),stm32wb) ARCH_FLASH_OFFSET=0x08000000 SPI_TARGET=stm32 @@ -221,6 +226,24 @@ ifeq ($(ARCH),ARM) endif endif + ifeq ($(TARGET),wolfhal_stm32wb) + ARCH_FLASH_OFFSET=0x08000000 + LSCRIPT_IN=hal/stm32wb.ld + WOLFHAL_ROOT?=$(WOLFBOOT_ROOT)/lib/wolfHAL + CFLAGS+=-I$(WOLFHAL_ROOT) -DWHAL_CFG_DIRECT_CALLBACKS + OBJS+=./hal/boards/$(BOARD).o + OBJS+=$(WOLFHAL_ROOT)/src/clock/stm32wb_rcc.o + OBJS+=$(WOLFHAL_ROOT)/src/flash/stm32wb_flash.o + ifeq ($(DEBUG_UART),1) + OBJS+=$(WOLFHAL_ROOT)/src/gpio/stm32wb_gpio.o + OBJS+=$(WOLFHAL_ROOT)/src/uart/stm32wb_uart.o + endif + ifeq ($(RAM_CODE),1) + WOLFHAL_FLASH_EXCLUDE_TEXT=*(EXCLUDE_FILE(*stm32wb_flash.o) .text*) + WOLFHAL_FLASH_EXCLUDE_RODATA=*(EXCLUDE_FILE(*stm32wb_flash.o) .rodata*) + WOLFHAL_FLASH_RAM_SECTIONS=*stm32wb_flash.o(.text* .rodata*) + endif + endif ifeq ($(TARGET),stm32l5) CORTEX_M33=1 diff --git a/config/examples/wolfhal_stm32wb_nucleo.config b/config/examples/wolfhal_stm32wb_nucleo.config new file mode 100644 index 0000000000..7f53ee3918 --- /dev/null +++ b/config/examples/wolfhal_stm32wb_nucleo.config @@ -0,0 +1,10 @@ +TARGET=wolfhal_stm32wb +BOARD=stm32wb_nucleo +SIGN=ECC256 +HASH=SHA256 +WOLFBOOT_SECTOR_SIZE=0x1000 +WOLFBOOT_PARTITION_SIZE=0x20000 +WOLFBOOT_PARTITION_BOOT_ADDRESS=0x08008000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08028000 +WOLFBOOT_PARTITION_SWAP_ADDRESS=0x08048000 +NVM_FLASH_WRITEONCE=1 diff --git a/docs/wolfHAL.md b/docs/wolfHAL.md new file mode 100644 index 0000000000..e2a718dabd --- /dev/null +++ b/docs/wolfHAL.md @@ -0,0 +1,209 @@ +# wolfHAL Integration + +wolfBoot supports [wolfHAL](https://github.com/wolfSSL/wolfHAL) as an alternative hardware abstraction layer backend. wolfHAL provides portable, vtable-dispatched drivers for common MCU peripherals (clock, flash, GPIO, UART, SPI, etc.) with a consistent API across platforms. + +## Overview + +The wolfHAL integration consists of three parts: + +1. **HAL implementation** (`hal/wolfhal_.c`) — implements the wolfBoot HAL API (`hal_init`, `hal_flash_write`, etc.) by calling wolfHAL driver functions. One file per MCU family (e.g. STM32WB). + +2. **Board configuration** (`hal/boards/.c`) — defines the wolfHAL device instances (flash, clock, and optionally GPIO/UART for `DEBUG_UART`) with board-specific register addresses, clock parameters, and flash geometry. One file per board. + +3. **wolfHAL library** (`lib/wolfHAL/`) — the wolfHAL submodule containing the platform drivers. + +## Configuration + +A wolfHAL-based config requires two variables beyond the standard wolfBoot settings: + +``` +TARGET=wolfhal_stm32wb +BOARD=stm32wb_nucleo +``` + +- `TARGET` selects the MCU family HAL implementation (`hal/wolfhal_stm32wb.c`) +- `BOARD` selects the board configuration file (`hal/boards/stm32wb_nucleo.c`) + +## Adding a New Board + +To add a new board for an existing MCU family (e.g. a custom STM32WB board): + +1. Create `hal/boards/.c` with the wolfHAL device configuration: + +```c +#include +#include +#ifdef DEBUG_UART +#include +#include +#endif +#include + +/* Forward declarations for circular references */ +whal_Flash g_wbFlash; +whal_Clock g_wbClock; + +/* PLL, clock, and flash configuration for your board */ +static whal_Stm32wbRcc_PllClkCfg pllCfg = { ... }; +static whal_Stm32wbRcc_Cfg rccCfg = { .flash = &g_wbFlash, ... }; +static whal_Stm32wbFlash_Cfg flashCfg = { .clkCtrl = &g_wbClock, ... }; + +/* Minimal clock driver vtable: Enable/Disable are used by the flash, GPIO, and + * UART drivers for peripheral clock gating. GetRate is only needed by the UART + * driver for baud rate calculation. */ +static const whal_ClockDriver clockDriver = { + .Enable = whal_Stm32wbRcc_Enable, + .Disable = whal_Stm32wbRcc_Disable, +#ifdef DEBUG_UART + .GetRate = whal_Stm32wbRccPll_GetRate, +#endif +}; + +/* Device definitions */ +whal_Clock g_wbClock = { + .regmap = { .base = 0x58000000, .size = 0x400 }, + .driver = &clockDriver, + .cfg = &rccCfg, +}; + +whal_Flash g_wbFlash = { + .regmap = { .base = 0x58004000, .size = 0x400 }, + .cfg = &flashCfg, +}; + +#ifdef DEBUG_UART +/* GPIO — UART1 TX/RX pins */ +static whal_Stm32wbGpio_PinCfg gpioPins[] = { ... }; +static whal_Stm32wbGpio_Cfg gpioCfg = { .clkCtrl = &g_wbClock, ... }; + +whal_Gpio g_wbGpio = { + .regmap = { .base = 0x48000000, .size = 0x400 }, + .cfg = &gpioCfg, +}; + +/* UART1 at 115200 baud */ +static whal_Stm32wbUart_Cfg uartCfg = { .clkCtrl = &g_wbClock, .baud = 115200 }; + +whal_Uart g_wbUart = { + .regmap = { .base = 0x40013800, .size = 0x400 }, + .cfg = &uartCfg, +}; +#endif /* DEBUG_UART */ +``` + +The board file exports `g_wbFlash` and `g_wbClock` as non-static globals (and `g_wbGpio`/`g_wbUart` when `DEBUG_UART` is enabled). The HAL implementation references these via `extern`. + +2. Create `config/examples/wolfhal__.config`: + +``` +TARGET=wolfhal_stm32wb +BOARD= +SIGN=ECC256 +HASH=SHA256 +WOLFBOOT_SECTOR_SIZE=0x1000 +WOLFBOOT_PARTITION_SIZE=0x20000 +WOLFBOOT_PARTITION_BOOT_ADDRESS=0x08008000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08028000 +WOLFBOOT_PARTITION_SWAP_ADDRESS=0x08048000 +NVM_FLASH_WRITEONCE=1 +``` + +Adjust partition addresses and sizes for your board's flash layout. + +Optionally add `DEBUG_UART=1` to enable UART debug output via wolfHAL. + +### RAM_CODE + +When `RAM_CODE=1` is set, wolfBoot's core flash update functions are placed in RAM +via the `RAMFUNCTION` attribute. For wolfHAL targets, the wolfHAL flash driver +(`stm32wb_flash.o`) is also placed in RAM using `EXCLUDE_FILE` directives in the +linker script. This ensures all flash operations execute from RAM, which is required +on some MCUs that stall or fault when code executes from the same flash bank being +programmed. + +``` +RAM_CODE=1 +``` + +The linker script (`hal/stm32wb.ld`) uses `@WOLFHAL_FLASH_EXCLUDE_TEXT@`, +`@WOLFHAL_FLASH_EXCLUDE_RODATA@`, and `@WOLFHAL_FLASH_RAM_SECTIONS@` placeholders +that are substituted at build time. When `RAM_CODE=1`, these expand to +`EXCLUDE_FILE(*stm32wb_flash.o)` rules that move the flash driver's `.text` and +`.rodata` sections from flash into the `.data` section (loaded to RAM at startup). +When `RAM_CODE` is not set, all code remains in flash as normal. + +## Adding a New MCU Family + +To add support for a new MCU family (e.g. STM32H7): + +1. Create `hal/wolfhal_.c` implementing the wolfBoot HAL functions. Use the appropriate wolfHAL driver headers and call driver functions directly for minimal overhead: + +```c +#include +#include "hal.h" +#include _rcc.h> +#include _flash.h> +#ifdef DEBUG_UART +#include _gpio.h> +#include _uart.h> +#endif + +extern whal_Flash g_wbFlash; +extern whal_Clock g_wbClock; +#ifdef DEBUG_UART +extern whal_Gpio g_wbGpio; +extern whal_Uart g_wbUart; +#endif + +void hal_init(void) +{ + /* Family-specific clock and flash initialization */ +#ifdef DEBUG_UART + /* GPIO and UART initialization */ +#endif +} + +void hal_prepare_boot(void) +{ +#ifdef DEBUG_UART + /* UART and GPIO deinitialization */ +#endif + /* Family-specific flash and clock deinitialization */ +} + +/* hal_flash_unlock, hal_flash_lock, hal_flash_write, hal_flash_erase */ + +#ifdef DEBUG_UART +void uart_write(const char *buf, unsigned int len) +{ + /* Send via wolfHAL UART driver */ +} +#endif +``` + +2. Add the target block in `arch.mk`: + +```makefile +ifeq ($(TARGET),wolfhal_) + ARCH_FLASH_OFFSET=0x08000000 + LSCRIPT_IN=hal/.ld + WOLFHAL_ROOT?=$(WOLFBOOT_ROOT)/lib/wolfHAL + CFLAGS+=-I$(WOLFHAL_ROOT) -DWHAL_CFG_DIRECT_CALLBACKS + OBJS+=./hal/boards/$(BOARD).o + OBJS+=$(WOLFHAL_ROOT)/src//.o +endif +``` + +3. Create at least one board configuration file in `hal/boards/`. + +## Test Application + +The test application (`test-app/app_wolfhal_stm32wb.c`) demonstrates using wolfHAL peripherals beyond what the bootloader needs. It initializes GPIO (LED on PB5) and UART (UART1 at 115200 baud) via wolfHAL, then exercises the wolfBoot update mechanism. + +The test app accesses the board's clock instance via `extern whal_Clock g_wbClock` for peripheral clock gating. + +The test-app compiles its own copy of the board file (`board_.o`) with +`-DDEBUG_UART` always defined, since the app needs `GetRate` in the clock vtable +for UART baud rate calculation. This is independent of the bootloader's +`DEBUG_UART` setting — the bootloader's board object only includes `GetRate` when +`DEBUG_UART=1` is in the config. diff --git a/hal/boards/stm32wb_nucleo.c b/hal/boards/stm32wb_nucleo.c new file mode 100644 index 0000000000..a21bdaa6cd --- /dev/null +++ b/hal/boards/stm32wb_nucleo.c @@ -0,0 +1,145 @@ +/* stm32wb_nucleo.c + * + * wolfHAL board configuration for the STM32WB55 Nucleo + * + * Copyright (C) 2026 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot 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. + * + * wolfBoot 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 +#include +#ifdef DEBUG_UART +#include +#include +#endif +#include + +/* Device instances — defined before configs to break the circular reference */ +whal_Flash g_wbFlash; +whal_Clock g_wbClock; + +/* PLL configuration */ +static whal_Stm32wbRcc_PllClkCfg pllCfg = { + .clkSrc = WHAL_STM32WB_RCC_PLLCLK_SRC_MSI, + /* 64 MHz: (4 MHz MSI / 1) * 32 / 2 = 64 MHz */ + .n = 32, + .m = 0, + .r = 1, + .q = 0, + .p = 0, +}; + +/* Clock configuration — references flash for latency adjustment */ +static whal_Stm32wbRcc_Cfg rccCfg = { + .flash = &g_wbFlash, + .flashLatency = WHAL_STM32WB_FLASH_LATENCY_3, + .sysClkSrc = WHAL_STM32WB_RCC_SYSCLK_SRC_PLL, + .sysClkCfg = &pllCfg, +}; + +/* Flash configuration — references clock for peripheral clock gating */ +static whal_Stm32wbRcc_Clk flashClk = {WHAL_STM32WB55_FLASH_CLOCK}; +static whal_Stm32wbFlash_Cfg flashCfg = { + .clkCtrl = &g_wbClock, + .clk = &flashClk, + .startAddr = 0x08000000, + .size = 0x100000, +}; + +/* Minimal clock driver vtable: Enable/Disable are used by the flash, GPIO, and + * UART drivers for peripheral clock gating. GetRate is only needed by the UART + * driver for baud rate calculation. */ +static const whal_ClockDriver clockDriver = { + .Enable = whal_Stm32wbRcc_Enable, + .Disable = whal_Stm32wbRcc_Disable, +#ifdef DEBUG_UART + .GetRate = whal_Stm32wbRccPll_GetRate, +#endif +}; + +/* Clock controller: PLL driven from MSI at 64 MHz */ +whal_Clock g_wbClock = { + .regmap = { .base = 0x58000000, .size = 0x400 }, + .driver = &clockDriver, + .cfg = &rccCfg, +}; + +/* Flash device */ +whal_Flash g_wbFlash = { + .regmap = { .base = 0x58004000, .size = 0x400 }, + .cfg = &flashCfg, +}; + +#ifdef DEBUG_UART + +/* GPIO pin indices */ +enum { + UART_TX_PIN, + UART_RX_PIN, +}; + +/* GPIO — UART1 TX/RX on PB6/PB7 */ +static whal_Stm32wbRcc_Clk gpiobClk = {WHAL_STM32WB55_GPIOB_CLOCK}; +static whal_Stm32wbGpio_PinCfg gpioPins[] = { + [UART_TX_PIN] = { + .port = WHAL_STM32WB_GPIO_PORT_B, + .pin = 6, + .mode = WHAL_STM32WB_GPIO_MODE_ALTFN, + .outType = WHAL_STM32WB_GPIO_OUTTYPE_PUSHPULL, + .speed = WHAL_STM32WB_GPIO_SPEED_FAST, + .pull = WHAL_STM32WB_GPIO_PULL_UP, + .altFn = 7, + }, + [UART_RX_PIN] = { + .port = WHAL_STM32WB_GPIO_PORT_B, + .pin = 7, + .mode = WHAL_STM32WB_GPIO_MODE_ALTFN, + .outType = WHAL_STM32WB_GPIO_OUTTYPE_PUSHPULL, + .speed = WHAL_STM32WB_GPIO_SPEED_FAST, + .pull = WHAL_STM32WB_GPIO_PULL_UP, + .altFn = 7, + }, +}; + +static whal_Stm32wbGpio_Cfg gpioCfg = { + .clkCtrl = &g_wbClock, + .clk = (const void *[1]) { &gpiobClk }, + .clkCount = 1, + .pinCfg = gpioPins, + .pinCount = 2, +}; + +whal_Gpio g_wbGpio = { + .regmap = { .base = 0x48000000, .size = 0x400 }, + .cfg = &gpioCfg, +}; + +/* UART1 at 115200 baud */ +static whal_Stm32wbRcc_Clk uart1Clk = {WHAL_STM32WB55_UART1_CLOCK}; +static whal_Stm32wbUart_Cfg uartCfg = { + .clkCtrl = &g_wbClock, + .clk = &uart1Clk, + .baud = 115200, +}; + +whal_Uart g_wbUart = { + .regmap = { .base = 0x40013800, .size = 0x400 }, + .cfg = &uartCfg, +}; + +#endif /* DEBUG_UART */ diff --git a/hal/stm32wb.ld b/hal/stm32wb.ld index 14dd5aada4..d7ff658f61 100644 --- a/hal/stm32wb.ld +++ b/hal/stm32wb.ld @@ -10,10 +10,8 @@ SECTIONS { _start_text = .; KEEP(*(.isr_vector)) -; *(EXCLUDE_FILE(*chacha*) .text*) -; *(EXCLUDE_FILE(*chacha*) .rodata*) - *(.text*) - *(.rodata*) + @WOLFHAL_FLASH_EXCLUDE_TEXT@ + @WOLFHAL_FLASH_EXCLUDE_RODATA@ . = ALIGN(4); _end_text = .; } > FLASH @@ -30,9 +28,7 @@ SECTIONS KEEP(*(.data*)) . = ALIGN(4); KEEP(*(.ramcode)) -; KEEP(*(.text.wc_Chacha*)) -; KEEP(*(.rodata.sigma)) -; KEEP(*(.rodata.tau)) + @WOLFHAL_FLASH_RAM_SECTIONS@ . = ALIGN(4); _end_data = .; } > RAM diff --git a/hal/wolfhal_stm32wb.c b/hal/wolfhal_stm32wb.c new file mode 100644 index 0000000000..f1e45316cf --- /dev/null +++ b/hal/wolfhal_stm32wb.c @@ -0,0 +1,85 @@ +/* wolfhal_stm32wb.c + * + * Copyright (C) 2026 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot 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. + * + * wolfBoot 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 +#include "hal.h" +#include "wolfboot/wolfboot.h" +#include +#include +#ifdef DEBUG_UART +#include +#include +#endif + +/* Board-provided device instances */ +extern whal_Flash g_wbFlash; +extern whal_Clock g_wbClock; +#ifdef DEBUG_UART +extern whal_Gpio g_wbGpio; +extern whal_Uart g_wbUart; +#endif + +void hal_init(void) +{ + whal_Stm32wbRccPll_Init(&g_wbClock); + whal_Stm32wbFlash_Init(&g_wbFlash); +#ifdef DEBUG_UART + whal_Stm32wbGpio_Init(&g_wbGpio); + whal_Stm32wbUart_Init(&g_wbUart); +#endif +} + +void hal_prepare_boot(void) +{ +#ifdef DEBUG_UART + whal_Stm32wbUart_Deinit(&g_wbUart); + whal_Stm32wbGpio_Deinit(&g_wbGpio); +#endif + whal_Stm32wbFlash_Deinit(&g_wbFlash); + whal_Stm32wbRccPll_Deinit(&g_wbClock); +} + +void RAMFUNCTION hal_flash_unlock(void) +{ + whal_Stm32wbFlash_Unlock(&g_wbFlash, 0, 0); +} + +void RAMFUNCTION hal_flash_lock(void) +{ + whal_Stm32wbFlash_Lock(&g_wbFlash, 0, 0); +} + +int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len) +{ + return whal_Stm32wbFlash_Write(&g_wbFlash, (size_t)address, data, (size_t)len); +} + +int RAMFUNCTION hal_flash_erase(uint32_t address, int len) +{ + return whal_Stm32wbFlash_Erase(&g_wbFlash, (size_t)address, (size_t)len); +} + +#ifdef DEBUG_UART +void uart_write(const char *buf, unsigned int len) +{ + whal_Stm32wbUart_Send(&g_wbUart, (const uint8_t *)buf, (size_t)len); +} +#endif diff --git a/lib/wolfHAL b/lib/wolfHAL new file mode 160000 index 0000000000..18cde7f238 --- /dev/null +++ b/lib/wolfHAL @@ -0,0 +1 @@ +Subproject commit 18cde7f238eaf0b15ca489fe8fda176e78c269c0 diff --git a/test-app/Makefile b/test-app/Makefile index cb9876ecbd..a347655a17 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -54,7 +54,7 @@ ifeq ($(TARGET),ti_hercules) APP_OBJS:=app_$(TARGET).o ../test-app/libwolfboot.o CFLAGS+=-I"../include" else - CFLAGS+=-Wall -ffreestanding -Wno-unused + CFLAGS+=-Wall -ffreestanding -Wno-unused -ffunction-sections -fdata-sections # Stack usage computation not supported on TriCore ifneq ($(ARCH),AURIX_TC3) CFLAGS+=-Wstack-usage=1024 -nostartfiles @@ -550,6 +550,14 @@ else ifeq ($(TARGET),stm32wb) APP_OBJS+=../hal/uart/uart_drv_$(UART_TARGET).o endif + ifeq ($(TARGET),wolfhal_stm32wb) + WOLFHAL_ROOT?=$(WOLFBOOT_ROOT)/lib/wolfHAL + APP_OBJS+=board_$(BOARD).o + APP_OBJS+=$(WOLFHAL_ROOT)/src/clock/stm32wb_rcc.o + APP_OBJS+=$(WOLFHAL_ROOT)/src/flash/stm32wb_flash.o + APP_OBJS+=$(WOLFHAL_ROOT)/src/gpio/stm32wb_gpio.o + APP_OBJS+=$(WOLFHAL_ROOT)/src/uart/stm32wb_uart.o + endif endif ifeq ($(TARGET),kinetis) @@ -900,6 +908,10 @@ delta-extra-data: image.bin ../hal/spi/spi_drv_$(SPI_TARGET)_ns.o: ../hal/spi/spi_drv_$(SPI_TARGET).c FORCE $(Q)$(CC) $(CFLAGS) -c -o $(@) ../hal/spi/spi_drv_$(SPI_TARGET).c -DNONSECURE_APP +board_$(BOARD).o: ../hal/boards/$(BOARD).c + @echo "\t[CC-$(ARCH)] $@" + $(Q)$(CC) $(CFLAGS) -DDEBUG_UART -c $(OUTPUT_FLAG) $@ $< + %.o:%.c @echo "\t[CC-$(ARCH)] $@" $(Q)$(CC) $(CFLAGS) -c $(OUTPUT_FLAG) $@ $^ diff --git a/test-app/app_wolfhal_stm32wb.c b/test-app/app_wolfhal_stm32wb.c new file mode 100644 index 0000000000..239562f81b --- /dev/null +++ b/test-app/app_wolfhal_stm32wb.c @@ -0,0 +1,157 @@ +/* app_wolfhal_stm32wb.c + * + * Test bare-metal application using wolfHAL for the STM32WB55 Nucleo + * + * Copyright (C) 2026 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot 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. + * + * wolfBoot 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 +#include +#include +#include "hal.h" +#include "wolfboot/wolfboot.h" +#include "target.h" + +#include +#include +#include +#include + +#ifdef TARGET_wolfhal_stm32wb + +/* Re-use the clock instance from the board file */ +extern whal_Clock g_wbClock; + +/* GPIO pin indices */ +enum { + LED_PIN, + UART_TX_PIN, + UART_RX_PIN, +}; + +/* GPIO — LED on PB5, UART1 TX/RX on PB6/PB7 */ +static whal_Gpio wbGpio = { + .regmap = { .base = 0x48000000, .size = 0x400 }, + + .cfg = &(whal_Stm32wbGpio_Cfg) { + .clkCtrl = &g_wbClock, + .clk = (const void *[1]) { + &(whal_Stm32wbRcc_Clk){WHAL_STM32WB55_GPIOB_CLOCK}, + }, + .clkCount = 1, + + .pinCfg = (whal_Stm32wbGpio_PinCfg[3]) { + [LED_PIN] = { + .port = WHAL_STM32WB_GPIO_PORT_B, + .pin = 5, + .mode = WHAL_STM32WB_GPIO_MODE_OUT, + .outType = WHAL_STM32WB_GPIO_OUTTYPE_PUSHPULL, + .speed = WHAL_STM32WB_GPIO_SPEED_LOW, + .pull = WHAL_STM32WB_GPIO_PULL_UP, + }, + [UART_TX_PIN] = { + .port = WHAL_STM32WB_GPIO_PORT_B, + .pin = 6, + .mode = WHAL_STM32WB_GPIO_MODE_ALTFN, + .outType = WHAL_STM32WB_GPIO_OUTTYPE_PUSHPULL, + .speed = WHAL_STM32WB_GPIO_SPEED_FAST, + .pull = WHAL_STM32WB_GPIO_PULL_UP, + .altFn = 7, + }, + [UART_RX_PIN] = { + .port = WHAL_STM32WB_GPIO_PORT_B, + .pin = 7, + .mode = WHAL_STM32WB_GPIO_MODE_ALTFN, + .outType = WHAL_STM32WB_GPIO_OUTTYPE_PUSHPULL, + .speed = WHAL_STM32WB_GPIO_SPEED_FAST, + .pull = WHAL_STM32WB_GPIO_PULL_UP, + .altFn = 7, + }, + }, + .pinCount = 3, + }, +}; + +/* UART1 at 115200 baud */ +static whal_Uart wbUart = { + .regmap = { .base = 0x40013800, .size = 0x400 }, + + .cfg = &(whal_Stm32wbUart_Cfg) { + .clkCtrl = &g_wbClock, + .clk = &(whal_Stm32wbRcc_Clk) {WHAL_STM32WB55_UART1_CLOCK}, + .baud = 115200, + }, +}; + +/* Matches all keys: + * - chacha (32 + 12) + * - aes128 (16 + 16) + * - aes256 (32 + 16) + */ +char enc_key[] = "0123456789abcdef0123456789abcdef" + "0123456789abcdef"; + +volatile uint32_t time_elapsed = 0; + +void main(void) +{ + uint32_t version; + uint32_t updv; + uint8_t ver_buf[5]; + + hal_init(); + + /* Initialize GPIO and UART via wolfHAL */ + whal_Stm32wbGpio_Init(&wbGpio); + whal_Stm32wbUart_Init(&wbUart); + + /* LED on */ + whal_Stm32wbGpio_Set(&wbGpio, LED_PIN, 1); + + version = wolfBoot_current_firmware_version(); + updv = wolfBoot_update_firmware_version(); + + ver_buf[0] = '*'; + ver_buf[1] = (version >> 24) & 0xFF; + ver_buf[2] = (version >> 16) & 0xFF; + ver_buf[3] = (version >> 8) & 0xFF; + ver_buf[4] = version & 0xFF; + whal_Stm32wbUart_Send(&wbUart, ver_buf, sizeof(ver_buf)); + + if ((version == 1) && (updv != 8)) { + /* LED off */ + whal_Stm32wbGpio_Set(&wbGpio, LED_PIN, 0); +#if EXT_ENCRYPTED + wolfBoot_set_encrypt_key((uint8_t *)enc_key, + (uint8_t *)(enc_key + 32)); +#endif + wolfBoot_update_trigger(); + /* LED on */ + whal_Stm32wbGpio_Set(&wbGpio, LED_PIN, 1); + } else { + if (version != 7) + wolfBoot_success(); + } + + /* Wait for reboot */ + while (1) + __asm__ volatile("wfi"); +} + +#endif /* TARGET_wolfhal_stm32wb */