Merge 20d56607d3 into e691776d7f
commit
ba335b871f
|
|
@ -0,0 +1,45 @@
|
|||
name: 'Build a wolfHAL board'
|
||||
description: 'Cross-build the wolfHAL example for one board and assert the port is linked'
|
||||
|
||||
inputs:
|
||||
board:
|
||||
description: 'directory name under wolfHAL/boards'
|
||||
required: true
|
||||
wolfssl-root:
|
||||
description: 'path to the wolfSSL source tree to compile wolfCrypt from'
|
||||
required: false
|
||||
default: '/tmp/wolfssl'
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
board='${{ inputs.board }}'
|
||||
[ -f "wolfHAL/boards/$board/board.mk" ] \
|
||||
|| { echo "no such board: wolfHAL/boards/$board/board.mk"; exit 1; }
|
||||
|
||||
make -C wolfHAL BOARD="$board" WOLFSSL_ROOT='${{ inputs.wolfssl-root }}' -j"$(nproc)"
|
||||
|
||||
# The board declares its own toolchain, so ask make rather than assume
|
||||
# a prefix here.
|
||||
cross=$(make -s -C wolfHAL BOARD="$board" print-CROSS_COMPILE)
|
||||
elf=wolfHAL/wolfcrypt_test.elf
|
||||
arch=$(file -b "$elf")
|
||||
echo "$arch"
|
||||
case "$arch" in
|
||||
*x86-64*) echo "FAIL: host binary, the cross toolchain was not used"; exit 1 ;;
|
||||
esac
|
||||
|
||||
# A build with the port configured away would still link and still be
|
||||
# the right arch, so assert the callback is registered and reaches a
|
||||
# driver. Which modes are offloaded is the board's choice, so accept any.
|
||||
"${cross}nm" "$elf" | grep -q ' T wc_wolfHAL_RegisterDevice' \
|
||||
|| { echo "FAIL: wolfHAL port not linked"; exit 1; }
|
||||
modes=$("${cross}objdump" -d "$elf" --disassemble=wc_wolfHAL_CryptoDevCb \
|
||||
| grep -oE 'whal_Aes(Ecb|Cbc|Gcm|Ccm)_Oneshot' | sort -u | tr '\n' ' ')
|
||||
[ -n "$modes" ] || { echo "FAIL: no AES mode dispatched to wolfHAL"; exit 1; }
|
||||
echo "$board offloads: $modes"
|
||||
|
||||
make -C wolfHAL BOARD="$board" clean >/dev/null
|
||||
|
|
@ -1706,3 +1706,9 @@ examples:
|
|||
path: utasker
|
||||
mode: skip
|
||||
reason: "uTasker project task files; no standalone build"
|
||||
|
||||
- id: wolfhal
|
||||
path: wolfHAL
|
||||
tier: cross
|
||||
profile: all
|
||||
mode: build-only
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ def job_built_paths():
|
|||
("java", "java/https-url"), ("rt1060", "RT1060"),
|
||||
("csharp", "CSharp/wolfSSL-TLS-pq-Client"),
|
||||
("psa", "psa"),
|
||||
("wolfhal", "wolfHAL"),
|
||||
("bsdkm", "kernel/bsdkm"),
|
||||
("cmake", "cmake")):
|
||||
if job in jobs_seen:
|
||||
|
|
|
|||
|
|
@ -151,6 +151,12 @@ jobs:
|
|||
with:
|
||||
caller_run_id: ${{ github.run_id }}
|
||||
|
||||
wolfhal:
|
||||
needs: [refs]
|
||||
uses: ./.github/workflows/wolfhal.yml
|
||||
with:
|
||||
caller_run_id: ${{ github.run_id }}
|
||||
|
||||
ebpf:
|
||||
needs: [refs]
|
||||
uses: ./.github/workflows/ebpf.yml
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
name: wolfHAL
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths:
|
||||
- 'wolfHAL/**'
|
||||
- '.github/workflows/wolfhal.yml'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
paths:
|
||||
- 'wolfHAL/**'
|
||||
- '.github/workflows/wolfhal.yml'
|
||||
# No cron: nightly.yml calls this, so the nightly stays one run and one triage writer
|
||||
workflow_call:
|
||||
inputs:
|
||||
caller_run_id:
|
||||
description: 'run id of the calling workflow; keeps a called run in its own concurrency group'
|
||||
type: string
|
||||
default: ''
|
||||
workflow_dispatch:
|
||||
|
||||
# github.workflow is the CALLER's name in a called workflow, so hardcode ours
|
||||
concurrency:
|
||||
group: ${{ inputs.caller_run_id && format('wolfhal-call-{0}', inputs.caller_run_id) || format('wolfhal-{0}', github.ref) }}
|
||||
cancel-in-progress: ${{ !inputs.caller_run_id }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
resolve:
|
||||
uses: ./.github/workflows/_resolve-wolfssl.yml
|
||||
with:
|
||||
# master only: the wolfHAL crypto-callback port (wolfcrypt/src/port/wolfHAL)
|
||||
# is not in any released tag
|
||||
refs: master
|
||||
|
||||
wolfhal:
|
||||
needs: resolve
|
||||
name: Build / wolfHAL boards, wolfSSL ${{ matrix.wolfssl_ref }}
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }}
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
# The wolfHAL drivers come from the pinned submodule at wolfHAL/wolfHAL.
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- uses: ./.github/actions/apt-update
|
||||
|
||||
# Every toolchain any board under wolfHAL/boards needs, installed once for
|
||||
# the whole run. A board added with a different target adds its packages
|
||||
# here; the per-board prefix comes from that board's CROSS_COMPILE.
|
||||
- name: Install toolchains
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
gcc-arm-none-eabi binutils-arm-none-eabi libnewlib-arm-none-eabi
|
||||
|
||||
- name: Fetch wolfSSL
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# --branch, or every leg silently clones the default branch and the
|
||||
# stable leg builds master
|
||||
bash "$GITHUB_WORKSPACE/.github/scripts/git-clone-retry.sh" -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' \
|
||||
https://github.com/wolfSSL/wolfssl /tmp/wolfssl
|
||||
git -C /tmp/wolfssl log -1 --format='wolfssl at ${{ matrix.wolfssl_ref }}: %h %s'
|
||||
|
||||
# One step per board. A new board is not tested until it is listed
|
||||
# here; `if: !cancelled()` keeps a broken board from hiding the rest.
|
||||
- name: Build stm32wb55xx_nucleo
|
||||
if: '!cancelled()'
|
||||
uses: ./.github/actions/wolfhal-build
|
||||
with:
|
||||
board: stm32wb55xx_nucleo
|
||||
|
|
@ -16,3 +16,6 @@
|
|||
[submodule "android/wolfcryptjni-ndk-gradle/wolfcrypt-jni"]
|
||||
path = android/wolfcryptjni-ndk-gradle/wolfcrypt-jni
|
||||
url = https://github.com/wolfssl/wolfcrypt-jni
|
||||
[submodule "wolfHAL/wolfHAL"]
|
||||
path = wolfHAL/wolfHAL
|
||||
url = https://github.com/wolfSSL/wolfHAL.git
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
wolfcrypt_test.bin
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
# Makefile for the wolfCrypt + wolfHAL example
|
||||
#
|
||||
# Usage:
|
||||
# make
|
||||
# make BOARD=stm32wb55xx_nucleo
|
||||
# make flash
|
||||
|
||||
BOARD ?= stm32wb55xx_nucleo
|
||||
|
||||
WOLFSSL_ROOT ?= $(abspath ../../wolfssl)
|
||||
WHAL_DIR ?= $(abspath wolfHAL)
|
||||
GCC_PATH ?=
|
||||
|
||||
TARGET = wolfcrypt_test
|
||||
IMAGE ?= $(TARGET).bin
|
||||
|
||||
# Toolchain, the direct-API-mapping selection, the wolfHAL drivers this board
|
||||
# needs (BOARD_SOURCE) and the linker script.
|
||||
include boards/$(BOARD)/board.mk
|
||||
|
||||
CFLAGS += -I. -I$(WHAL_DIR) -I$(WOLFSSL_ROOT) -DWOLFSSL_USER_SETTINGS
|
||||
|
||||
# Application
|
||||
SRC = main.c
|
||||
SRC += syscalls.c
|
||||
|
||||
# Board and wolfHAL drivers
|
||||
SRC += $(BOARD_SOURCE)
|
||||
|
||||
# wolfCrypt core
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/wc_port.c
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/memory.c
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/aes.c
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/cryptocb.c
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/sha256.c
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/hash.c
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/random.c
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/logging.c
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/error.c
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/wc_encrypt.c
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/sp_int.c
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/test/test.c
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/benchmark/benchmark.c
|
||||
|
||||
# wolfSSL's wolfHAL port
|
||||
SRC += $(WOLFSSL_ROOT)/wolfcrypt/src/port/wolfHAL/wolfhal.c
|
||||
|
||||
# Objects go under build/ with their path flattened into the name. Compiling in
|
||||
# place would drop ARM objects into the wolfSSL and wolfHAL checkouts, where
|
||||
# they collide with those trees' own builds.
|
||||
OBJDIR = build
|
||||
objname = $(OBJDIR)/$(subst /,_,$(patsubst /%,%,$(basename $(1)))).o
|
||||
OBJ = $(foreach s,$(SRC),$(call objname,$(s)))
|
||||
|
||||
all: $(TARGET).bin
|
||||
$(SIZE) $(TARGET).elf
|
||||
|
||||
$(TARGET).elf: $(OBJ)
|
||||
$(GCC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
|
||||
|
||||
$(TARGET).bin: $(TARGET).elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
|
||||
$(OBJDIR):
|
||||
mkdir -p $@
|
||||
|
||||
define compile_rule
|
||||
$(call objname,$(1)): $(1) | $(OBJDIR)
|
||||
$$(GCC) $$(CFLAGS) -c -o $$@ $$<
|
||||
endef
|
||||
$(foreach s,$(SRC),$(eval $(call compile_rule,$(s))))
|
||||
|
||||
# Flash via openocd (ST-LINK on the Nucleo).
|
||||
flash: $(TARGET).bin
|
||||
openocd -f interface/stlink.cfg -f target/stm32wbx.cfg \
|
||||
-c "program $(TARGET).bin 0x08000000 verify reset exit"
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJDIR) $(TARGET).elf $(TARGET).bin
|
||||
|
||||
# Query a variable, e.g. `make -s BOARD=x print-CROSS_COMPILE`. Lets CI ask the
|
||||
# board for its toolchain rather than keeping a second copy of that mapping.
|
||||
print-%:
|
||||
@echo "$($*)"
|
||||
|
||||
.PHONY: all flash clean
|
||||
|
||||
-include $(OBJ:.o=.d)
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# wolfCrypt + wolfHAL Example
|
||||
|
||||
Runs the wolfCrypt test suite and benchmark on bare metal, with AES and the RNG
|
||||
served by the board's hardware.
|
||||
|
||||
[wolfHAL](https://github.com/wolfSSL/wolfHAL) is a portable hardware abstraction
|
||||
layer with no OS, toolchain or platform dependencies. It provides a common API
|
||||
for accessing hardware functionality, with the platform-specific configuration
|
||||
kept in board files.
|
||||
|
||||
wolfSSL reaches it through `wolfcrypt/src/port/wolfHAL`, which registers a
|
||||
crypto callback at `wolfCrypt_Init()`. wolfCrypt then routes AES to the
|
||||
accelerator and falls back to software for anything the board does not offload.
|
||||
|
||||
## Supported boards
|
||||
|
||||
| Board | Offloaded |
|
||||
| --- | --- |
|
||||
| `stm32wb55xx_nucleo` | AES-ECB/CBC/GCM/CCM on AES1, RNG |
|
||||
|
||||
Each lives in `boards/<name>/` and owns its clock, pin and device setup, its
|
||||
toolchain, and its linker script.
|
||||
|
||||
## Building
|
||||
|
||||
Needs `arm-none-eabi-gcc` and a wolfSSL checkout beside this repository:
|
||||
|
||||
```sh
|
||||
sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi libnewlib-arm-none-eabi
|
||||
git submodule update --init wolfHAL # the wolfHAL drivers
|
||||
make # or: make BOARD=<name>
|
||||
make flash
|
||||
```
|
||||
|
||||
`WOLFSSL_ROOT` defaults to `../../wolfssl` and `WHAL_DIR` to the submodule;
|
||||
override either on the command line. wolfCrypt is compiled from source rather
|
||||
than linked, so no installed `libwolfssl` is involved.
|
||||
|
||||
## Adding a board
|
||||
|
||||
Copy `boards/stm32wb55xx_nucleo/` and adjust `wolfHAL_board.h` (device
|
||||
initializers plus the `WC_WOLFHAL_*_DEV` macros naming what to offload),
|
||||
`wolfHAL_board.c` (bring-up), `board.mk` (toolchain, driver list), `linker.ld`
|
||||
and `ivt.c`. Then add a build step for it in `.github/workflows/wolfhal.yml`.
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
# board.mk — STM32WB55 Nucleo
|
||||
#
|
||||
# Toolchain, the direct-API-mapping selection, and the wolfHAL drivers this
|
||||
# board needs. Only the peripherals the wolfCrypt test uses are built.
|
||||
|
||||
_BOARD_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
|
||||
GCC = $(GCC_PATH)$(CROSS_COMPILE)gcc
|
||||
OBJCOPY = $(GCC_PATH)$(CROSS_COMPILE)objcopy
|
||||
SIZE = $(GCC_PATH)$(CROSS_COMPILE)size
|
||||
|
||||
# Each WHAL_CFG_*_DIRECT_API_MAPPING binds a generic whal_<X>_* entry point
|
||||
# straight to this part's driver, so there is no vtable indirection at runtime.
|
||||
# Drop one and that subsystem falls back to pointer dispatch, which needs the
|
||||
# matching .driver field in the wolfHAL_board.h device initializer.
|
||||
CFLAGS += -Wall -Werror -g3 -Os \
|
||||
-ffreestanding -nostdlib -mcpu=cortex-m4 -mthumb \
|
||||
-ffunction-sections -fdata-sections \
|
||||
-MMD -MP \
|
||||
-DPLATFORM_STM32WB \
|
||||
-DWHAL_CFG_STM32WB_RCC_DIRECT_API_MAPPING \
|
||||
-DWHAL_CFG_STM32WB_GPIO_DIRECT_API_MAPPING \
|
||||
-DWHAL_CFG_STM32WB_UART_DIRECT_API_MAPPING \
|
||||
-DWHAL_CFG_STM32WB_RNG_DIRECT_API_MAPPING \
|
||||
-DWHAL_CFG_STM32WB_AES_INIT_DIRECT_API_MAPPING \
|
||||
-DWHAL_CFG_STM32WB_AES_ECB_DIRECT_API_MAPPING \
|
||||
-DWHAL_CFG_STM32WB_AES_CBC_DIRECT_API_MAPPING \
|
||||
-DWHAL_CFG_STM32WB_AES_CTR_DIRECT_API_MAPPING \
|
||||
-DWHAL_CFG_STM32WB_AES_GCM_DIRECT_API_MAPPING \
|
||||
-DWHAL_CFG_STM32WB_AES_GMAC_DIRECT_API_MAPPING \
|
||||
-DWHAL_CFG_STM32WB_AES_CCM_DIRECT_API_MAPPING \
|
||||
-DWHAL_CFG_SYSTICK_TIMER_DIRECT_API_MAPPING
|
||||
|
||||
LINKER_SCRIPT ?= $(_BOARD_DIR)/linker.ld
|
||||
|
||||
# Link through gcc rather than ld so newlib is available for the test suite's
|
||||
# printf. -lnosys resolves the stubs syscalls.c does not provide.
|
||||
LDFLAGS += -nostdlib -mcpu=cortex-m4 -mthumb -Wl,--gc-sections -T $(LINKER_SCRIPT)
|
||||
LDLIBS += -Wl,--start-group -lc -lm -lgcc -lnosys -Wl,--end-group
|
||||
|
||||
# wolfHAL_board.h has to be reachable by quoted include: wolfHAL's driver TUs
|
||||
# and wolfSSL's wolfhal.c both pull it in that way.
|
||||
CFLAGS += -I$(_BOARD_DIR)
|
||||
|
||||
BOARD_SOURCE = $(_BOARD_DIR)/wolfHAL_board.c
|
||||
BOARD_SOURCE += $(_BOARD_DIR)/ivt.c
|
||||
|
||||
# wolfHAL drivers
|
||||
BOARD_SOURCE += $(WHAL_DIR)/src/reg.c
|
||||
BOARD_SOURCE += $(WHAL_DIR)/src/gpio/stm32wb_gpio.c
|
||||
BOARD_SOURCE += $(WHAL_DIR)/src/uart/stm32wb_uart.c
|
||||
BOARD_SOURCE += $(WHAL_DIR)/src/rng/stm32wb_rng.c
|
||||
BOARD_SOURCE += $(WHAL_DIR)/src/crypto/stm32wb_aes.c
|
||||
BOARD_SOURCE += $(WHAL_DIR)/src/flash/stm32wb_flash.c
|
||||
BOARD_SOURCE += $(WHAL_DIR)/src/timer/systick.c
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
extern uint32_t _estack[];
|
||||
extern uint32_t _sidata[];
|
||||
extern uint32_t _sdata[];
|
||||
extern uint32_t _edata[];
|
||||
extern uint32_t _sbss[];
|
||||
extern uint32_t _ebss[];
|
||||
|
||||
extern void main();
|
||||
|
||||
void __attribute__((naked,noreturn)) Default_Handler()
|
||||
{
|
||||
while(1);
|
||||
}
|
||||
|
||||
void Reset_Handler() __attribute__((weak));
|
||||
void NMI_Handler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void HardFault_Handler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void MemManage_Handler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void BusFault_Handler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void UsageFault_Handler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void SVC_Handler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DebugMon_Handler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void PendSV_Handler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void SysTick_Handler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void WWDG_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void PVD_PVM_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void TAMP_STAMP_LSECSS_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void RTC_WKUP_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void FLASH_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void RCC_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void EXTI0_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void EXTI1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void EXTI2_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void EXTI3_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void EXTI4_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA1_Channel1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA1_Channel2_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA1_Channel3_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA1_Channel4_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA1_Channel5_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA1_Channel6_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA1_Channel7_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void ADC1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void USB_HP_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void USB_LP_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void C2SEV_PWR_C2H_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void COMP_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void EXTI9_5_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void TIM1_BRK_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void TIM1_UP_TIM16_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void TIM1_TRG_COM_TIM17_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void TIM1_CC_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void TIM2_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void PKA_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void I2C1_EV_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void I2C1_ER_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void I2C3_EV_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void I2C3_ER_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void SPI1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void SPI2_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void USART1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void LPUART1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void SAI1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void TSC_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void EXTI15_10_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void RTC_Alarm_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void CRS_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void IPCC_C1_RX_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void IPCC_C1_TX_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void HSEM_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void LPTIM1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void LPTIM2_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void LCD_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void QUADSPI_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void AES1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void AES2_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void RNG_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void FPU_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA2_Channel1_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA2_Channel2_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA2_Channel3_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA2_Channel4_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA2_Channel5_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA2_Channel6_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMA2_Channel7_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
void DMAMUX1_OVR_IRQHandler() __attribute__((weak, noreturn, alias("Default_Handler")));
|
||||
|
||||
#define RESERVED Default_Handler
|
||||
|
||||
void (* const interrupt_vector_table[])() __attribute__((section(".isr_vector"))) = {
|
||||
(void (*)())_estack,
|
||||
Reset_Handler,
|
||||
NMI_Handler,
|
||||
HardFault_Handler,
|
||||
MemManage_Handler,
|
||||
BusFault_Handler,
|
||||
UsageFault_Handler,
|
||||
RESERVED,
|
||||
RESERVED,
|
||||
RESERVED,
|
||||
RESERVED,
|
||||
SVC_Handler,
|
||||
DebugMon_Handler,
|
||||
RESERVED,
|
||||
PendSV_Handler,
|
||||
SysTick_Handler,
|
||||
WWDG_IRQHandler,
|
||||
PVD_PVM_IRQHandler,
|
||||
TAMP_STAMP_LSECSS_IRQHandler,
|
||||
RTC_WKUP_IRQHandler,
|
||||
FLASH_IRQHandler,
|
||||
RCC_IRQHandler,
|
||||
EXTI0_IRQHandler,
|
||||
EXTI1_IRQHandler,
|
||||
EXTI2_IRQHandler,
|
||||
EXTI3_IRQHandler,
|
||||
EXTI4_IRQHandler,
|
||||
DMA1_Channel1_IRQHandler,
|
||||
DMA1_Channel2_IRQHandler,
|
||||
DMA1_Channel3_IRQHandler,
|
||||
DMA1_Channel4_IRQHandler,
|
||||
DMA1_Channel5_IRQHandler,
|
||||
DMA1_Channel6_IRQHandler,
|
||||
DMA1_Channel7_IRQHandler,
|
||||
ADC1_IRQHandler,
|
||||
USB_HP_IRQHandler,
|
||||
USB_LP_IRQHandler,
|
||||
C2SEV_PWR_C2H_IRQHandler,
|
||||
COMP_IRQHandler,
|
||||
EXTI9_5_IRQHandler,
|
||||
TIM1_BRK_IRQHandler,
|
||||
TIM1_UP_TIM16_IRQHandler,
|
||||
TIM1_TRG_COM_TIM17_IRQHandler,
|
||||
TIM1_CC_IRQHandler,
|
||||
TIM2_IRQHandler,
|
||||
PKA_IRQHandler,
|
||||
I2C1_EV_IRQHandler,
|
||||
I2C1_ER_IRQHandler,
|
||||
I2C3_EV_IRQHandler,
|
||||
I2C3_ER_IRQHandler,
|
||||
SPI1_IRQHandler,
|
||||
SPI2_IRQHandler,
|
||||
USART1_IRQHandler,
|
||||
LPUART1_IRQHandler,
|
||||
SAI1_IRQHandler,
|
||||
TSC_IRQHandler,
|
||||
EXTI15_10_IRQHandler,
|
||||
RTC_Alarm_IRQHandler,
|
||||
CRS_IRQHandler,
|
||||
PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler,
|
||||
IPCC_C1_RX_IRQHandler,
|
||||
IPCC_C1_TX_IRQHandler,
|
||||
HSEM_IRQHandler,
|
||||
LPTIM1_IRQHandler,
|
||||
LPTIM2_IRQHandler,
|
||||
LCD_IRQHandler,
|
||||
QUADSPI_IRQHandler,
|
||||
AES1_IRQHandler,
|
||||
AES2_IRQHandler,
|
||||
RNG_IRQHandler,
|
||||
FPU_IRQHandler,
|
||||
DMA2_Channel1_IRQHandler,
|
||||
DMA2_Channel2_IRQHandler,
|
||||
DMA2_Channel3_IRQHandler,
|
||||
DMA2_Channel4_IRQHandler,
|
||||
DMA2_Channel5_IRQHandler,
|
||||
DMA2_Channel6_IRQHandler,
|
||||
DMA2_Channel7_IRQHandler,
|
||||
DMAMUX1_OVR_IRQHandler,
|
||||
};
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
unsigned char *d = dest;
|
||||
const unsigned char *s = src;
|
||||
|
||||
for (size_t i = 0; i < n; i++)
|
||||
d[i] = s[i];
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
unsigned char *p = s;
|
||||
unsigned char v = (unsigned char)c;
|
||||
|
||||
for (size_t i = 0; i < n; i++)
|
||||
p[i] = v;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void __attribute__((naked)) Reset_Handler()
|
||||
{
|
||||
__asm__("ldr r0, =_estack\n\t"
|
||||
"mov sp, r0");
|
||||
|
||||
// Copy data section from flash memory to ram
|
||||
uint32_t data_section_size = _edata - _sdata;
|
||||
memcpy(_sdata, _sidata, data_section_size*4);
|
||||
|
||||
// Zero out bss
|
||||
uint32_t bss_section_size = _ebss - _sbss;
|
||||
memset(_sbss, 0, bss_section_size*4);
|
||||
|
||||
// Set Interrupt Vector Table Offset
|
||||
uint32_t *vtor = (uint32_t *)0xE000ED08;
|
||||
*vtor = (uint32_t)interrupt_vector_table;
|
||||
|
||||
main();
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
*****************************************************************************
|
||||
**
|
||||
** File : linker.ld
|
||||
**
|
||||
** Abstract : System Workbench Minimal System calls file
|
||||
**
|
||||
** For more information about which c-functions
|
||||
** need which of these lowlevel functions
|
||||
** please consult the Newlib libc-manual
|
||||
**
|
||||
** Environment : System Workbench for MCU
|
||||
**
|
||||
** Distribution: The file is distributed “as is,” without any warranty
|
||||
** of any kind.
|
||||
**
|
||||
*****************************************************************************
|
||||
**
|
||||
** <h2><center>© COPYRIGHT(c) 2019 Ac6</center></h2>
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
** 1. Redistributions of source code must retain the above copyright notice,
|
||||
** this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
** this list of conditions and the following disclaimer in the documentation
|
||||
** and/or other materials provided with the distribution.
|
||||
** 3. Neither the name of Ac6 nor the names of its contributors
|
||||
** may be used to endorse or promote products derived from this software
|
||||
** without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
/* Entry Point */
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
_estack = 0x20030000; /* end of RAM */
|
||||
/* Generate a link error if the stack don't fit into RAM */
|
||||
_Min_Stack_Size = 0x500; /* required amount of stack */
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
|
||||
RAM1 (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000
|
||||
}
|
||||
|
||||
/* Define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
/* The startup code goes first into FLASH */
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
/* The program code and other data goes into FLASH */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text) /* .text sections (code) */
|
||||
*(.text*) /* .text* sections (code) */
|
||||
*(.glue_7) /* glue arm to thumb code */
|
||||
*(.glue_7t) /* glue thumb to arm code */
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
_etext = .; /* define a global symbols at end of code */
|
||||
} >FLASH
|
||||
|
||||
/* Constant data goes into FLASH */
|
||||
.rodata :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
|
||||
.ARM : {
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} >FLASH
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array*))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
} >FLASH
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array*))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
} >FLASH
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.fini_array*))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
/* used by the startup to initialize data */
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
/* Initialized data sections goes into RAM, load LMA copy after code */
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .; /* create a global symbol at data start */
|
||||
*(.data) /* .data sections */
|
||||
*(.data*) /* .data* sections */
|
||||
|
||||
. = ALIGN(4);
|
||||
_edata = .; /* define a global symbol at data end */
|
||||
} >RAM1 AT> FLASH
|
||||
|
||||
|
||||
/* Uninitialized data section */
|
||||
. = ALIGN(4);
|
||||
.bss :
|
||||
{
|
||||
/* This is used by the startup in order to initialize the .bss section */
|
||||
_sbss = .; /* define a global symbol at bss start */
|
||||
__bss_start__ = _sbss;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
_ebss = .; /* define a global symbol at bss end */
|
||||
__bss_end__ = _ebss;
|
||||
} >RAM1
|
||||
|
||||
/* Heap grows up from _ebss, stack grows down from _estack */
|
||||
._user_heap_stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
PROVIDE ( end = . );
|
||||
PROVIDE ( _end = . );
|
||||
. = ABSOLUTE(_estack) - _Min_Stack_Size;
|
||||
_heap_limit = .;
|
||||
. = ALIGN(8);
|
||||
} >RAM1
|
||||
|
||||
/* .ARM.attributes 0 : { *(.ARM.attributes) } */
|
||||
/* MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM_SHARED */
|
||||
/* MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED */
|
||||
/* MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED */
|
||||
}
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
/* wolfHAL_board.c
|
||||
*
|
||||
* Board bring-up for the STM32WB55 Nucleo — wolfCrypt + wolfHAL example.
|
||||
*
|
||||
* Board_Init() must run before wolfCrypt_Init(): wolfCrypt_Init() registers the
|
||||
* wolfHAL crypto callback, and the callback expects the peripherals to be live.
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL 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.
|
||||
*
|
||||
* wolfSSL 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 "wolfHAL_board.h"
|
||||
|
||||
volatile uint32_t g_tick = 0;
|
||||
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
g_tick++;
|
||||
}
|
||||
|
||||
uint32_t Board_GetTick(void)
|
||||
{
|
||||
return g_tick;
|
||||
}
|
||||
|
||||
/* Bounds the AES and RNG status-flag polls: a wedged peripheral surfaces as
|
||||
* WC_TIMEOUT_E instead of hanging the test run. */
|
||||
whal_Timeout g_whalTimeout = {
|
||||
.timeoutTicks = 1000, /* 1 s at the 1 ms SysTick */
|
||||
.GetTick = Board_GetTick,
|
||||
};
|
||||
|
||||
whal_Uart g_whalUart = {
|
||||
.base = WHAL_STM32WB55_UART1_BASE,
|
||||
/* .driver: direct API mapping */
|
||||
|
||||
.cfg = &(whal_Stm32wb_Uart_Cfg) {
|
||||
.brr = WHAL_STM32WB_UART_BRR(64000000, 115200),
|
||||
.timeout = &g_whalTimeout,
|
||||
},
|
||||
};
|
||||
|
||||
static const whal_Stm32wb_Rcc_PeriphClk g_periphClks[] = {
|
||||
{WHAL_STM32WB55_GPIOB_GATE},
|
||||
{WHAL_STM32WB55_UART1_GATE},
|
||||
{WHAL_STM32WB55_RNG_GATE},
|
||||
{WHAL_STM32WB55_AES1_GATE},
|
||||
};
|
||||
#define PERIPH_CLK_COUNT (sizeof(g_periphClks) / sizeof(g_periphClks[0]))
|
||||
|
||||
whal_Error Board_Init(void)
|
||||
{
|
||||
whal_Error err;
|
||||
size_t i;
|
||||
|
||||
/* Wait states first — the core would outrun flash once SYSCLK passes
|
||||
* ~16 MHz, and the fetch faults before anything else can report it. */
|
||||
err = whal_Stm32wb_Flash_Ext_SetLatency(BOARD_FLASH_DEV,
|
||||
WHAL_STM32WB_FLASH_LATENCY_3);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* MSI 4 MHz -> VCO 128 MHz -> PLLR /2 = 64 MHz SYSCLK. */
|
||||
err = whal_Stm32wb_Rcc_EnableMsi(WHAL_STM32WB_RCC_MSIRANGE_4MHz);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = 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,
|
||||
});
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* The RNG is clocked from HSI48, not SYSCLK. */
|
||||
err = whal_Stm32wb_Rcc_EnableOsc(
|
||||
&(whal_Stm32wb_Rcc_OscCfg){WHAL_STM32WB_RCC_HSI48_CFG});
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = whal_Stm32wb_Rcc_SetSysClock(WHAL_STM32WB_RCC_SYSCLK_SRC_PLL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < PERIPH_CLK_COUNT; i++) {
|
||||
err = whal_Stm32wb_Rcc_EnablePeriphClk(&g_periphClks[i]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = whal_Gpio_Init(WHAL_INTERNAL_DEV);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = whal_Uart_Init(&g_whalUart);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Before the peripherals that poll against it. */
|
||||
err = whal_Timer_Init(WHAL_INTERNAL_DEV);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = whal_Timer_Start(WHAL_INTERNAL_DEV);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = whal_Rng_Init(WHAL_INTERNAL_DEV);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = whal_Crypto_Init(WHAL_INTERNAL_DEV);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return WHAL_SUCCESS;
|
||||
}
|
||||
|
||||
whal_Error Board_Deinit(void)
|
||||
{
|
||||
whal_Error err;
|
||||
size_t i;
|
||||
|
||||
err = whal_Crypto_Deinit(WHAL_INTERNAL_DEV);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = whal_Rng_Deinit(WHAL_INTERNAL_DEV);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = whal_Timer_Stop(WHAL_INTERNAL_DEV);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = whal_Timer_Deinit(WHAL_INTERNAL_DEV);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = whal_Uart_Deinit(&g_whalUart);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = whal_Gpio_Deinit(WHAL_INTERNAL_DEV);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Unwind the clock tree in reverse: gates, then SYSCLK back to MSI, then
|
||||
* the sources. MSI stays on as the fallback. */
|
||||
for (i = PERIPH_CLK_COUNT; i-- > 0; ) {
|
||||
err = whal_Stm32wb_Rcc_DisablePeriphClk(&g_periphClks[i]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = whal_Stm32wb_Rcc_SetSysClock(WHAL_STM32WB_RCC_SYSCLK_SRC_MSI);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = whal_Stm32wb_Rcc_DisablePll();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = whal_Stm32wb_Rcc_DisableOsc(
|
||||
&(whal_Stm32wb_Rcc_OscCfg){WHAL_STM32WB_RCC_HSI48_CFG});
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Latency back down only after the clock is slow again. */
|
||||
err = whal_Stm32wb_Flash_Ext_SetLatency(BOARD_FLASH_DEV,
|
||||
WHAL_STM32WB_FLASH_LATENCY_0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return WHAL_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
/* wolfHAL_board.h
|
||||
*
|
||||
* Board configuration for the STM32WB55 Nucleo — wolfCrypt + wolfHAL example.
|
||||
*
|
||||
* Scoped to what the wolfCrypt test needs: a 64 MHz clock, UART1 for output,
|
||||
* SysTick for timeouts, and the AES1 and RNG peripherals. wolfHAL's own
|
||||
* boards/stm32wb55xx_nucleo brings up SPI, I2C, PKA and more.
|
||||
*
|
||||
* Two sets of macros matter here:
|
||||
*
|
||||
* WHAL_CFG_*_DEV wolfHAL's driver TUs #include "wolfHAL_board.h" and
|
||||
* expand these to define their device singletons.
|
||||
* WC_WOLFHAL_*_DEV wolfSSL's wolfhal.c reads these to pick the device it
|
||||
* dispatches each algorithm on. A mode left out here falls
|
||||
* back to wolfCrypt's software implementation.
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL 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.
|
||||
*
|
||||
* wolfSSL 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 <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <wolfHAL/wolfHAL.h>
|
||||
#include <wolfHAL/platform/st/stm32wb55xx.h>
|
||||
#include <wolfHAL/timer/systick.h>
|
||||
|
||||
extern whal_Uart g_whalUart;
|
||||
extern whal_Timeout g_whalTimeout;
|
||||
extern volatile uint32_t g_tick;
|
||||
|
||||
enum {
|
||||
LED_PIN,
|
||||
UART_TX_PIN,
|
||||
UART_RX_PIN,
|
||||
PIN_COUNT,
|
||||
};
|
||||
|
||||
#define BOARD_FLASH_DEV ((whal_Flash *)&whal_Stm32wb_Flash_Dev)
|
||||
|
||||
/* GPIO — LED on PB5, UART1 TX/RX on PB6/PB7. */
|
||||
#define WHAL_CFG_STM32WB_GPIO_DEV { \
|
||||
.base = WHAL_STM32WB55_GPIO_BASE, \
|
||||
/* .driver: direct API mapping */ \
|
||||
.cfg = (void *)&(const whal_Stm32wb_Gpio_Cfg){ \
|
||||
.pinCfg = (const whal_Stm32wb_Gpio_PinCfg[PIN_COUNT]){ \
|
||||
[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), \
|
||||
[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), \
|
||||
[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 = PIN_COUNT, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/* Flash — only needed to raise the wait states before the clock goes to 64 MHz. */
|
||||
#define WHAL_CFG_STM32WB_FLASH_DEV { \
|
||||
.driver = WHAL_STM32WB55_FLASH_DRIVER, \
|
||||
.base = WHAL_STM32WB55_FLASH_BASE, \
|
||||
.cfg = (void *)&(const whal_Stm32wb_Flash_Cfg){ \
|
||||
.timeout = &g_whalTimeout, \
|
||||
.startAddr = 0x08000000, \
|
||||
.size = 0x80000, /* 512 KB; upper half reserved for the BLE stack */ \
|
||||
}, \
|
||||
}
|
||||
|
||||
/* SysTick at 1 ms — drives the timeout the AES and RNG polls are bounded by. */
|
||||
#define WHAL_CFG_SYSTICK_DEV { \
|
||||
.base = WHAL_CORTEX_M4_SYSTICK_BASE, \
|
||||
/* .driver: direct API mapping */ \
|
||||
.cfg = (void *)&(const whal_SysTick_Cfg){ \
|
||||
.cyclesPerTick = 64000000 / 1000, \
|
||||
.clkSrc = WHAL_SYSTICK_CLKSRC_SYSCLK, \
|
||||
.tickInt = WHAL_SYSTICK_TICKINT_ENABLED, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/* RNG. */
|
||||
#define WHAL_CFG_STM32WB_RNG_DEV { \
|
||||
.base = WHAL_STM32WB55_RNG_BASE, \
|
||||
/* .driver: direct API mapping */ \
|
||||
.cfg = (void *)&(const whal_Stm32wb_Rng_Cfg){ \
|
||||
.timeout = &g_whalTimeout, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/* AES1. stm32wb_aes.c defines all seven devices unconditionally, so every
|
||||
* initializer has to be present even though only four are dispatched below.
|
||||
* The GCM and CCM state buffers are static in that TU. */
|
||||
#define WHAL_CFG_STM32WB_AES_DEV { \
|
||||
.base = WHAL_STM32WB55_AES1_BASE, \
|
||||
/* .driver: direct API mapping */ \
|
||||
.cfg = (void *)&(const whal_Stm32wb_Aes_Cfg){ \
|
||||
.timeout = &g_whalTimeout, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define WHAL_CFG_STM32WB_AES_ECB_DEV { \
|
||||
.crypto = (whal_Crypto *)&whal_Stm32wb_Aes_Dev, \
|
||||
}
|
||||
|
||||
#define WHAL_CFG_STM32WB_AES_CBC_DEV { \
|
||||
.crypto = (whal_Crypto *)&whal_Stm32wb_Aes_Dev, \
|
||||
}
|
||||
|
||||
#define WHAL_CFG_STM32WB_AES_CTR_DEV { \
|
||||
.crypto = (whal_Crypto *)&whal_Stm32wb_Aes_Dev, \
|
||||
}
|
||||
|
||||
#define WHAL_CFG_STM32WB_AES_GCM_DEV { \
|
||||
.crypto = (whal_Crypto *)&whal_Stm32wb_Aes_Dev, \
|
||||
.state = &g_stm32wbAesGcmDevState, \
|
||||
}
|
||||
|
||||
#define WHAL_CFG_STM32WB_AES_GMAC_DEV { \
|
||||
.crypto = (whal_Crypto *)&whal_Stm32wb_Aes_Dev, \
|
||||
}
|
||||
|
||||
#define WHAL_CFG_STM32WB_AES_CCM_DEV { \
|
||||
.crypto = (whal_Crypto *)&whal_Stm32wb_Aes_Dev, \
|
||||
.state = &g_stm32wbAesCcmDevState, \
|
||||
}
|
||||
|
||||
/* What wolfSSL's wolfhal.c dispatches each algorithm on. CTR and GMAC are
|
||||
* deliberately absent — wolfCrypt has no crypto-callback path for them, and
|
||||
* anything not named here runs in software. */
|
||||
#define WC_WOLFHAL_AES_ECB_DEV ((whal_AesEcb *)&whal_Stm32wb_AesEcb_Dev)
|
||||
#define WC_WOLFHAL_AES_CBC_DEV ((whal_AesCbc *)&whal_Stm32wb_AesCbc_Dev)
|
||||
#define WC_WOLFHAL_AES_GCM_DEV ((whal_AesGcm *)&whal_Stm32wb_AesGcm_Dev)
|
||||
#define WC_WOLFHAL_AES_CCM_DEV ((whal_AesCcm *)&whal_Stm32wb_AesCcm_Dev)
|
||||
#define WC_WOLFHAL_RNG_DEV ((whal_Rng *)&whal_Stm32wb_Rng_Dev)
|
||||
|
||||
whal_Error Board_Init(void);
|
||||
whal_Error Board_Deinit(void);
|
||||
uint32_t Board_GetTick(void);
|
||||
|
||||
#endif /* WOLFHAL_BOARD_H */
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/* main.c
|
||||
*
|
||||
* wolfCrypt + wolfHAL example — runs the wolfCrypt test suite using
|
||||
* hardware-accelerated crypto via wolfHAL.
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL 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.
|
||||
*
|
||||
* wolfSSL 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 <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/wc_port.h>
|
||||
#include <wolfcrypt/test/test.h>
|
||||
#include <wolfcrypt/benchmark/benchmark.h>
|
||||
|
||||
#include "wolfHAL_board.h"
|
||||
|
||||
double current_time(int reset)
|
||||
{
|
||||
uint32_t timeMs = Board_GetTick();
|
||||
double timeNow;
|
||||
|
||||
(void)reset;
|
||||
|
||||
timeNow = (double)(timeMs / 1000); /* seconds */
|
||||
timeNow += (double)(timeMs % 1000) / 1000.0; /* milliseconds */
|
||||
|
||||
return timeNow;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Initialize board hardware (clocks, peripherals) */
|
||||
if (Board_Init() != 0) {
|
||||
while (1);
|
||||
}
|
||||
|
||||
/* Registers the wolfHAL crypto callback via wc_wolfHAL_RegisterDevice(),
|
||||
* so the peripherals Board_Init() brought up are already live. */
|
||||
ret = wolfCrypt_Init();
|
||||
if (ret != 0) {
|
||||
while (1);
|
||||
}
|
||||
|
||||
/* Correctness first, then throughput */
|
||||
wolfcrypt_test(NULL);
|
||||
benchmark_test(NULL);
|
||||
|
||||
wolfCrypt_Cleanup();
|
||||
Board_Deinit();
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/* syscalls.c
|
||||
*
|
||||
* Minimal libc stubs for bare-metal. Routes stdout through wolfHAL UART.
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "wolfHAL_board.h"
|
||||
|
||||
/* From the board's linker script: the heap runs from the end of .bss up to
|
||||
* where the stack is reserved. */
|
||||
extern uint32_t _ebss;
|
||||
extern uint32_t _heap_limit;
|
||||
|
||||
static char *heap_end;
|
||||
|
||||
int _write(int file, const char *ptr, int len)
|
||||
{
|
||||
(void)file;
|
||||
if (len > 0) {
|
||||
whal_Uart_Send(&g_whalUart, ptr, (size_t)len);
|
||||
if (ptr[len - 1] == '\n')
|
||||
whal_Uart_Send(&g_whalUart, "\r", 1);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int _close(int file)
|
||||
{
|
||||
(void)file;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _fstat(int file, struct stat *st)
|
||||
{
|
||||
(void)file;
|
||||
if (st == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _isatty(int file)
|
||||
{
|
||||
(void)file;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _lseek(int file, int ptr, int dir)
|
||||
{
|
||||
(void)file;
|
||||
(void)ptr;
|
||||
(void)dir;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _read(int file, char *ptr, int len)
|
||||
{
|
||||
(void)file;
|
||||
(void)ptr;
|
||||
(void)len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *_sbrk(ptrdiff_t incr)
|
||||
{
|
||||
char *prev;
|
||||
|
||||
if (heap_end == 0)
|
||||
heap_end = (char *)&_ebss;
|
||||
prev = heap_end;
|
||||
if ((heap_end + incr) >= (char *)&_heap_limit) {
|
||||
errno = ENOMEM;
|
||||
return (void *)-1;
|
||||
}
|
||||
heap_end += incr;
|
||||
return prev;
|
||||
}
|
||||
|
||||
void _exit(int status)
|
||||
{
|
||||
(void)status;
|
||||
while (1) { }
|
||||
}
|
||||
|
||||
int _kill(int pid, int sig)
|
||||
{
|
||||
(void)pid;
|
||||
(void)sig;
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _getpid(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void _fini(void)
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/* user_settings.h
|
||||
*
|
||||
* wolfCrypt configuration for the STM32WB55 Nucleo + wolfHAL example.
|
||||
* AES is offloaded to the AES1 peripheral, SHA-256 stays in software.
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL 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.
|
||||
*
|
||||
* wolfSSL 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 USER_SETTINGS_H
|
||||
#define USER_SETTINGS_H
|
||||
|
||||
/* wolfHAL port. Enabling it pulls in wolfhal_settings.h, which turns on
|
||||
* WOLF_CRYPTO_CB and points WC_USE_DEVID at the wolfHAL device, so the stock
|
||||
* wolfcrypt test routes through the hardware without changes. */
|
||||
#define WOLFSSL_WOLFHAL
|
||||
|
||||
#define WOLFSSL_WOLFHAL_RNG
|
||||
|
||||
/* wolfCrypt only — no TLS */
|
||||
#define WOLFCRYPT_ONLY
|
||||
|
||||
/* Small embedded target */
|
||||
#define SINGLE_THREADED
|
||||
#define NO_FILESYSTEM
|
||||
#define NO_WOLFSSL_DIR
|
||||
#define NO_WRITEV
|
||||
#define NO_MAIN_DRIVER
|
||||
#define NO_DEV_RANDOM
|
||||
|
||||
/* Benchmark: BENCH_EMBEDDED shrinks the working buffers, WOLFSSL_USER_CURRTIME
|
||||
* makes benchmark.c call the current_time() this example supplies rather than
|
||||
* reaching for a host clock it has no way to find. */
|
||||
#define BENCH_EMBEDDED
|
||||
#define WOLFSSL_USER_CURRTIME
|
||||
|
||||
/* AES — offloaded to AES1 via wolfHAL. wolfHAL_board.h names a device for each
|
||||
* of these, so all four are dispatched to hardware; a mode left unnamed there
|
||||
* would fall back to wolfCrypt's software implementation instead. */
|
||||
#define HAVE_AES_CBC
|
||||
#define HAVE_AESGCM
|
||||
#define HAVE_AESCCM
|
||||
#define HAVE_AES_ECB
|
||||
#define WOLFSSL_AES_DIRECT
|
||||
#define NO_AES_192
|
||||
|
||||
/* Disable everything else */
|
||||
#define NO_RSA
|
||||
#define NO_DSA
|
||||
#define NO_DH
|
||||
#define NO_RC4
|
||||
#define NO_MD4
|
||||
#define NO_MD5
|
||||
#define NO_SHA
|
||||
#define NO_DES3
|
||||
#define NO_PSK
|
||||
#define NO_PWDBASED
|
||||
#define NO_OLD_TLS
|
||||
#define NO_ASN
|
||||
#define NO_CODING
|
||||
#define NO_SIG_WRAPPER
|
||||
#define NO_HMAC
|
||||
#define WOLFSSL_NO_PEM
|
||||
|
||||
#endif /* USER_SETTINGS_H */
|
||||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 5302069e8d7baacefeeada94c4c8e5ef7426c1db
|
||||
Loading…
Reference in New Issue