mirror of https://github.com/wolfSSL/wolfBoot.git
Create STM32WB wolfHAL example. GC sections on all test apps
parent
b1ad603363
commit
125872c571
|
|
@ -667,6 +667,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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
16
Makefile
16
Makefile
|
|
@ -174,6 +174,17 @@ export WOLFBOOT_LIB_WOLFHSM
|
|||
## Architecture/CPU configuration
|
||||
include arch.mk
|
||||
|
||||
ifeq ($(TARGET),wolfhal)
|
||||
ifeq ($(strip $(BOARD)),)
|
||||
$(error TARGET=wolfhal requires BOARD to be set, e.g. BOARD=stm32wb_nucleo)
|
||||
endif
|
||||
# wolfHAL target: hal/wolfhal.o is added by the per-TARGET rule
|
||||
# above. The board's board.c provides hal_init/hal_prepare_boot and
|
||||
# the wolfHAL device handles; board.mk pulls in chip drivers.
|
||||
OBJS+=./hal/boards/$(BOARD)/board.o
|
||||
include hal/boards/$(BOARD)/board.mk
|
||||
endif
|
||||
|
||||
# Parse config options
|
||||
include options.mk
|
||||
|
||||
|
|
@ -567,7 +578,10 @@ $(LSCRIPT): $(LSCRIPT_IN) FORCE
|
|||
sed -e "s/@WOLFBOOT_LOAD_ADDRESS@/$(WOLFBOOT_LOAD_ADDRESS)/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/@L2SRAM_ADDR@/$(L2SRAM_ADDR)/g" \
|
||||
sed -e "s/@L2SRAM_ADDR@/$(L2SRAM_ADDR)/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
|
||||
|
|
|
|||
11
arch.mk
11
arch.mk
|
|
@ -223,6 +223,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
|
||||
|
|
@ -238,7 +243,6 @@ ifeq ($(ARCH),ARM)
|
|||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(TARGET),stm32l5)
|
||||
CORTEX_M33=1
|
||||
CFLAGS+=-Ihal
|
||||
|
|
@ -570,6 +574,11 @@ endif
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),wolfhal)
|
||||
WOLFHAL_ROOT?=$(WOLFBOOT_ROOT)/lib/wolfHAL
|
||||
CFLAGS+=-I$(WOLFHAL_ROOT) -Ihal/boards/$(BOARD)
|
||||
endif
|
||||
|
||||
|
||||
## Renesas RX
|
||||
ifeq ($(ARCH),RENESAS_RX)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
TARGET=wolfhal
|
||||
BOARD=stm32wb_nucleo
|
||||
PKA=0
|
||||
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
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
# wolfHAL Integration
|
||||
|
||||
wolfBoot supports [wolfHAL](https://github.com/wolfSSL/wolfHAL) as an alternative
|
||||
hardware abstraction layer backend. wolfHAL provides portable drivers for common MCU
|
||||
peripherals (clock, flash, GPIO, UART, SPI, etc.) with a consistent API across
|
||||
platforms.
|
||||
|
||||
## Overview
|
||||
|
||||
The wolfHAL integration uses a single generic `TARGET=wolfhal` with a per-board
|
||||
abstraction layer. All board-specific details — device instances, driver bindings,
|
||||
build flags, and linker scripts — live in a self-contained board directory. Adding
|
||||
support for a new board or MCU family requires no changes to the core build system or
|
||||
HAL shim.
|
||||
|
||||
The integration uses wolfHAL's **direct API mapping** feature. Each platform
|
||||
driver source provides an optional `#ifdef` block that renames its driver
|
||||
functions to the top-level API names. When the corresponding
|
||||
`WHAL_CFG_<TYPE>_API_MAPPING_<VARIANT>` flag is defined, the driver file
|
||||
itself provides the definition of the top-level API — no wrapper, no vtable
|
||||
indirection, no runtime null-check. Calling `whal_Flash_Write(&dev, ...)` links
|
||||
directly to the platform driver's implementation.
|
||||
|
||||
The integration consists of four parts:
|
||||
|
||||
1. **Generic HAL shim** (`hal/wolfhal.c`) — implements the wolfBoot HAL API
|
||||
(`hal_flash_write`, `hal_flash_erase`, etc.) by calling the top-level wolfHAL
|
||||
API (`whal_Flash_Write`, `whal_Uart_Send`, etc.). This file is shared across
|
||||
all wolfHAL boards.
|
||||
|
||||
2. **Board directory** (`hal/boards/<board>/`) — contains three files that fully
|
||||
describe a board:
|
||||
- `board.h` — includes the chip-specific wolfHAL driver headers and defines
|
||||
any board-level pin/peripheral enums.
|
||||
- `board.c` — device instances (clock, flash, GPIO, UART), configuration
|
||||
structs, and `hal_init`/`hal_prepare_boot` implementations.
|
||||
- `board.mk` — build variables (`ARCH_FLASH_OFFSET`, `LSCRIPT_IN`, the
|
||||
`WHAL_CFG_*_API_MAPPING_*` flags, wolfHAL driver objects, `RAM_CODE`
|
||||
linker rules).
|
||||
|
||||
3. **Generic test application** (`test-app/app_wolfhal.c`) — demonstrates using
|
||||
wolfHAL peripherals (GPIO, UART) beyond what the bootloader needs, using the
|
||||
same top-level wolfHAL API.
|
||||
|
||||
4. **wolfHAL library** (`lib/wolfHAL/`) — the wolfHAL submodule containing the
|
||||
platform drivers.
|
||||
|
||||
### How It Fits Together
|
||||
|
||||
```
|
||||
config/examples/wolfhal_<board>.config
|
||||
└─ TARGET=wolfhal BOARD=<board>
|
||||
|
||||
arch.mk
|
||||
└─ Sets WOLFHAL_ROOT, CFLAGS += -Ihal/boards/$(BOARD)
|
||||
|
||||
Makefile
|
||||
└─ OBJS += hal/boards/$(BOARD)/board.o
|
||||
└─ include hal/boards/$(BOARD)/board.mk
|
||||
|
||||
hal/wolfhal.c (generic — calls whal_Flash_Write, whal_Uart_Send, etc.)
|
||||
└─ #include "board.h" (resolved via -I to the board directory)
|
||||
|
||||
hal/boards/<board>/
|
||||
├─ board.h (includes wolfHAL driver headers, pin enums)
|
||||
├─ board.c (device instances, hal_init, hal_prepare_boot)
|
||||
└─ board.mk (WHAL_CFG_*_API_MAPPING_*, driver objects, RAM_CODE rules)
|
||||
```
|
||||
|
||||
The `WHAL_CFG_*_API_MAPPING_*` flags cause each wolfHAL driver source to emit
|
||||
its functions under the top-level API name. Since only one driver source per
|
||||
device type is compiled, there is no conflict — and since no dispatch source
|
||||
(e.g., `src/flash/flash.c`) is included, there is no vtable indirection. The
|
||||
linker can garbage-collect any unused symbols with `-Wl,--gc-sections`.
|
||||
|
||||
## Configuration
|
||||
|
||||
A wolfHAL-based config requires two variables beyond the standard wolfBoot settings:
|
||||
|
||||
```
|
||||
TARGET=wolfhal
|
||||
BOARD=stm32wb_nucleo
|
||||
```
|
||||
|
||||
- `TARGET=wolfhal` selects the generic wolfHAL HAL shim and build path.
|
||||
- `BOARD` selects the board directory under `hal/boards/`.
|
||||
|
||||
See `config/examples/wolfhal_*.config` for complete examples.
|
||||
|
||||
## Adding a New Board
|
||||
|
||||
To add a new board, create a directory `hal/boards/<board_name>/` with three files:
|
||||
|
||||
### 1. `board.h` — Driver Headers and Pin Enums
|
||||
|
||||
Include the chip-specific wolfHAL driver headers and declare any board-level
|
||||
enums (pin indices, peripheral identifiers):
|
||||
|
||||
```c
|
||||
#ifndef WOLFHAL_BOARD_H
|
||||
#define WOLFHAL_BOARD_H
|
||||
|
||||
#include <wolfHAL/clock/<family>_rcc.h>
|
||||
#include <wolfHAL/flash/<family>_flash.h>
|
||||
#include <wolfHAL/gpio/<family>_gpio.h>
|
||||
#include <wolfHAL/uart/<family>_uart.h>
|
||||
|
||||
/* GPIO pin indices (matches pin array in board.c) */
|
||||
enum {
|
||||
BOARD_LED_PIN,
|
||||
BOARD_UART_TX_PIN,
|
||||
BOARD_UART_RX_PIN,
|
||||
BOARD_PIN_COUNT,
|
||||
};
|
||||
|
||||
#endif /* WOLFHAL_BOARD_H */
|
||||
```
|
||||
|
||||
### 2. `board.c` — Device Instances and Initialization
|
||||
|
||||
Define the wolfHAL device instances and implement `hal_init` and `hal_prepare_boot`
|
||||
using the top-level wolfHAL API. The file must export `g_wbFlash` (and `g_wbUart`
|
||||
when `DEBUG_UART` is enabled) as non-static globals — these are referenced by
|
||||
`hal/wolfhal.c` via `extern`.
|
||||
|
||||
```c
|
||||
#include "hal.h"
|
||||
#include "board.h"
|
||||
|
||||
/* Clock controller */
|
||||
whal_Clock g_wbClock = {
|
||||
.regmap = { .base = ..., .size = 0x400 },
|
||||
.cfg = &(whal_<Family>Rcc_Cfg) { ... },
|
||||
};
|
||||
|
||||
/* Flash */
|
||||
whal_Flash g_wbFlash = {
|
||||
.regmap = { .base = ..., .size = 0x400 },
|
||||
.cfg = &(whal_<Family>Flash_Cfg) {
|
||||
.startAddr = 0x08000000,
|
||||
.size = ...,
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef DEBUG_UART
|
||||
whal_Gpio g_wbGpio = { ... };
|
||||
whal_Uart g_wbUart = { ... };
|
||||
#endif
|
||||
|
||||
void hal_init(void)
|
||||
{
|
||||
whal_Clock_Init(&g_wbClock);
|
||||
whal_Flash_Init(&g_wbFlash);
|
||||
#ifdef DEBUG_UART
|
||||
whal_Gpio_Init(&g_wbGpio);
|
||||
whal_Uart_Init(&g_wbUart);
|
||||
#endif
|
||||
}
|
||||
|
||||
void hal_prepare_boot(void)
|
||||
{
|
||||
#ifdef DEBUG_UART
|
||||
whal_Uart_Deinit(&g_wbUart);
|
||||
whal_Gpio_Deinit(&g_wbGpio);
|
||||
#endif
|
||||
whal_Flash_Deinit(&g_wbFlash);
|
||||
whal_Clock_Deinit(&g_wbClock);
|
||||
}
|
||||
```
|
||||
|
||||
Note: the device instance's `.driver` field is intentionally left unset. With
|
||||
API mapping, the top-level `whal_*_Init`/etc. symbols are the driver functions
|
||||
themselves — there is no dispatch through a vtable.
|
||||
|
||||
### 3. `board.mk` — Build Variables
|
||||
|
||||
Provide the build-time configuration: API mapping flags, flash offset, linker
|
||||
script, and the wolfHAL driver objects needed for your MCU family. **Do not
|
||||
compile the dispatch source (`src/<type>/<type>.c`)** — it would provide a
|
||||
duplicate definition of the top-level API symbols.
|
||||
|
||||
```makefile
|
||||
ARCH_FLASH_OFFSET=0x08000000
|
||||
LSCRIPT_IN=hal/<family>.ld
|
||||
|
||||
# Bind wolfHAL driver sources directly to the top-level API symbols.
|
||||
CFLAGS+=-DWHAL_CFG_CLOCK_API_MAPPING_<FAMILY>
|
||||
CFLAGS+=-DWHAL_CFG_FLASH_API_MAPPING_<FAMILY>
|
||||
CFLAGS+=-DWHAL_CFG_GPIO_API_MAPPING_<FAMILY>
|
||||
CFLAGS+=-DWHAL_CFG_UART_API_MAPPING_<FAMILY>
|
||||
|
||||
WOLFHAL_OBJS+=$(WOLFHAL_ROOT)/src/clock/<family>_rcc.o
|
||||
WOLFHAL_OBJS+=$(WOLFHAL_ROOT)/src/flash/<family>_flash.o
|
||||
ifeq ($(DEBUG_UART),1)
|
||||
WOLFHAL_OBJS+=$(WOLFHAL_ROOT)/src/gpio/<family>_gpio.o
|
||||
WOLFHAL_OBJS+=$(WOLFHAL_ROOT)/src/uart/<family>_uart.o
|
||||
endif
|
||||
|
||||
OBJS+=$(WOLFHAL_OBJS)
|
||||
APP_OBJS+=$(WOLFHAL_OBJS)
|
||||
|
||||
ifeq ($(RAM_CODE),1)
|
||||
WOLFHAL_FLASH_EXCLUDE_TEXT=*(EXCLUDE_FILE(*<family>_flash.o) .text*)
|
||||
WOLFHAL_FLASH_EXCLUDE_RODATA=*(EXCLUDE_FILE(*<family>_flash.o) .rodata*)
|
||||
WOLFHAL_FLASH_RAM_SECTIONS=*<family>_flash.o(.text* .rodata*)
|
||||
endif
|
||||
```
|
||||
|
||||
Only one API mapping flag may be active per device type per build.
|
||||
|
||||
### 4. Config File
|
||||
|
||||
Create `config/examples/wolfhal_<board_name>.config`:
|
||||
|
||||
```
|
||||
TARGET=wolfhal
|
||||
BOARD=<board_name>
|
||||
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 sector sizes for your board's flash layout. Optionally
|
||||
add `DEBUG_UART=1` to enable UART debug output.
|
||||
|
||||
## RAM_CODE
|
||||
|
||||
When `RAM_CODE=1` is set, wolfBoot's core flash update functions are placed in RAM
|
||||
via the `RAMFUNCTION` attribute. For wolfHAL boards, the `board.mk` defines
|
||||
`EXCLUDE_FILE` rules that also place the wolfHAL flash driver into RAM. This ensures
|
||||
all flash operations execute from RAM, which is required on MCUs that stall or fault
|
||||
when code executes from the same flash bank being programmed.
|
||||
|
||||
The linker script 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` 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.
|
||||
|
||||
## Test Application
|
||||
|
||||
The generic test application (`test-app/app_wolfhal.c`) demonstrates using wolfHAL
|
||||
peripherals beyond what the bootloader needs. It accesses the board-provided GPIO and
|
||||
UART instances (`g_wbGpio`, `g_wbUart`) via `extern`, using the top-level wolfHAL
|
||||
API (`whal_Gpio_Set`, `whal_Uart_Send`) to toggle an LED and send serial output,
|
||||
then exercises the wolfBoot update mechanism.
|
||||
|
||||
The test-app Makefile compiles its own copy of the board file (`board_<board>.o`)
|
||||
with `DEBUG_UART=1` always defined, since the app needs UART and GPIO regardless of
|
||||
the bootloader's `DEBUG_UART` setting.
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/* board.c
|
||||
*
|
||||
* STM32WB55 Nucleo board configuration using upstream wolfHAL drivers.
|
||||
* Gpio/Flash/Uart singletons are instantiated by the driver .c files
|
||||
* from WHAL_CFG_STM32WB_*_DEV initializer macros in board.h; board.c
|
||||
* uses the BOARD_*_DEV handles for the rest. RCC is header-inlined and
|
||||
* hardcodes WHAL_STM32WB_RCC_BASE — no dev pointer needed.
|
||||
*
|
||||
* 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 <stddef.h>
|
||||
#include "hal.h"
|
||||
#include "board.h"
|
||||
|
||||
#ifdef DEBUG_UART
|
||||
static const whal_Stm32wb_Rcc_PeriphClk g_periphClks[] = {
|
||||
{WHAL_STM32WB55_GPIOB_GATE},
|
||||
{WHAL_STM32WB55_UART1_GATE},
|
||||
};
|
||||
#define PERIPH_CLK_COUNT (sizeof(g_periphClks) / sizeof(g_periphClks[0]))
|
||||
#endif
|
||||
|
||||
/* MSI 4 MHz -> PLL VCO 128 MHz -> PLLR /2 = 64 MHz -> SYSCLK */
|
||||
static void pll_clock_on(void)
|
||||
{
|
||||
whal_Stm32wb_Flash_Ext_SetLatency(BOARD_FLASH_DEV, WHAL_STM32WB_FLASH_LATENCY_3);
|
||||
whal_Stm32wb_Rcc_EnablePll(&(whal_Stm32wb_Rcc_PllCfg){
|
||||
.clkSrc = WHAL_STM32WB_RCC_PLLCLK_SRC_MSI,
|
||||
.n = 32, .m = 0, .r = 1, .q = 0, .p = 0,
|
||||
});
|
||||
whal_Stm32wb_Rcc_SetSysClock(WHAL_STM32WB_RCC_SYSCLK_SRC_PLL);
|
||||
}
|
||||
|
||||
static void pll_clock_off(void)
|
||||
{
|
||||
whal_Stm32wb_Rcc_SetSysClock(WHAL_STM32WB_RCC_SYSCLK_SRC_MSI);
|
||||
whal_Stm32wb_Rcc_DisablePll();
|
||||
whal_Stm32wb_Flash_Ext_SetLatency(BOARD_FLASH_DEV, WHAL_STM32WB_FLASH_LATENCY_0);
|
||||
}
|
||||
|
||||
void hal_init(void)
|
||||
{
|
||||
pll_clock_on();
|
||||
whal_Flash_Init(BOARD_FLASH_DEV);
|
||||
|
||||
#ifdef DEBUG_UART
|
||||
for (size_t i = 0; i < PERIPH_CLK_COUNT; i++) {
|
||||
whal_Stm32wb_Rcc_EnablePeriphClk(&g_periphClks[i]);
|
||||
}
|
||||
|
||||
whal_Gpio_Init(BOARD_GPIO_DEV);
|
||||
whal_Uart_Init(BOARD_UART_DEV);
|
||||
#endif
|
||||
}
|
||||
|
||||
void hal_prepare_boot(void)
|
||||
{
|
||||
#ifdef DEBUG_UART
|
||||
whal_Uart_Deinit(BOARD_UART_DEV);
|
||||
whal_Gpio_Deinit(BOARD_GPIO_DEV);
|
||||
|
||||
for (size_t i = PERIPH_CLK_COUNT; i-- > 0; ) {
|
||||
whal_Stm32wb_Rcc_DisablePeriphClk(&g_periphClks[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
whal_Flash_Deinit(BOARD_FLASH_DEV);
|
||||
pll_clock_off();
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/* board.h
|
||||
*
|
||||
* STM32WB55 Nucleo wolfHAL board header. Provides the WHAL_CFG_STM32WB_X_DEV
|
||||
* initializer macros that the upstream chip drivers use to instantiate the
|
||||
* whal_Stm32wb_X_Dev singletons (in their own .c file), plus the BOARD_X_DEV
|
||||
* handles that the wolfBoot adapter (hal/wolfhal.c) and board.c pass into
|
||||
* the wolfHAL API.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef WOLFHAL_BOARD_H
|
||||
#define WOLFHAL_BOARD_H
|
||||
|
||||
#include <wolfHAL/wolfHAL.h>
|
||||
#include <wolfHAL/platform/st/stm32wb55xx.h>
|
||||
#include <wolfHAL/clock/stm32wb_rcc.h>
|
||||
#include <wolfHAL/flash/stm32wb_flash.h>
|
||||
#include <wolfHAL/gpio/stm32wb_gpio.h>
|
||||
#include <wolfHAL/uart/stm32wb_uart.h>
|
||||
|
||||
/* GPIO pin indices used by the runtime-addressable pinCfg table. */
|
||||
enum {
|
||||
BOARD_LED_PIN,
|
||||
BOARD_UART_TX_PIN,
|
||||
BOARD_UART_RX_PIN,
|
||||
BOARD_PIN_COUNT,
|
||||
};
|
||||
|
||||
/* Singletons owned by the upstream driver .c files. Declared here so
|
||||
* BOARD_FLASH_DEV can take its address. */
|
||||
extern const whal_Gpio whal_Stm32wb_Gpio_Dev;
|
||||
extern const whal_Flash whal_Stm32wb_Flash_Dev;
|
||||
extern const whal_Uart whal_Stm32wb_Uart_Dev;
|
||||
|
||||
/* Device handles passed into the wolfHAL API. GPIO/UART use the
|
||||
* INTERNAL_DEV sentinel (the SINGLE_INSTANCE drivers ignore the dev
|
||||
* pointer and read from their static singleton); FLASH takes the
|
||||
* address so it could coexist with another flash driver in the future
|
||||
* without API churn. */
|
||||
#define BOARD_GPIO_DEV WHAL_INTERNAL_DEV
|
||||
#define BOARD_UART_DEV WHAL_INTERNAL_DEV
|
||||
#define BOARD_FLASH_DEV WHAL_INTERNAL_DEV
|
||||
|
||||
/* GPIO singleton initializer — instantiated by stm32wb_gpio.c. */
|
||||
#define WHAL_CFG_STM32WB_GPIO_DEV { \
|
||||
.base = WHAL_STM32WB55_GPIO_BASE, \
|
||||
.cfg = (void *)&(const whal_Stm32wb_Gpio_Cfg){ \
|
||||
.pinCfg = (const whal_Stm32wb_Gpio_PinCfg[BOARD_PIN_COUNT]){ \
|
||||
[BOARD_LED_PIN] = WHAL_STM32WB_GPIO_PIN( \
|
||||
WHAL_STM32WB_GPIO_PORT_B, 5, WHAL_STM32WB_GPIO_MODE_OUT, \
|
||||
WHAL_STM32WB_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32WB_GPIO_SPEED_LOW, \
|
||||
WHAL_STM32WB_GPIO_PULL_UP, 0), \
|
||||
[BOARD_UART_TX_PIN] = WHAL_STM32WB_GPIO_PIN( \
|
||||
WHAL_STM32WB_GPIO_PORT_B, 6, WHAL_STM32WB_GPIO_MODE_ALTFN, \
|
||||
WHAL_STM32WB_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32WB_GPIO_SPEED_FAST, \
|
||||
WHAL_STM32WB_GPIO_PULL_UP, 7), \
|
||||
[BOARD_UART_RX_PIN] = WHAL_STM32WB_GPIO_PIN( \
|
||||
WHAL_STM32WB_GPIO_PORT_B, 7, WHAL_STM32WB_GPIO_MODE_ALTFN, \
|
||||
WHAL_STM32WB_GPIO_OUTTYPE_PUSHPULL, WHAL_STM32WB_GPIO_SPEED_FAST, \
|
||||
WHAL_STM32WB_GPIO_PULL_UP, 7), \
|
||||
}, \
|
||||
.pinCount = BOARD_PIN_COUNT, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/* Flash singleton initializer — instantiated by stm32wb_flash.c. */
|
||||
#define WHAL_CFG_STM32WB_FLASH_DEV { \
|
||||
.base = WHAL_STM32WB55_FLASH_BASE, \
|
||||
.cfg = (void *)&(const whal_Stm32wb_Flash_Cfg){ \
|
||||
.startAddr = 0x08000000, \
|
||||
.size = 0x100000, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/* UART singleton initializer — instantiated by stm32wb_uart.c when
|
||||
* WHAL_CFG_STM32WB_UART_SINGLE_INSTANCE is defined. */
|
||||
#define WHAL_CFG_STM32WB_UART_DEV { \
|
||||
.base = WHAL_STM32WB55_UART1_BASE, \
|
||||
.cfg = (void *)&(const whal_Stm32wb_Uart_Cfg){ \
|
||||
.brr = WHAL_STM32WB_UART_BRR(64000000, 115200), \
|
||||
}, \
|
||||
}
|
||||
|
||||
#endif /* WOLFHAL_BOARD_H */
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
ARCH_FLASH_OFFSET=0x08000000
|
||||
LSCRIPT_IN=hal/stm32wb.ld
|
||||
|
||||
CFLAGS+=-DWHAL_CFG_NO_TIMEOUT
|
||||
|
||||
# Upstream wolfHAL drivers from lib/wolfHAL/src/. wolfBoot's hal_flash_*
|
||||
# contract is satisfied by hal/wolfhal.c (added automatically because
|
||||
# TARGET=wolfhal) calling whal_Flash_*.
|
||||
|
||||
CFLAGS+=-DWHAL_CFG_STM32WB_FLASH_DIRECT_API_MAPPING
|
||||
CFLAGS+=-DWHAL_CFG_STM32WB_GPIO_DIRECT_API_MAPPING
|
||||
CFLAGS+=-DWHAL_CFG_STM32WB_UART_DIRECT_API_MAPPING
|
||||
# UART driver is single-instance — reads whal_Stm32wb_Uart_Dev from board.h
|
||||
# instead of the passed dev pointer.
|
||||
CFLAGS+=-DWHAL_CFG_STM32WB_UART_SINGLE_INSTANCE
|
||||
|
||||
WOLFHAL_OBJS+=$(WOLFHAL_ROOT)/src/reg.o
|
||||
WOLFHAL_OBJS+=$(WOLFHAL_ROOT)/src/flash/stm32wb_flash.o
|
||||
ifeq ($(DEBUG_UART),1)
|
||||
WOLFHAL_OBJS+=$(WOLFHAL_ROOT)/src/gpio/stm32wb_gpio.o
|
||||
WOLFHAL_OBJS+=$(WOLFHAL_ROOT)/src/uart/stm32wb_uart.o
|
||||
endif
|
||||
|
||||
OBJS+=$(WOLFHAL_OBJS)
|
||||
APP_OBJS+=$(WOLFHAL_OBJS)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
/* wolfhal.c
|
||||
*
|
||||
* Generic wolfHAL port for wolfBoot. wolfBoot's HAL contract
|
||||
* (hal_flash_*, uart_write) is satisfied here by forwarding to the
|
||||
* wolfHAL API. The chip drivers behind the wolfHAL API are singletons,
|
||||
* instantiated by the driver .c files from initializer macros in
|
||||
* board.h; this file passes the BOARD_*_DEV handles defined there.
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include "hal.h"
|
||||
#include "wolfboot/wolfboot.h"
|
||||
#include "board.h"
|
||||
|
||||
void RAMFUNCTION hal_flash_unlock(void)
|
||||
{
|
||||
whal_Flash_Unlock(BOARD_FLASH_DEV, 0, 0);
|
||||
}
|
||||
|
||||
void RAMFUNCTION hal_flash_lock(void)
|
||||
{
|
||||
whal_Flash_Lock(BOARD_FLASH_DEV, 0, 0);
|
||||
}
|
||||
|
||||
int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
|
||||
{
|
||||
return whal_Flash_Write(BOARD_FLASH_DEV, (size_t)address, data, (size_t)len);
|
||||
}
|
||||
|
||||
int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
|
||||
{
|
||||
return whal_Flash_Erase(BOARD_FLASH_DEV, (size_t)address, (size_t)len);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_UART
|
||||
void uart_write(const char *buf, unsigned int len)
|
||||
{
|
||||
whal_Uart_Send(BOARD_UART_DEV, (const uint8_t *)buf, (size_t)len);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 2bc2938b0bbcc977177153a7f38393710702bf70
|
||||
|
|
@ -1215,7 +1215,9 @@ OBJS+=$(SECURE_OBJS)
|
|||
ifeq ($(RAM_CODE),1)
|
||||
ifeq ($(ENCRYPT),1)
|
||||
ifeq ($(ENCRYPT_WITH_CHACHA),1)
|
||||
LSCRIPT_IN=hal/$(TARGET)_chacha_ram.ld
|
||||
ifneq ($(TARGET),wolfhal)
|
||||
LSCRIPT_IN=hal/$(TARGET)_chacha_ram.ld
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH),ARM)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ vpath %.S $(WOLFBOOT_LIB_WOLFSSL)
|
|||
vpath %.c $(WOLFBOOT_LIB_WOLFTPM)
|
||||
vpath %.S $(WOLFBOOT_LIB_WOLFTPM)
|
||||
|
||||
WOLFBOOT_ROOT?=..
|
||||
TARGET?=none
|
||||
ARCH?=ARM
|
||||
MCUXPRESSO_CMSIS?=$(MCUXPRESSO)/CMSIS
|
||||
|
|
@ -68,7 +69,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)
|
||||
ifneq ($(USE_CLANG),1)
|
||||
|
|
@ -89,6 +90,8 @@ else
|
|||
APP_OBJS:=app_renesas_rx.o ../test-app/libwolfboot.o ../src/boot_renesas.o ../src/boot_renesas_start.o ../hal/renesas-rx.o
|
||||
LDFLAGS+=-ffreestanding -nostartfiles
|
||||
CFLAGS+=-DWOLFBOOT_RENESAS_APP
|
||||
else ifeq ($(TARGET),wolfhal)
|
||||
APP_OBJS:=app_wolfhal.o led.o system.o timer.o ../test-app/libwolfboot.o
|
||||
else
|
||||
APP_OBJS:=app_$(TARGET).o led.o system.o timer.o ../test-app/libwolfboot.o
|
||||
endif
|
||||
|
|
@ -682,13 +685,24 @@ ifeq ($(QSPI_FLASH),1)
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),wolfhal)
|
||||
ifeq ($(strip $(BOARD)),)
|
||||
$(error TARGET=wolfhal requires BOARD to be set, e.g. BOARD=stm32wb_nucleo)
|
||||
endif
|
||||
WOLFHAL_ROOT?=$(WOLFBOOT_ROOT)/lib/wolfHAL
|
||||
CFLAGS+=-I$(WOLFHAL_ROOT) -DWHAL_CFG_NO_TIMEOUT -I$(WOLFBOOT_ROOT)/hal/boards/$(BOARD)
|
||||
DEBUG_UART=1
|
||||
APP_OBJS+=board_$(BOARD).o
|
||||
# hal/wolfhal.o is added by the generic ../hal/$(TARGET).o rule below
|
||||
# when TARGET=wolfhal, so we don't add it explicitly here.
|
||||
include $(WOLFBOOT_ROOT)/hal/boards/$(BOARD)/board.mk
|
||||
endif
|
||||
|
||||
ifeq ($(UART_FLASH),1)
|
||||
CFLAGS+=-D"UART_FLASH=1"
|
||||
APP_OBJS+= ../src/uart_flash.o ../hal/uart/uart_drv_$(UART_TARGET).o
|
||||
else
|
||||
ifeq ($(TARGET),stm32wb)
|
||||
APP_OBJS+=../hal/uart/uart_drv_$(UART_TARGET).o
|
||||
endif
|
||||
else ifeq ($(TARGET),stm32wb)
|
||||
APP_OBJS+=../hal/uart/uart_drv_$(UART_TARGET).o
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),kinetis)
|
||||
|
|
@ -1139,6 +1153,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)/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) $@ $^
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
/* app_wolfhal.c
|
||||
*
|
||||
* Generic test bare-metal application using wolfHAL
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "hal.h"
|
||||
#include "wolfboot/wolfboot.h"
|
||||
#include "target.h"
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#ifdef TARGET_wolfhal
|
||||
|
||||
/* Chip drivers behind the wolfHAL API are singletons (configured via
|
||||
* board.h). Use the BOARD_*_DEV handles defined there. */
|
||||
|
||||
/* 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();
|
||||
|
||||
/* LED on */
|
||||
whal_Gpio_Set(BOARD_GPIO_DEV, BOARD_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_Uart_Send(BOARD_UART_DEV, ver_buf, sizeof(ver_buf));
|
||||
|
||||
if ((version == 1) && (updv != 8)) {
|
||||
/* LED off */
|
||||
whal_Gpio_Set(BOARD_GPIO_DEV, BOARD_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_Gpio_Set(BOARD_GPIO_DEV, BOARD_LED_PIN, 1);
|
||||
} else {
|
||||
if (version != 7)
|
||||
wolfBoot_success();
|
||||
}
|
||||
|
||||
/* Wait for reboot */
|
||||
while (1)
|
||||
__asm__ volatile("wfi");
|
||||
}
|
||||
|
||||
#endif /* TARGET_wolfhal */
|
||||
Loading…
Reference in New Issue