From 1abf736dc9a4a3ab41dee536390ad3ee7ecf7066 Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Mon, 6 Oct 2025 09:38:51 -0700 Subject: [PATCH 1/9] CMake Improvements --- .editorconfig | 6 + .gitignore | 12 ++ CMakeLists.txt | 68 ++++++- CMakePresets.json | 132 +++++++++++++ CMakeSettings.json | 15 ++ IDE/VSCode/.vscode/launch.json | 21 ++ IDE/VSCode/.vscode/settings.json | 10 + IDE/VSCode/.vscode/tasks.json | 35 ++++ IDE/VSCode/README.md | 2 + IDE/VisualGDB/README.md | 68 +++++++ IDE/VisualGDB/wolfBoot.sln | 31 +++ IDE/VisualGDB/wolfBoot.vcxproj | 201 ++++++++++++++++++++ IDE/VisualStudio/EmbeddedProject1/stm32.xml | 25 +++ IDE/VisualStudio/wolfboot/CMakeLists.txt | 21 ++ IDE/VisualStudio/wolfboot/CMakePresets.json | 101 ++++++++++ IDE/VisualStudio/wolfboot/wolfboot.cpp | 12 ++ IDE/VisualStudio/wolfboot/wolfboot.h | 8 + Makefile | 73 ++++++- README.md | 57 +++++- cmake/load_dot_config.cmake | 120 ++++++++++++ config/examples/README.md | 17 ++ config/examples/visualgdb-stm32l4.config | 33 ++++ config2presets.py | 150 +++++++++++++++ test-app/Makefile | 49 ++++- wolfbuild.sh | 118 ++++++++++++ 25 files changed, 1375 insertions(+), 10 deletions(-) create mode 100644 .editorconfig create mode 100644 CMakePresets.json create mode 100644 CMakeSettings.json create mode 100644 IDE/VSCode/.vscode/launch.json create mode 100644 IDE/VSCode/.vscode/settings.json create mode 100644 IDE/VSCode/.vscode/tasks.json create mode 100644 IDE/VSCode/README.md create mode 100644 IDE/VisualGDB/README.md create mode 100644 IDE/VisualGDB/wolfBoot.sln create mode 100644 IDE/VisualGDB/wolfBoot.vcxproj create mode 100644 IDE/VisualStudio/EmbeddedProject1/stm32.xml create mode 100644 IDE/VisualStudio/wolfboot/CMakeLists.txt create mode 100644 IDE/VisualStudio/wolfboot/CMakePresets.json create mode 100644 IDE/VisualStudio/wolfboot/wolfboot.cpp create mode 100644 IDE/VisualStudio/wolfboot/wolfboot.h create mode 100644 cmake/load_dot_config.cmake create mode 100644 config/examples/README.md create mode 100644 config/examples/visualgdb-stm32l4.config create mode 100644 config2presets.py create mode 100644 wolfbuild.sh diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..8138f66086 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,6 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true diff --git a/.gitignore b/.gitignore index 65b8a8dce7..e7d512e398 100644 --- a/.gitignore +++ b/.gitignore @@ -255,3 +255,15 @@ lib/r_tsip_rx Debug/ Release/ language.settings.xml + +# Backup files +*.bak + +# Any Visual Studio / VisualGDB +/**/.vs +/**/.visualgdb/* + +# Any build directories +/**/build +/**/build-** + diff --git a/CMakeLists.txt b/CMakeLists.txt index 7708fba085..e1db5a391d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,12 +42,38 @@ endif() project(wolfBoot) +include(cmake/load_dot_config.cmake) include(cmake/utils.cmake) include(cmake/functions.cmake) include_directories(include) include_directories(lib/wolfssl) +# Where should configuration values come from? +# dot : parse .config via load_dot_config() +# preset : use cacheVariables from CMakePresets.json +set(WOLFBOOT_CONFIG_MODE "dot" CACHE STRING "Config source: dot or preset") +set_property(CACHE WOLFBOOT_CONFIG_MODE PROPERTY STRINGS dot preset) + +if(WOLFBOOT_CONFIG_MODE STREQUAL "dot") + message(STATUS "Config mode: dot (.config cache)") + include(cmake/load_dot_config.cmake) + message(STATUS "Loading config from: ${CMAKE_SOURCE_DIR}") + load_dot_config("${CMAKE_SOURCE_DIR}/.config") + +elseif(WOLFBOOT_CONFIG_MODE STREQUAL "preset") + message(STATUS "Config mode: preset (using cacheVariables; skipping .config)") + +else() + message(FATAL_ERROR "Invalid WOLFBOOT_CONFIG_MODE='${WOLFBOOT_CONFIG_MODE}'. Use 'dot' or 'preset'.") +endif() + + +if ("${WOLFBOOT_TARGET}" STREQUAL "") + message(STATUS "Setting WOLFBOOT_TARGET from TARGET=${TARGET}") + set(WOLFBOOT_TARGET "${TARGET}") +endif() + if(NOT DEFINED WOLFBOOT_TARGET) message(FATAL_ERROR "WOLFBOOT_TARGET must be defined") else() @@ -59,7 +85,7 @@ if(NOT DEFINED WOLFBOOT_SECTOR_SIZE) endif() if(NOT DEFINED ARM_TARGETS) - list(APPEND ARM_TARGETS cypsoc6 imx kinetis lpc54606j512 mcxa mcxw nrf52 nrf52840 nrf5340 nrf5340_net rp2350 sama5d3 same51 stm32c0 stm32f1 stm32f4 stm32f7 stm32g0 stm32h5 stm32h7 stm32l0 stm32l5 stm32u5 stm32wb ti zynqmp) + list(APPEND ARM_TARGETS cypsoc6 imx kinetis lpc54606j512 mcxa mcxw nrf52 nrf52840 nrf5340 nrf5340_net rp2350 sama5d3 same51 stm32c0 stm32f1 stm32f4 stm32f7 stm32g0 stm32h5 stm32h7 stm32l0 stm32l4 stm32l5 stm32u5 stm32wb ti zynqmp) set(ARM_TARGETS "${ARM_TARGETS}" CACHE INTERNAL "") @@ -654,7 +680,45 @@ target_compile_definitions(user_settings INTERFACE ${USER_SETTINGS} ${SIGN_OPTIO add_library(wolfboothal) target_sources(wolfboothal PRIVATE include/hal.h hal/${WOLFBOOT_TARGET}.c ${WOLFBOOT_FLASH_SOURCES} ${PARTITION_SOURCE}) -target_link_libraries(wolfboothal target user_settings) + + +# --- HAL for STM32L4 (only the pieces we need) --- +if(WOLFBOOT_TARGET STREQUAL "stm32l4") + set(HAL_BASE "/mnt/c/Users/gojimmypi/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx") + set(HAL_DRV "${HAL_BASE}/STM32L4xx_HAL_Driver") + set(HAL_CMSIS_DEV "${HAL_BASE}/CMSIS_HAL/Device/ST/STM32L4xx/Include") + set(HAL_CMSIS_CORE "${HAL_BASE}/CMSIS_HAL/Include") + set(HAL_TEMPLATE_INC "${HAL_BASE}/VendorSamples/L4/Projects/B-L475E-IOT01A/Templates/Inc") + + add_library(stm32l4_hal STATIC + ${HAL_DRV}/Src/stm32l4xx_hal.c + ${HAL_DRV}/Src/stm32l4xx_hal_flash.c + ${HAL_DRV}/Src/stm32l4xx_hal_flash_ex.c + # add more modules later if you get missing symbols, e.g. RCC/GPIO/etc: + # ${HAL_DRV}/Src/stm32l4xx_hal_rcc.c + # ${HAL_DRV}/Src/stm32l4xx_hal_gpio.c + ) + + target_include_directories(stm32l4_hal PUBLIC + ${HAL_DRV}/Inc + ${HAL_CMSIS_DEV} + ${HAL_CMSIS_CORE} + ${HAL_TEMPLATE_INC} + ) + + target_compile_definitions(stm32l4_hal PUBLIC + USE_HAL_DRIVER + STM32L475xx + # If your stm32l4xx_hal_conf.h doesnt enable FLASH, you can force it: + # HAL_FLASH_MODULE_ENABLED + ) + + # Link HAL into the HAL wrapper lib so the final image pulls symbols from a single archive + target_link_libraries(wolfboothal PUBLIC target user_settings stm32l4_hal) +else() + target_link_libraries(wolfboothal target user_settings) +endif() + target_compile_definitions(wolfboothal PRIVATE ${WOLFBOOT_DEFS}) target_include_directories(wolfboothal PRIVATE ${WOLFBOOT_ROOT} include) target_compile_options(wolfboothal PRIVATE ${WOLFBOOT_COMPILE_OPTIONS} ${EXTRA_COMPILE_OPTIONS}) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000000..376edd56b1 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,132 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "base", + "hidden": true, + "binaryDir": "${sourceDir}/build-${presetName}" + }, + { + "name": "windows-stm32h7", + "displayName": "Windows ARM (STM32H7)", + "generator": "Ninja", + "cacheVariables": { + "WOLFBOOT_CONFIG_MODE": "preset", + "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", + "WOLFBOOT_TARGET": "stm32h7", + "BUILD_TEST_APPS": "yes" + } + }, + { + "name": "vs-debug-trace", + "displayName": "VS Debug Trace (STM32H7)", + "inherits": [ + "linux-stm32h7" + ], + "binaryDir": "${sourceDir}/out/build/${presetName}", + "cacheVariables": { + "WOLFBOOT_CONFIG_MODE": "preset", + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_VERBOSE_MAKEFILE": "ON", + "CMAKE_FIND_DEBUG_MODE": "ON" + } + }, + { + "name": "linux-stm32h7", + "inherits": [ "base" ], + "displayName": "Linux/WSL ARM (stm32h7)", + "generator": "Ninja", + "cacheVariables": { + "WOLFBOOT_CONFIG_MODE": "preset", + "ARCH": "ARM", + "WOLFBOOT_TARGET": "stm32h7", + "SIGN": "ECC256", + "HASH": "SHA256", + "DEBUG": "OFF", + "DEBUG_UART": "OFF", + "VTOR": "ON", + "NO_ASM": "OFF", + "EXT_FLASH": "OFF", + "SPI_FLASH": "OFF", + "QSPI_FLASH": "OFF", + "OCTOSPI_FLASH": "OFF", + "ALLOW_DOWNGRADE": "OFF", + "NVM_FLASH_WRITEONCE": "OFF", + "WOLFBOOT_VERSION": "ON", + "V": "OFF", + "SPMATH": "ON", + "RAM_CODE": "OFF", + "DUALBANK_SWAP": "OFF", + "WOLFBOOT_PARTITION_SIZE": "0xD0000", + "WOLFBOOT_SECTOR_SIZE": "0x20000", + "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x8020000", + "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x80F0000", + "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x81C0000", + "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", + "BUILD_TEST_APPS": "ON" + } + }, + { + "name": "linux-stm32l4", + "inherits": [ "base" ], + "displayName": "Linux/WSL ARM (stm32l4)", + "generator": "Ninja", + "cacheVariables": { + "WOLFBOOT_CONFIG_MODE": "preset", + "VISUALGDB": "ON", + "VISUALGDB_BASE": "/mnt/c/Users/$env{USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx", + "CMAKE_C_STANDARD_INCLUDE_DIRECTORIES": "/mnt/c/Users/$env{USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/VendorSamples/L4/Projects/B-L475E-IOT01A/Templates/Inc", + "WOLFBOOT_TARGET": "stm32l4", + "STM32L4_PART": "STM32L475xx", + "BOARD": "B-L475E-IOT01A", + "ARCH": "ARM", + "SIGN": "ECC256", + "HASH": "SHA256", + "DEBUG": "OFF", + "VTOR": "ON", + "CORTEX_M0": "OFF", + "NO_ASM": "OFF", + "EXT_FLASH": "OFF", + "SPI_FLASH": "OFF", + "ALLOW_DOWNGRADE": "OFF", + "NVM_FLASH_WRITEONCE": "ON", + "WOLFBOOT_VERSION": "OFF", + "V": "OFF", + "SPMATH": "ON", + "RAM_CODE": "OFF", + "DUALBANK_SWAP": "OFF", + "IMAGE_HEADER_SIZE": "256", + "WOLFBOOT_SECTOR_SIZE": "0x1000", + "WOLFBOOT_PARTITION_SIZE": "0x7A000", + "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x0800A000", + "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x08084000", + "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x080FE000", + "WOLFTPM": "OFF", + "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", + "BUILD_TEST_APPS": "ON" + } + } + ], + "buildPresets": [ + { + "name": "windows-stm32h7", + "configurePreset": "windows-stm32h7", + "jobs": 0 + }, + { + "name": "vs-debug-trace", + "configurePreset": "vs-debug-trace", + "jobs": 0 + }, + { + "name": "linux-stm32h7", + "configurePreset": "linux-stm32h7", + "jobs": 0 + }, + { + "name": "linux-stm32l4", + "configurePreset": "linux-stm32l4", + "jobs": 0 + } + ] +} diff --git a/CMakeSettings.json b/CMakeSettings.json new file mode 100644 index 0000000000..a9c794aa7e --- /dev/null +++ b/CMakeSettings.json @@ -0,0 +1,15 @@ +{ + "configurations": [ + { + "name": "x64-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "" + } + ] +} \ No newline at end of file diff --git a/IDE/VSCode/.vscode/launch.json b/IDE/VSCode/.vscode/launch.json new file mode 100644 index 0000000000..9126709f05 --- /dev/null +++ b/IDE/VSCode/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "STM32L4 - OpenOCD", + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "cwd": "${workspaceFolder:wolfBoot}", + "executable": "${workspaceFolder:wolfBoot}/build-linux-stm32l4/wolfboot.elf", + "device": "STM32L475VG", + "configFiles": [ + "interface/stlink-dap.cfg", + "target/stm32l4x.cfg" + ], + "runToMain": true, + "svdFile": "${workspaceFolder:wolfBoot}/hal/stm32l4/STM32L4x.svd", + "preLaunchTask": "CMake: Build (linux-stm32l4)" + } + ] +} diff --git a/IDE/VSCode/.vscode/settings.json b/IDE/VSCode/.vscode/settings.json new file mode 100644 index 0000000000..74419f2aa0 --- /dev/null +++ b/IDE/VSCode/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "cmake.useCMakePresets": "always", + "cmake.buildDirectory": "${workspaceFolder}/build-${buildPresetName}", + "cmake.configureOnOpen": true, + "cmake.generator": "Ninja", + "cmake.loggingLevel": "info", + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", + "files.encoding": "utf8", + "files.eol": "\n" +} diff --git a/IDE/VSCode/.vscode/tasks.json b/IDE/VSCode/.vscode/tasks.json new file mode 100644 index 0000000000..65aff45aec --- /dev/null +++ b/IDE/VSCode/.vscode/tasks.json @@ -0,0 +1,35 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "CMake: Configure (linux-stm32l4)", + "command": "cmake", + "args": [ "--preset", "linux-stm32l4" ], + "options": { "cwd": "${workspaceFolder:wolfBoot}" }, + "problemMatcher": [] + }, + { + "label": "CMake: Build (linux-stm32l4)", + "command": "cmake", + "args": [ "--build", "--preset", "linux-stm32l4" ], + "options": { "cwd": "${workspaceFolder:wolfBoot}" }, + "group": "build", + "problemMatcher": "$gcc" + }, + { + "label": "OpenOCD: Flash wolfBoot (linux-stm32l4)", + "type": "shell", + "command": "openocd", + "args": [ + "-f", + "interface/stlink-dap.cfg", + "-f", + "target/stm32l4x.cfg", + "-c", + "program ${workspaceFolder:wolfBoot}/build-linux-stm32l4/wolfboot.elf verify reset exit" + ], + "options": { "cwd": "${workspaceFolder:wolfBoot}" }, + "problemMatcher": [] + } + ] +} diff --git a/IDE/VSCode/README.md b/IDE/VSCode/README.md new file mode 100644 index 0000000000..5123cd5a63 --- /dev/null +++ b/IDE/VSCode/README.md @@ -0,0 +1,2 @@ +# VS Code wolfBoot Project + diff --git a/IDE/VisualGDB/README.md b/IDE/VisualGDB/README.md new file mode 100644 index 0000000000..053bc49b17 --- /dev/null +++ b/IDE/VisualGDB/README.md @@ -0,0 +1,68 @@ +# VisualGDB SDK wolfBoot Project + + + +## Required include files + +The device manufacturer files are installed by VisualGDB in `C:\Users\%USERNAME%\AppData\Local\VisualGDB`. + +In the case of the STM32L4 needing `stm32l4xx_hal.h`, here: + +```text +C:\Users\%USERNAME%\AppData\Local\VisualGDB\EmbeddedBSPs\arm-eabi\com.sysprogs.arm.stm32\STM32L4xxxx\STM32L4xx_HAL_Driver\Inc +``` + +This is in addition to the similar files installed by the STM32CubeIDE software here (for v1.18.0): + +``` +C:\Users\%USERNAME%\STM32Cube\Repository\STM32Cube_FW_L4_V1.18.0\Drivers\STM32L4xx_HAL_Driver\Inc +``` + +Project workspace directories created by STM32CubeIDE may also have include files in `[project]` directories like there: + +``` +C:\Users\gojimmypi\STM32CubeIDE\workspace_1.14.1\[project]\Drivers\STM32L4xx_HAL_Driver\Inc +``` + + +When using VisualGDB files in WSL: + +```bash +# Base where you found stm32l4xx_hal.h +export HAL_BASE="/mnt/c/Users/$USER/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx" + +# HAL driver includes: +export HAL_INC="$HAL_BASE/STM32L4xx_HAL_Driver/Inc" + +# (Legacy headers are sometimes needed by HAL) +export HAL_INC_LEGACY="$HAL_BASE/STM32L4xx_HAL_Driver/Inc/Legacy" + +# The CMSIS *core* is usually in the Cortex pack VisualGDB ships separately: +# Find the CMSIS *device* (stm32l4xx.h) and *core* (core_cm4.h) include dirs: +export CMSIS_DEV="$(dirname "$(find "$HAL_BASE" -type f -name stm32l4xx.h | head -n1)")" +export CMSIS_CORE="$(dirname "$(find "$HAL_BASE" -type f -name core_cm4.h | head -n1)")" + +# Peek at results +echo "HAL_INC = $HAL_INC" +echo "HAL_INC_LEGACY = $HAL_INC_LEGACY" +echo "CMSIS_DEV = $CMSIS_DEV" +echo "CMSIS_CORE = $CMSIS_CORE" + +# Sanity check to ensure files found +ls "$HAL_INC/stm32l4xx_hal.h" +ls "$CMSIS_DEV/stm32l4xx.h" +ls "$CMSIS_CORE/core_cm4.h" + +# 1) Expose the include paths to GCC (so no Makefile changes needed) +export C_INCLUDE_PATH="$HAL_INC:$HAL_INC/Legacy:$CMSIS_DEV:$CMSIS_CORE" +export CPLUS_INCLUDE_PATH="$C_INCLUDE_PATH" + +echo "C_INCLUDE_PATH = $C_INCLUDE_PATH" +echo "CPLUS_INCLUDE_PATH = $CPLUS_INCLUDE_PATH" + +# 2) Build wolfBoot for STM32L4 with your exact device macro +make TARGET=stm32l4 V=1 CFLAGS+=" -DUSE_HAL_DRIVER -DSTM32L475xx" +``` + +The `.config` file needs to be edited. See the [visualgdb-stm32l4.config](../config/examples/visualgdb-stm32l4.config) example for the STM32-L4. + diff --git a/IDE/VisualGDB/wolfBoot.sln b/IDE/VisualGDB/wolfBoot.sln new file mode 100644 index 0000000000..3d17cf78c8 --- /dev/null +++ b/IDE/VisualGDB/wolfBoot.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36518.9 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wolfBoot", "wolfBoot.vcxproj", "{B6C57BD0-E030-2488-DAD8-8BCE4B8E8FAC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B6C57BD0-E030-2488-DAD8-8BCE4B8E8FAC}.Debug|x64.ActiveCfg = Debug|x64 + {B6C57BD0-E030-2488-DAD8-8BCE4B8E8FAC}.Debug|x64.Build.0 = Debug|x64 + {B6C57BD0-E030-2488-DAD8-8BCE4B8E8FAC}.Debug|x86.ActiveCfg = Debug|Win32 + {B6C57BD0-E030-2488-DAD8-8BCE4B8E8FAC}.Debug|x86.Build.0 = Debug|Win32 + {B6C57BD0-E030-2488-DAD8-8BCE4B8E8FAC}.Release|x64.ActiveCfg = Release|x64 + {B6C57BD0-E030-2488-DAD8-8BCE4B8E8FAC}.Release|x64.Build.0 = Release|x64 + {B6C57BD0-E030-2488-DAD8-8BCE4B8E8FAC}.Release|x86.ActiveCfg = Release|Win32 + {B6C57BD0-E030-2488-DAD8-8BCE4B8E8FAC}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F94F2BC6-653D-4E7C-B79F-ECB97184C928} + EndGlobalSection +EndGlobal diff --git a/IDE/VisualGDB/wolfBoot.vcxproj b/IDE/VisualGDB/wolfBoot.vcxproj new file mode 100644 index 0000000000..2a56945b64 --- /dev/null +++ b/IDE/VisualGDB/wolfBoot.vcxproj @@ -0,0 +1,201 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + {B6C57BD0-E030-2488-DAD8-8BCE4B8E8FAC} + Win32Proj + + + + Application + true + v143 + + + Application + false + v143 + + + Application + true + v143 + + + Application + false + v143 + + + + + + + + + + + + + + + + + + + + + true + + + true + + + true + + + true + + + + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + Level3 + + + true + Console + + + + + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + Level3 + + + true + Console + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + Level3 + + + true + Console + true + true + + + + + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + Level3 + + + true + Console + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/IDE/VisualStudio/EmbeddedProject1/stm32.xml b/IDE/VisualStudio/EmbeddedProject1/stm32.xml new file mode 100644 index 0000000000..0f35427a19 --- /dev/null +++ b/IDE/VisualStudio/EmbeddedProject1/stm32.xml @@ -0,0 +1,25 @@ + + + com.visualgdb.arm-eabi + + 10.3.1 + 10.2.90 + 1 + + com.sysprogs.arm.stm32 + 2025.06 + STM32L475VG + STM32L4xxxx/DeviceDefinitions/stm32l475xx.xml + + + + Device-specific files + stm32.mak + + + + + + + + \ No newline at end of file diff --git a/IDE/VisualStudio/wolfboot/CMakeLists.txt b/IDE/VisualStudio/wolfboot/CMakeLists.txt new file mode 100644 index 0000000000..586849e2e4 --- /dev/null +++ b/IDE/VisualStudio/wolfboot/CMakeLists.txt @@ -0,0 +1,21 @@ +# CMakeList.txt : CMake project for wolfboot, include source and define +# project specific logic here. +# +cmake_minimum_required (VERSION 3.8) + +# Enable Hot Reload for MSVC compilers if supported. +if (POLICY CMP0141) + cmake_policy(SET CMP0141 NEW) + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$,$>,$<$:EditAndContinue>,$<$:ProgramDatabase>>") +endif() + +project ("wolfboot") + +# Add source to this project's executable. +add_executable (wolfboot "wolfboot.cpp" "wolfboot.h") + +if (CMAKE_VERSION VERSION_GREATER 3.12) + set_property(TARGET wolfboot PROPERTY CXX_STANDARD 20) +endif() + +# TODO: Add tests and install targets if needed. diff --git a/IDE/VisualStudio/wolfboot/CMakePresets.json b/IDE/VisualStudio/wolfboot/CMakePresets.json new file mode 100644 index 0000000000..fd16405684 --- /dev/null +++ b/IDE/VisualStudio/wolfboot/CMakePresets.json @@ -0,0 +1,101 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "windows-base", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "installDir": "${sourceDir}/out/install/${presetName}", + "cacheVariables": { + "CMAKE_C_COMPILER": "cl.exe", + "CMAKE_CXX_COMPILER": "cl.exe" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } + }, + { + "name": "x64-debug", + "displayName": "x64 Debug", + "inherits": "windows-base", + "architecture": { + "value": "x64", + "strategy": "external" + }, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "x64-release", + "displayName": "x64 Release", + "inherits": "x64-debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "x86-debug", + "displayName": "x86 Debug", + "inherits": "windows-base", + "architecture": { + "value": "x86", + "strategy": "external" + }, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "x86-release", + "displayName": "x86 Release", + "inherits": "x86-debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "linux-debug", + "displayName": "Linux Debug", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "installDir": "${sourceDir}/out/install/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Linux" + }, + "vendor": { + "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { + "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" + } + } + }, + { + "name": "macos-debug", + "displayName": "macOS Debug", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "installDir": "${sourceDir}/out/install/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Darwin" + }, + "vendor": { + "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { + "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" + } + } + } + ] +} diff --git a/IDE/VisualStudio/wolfboot/wolfboot.cpp b/IDE/VisualStudio/wolfboot/wolfboot.cpp new file mode 100644 index 0000000000..680ecbd5f9 --- /dev/null +++ b/IDE/VisualStudio/wolfboot/wolfboot.cpp @@ -0,0 +1,12 @@ +// wolfboot.cpp : Defines the entry point for the application. +// + +#include "wolfboot.h" + +using namespace std; + +int main() +{ + cout << "Hello CMake." << endl; + return 0; +} diff --git a/IDE/VisualStudio/wolfboot/wolfboot.h b/IDE/VisualStudio/wolfboot/wolfboot.h new file mode 100644 index 0000000000..84b5adb763 --- /dev/null +++ b/IDE/VisualStudio/wolfboot/wolfboot.h @@ -0,0 +1,8 @@ +// wolfboot.h : Include file for standard system include files, +// or project specific include files. + +#pragma once + +#include + +// TODO: Reference additional headers your program requires here. diff --git a/Makefile b/Makefile index d1f7e07565..ef5eefdd50 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ else endif endif -WOLFCRYPT_OBJS:= +WOLFCRYPT_OBJS?= SECURE_OBJS:= PUBLIC_KEY_OBJS:= WOLFHSM_OBJS:= @@ -85,7 +85,69 @@ include arch.mk # Parse config options include options.mk -OBJS+=$(WOLFCRYPT_OBJS) + +# ==== VisualGDB remap (opt-in) ============================================== +# Only active if VISUALGDB=1 is set (e.g., in .config or on the CLI). +ifeq ($(VISUALGDB),1) + + # 1) Strip stale Cube includes/macros that may come from options.mk + CFLAGS := $(filter-out -I/home/%/STM32Cube/Repository/%,$(CFLAGS)) + CFLAGS := $(filter-out -DSTM32L4A6xx,$(CFLAGS)) + + # 2) Inject the correct VisualGDB include paths + MCU macro + CFLAGS += \ + -I$(VISUALGDB_BASE)/STM32L4xx_HAL_Driver/Inc \ + -I$(VISUALGDB_BASE)/STM32L4xx_HAL_Driver/Inc/Legacy \ + -I$(VISUALGDB_BASE)/CMSIS_HAL/Core/Include \ + -I$(VISUALGDB_BASE)/CMSIS_HAL/Device/ST/STM32L4xx/Include \ + -DUSE_HAL_DRIVER -D$(STM32L4_PART) + + # --- Finalize crypto objects (dedupe & add once) ---------------------------- + # Normalize paths so filter-out can match both "x.o" and "./x.o" + override WOLFCRYPT_OBJS := $(patsubst ./%,%,$(WOLFCRYPT_OBJS)) + override MATH_OBJS := $(patsubst ./%,%,$(MATH_OBJS)) + + # Remove any pre-existing copies in OBJS, then add the union once + override OBJS := $(filter-out $(WOLFCRYPT_OBJS) $(MATH_OBJS),$(OBJS)) + override OBJS += $(sort $(WOLFCRYPT_OBJS) $(MATH_OBJS)) + # --------------------------------------------------------------------------- + + # Where to read sources from in the VisualGDB pack: + VISUALGDB_HAL_SRC ?= $(VISUALGDB_BASE)/STM32L4xx_HAL_Driver/Src + VISUALGDB_CMSIS_SRC ?= $(VISUALGDB_BASE)/CMSIS_HAL/Device/ST/STM32L4xx/Source/Templates + + # Local object output dirs (inside this repo; not touching VisualGDB files): + HAL_LOCAL_OBJ_DIR ?= build/vis_hal + CMSIS_LOCAL_OBJ_DIR ?= build/vis_cmsis + + # options.mk added classic-Cube object paths under $(STM32CUBE)/Drivers/.../Src/*.o + # Rewrite those object targets to our local obj dirs: + override OBJS := $(patsubst $(STM32CUBE)/Drivers/STM32L4xx_HAL_Driver/Src/%.o,\ + $(HAL_LOCAL_OBJ_DIR)/%.o,$(OBJS)) + override OBJS := $(patsubst $(STM32CUBE)/Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/%.o,\ + $(CMSIS_LOCAL_OBJ_DIR)/%.o,$(OBJS)) + + # Pattern rules to actually build them from the VisualGDB sources: + $(HAL_LOCAL_OBJ_DIR)/%.o: $(VISUALGDB_HAL_SRC)/%.c + @mkdir -p $(HAL_LOCAL_OBJ_DIR) + $(CC) $(CFLAGS) -c $< -o $@ + + $(CMSIS_LOCAL_OBJ_DIR)/%.o: $(VISUALGDB_CMSIS_SRC)/%.c + @mkdir -p $(CMSIS_LOCAL_OBJ_DIR) + $(CC) $(CFLAGS) -c $< -o $@ +endif +# ============================================================================ + +-include .config + +$(info WOLFCRYPT_OBJS=$(WOLFCRYPT_OBJS)) +$(info MATH_OBJS=$(MATH_OBJS)) + + +$(info SIGN=$(SIGN)) +$(info WOLFCRYPT_OBJS=$(WOLFCRYPT_OBJS)) + + OBJS+=$(PUBLIC_KEY_OBJS) OBJS+=$(WOLFHSM_OBJS) @@ -95,6 +157,8 @@ CFLAGS+= \ -D"WOLFSSL_USER_SETTINGS" \ -D"WOLFTPM_USER_SETTINGS" +CFLAGS += $(EXTRA_CFLAGS) + # Setup default optimizations (for GCC) ifeq ($(USE_GCC_HEADLESS),1) CFLAGS+=-Wall -Wextra -Wno-main -ffreestanding -Wno-unused -nostartfiles @@ -122,6 +186,7 @@ SIGN_ENV=IMAGE_HEADER_SIZE=$(IMAGE_HEADER_SIZE) \ MAIN_TARGET=factory.bin TARGET_H_TEMPLATE:=include/target.h.in +# TZEN only for TrustZone-capable parts (L5/U5/H5) ifeq ($(TZEN),1) ifeq ($(TARGET),stm32l5) # Don't build a contiguous image @@ -327,6 +392,10 @@ factory_wstage1.bin: $(BINASSEMBLE) stage1/loader_stage1.bin wolfboot.bin $(BOOT wolfboot_stage1.bin: wolfboot.elf stage1/loader_stage1.bin $(Q) cp stage1/loader_stage1.bin wolfboot_stage1.bin +lib/wolfssl/wolfcrypt/src/%.o: lib/wolfssl/wolfcrypt/src/%.c + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) -c $< -o $@ + wolfboot.elf: include/target.h $(LSCRIPT) $(OBJS) $(BINASSEMBLE) FORCE $(Q)(test $(SIGN) = NONE) || (test $(FLASH_OTP_KEYSTORE) = 1) || (grep -q $(SIGN_ALG) src/keystore.c) || \ (echo "Key mismatch: please run 'make keysclean' to remove all keys if you want to change algorithm" && false) diff --git a/README.md b/README.md index d07c084a7f..06bfb18a62 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,53 @@ The bootloader consists of the following components: - The core bootloader - A small application library used by the application to interact with the bootloader [src/libwolfboot.c](src/libwolfboot.c) +## Requirements + +### Linux + +Ensure the proper toolchain is installed. The default [Makefile](./Makefile) needs at least the `gcc-arm-none-eabi`. + +```bash +sudo apt update +sudo apt install -y build-essential gcc-arm-none-eabi binutils-arm-none-eabi +# optional (often handy): gdb-multiarch or gdb-arm-none-eabi +arm-none-eabi-gcc --version # should print the version +``` + +The device manufacturer toolchain _also_ needs to be installed. For example without the [STM32CubeIDE Software](https://www.st.com/en/development-tools/stm32cubeide.html), +errors like this will otherwise be encountered: + +``` + [CC ARM] hal/stm32l4.o +hal/stm32l4.c:24:10: fatal error: stm32l4xx_hal.h: No such file or directory + 24 | #include "stm32l4xx_hal.h" + | ^~~~~~~~~~~~~~~~~ +``` + +## Quick Start + +```bash +git clone https://github.com/gojimmypi/wolfBoot.git +cd wolfBoot +git submodule update --init + +## Use make +# edit your .config or copy from config/examples +make + +## OR ## + +# use cmake via wolfbuild.sh script: + +./wolfbuild.sh --CLEAN +./wolfbuild.sh --CLEAN stm32h7 +./wolfbuild.sh --target stm32h7 +``` + +### VS Code + + + ## Integrating wolfBoot in an existing project ### Required steps @@ -241,12 +288,12 @@ options to configuring wolfBoot, add `-LAH` to your cmake command, along with th $ cmake -DWOLFBOOT_TARGET=stm32h7 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x8020000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_SIZE=0xD0000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x80F0000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x81C0000 -LAH .. ``` -##### stm32f4 +#### stm32f4 ``` $ cmake -DWOLFBOOT_TARGET=stm32f4 -DWOLFBOOT_PARTITION_SIZE=0x20000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x08020000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08040000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x08060000 .. ``` -##### stm32u5 +#### stm32u5 ``` $ cmake -DWOLFBOOT_TARGET=stm32u5 -DBUILD_TEST_APPS=yes -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x08100000 -DWOLFBOOT_SECTOR_SIZE=0x2000 -DWOLFBOOT_PARTITION_SIZE=0x20000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x817F000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x81FE000 -DNO_MPU=yes .. ``` @@ -690,12 +737,12 @@ Use `make keysclean` to delete keys and regenerate. * RP2350 (Raspberry Pi Pico 2, ARM Cortex-M33 with TrustZone) * NXP MCXA153 * NXP MCXW716 - * STM32F1 series (STM32F103 “Blue Pill” board) + * STM32F1 series (STM32F103 “Blue Pill” board) * Improvements to supported targets * Xilinx UltraScale+ (ZynqMP) * Added hardware-accelerated SHA3 hashing via the CSU engine * Added support for enabling JTAG at runtime when `CSU_DEBUG` is set - * Introduced support for the device’s PUF (Physically Unclonable Function) for unique key generation and secure key storage (requires eFuses) + * Introduced support for the device’s PUF (Physically Unclonable Function) for unique key generation and secure key storage (requires eFuses) * Renesas RX * Added option for TSIP hardware crypto engine * Infineon TriCore (AURIX TC3xx) @@ -725,7 +772,7 @@ Use `make keysclean` to delete keys and regenerate. * Added support for x509 auth with wolfHSM in server mode * Added support for encrypted updates on Renesas RX (also via TSIP) * Added support for assembly optimizations for PowerPC 32bit (SHA, AES) - * STM32F4: new clock configuration to support all models, added support for STM32F411 + * STM32F4: new clock configuration to support all models, added support for STM32F411 * Bugfixes: * Fixed unaligned access in Cortex-A5 * Fixed compile flags to properly run code from RAM on ARM diff --git a/cmake/load_dot_config.cmake b/cmake/load_dot_config.cmake new file mode 100644 index 0000000000..76b7b92dd5 --- /dev/null +++ b/cmake/load_dot_config.cmake @@ -0,0 +1,120 @@ +# Usage: +# include(cmake/load_dot_config.cmake) +# load_dot_config("${CMAKE_SOURCE_DIR}/.config") # set normal CMake vars +# # or cache them so GUIs (e.g. Visual Studio) can see/edit them: +# load_dot_config("${CMAKE_SOURCE_DIR}/.config" CACHE_VARS) + +function(load_dot_config CONFIG_PATH) + set(_USE_CACHE OFF) + foreach(_arg IN LISTS ARGN) + if(_arg STREQUAL "CACHE_VARS") + set(_USE_CACHE ON) + endif() + endforeach() + + message(STATUS "Reading config file: ${CONFIG_PATH}") + if(NOT EXISTS "${CONFIG_PATH}") + message(FATAL_ERROR "load_dot_config: File not found: ${CONFIG_PATH}") + endif() + + # Read the entire file, normalize newlines to \n, then split into a CMake list. + file(READ "${CONFIG_PATH}" _cfg_raw) + # Normalize CRLF and CR to LF + string(REPLACE "\r\n" "\n" _cfg_raw "${_cfg_raw}") + string(REPLACE "\r" "\n" _cfg_raw "${_cfg_raw}") + # Split into a list where each element is one line + string(REPLACE "\n" ";" _cfg_lines "${_cfg_raw}") + + message(STATUS "-- Parsing lines from config file...") + foreach(_line IN LISTS _cfg_lines) + # Strip comments and whitespace + string(REGEX REPLACE "\\s*#.*$" "" _line "${_line}") + string(STRIP "${_line}" _line) + if(_line STREQUAL "") + message(STATUS "-- Skipping blank line") + continue() + endif() + message(STATUS "-- Found line: ${_line}") + + # KEY[?]=VALUE + # CMAKE_MATCH_1 = KEY, CMAKE_MATCH_2 = "?" or "", CMAKE_MATCH_3 = VALUE + # Visual guide (ASCII only): + # Group 1: Key name (...........1..........) + # Optional Space [ \t]* + # Group 2: Operand ( 2 ) + # Literal equals = + # Optional Space [ \t] + # Group 3: Value ( 3) + if(NOT _line MATCHES "^([A-Za-z_][A-Za-z0-9_]*)[ \t]*([?]?)=[ \t]*(.*)$") + message(WARNING "load_dot_config: Skipping unrecognized line: ${_line}") + continue() + endif() + set(_key "${CMAKE_MATCH_1}") # Setting name + set(_op "${CMAKE_MATCH_2}") # operand "?" or "" + set(_val "${CMAKE_MATCH_3}") # the value to + message(STATUS "-- Parsed key: ${_key}") + message(STATUS "-- Parsed op: ${_op}") + message(STATUS "-- Parsed val: ${_val}") + + # Trim value spaces + string(STRIP "${_val}" _val) + + # Remove value surrounding double quotes if present + if(_val MATCHES "^\"(.*)\"$") + set(_val "${CMAKE_MATCH_1}") + endif() + + # Expand Make-style $(VAR) to CMake env form $ENV{VAR} + # We keep $ENV{VAR} literal in the set() call so it expands now. + # Do multiple replacements if many occurrences exist. + while(_val MATCHES "\\$\\(([A-Za-z_][A-Za-z0-9_]*)\\)") + string(REGEX REPLACE "\\$\\(([A-Za-z_][A-Za-z0-9_]*)\\)" "\$ENV{\\1}" _val "${_val}") + endwhile() + + # After replacing with $ENV{...}, expand it to its actual value now. + # The "configure" trick expands env refs without touching other text. + set(_expanded "${_val}") + string(CONFIGURE "${_expanded}" _expanded @ONLY) + + # Detect prior definition + set(_already_defined FALSE) + if(DEFINED ${_key}) + set(_already_defined TRUE) + message(STATUS "-- Already defined: ${_key}=${_val}") + else() + # Check cache + get_property(_cache_type CACHE "${_key}" PROPERTY TYPE SET) + if(_cache_type) + set(_already_defined TRUE) + message(STATUS "-- Already defined (cache) ${_key}=${_val}") + endif() + endif() + + # Respect ?= (only set if not already defined) + set(_should_set TRUE) + if(_op STREQUAL "?" AND _already_defined) + set(_should_set FALSE) + endif() + + if(_should_set) + if(_USE_CACHE) + # Use STRING so values like "0x1000" stay as text; FORCE to mirror Make's "=" + # For "?=", do not FORCE to preserve user edits from cache/GUI. + if(_op STREQUAL "?") + message(STATUS "-- Cache Conditional Assignment: ${_key}=${_expanded} from ${CONFIG_PATH}") + set(${_key} "${_expanded}" CACHE STRING "Imported from ${CONFIG_PATH}") + else() + message(STATUS "-- Cache Assignment: ${_key}=${_expanded} from ${CONFIG_PATH}") + set(${_key} "${_expanded}" CACHE STRING "Imported from ${CONFIG_PATH}" FORCE) + endif() + else() + # Set variable in parent scope so caller can see value. + message(STATUS "-- Assignment: ${_key}=${_val}") + set(${_key} "${_expanded}" PARENT_SCOPE) + endif() + else() + message(STATUS "-- Skipping assignment: ${_key}=${_val}") + endif() + endforeach() + message(STATUS "-- Done processing ${CONFIG_PATH}") +endfunction() diff --git a/config/examples/README.md b/config/examples/README.md new file mode 100644 index 0000000000..495d11e7e8 --- /dev/null +++ b/config/examples/README.md @@ -0,0 +1,17 @@ +# Config Example Files + +This directory contains example `.config` presets for various target devices. + +## Make + +The examples here can be copied directly to the project `.config` file to use with `make`. + +## CMake + +See the [CMakePresets.json](../../CMakePresets.json) file. + +Config files can be added or updated to the `CMakePresets.json` like this: + +```bash +python3 config2presets.py ./config/examples/stm32h7.config +``` diff --git a/config/examples/visualgdb-stm32l4.config b/config/examples/visualgdb-stm32l4.config new file mode 100644 index 0000000000..2bb6aed08e --- /dev/null +++ b/config/examples/visualgdb-stm32l4.config @@ -0,0 +1,33 @@ +VISUALGDB=1 +VISUALGDB_BASE=/mnt/c/Users/$(USER)/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx + +TARGET=stm32l4 +STM32L4_PART?=STM32L475xx +BOARD=B-L475E-IOT01A + +SIGN=ECC256 +HASH=SHA256 +DEBUG?=0 +VTOR?=1 +CORTEX_M0?=0 +NO_ASM?=0 +EXT_FLASH?=0 +SPI_FLASH?=0 +ALLOW_DOWNGRADE?=0 +NVM_FLASH_WRITEONCE=1 +WOLFBOOT_VERSION?=0 +V?=0 +SPMATH?=1 +RAM_CODE?=0 +DUALBANK_SWAP?=0 + +# (Optional) Silence the "integer expression expected" warning cleanly +# Hex is fine functionally, but bash 'test' in some make rules dislikes it. +IMAGE_HEADER_SIZE?=512 # 0x200 + +WOLFBOOT_SECTOR_SIZE=0x1000 +WOLFBOOT_PARTITION_SIZE=0x7A000 +WOLFBOOT_PARTITION_BOOT_ADDRESS=0x0800A000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08084000 +WOLFBOOT_PARTITION_SWAP_ADDRESS=0x080FE000 +WOLFTPM?=0 diff --git a/config2presets.py b/config2presets.py new file mode 100644 index 0000000000..1b40ec5c58 --- /dev/null +++ b/config2presets.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python3 +import argparse, json, os, re, sys +from collections import OrderedDict + +COMMENT_RE = re.compile(r"\s*(#.*)?$") +LINE_RE = re.compile(r'^([A-Za-z_][A-Za-z0-9_]*)\s*\??=\s*(.*)$') + +BOOL_TRUE = {"1", "on", "true", "yes", "y"} +BOOL_FALSE = {"0", "off", "false", "no", "n"} + +def normalize_bool(s: str): + v = s.strip().lower() + if v in BOOL_TRUE: return "ON" + if v in BOOL_FALSE: return "OFF" + return None + +def parse_config(path: str): + kv = OrderedDict() + with open(path, "r", encoding="utf-8") as f: + for ln in f: + if COMMENT_RE.fullmatch(ln): + continue + m = LINE_RE.match(ln.rstrip("\n")) + if not m: + # skip silently; load_dot_config warns + continue + key, val = m.group(1), m.group(2).strip() + kv[key] = val + return kv + +def choose_target(kv): + # Prefer explicit wolfBoot var; else accept TARGET if present + if "WOLFBOOT_TARGET" in kv and kv["WOLFBOOT_TARGET"]: + return kv["WOLFBOOT_TARGET"] + if "TARGET" in kv and kv["TARGET"]: + return kv["TARGET"] + return "custom" + +def to_cache_vars(kv): + cache = OrderedDict() + for k, v in kv.items(): + # Map TARGET -> WOLFBOOT_TARGET if the latter is not already set + if k == "TARGET" and "WOLFBOOT_TARGET" not in kv: + cache["WOLFBOOT_TARGET"] = v + continue + + # Normalize booleans to ON/OFF; keep everything else as strings + nb = normalize_bool(v) + cache[k] = nb if nb is not None else v + return cache + +def ensure_base_vars(cache, toolchain_path): + # Always ensure toolchain file is set + cache.setdefault("CMAKE_TOOLCHAIN_FILE", toolchain_path) + # Your build typically wants this on + cache.setdefault("BUILD_TEST_APPS", "ON") + # Force preset mode when generating from .config into presets + cache["WOLFBOOT_CONFIG_MODE"] = "preset" + return cache + +def make_preset_name(target): + return f"linux-{target}" + +def make_binary_dir(source_dir, target): + return os.path.join(source_dir, f"build-{target}") + +def load_existing_presets(presets_path): + try: + with open(presets_path, "r", encoding="utf-8") as f: + return json.load(f) + except FileNotFoundError: + return None + +def merge_preset(doc, cfg_preset, bld_preset): + if doc is None: + return { + "version": 3, + "configurePresets": [cfg_preset], + "buildPresets": [bld_preset], + } + + # If file has newer schema that your CMake can't handle, you can still append, + # but CMake 3.22.1 will choke. We keep the existing version as-is. + if "configurePresets" not in doc: doc["configurePresets"] = [] + if "buildPresets" not in doc: doc["buildPresets"] = [] + + # Replace presets with same name + doc["configurePresets"] = [p for p in doc["configurePresets"] if p.get("name") != cfg_preset["name"]] + [cfg_preset] + doc["buildPresets"] = [p for p in doc["buildPresets"] if p.get("name") != bld_preset["name"]] + [bld_preset] + return doc + +def main(): + ap = argparse.ArgumentParser(description="Generate or merge a CMakePresets.json from a .config file") + ap.add_argument("config", help="Path to .config") + ap.add_argument("--toolchain", default="cmake/toolchain_arm-none-eabi.cmake", help="Path to toolchain file (relative to repo)") + ap.add_argument("--presets", default="CMakePresets.json", help="Path to CMakePresets.json to create/merge") + ap.add_argument("--generator", default="Ninja", help="CMake generator") + ap.add_argument("--preset-name", default=None, help="Override preset name") + ap.add_argument("--binary-dir", default=None, help="Override binaryDir") + ap.add_argument("--display-name", default=None, help="Override displayName") + args = ap.parse_args() + + kv = parse_config(args.config) + if not kv: + print("No settings parsed from .config", file=sys.stderr) + sys.exit(2) + + target = choose_target(kv) + cache = to_cache_vars(kv) + cache = ensure_base_vars(cache, args.toolchain) + + # Build preset objects + source_dir = "${sourceDir}" # CMake variable; leave literal + preset_name = args.preset_name or make_preset_name(target) + binary_dir = args.binary_dir or make_binary_dir(source_dir, target) + display_name = args.display_name or f"Linux/WSL ARM ({target})" + + cfg_preset = OrderedDict([ + ("name", preset_name), + ("displayName", display_name), + ("generator", args.generator), + ("binaryDir", binary_dir), + ("cacheVariables", cache), + ]) + bld_preset = OrderedDict([ + ("name", preset_name), + ("configurePreset", preset_name), + ("jobs", 0), + ]) + + # Ensure schema v3 unless existing file says otherwise + doc = load_existing_presets(args.presets) + if doc is None: + doc = {"version": 3} + + # If existing file has version >3, we *keep it*, but remember your CMake 3.22 understands v3 only. + if "version" not in doc: + doc["version"] = 3 + + result = merge_preset(doc, cfg_preset, bld_preset) + + # Pretty-print with stable key order + with open(args.presets, "w", encoding="utf-8") as f: + json.dump(result, f, indent=2) + f.write("\n") + + print(f"Updated {args.presets} with preset '{preset_name}' targeting '{target}'") + +if __name__ == "__main__": + main() diff --git a/test-app/Makefile b/test-app/Makefile index d447226320..bd1fde78cf 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -116,6 +116,53 @@ else APP_OBJS+=../hal/$(TARGET).o endif +# ==== VisualGDB remap for STM32L4 (opt-in) =================================== +# Requires VISUALGDB=1 and VISUALGDB_BASE in ../.config +ifeq ($(VISUALGDB),1) + # VisualGDB pack source locations + VISUALGDB_HAL_SRC ?= $(VISUALGDB_BASE)/STM32L4xx_HAL_Driver/Src + VISUALGDB_CMSIS_SRC ?= $(VISUALGDB_BASE)/CMSIS_HAL/Device/ST/STM32L4xx/Source/Templates + + # Local object output dirs (kept inside this repo) + HAL_LOCAL_OBJ_DIR ?= build/vis_hal + CMSIS_LOCAL_OBJ_DIR ?= build/vis_cmsis + + # Include dirs + MCU macro fix (use L475 without editing pack files) + CFLAGS += \ + -I$(VISUALGDB_BASE)/STM32L4xx_HAL_Driver/Inc \ + -I$(VISUALGDB_BASE)/STM32L4xx_HAL_Driver/Inc/Legacy \ + -I$(VISUALGDB_BASE)/CMSIS_HAL/Core/Include \ + -I$(VISUALGDB_BASE)/CMSIS_HAL/Device/ST/STM32L4xx/Include \ + -USTM32L4A6xx -DSTM32L475xx -DUSE_HAL_DRIVER + + # For stm32l4, ensure we build the needed HAL Flash objs locally + ifeq ($(TARGET),stm32l4) + # If anything in APP_OBJS still references STM32Cube objects, rewrite them: + override APP_OBJS := $(patsubst $(STM32CUBE)/Drivers/STM32L4xx_HAL_Driver/Src/%.o,\ + $(HAL_LOCAL_OBJ_DIR)/%.o,$(APP_OBJS)) + + # Make sure these two are present (the test-app needs them): + APP_OBJS+=$(STM32CUBE)/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.o + APP_OBJS+=$(STM32CUBE)/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.o + + APP_OBJS += \ + $(HAL_LOCAL_OBJ_DIR)/stm32l4xx_hal_flash.o \ + $(HAL_LOCAL_OBJ_DIR)/stm32l4xx_hal_flash_ex.o + endif + + # Pattern rules to compile VisualGDB pack sources into our local obj dirs + $(HAL_LOCAL_OBJ_DIR)/%.o: $(VISUALGDB_HAL_SRC)/%.c + @mkdir -p $(HAL_LOCAL_OBJ_DIR) + $(CC) $(CFLAGS) -c $< -o $@ + + $(CMSIS_LOCAL_OBJ_DIR)/%.o: $(VISUALGDB_CMSIS_SRC)/%.c + @mkdir -p $(CMSIS_LOCAL_OBJ_DIR) + $(CC) $(CFLAGS) -c $< -o $@ +endif +# ============================================================================= + + + ifeq ($(ARCH),RISCV) APP_OBJS+=startup_riscv.o vector_riscv.o endif @@ -154,7 +201,7 @@ ifeq ($(TARGET),sama5d3) LSCRIPT_TEMPLATE:=$(ARCH)-$(TARGET).ld endif -ifeq ($(TARGET),stm32l4) +ifeq ($(TARGET),stm32l4_disabled) APP_OBJS+=$(STM32CUBE)/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.o APP_OBJS+=$(STM32CUBE)/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.o CFLAGS+=-DSTM32L4A6xx -DUSE_HAL_DRIVER -Isrc -Ihal \ diff --git a/wolfbuild.sh b/wolfbuild.sh new file mode 100644 index 0000000000..9ae3f5be40 --- /dev/null +++ b/wolfbuild.sh @@ -0,0 +1,118 @@ +#!/bin/bash + +# Specify the executable shell checker you want to use: +MY_SHELLCHECK="shellcheck" + +# Check if the executable is available in the PATH +if command -v "$MY_SHELLCHECK" >/dev/null 2>&1; then + # Run your command here + shellcheck "$0" || exit 1 +else + echo "$MY_SHELLCHECK is not installed. Please install it if changes to this script have been made." +fi + +if [ $# -gt 0 ]; then + THIS_OPERATION="$1" + + TARGET="$2" + if [ "$TARGET" = "" ]; then + echo "No target specified" + fi + + if [ "$THIS_OPERATION" = "--CLEAN" ]; then + if [ "$TARGET" = "" ]; then + echo "Clean... (build)" + rm -rf ./build + else + echo "Clean... (build-$TARGET)" + rm -rf "./build-$TARGET" + fi + + # Any other build directories? + shopt -s nullglob + dirs=(build-*/) + if ((${#dirs[@]})); then + printf 'Warning: Found %d other build directory target(s):\n' "${#dirs[@]}" + printf '\n' + printf '%s\n' "${dirs[@]%/}" + printf '\n' + echo "Try: $0 --CLEAN [target]" + exit 1 + else + echo 'Success: No other build-[target] directories found.' + exit 0 + fi + fi + + if [ "$THIS_OPERATION" = "--target" ]; then + TARGET="$2" + echo "Set target: $TARGET" + fi + + if [ "$THIS_OPERATION" = "--stlink-upgrade" ]; then + echo "ST-Link upgrade!" + CLI="/mnt/c/Program Files/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STLinkUpgrade.exe" + + "$CLI" + status=$? + if [ "$status" -eq 0 ]; then + echo "OK: command succeeded" + else + echo "Failed: command exited with status $status" + fi + exit "$status" + fi + + if [ "$THIS_OPERATION" = "--flash" ]; then + CLI="/mnt/c/Program Files/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STM32_Programmer_CLI.exe" + + WOLFBOOT_BIN="build-linux-stm32l4/test-app/wolfboot_stm32l4.bin" + if [ ! -f "$WOLFBOOT_BIN" ]; then + echo "Missing: $WOLFBOOT_BIN (build first: cmake --build --preset \"$TARGET\")" + exit 2 + fi + IMAGE_WOLFBOOT=$(wslpath -w "$WOLFBOOT_BIN") + "$CLI" -c port=SWD mode=UR freq=400 -w "$IMAGE_WOLFBOOT" 0x08000000 -v + + SIGNED="build-$TARGET/test-app/image_v1_signed.bin" + if [ ! -f "$SIGNED" ]; then + echo "Missing: $SIGNED (try: cmake --build --preset \"$TARGET\" --target test-app)" + exit 2 + fi + + BOOT_ADDR=0x0800A000 # your wolfBoot BOOT address + IMAGE_SIGNED=$(wslpath -w "$SIGNED") + echo "IMAGE_SIGNED=$IMAGE_SIGNED" + + # SWD via ST-LINK (Windows handles the USB) + "$CLI" -c port=SWD mode=UR freq=400 -w "$IMAGE_SIGNED" "$BOOT_ADDR" -v -hardRst + status=$? + if [ "$status" -eq 0 ]; then + echo "OK: command succeeded" + else + echo "Failed: command exited with status $status" + fi + exit "$status" + fi +fi + +if [ "$TARGET" = "" ]; then + echo "Please specify a target." + echo "" + echo " $0 --target [your target]" + echo "" + cmake -S . -B build --list-presets=configure + exit 1 +fi + +echo "cmake --preset $TARGET" + cmake --preset "$TARGET" + +echo "cmake --build --preset $TARGET -j" + cmake --build --preset "$TARGET" -j + +# Reminder: Manual build +# mkdir -p build +# cd build +# cmake -DWOLFBOOT_TARGET=stm32h7 -DBUILD_TEST_APPS=yes -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x8020000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_SIZE=0xD0000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x80F0000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x81C0000 .. +# make From c89b858f35cf7fc81f2213dfb4b2ca249654f5a8 Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Mon, 6 Oct 2025 10:34:15 -0700 Subject: [PATCH 2/9] Cleanup, revert some Makefile edits --- CMakeSettings.json | 30 +++++++++++++++--------------- Makefile | 6 +++--- README.md | 4 ++-- test-app/Makefile | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/CMakeSettings.json b/CMakeSettings.json index a9c794aa7e..e2a6294df9 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -1,15 +1,15 @@ -{ - "configurations": [ - { - "name": "x64-Debug", - "generator": "Ninja", - "configurationType": "Debug", - "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${projectDir}\\out\\build\\${name}", - "installRoot": "${projectDir}\\out\\install\\${name}", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "" - } - ] -} \ No newline at end of file +{ + "configurations": [ + { + "name": "x64-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "" + } + ] +} diff --git a/Makefile b/Makefile index ef5eefdd50..d9498bdd45 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ else endif endif -WOLFCRYPT_OBJS?= +WOLFCRYPT_OBJS:= SECURE_OBJS:= PUBLIC_KEY_OBJS:= WOLFHSM_OBJS:= @@ -135,11 +135,11 @@ ifeq ($(VISUALGDB),1) $(CMSIS_LOCAL_OBJ_DIR)/%.o: $(VISUALGDB_CMSIS_SRC)/%.c @mkdir -p $(CMSIS_LOCAL_OBJ_DIR) $(CC) $(CFLAGS) -c $< -o $@ +else + OBJS+=$(WOLFCRYPT_OBJS) endif # ============================================================================ --include .config - $(info WOLFCRYPT_OBJS=$(WOLFCRYPT_OBJS)) $(info MATH_OBJS=$(MATH_OBJS)) diff --git a/README.md b/README.md index 06bfb18a62..733aefe248 100644 --- a/README.md +++ b/README.md @@ -737,12 +737,12 @@ Use `make keysclean` to delete keys and regenerate. * RP2350 (Raspberry Pi Pico 2, ARM Cortex-M33 with TrustZone) * NXP MCXA153 * NXP MCXW716 - * STM32F1 series (STM32F103 “Blue Pill” board) + * STM32F1 series (STM32F103 "Blue Pill" board) * Improvements to supported targets * Xilinx UltraScale+ (ZynqMP) * Added hardware-accelerated SHA3 hashing via the CSU engine * Added support for enabling JTAG at runtime when `CSU_DEBUG` is set - * Introduced support for the device’s PUF (Physically Unclonable Function) for unique key generation and secure key storage (requires eFuses) + * Introduced support for the device's PUF (Physically Unclonable Function) for unique key generation and secure key storage (requires eFuses) * Renesas RX * Added option for TSIP hardware crypto engine * Infineon TriCore (AURIX TC3xx) diff --git a/test-app/Makefile b/test-app/Makefile index bd1fde78cf..5e371ff3c7 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -201,7 +201,7 @@ ifeq ($(TARGET),sama5d3) LSCRIPT_TEMPLATE:=$(ARCH)-$(TARGET).ld endif -ifeq ($(TARGET),stm32l4_disabled) +ifeq ($(TARGET),stm32l4) APP_OBJS+=$(STM32CUBE)/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.o APP_OBJS+=$(STM32CUBE)/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.o CFLAGS+=-DSTM32L4A6xx -DUSE_HAL_DRIVER -Isrc -Ihal \ From b28fcb08cbef25f1039428e7fe652ae342c560a1 Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Mon, 6 Oct 2025 11:06:53 -0700 Subject: [PATCH 3/9] Do not assume .config or CMakePresets --- CMakeLists.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e1db5a391d..84a2ba6899 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,8 +52,13 @@ include_directories(lib/wolfssl) # Where should configuration values come from? # dot : parse .config via load_dot_config() # preset : use cacheVariables from CMakePresets.json -set(WOLFBOOT_CONFIG_MODE "dot" CACHE STRING "Config source: dot or preset") -set_property(CACHE WOLFBOOT_CONFIG_MODE PROPERTY STRINGS dot preset) +if( EXISTS "./.config") + message(STATUS "Found a .config file, will parse") + set(WOLFBOOT_CONFIG_MODE "dot" CACHE STRING "Config source: dot or preset") + set_property(CACHE WOLFBOOT_CONFIG_MODE PROPERTY STRINGS dot preset) +else() + message(STATUS "No .config file found.") +endif() if(WOLFBOOT_CONFIG_MODE STREQUAL "dot") message(STATUS "Config mode: dot (.config cache)") @@ -65,7 +70,7 @@ elseif(WOLFBOOT_CONFIG_MODE STREQUAL "preset") message(STATUS "Config mode: preset (using cacheVariables; skipping .config)") else() - message(FATAL_ERROR "Invalid WOLFBOOT_CONFIG_MODE='${WOLFBOOT_CONFIG_MODE}'. Use 'dot' or 'preset'.") + message(STATUS "Not using .config nor CMakePresets.json for WOLFBOOT_CONFIG_MODE.") endif() From 84fbf0f1a2e4a4ec1353b46a3093b81b5dd3b66b Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Sun, 12 Oct 2025 18:13:41 -0700 Subject: [PATCH 4/9] Latest WIP dev --- .github/workflows/test-build-cmake-mac.yml | 77 +++ .github/workflows/test-build-cmake-script.yml | 72 +++ .../workflows/test-build-cmake-windows.yml | 113 ++++ .github/workflows/test-build-cmake.yml | 58 ++- .vscode/launch.json | 20 + .vscode/settings.json | 11 + .vscode/tasks.json | 35 ++ CMakeLists.txt | 486 ++++++++++++++---- CMakePresets.json | 225 +++++++- CMakeUserPresets.json.sample | 18 + Makefile | 4 +- README.md | 195 ++++++- cmake/config_defaults.cmake | 92 ++++ cmake/current_user.cmake | 94 ++++ cmake/functions.cmake | 7 + cmake/load_dot_config.cmake | 258 +++++----- cmake/toolchain_arm-none-eabi.cmake | 126 +++-- hal/stm32l4xx_hal_conf.h | 24 +- my_test.bat | 8 + my_test.sh | 7 + wolfBoot.code-workspace | 83 +++ wolfbuild.sh | 5 + 22 files changed, 1746 insertions(+), 272 deletions(-) create mode 100644 .github/workflows/test-build-cmake-mac.yml create mode 100644 .github/workflows/test-build-cmake-script.yml create mode 100644 .github/workflows/test-build-cmake-windows.yml create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json create mode 100644 CMakeUserPresets.json.sample create mode 100644 cmake/config_defaults.cmake create mode 100644 cmake/current_user.cmake create mode 100644 my_test.bat create mode 100644 my_test.sh create mode 100644 wolfBoot.code-workspace diff --git a/.github/workflows/test-build-cmake-mac.yml b/.github/workflows/test-build-cmake-mac.yml new file mode 100644 index 0000000000..92dc26bf0d --- /dev/null +++ b/.github/workflows/test-build-cmake-mac.yml @@ -0,0 +1,77 @@ +name: WolfBoot CMake Build (macOS) + +on: + push: + branches: [ "*" ] + pull_request: + branches: [ "*" ] + +jobs: + macos-cmake: + name: Build on macOS (CMake + Ninja) + runs-on: macos-14 + timeout-minutes: 20 + + env: + HOMEBREW_NO_AUTO_UPDATE: "1" # avoid updating taps during install + HOMEBREW_NO_ANALYTICS: "1" + HOMEBREW_CURL_RETRIES: "6" # ask curl inside brew to retry + + steps: + - name: Checkout (with submodules) + uses: actions/checkout@v4 + with: + submodules: true + + - name: Cache Homebrew bottles # downloads (so retries don’t redownload) + uses: actions/cache@v4 + with: + path: | + ~/Library/Caches/Homebrew + /Users/runner/Library/Caches/Homebrew + key: homebrew-${{ runner.os }}-mac14-cmake-gcc-newlib + restore-keys: | + homebrew-${{ runner.os }}- + + - name: Install toolchain and build tools + run: | + # Install with step throttle to hopefully avoid stuck jobs + + set -euxo pipefail + + throttle_delay=5 + brew update + + sleep "$throttle_delay" + brew install --force-bottle cmake + + sleep "$throttle_delay" + brew install --force-bottle ninja + + sleep "$throttle_delay" + brew install --force-bottle arm-none-eabi-gcc + + - name: Probe GCC sysroot (headers check) + run: | + set -euxo pipefail + SYSROOT="$(arm-none-eabi-gcc -print-sysroot)" + echo "GCC sysroot: $SYSROOT" + test -f "$SYSROOT/include/stdlib.h" || { echo "Missing stdlib.h in $SYSROOT/include"; exit 1; } + test -f "$SYSROOT/include/string.h" || { echo "Missing string.h in $SYSROOT/include"; exit 1; } + + - name: Configure (STM32L4) + run: | + echo "Disabled, missing params" + # rm -rf build + # cmake -B build -G Ninja \ + # -DWOLFBOOT_CONFIG_MODE=preset \ + # -DWOLFBOOT_TARGET=stm32l4 \ + # -DBUILD_TEST_APPS=ON \ + # -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain_arm-none-eabi.cmake + + - name: Presets + run: | + rm -rf ./build-mac-stm32l4 + + cmake --preset mac-stm32l4 + cmake --build --preset mac-stm32l4 diff --git a/.github/workflows/test-build-cmake-script.yml b/.github/workflows/test-build-cmake-script.yml new file mode 100644 index 0000000000..e17a48a991 --- /dev/null +++ b/.github/workflows/test-build-cmake-script.yml @@ -0,0 +1,72 @@ +name: Wolfboot CMake Script +on: + push: + branches: [ '*' ] + pull_request: + branches: [ '*' ] +jobs: + cmake_automated_test: + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Workaround for sources.list + run: | + # Replace sources + + set -euxo pipefail + + # Peek (what repos are active now) + apt-cache policy + grep -RInE '^(deb|Types|URIs)' /etc/apt || true + + # Enable nullglob so *.list/*.sources that don't exist don't break sed + shopt -s nullglob + + echo "Replace sources.list (legacy)" + sudo sed -i \ + -e "s|https\?://azure\.archive\.ubuntu\.com/ubuntu/?|http://mirror.arizona.edu/ubuntu/|g" \ + /etc/apt/sources.list || true + + echo "Replace sources.list.d/*.list (legacy)" + for f in /etc/apt/sources.list.d/*.list; do + sudo sed -i \ + -e "s|https\?://azure\.archive\.ubuntu\.com/ubuntu/?|http://mirror.arizona.edu/ubuntu/|g" \ + "$f" + done + + echo "Replace sources.list.d/*.sources (deb822)" + for f in /etc/apt/sources.list.d/*.sources; do + sudo sed -i \ + -e "s|https\?://azure\.archive\.ubuntu\.com/ubuntu/?|http://mirror.arizona.edu/ubuntu/|g" \ + -e "s|https\?://azure\.archive\.ubuntu\.com|http://mirror.arizona.edu|g" \ + "$f" + done + + echo "Fix /etc/apt/apt-mirrors.txt (used by URIs: mirror+file:...)" + if grep -qE '^[[:space:]]*https?://azure\.archive\.ubuntu\.com/ubuntu/?' /etc/apt/apt-mirrors.txt; then + # Replace azure with our mirror (idempotent) + sudo sed -i 's|https\?://azure\.archive\.ubuntu\.com/ubuntu/|http://mirror.arizona.edu/ubuntu/|g' /etc/apt/apt-mirrors.txt + fi + + # Peek (verify changes) + grep -RIn "azure.archive.ubuntu.com" /etc/apt || true + grep -RInE '^(deb|Types|URIs)' /etc/apt || true + echo "--- apt-mirrors.txt ---" + cat /etc/apt/apt-mirrors.txt || true + + + - name: Install requirements + run: | + sudo apt-get update + sudo apt-get install -y gcc-arm-none-eabi gcc-powerpc-linux-gnu cmake + + - name: Run wolfbuild script + run: | + rm -rf ./build + ./wolfbuild.sh --CLEAN "linux-stm32l4" + ./wolfbuild.sh --target "linux-stm32l4" diff --git a/.github/workflows/test-build-cmake-windows.yml b/.github/workflows/test-build-cmake-windows.yml new file mode 100644 index 0000000000..524393730a --- /dev/null +++ b/.github/workflows/test-build-cmake-windows.yml @@ -0,0 +1,113 @@ +name: WolfBoot CMake Build (Windows) + +on: + push: + branches: [ "*" ] + pull_request: + branches: [ "*" ] + +jobs: + windows-cmake: + name: Build on Windows (CMake + Ninja) + runs-on: windows-latest + timeout-minutes: 20 + + strategy: + fail-fast: false + matrix: + target: + - stm32l4 + - stm32h7 + include: + # Optional per-target cache variables you might want to pass later. + # Keep empty for now to avoid guessing addresses. + - target: stm32l4 + extra_cache: "" + - target: stm32h7 + extra_cache: "" + + steps: + - name: Checkout (with submodules) + uses: actions/checkout@v4 + with: + submodules: true + + # ARM GCC toolchain (adds the bin dir to PATH) + - name: Set up ARM none-eabi GCC 14.x + uses: carlosperate/arm-none-eabi-gcc-action@v1 + with: + version: "14.2.Rel1" # <-- use 'release', not 'version' + path-env-var: ARM_NONE_EABI_GCC_PATH + + # CMake + Ninja are preinstalled on windows-latest, but verify & print versions + - name: Tool versions + shell: bash + run: | + echo "Compiler versions:" + arm-none-eabi-gcc --version + echo + echo "CMake:" + cmake --version + echo + echo "Ninja:" + ninja --version + echo + echo "MSVC (via vswhere):" + cmd.exe /c "\"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe\" -latest -products * -requires Microsoft.Component.MSBuild -property installationVersion" + + - name: Build via cmd inline + shell: cmd + run: | + if exist build-windows-stm32l4 rmdir /s /q build-windows-stm32l4 + cmake --preset windows-stm32l4 + cmake --build --preset windows-stm32l4 --parallel %NUMBER_OF_PROCESSORS% + + - name: Build via batch (cmd) + shell: cmd + run: | + :: # Call my_test.bat + + call my_test.bat + + - name: Configure (CMake + Ninja) + shell: bash + run: | + # cmake runs in git bash + echo "disabled" + + #BUILD_DIR="build-${{ matrix.target }}" + #cmake -S . -B "$BUILD_DIR" -G Ninja \ + # -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain_arm-none-eabi.cmake \ + # -DWOLFBOOT_CONFIG_MODE=preset \ + # -DWOLFBOOT_TARGET=${{ matrix.target }} \ + # -DBUILD_TEST_APPS=ON \ + # ${{ matrix.extra_cache }} + #echo "Configured: $BUILD_DIR" + + - name: Build + shell: bash + run: | + # cmake runs in git bash + BUILD_DIR="build-${{ matrix.target }}" + cmake --build "$BUILD_DIR" --parallel + + # Optional: show interesting artifacts + - name: List build outputs + if: always() + shell: bash + run: | + BUILD_DIR="build-${{ matrix.target }}" + echo "=== Artifacts in $BUILD_DIR ===" + find "$BUILD_DIR" -maxdepth 3 -type f \( -name "*.elf" -o -name "*.bin" -o -name "*.hex" -o -name "bin-assemble" -o -name "keystore" \) -print || true + + # Upload binaries if present (non-fatal if none) + - name: Upload firmware/artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: wolfboot-${{ matrix.target }} + path: | + build-${{ matrix.target }}/**/*.elf + build-${{ matrix.target }}/**/*.bin + build-${{ matrix.target }}/**/*.hex + if-no-files-found: warn diff --git a/.github/workflows/test-build-cmake.yml b/.github/workflows/test-build-cmake.yml index eb41a92e26..b72dea367a 100644 --- a/.github/workflows/test-build-cmake.yml +++ b/.github/workflows/test-build-cmake.yml @@ -1,5 +1,7 @@ -name: Wolfboot CMake Build +name: Wolfboot CMake Build (Ubuntu) on: + push: + branches: [ '*' ] pull_request: branches: [ '*' ] jobs: @@ -12,9 +14,54 @@ jobs: with: submodules: true + - name: Workaround for sources.list + run: | + # Replace sources + + set -euxo pipefail + + # Peek (what repos are active now) + apt-cache policy + grep -RInE '^(deb|Types|URIs)' /etc/apt || true + + # Enable nullglob so *.list/*.sources that don't exist don't break sed + shopt -s nullglob + + echo "Replace sources.list (legacy)" + sudo sed -i \ + -e "s|https\?://azure\.archive\.ubuntu\.com/ubuntu/?|http://mirror.arizona.edu/ubuntu/|g" \ + /etc/apt/sources.list || true + + echo "Replace sources.list.d/*.list (legacy)" + for f in /etc/apt/sources.list.d/*.list; do + sudo sed -i \ + -e "s|https\?://azure\.archive\.ubuntu\.com/ubuntu/?|http://mirror.arizona.edu/ubuntu/|g" \ + "$f" + done + + echo "Replace sources.list.d/*.sources (deb822)" + for f in /etc/apt/sources.list.d/*.sources; do + sudo sed -i \ + -e "s|https\?://azure\.archive\.ubuntu\.com/ubuntu/?|http://mirror.arizona.edu/ubuntu/|g" \ + -e "s|https\?://azure\.archive\.ubuntu\.com|http://mirror.arizona.edu|g" \ + "$f" + done + + echo "Fix /etc/apt/apt-mirrors.txt (used by URIs: mirror+file:...)" + if grep -qE '^[[:space:]]*https?://azure\.archive\.ubuntu\.com/ubuntu/?' /etc/apt/apt-mirrors.txt; then + # Replace azure with our mirror (idempotent) + sudo sed -i 's|https\?://azure\.archive\.ubuntu\.com/ubuntu/|http://mirror.arizona.edu/ubuntu/|g' /etc/apt/apt-mirrors.txt + fi + + # Peek (verify changes) + grep -RIn "azure.archive.ubuntu.com" /etc/apt || true + grep -RInE '^(deb|Types|URIs)' /etc/apt || true + echo "--- apt-mirrors.txt ---" + cat /etc/apt/apt-mirrors.txt || true + + - name: Install requirements run: | - sudo sed -i 's|http://azure.archive.ubuntu.com/ubuntu/|http://mirror.arizona.edu/ubuntu/|g' /etc/apt/sources.list sudo apt-get update sudo apt-get install -y gcc-arm-none-eabi gcc-powerpc-linux-gnu cmake @@ -22,6 +69,7 @@ jobs: run: | rm -rf ./build cmake -B build -DWOLFBOOT_TARGET=stm32u5 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x08100000 -DWOLFBOOT_SECTOR_SIZE=0x2000 -DWOLFBOOT_PARTITION_SIZE=0x20000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x817F000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x81FE000 -DNO_MPU=yes + - name: Build wolfBoot run: make -C build @@ -59,3 +107,9 @@ jobs: cmake -B build -DWOLFBOOT_TARGET=nrf52 -DWOLFBOOT_PARTITION_SIZE=0x8000 -DWOLFBOOT_SECTOR_SIZE=0x1000 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x27000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x2F000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x37000 - name: Build wolfBoot run: make -C build + + - name: Run wolfbuild script + run: | + rm -rf ./build + ./wolfbuild.sh --CLEAN "linux-stm32l4" + ./wolfbuild.sh --target "linux-stm32l4" diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..14ec097716 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "STM32L4 - OpenOCD", + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "cwd": "${workspaceFolder:wolfBoot}", + "executable": "${workspaceFolder:wolfBoot}/build-linux-stm32l4/wolfboot.elf", + "device": "STM32L475VG", + "configFiles": [ + "interface/stlink-dap.cfg", + "target/stm32l4x.cfg" + ], + "runToMain": true, + "svdFile": "${workspaceFolder:wolfBoot}/hal/stm32l4/STM32L4x.svd", + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..1fc382aabb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "cmake.useCMakePresets": "auto", + "cmake.buildDirectory": "${workspaceFolder}/build-${buildPresetName}", + "cmake.configureOnOpen": true, + "cmake.generator": "Ninja", + "cmake.loggingLevel": "info", + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", + "files.encoding": "utf8", + "files.eol": "\n", + "cmake.preferredGenerators": [ "Ninja", "Visual Studio 17 2022" ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000000..f20b19f787 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,35 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "CMake: Configure (linux-stm32l4)", + "command": "cmake", + "args": [ "--preset", "linux-stm32l4" ], + "options": { "cwd": "${workspaceFolder:wolfBoot}" }, + "problemMatcher": [] + }, + { + "label": "CMake: Build (linux-stm32l4)", + "command": "cmake", + "args": [ "--build", "--preset", "linux-stm32l4" ], + "options": { "cwd": "${workspaceFolder:wolfBoot}" }, + "group": "build", + "problemMatcher": "$gcc" + }, + { + "label": "OpenOCD: Flash wolfBoot (linux-stm32l4)", + "type": "shell", + "command": "openocd", + "args": [ + "-f", + "interface/stlink-dap.cfg", + "-f", + "target/stm32l4x.cfg", + "-c", + "program ${workspaceFolder:wolfBoot}/build-linux-stm32l4/wolfboot.elf verify reset exit" + ], + "options": { "cwd": "${workspaceFolder:wolfBoot}" }, + "problemMatcher": [] + } + ] +} diff --git a/CMakeLists.txt b/CMakeLists.txt index 84a2ba6899..069eca4aaa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,11 @@ # $ cmake --build . cmake_minimum_required(VERSION 3.16) +include(cmake/config_defaults.cmake) +# ------------------------------------------------------------------------------ +# Initial environment checks +# ------------------------------------------------------------------------------ if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") message( FATAL_ERROR @@ -40,15 +44,184 @@ if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") You must delete them, or cmake will refuse to work.") endif() +if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) + if(DEFINED WOLFBOOT_TARGET AND + NOT WOLFBOOT_TARGET STREQUAL "x86_64_efi" AND + NOT WOLFBOOT_TARGET STREQUAL "sim") + set(CMAKE_TOOLCHAIN_FILE + "${CMAKE_SOURCE_DIR}/cmake/toolchain_arm-none-eabi.cmake" + CACHE FILEPATH "" FORCE) + endif() +endif() + +# ------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ project(wolfBoot) +# ------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ +include(cmake/functions.cmake) + +# set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES "" CACHE STRING "" FORCE) + +# ---- Host compiler (for native tools only) ----------------------------------- +# Build-time tools (bin-assemble/sign/keygen) must compile for the HOST. +if (CMAKE_HOST_WIN32) + # Prefer gcc/clang on Windows so POSIX-y headers (unistd.h) are available. + message(STATUS "Tip: If find_program cannot find HOST_CC (not in path?), try launching from VS2022 dev prompt or edit path.") + find_program(HOST_CC NAMES gcc clang cl REQUIRED) + + if (HOST_CC MATCHES [[(^|[/\\])cl(\.exe)?$]]) + message(STATUS "Found CMAKE_HOST_WIN32 and .exe in HOST_CC: Setting HOST_IS_MSVC") + # Are we running in Visual Studio 2022 or VSCode from VS2022 command prompt? + print_env(VSCMD_VER) + print_env(VCToolsInstallDir) + print_env(VCINSTALLDIR) + print_env(WindowsSdkDir) + # DOS/Windows detected by ".exe" extension, not to be confused with WSL and/or WinGW + set(HOST_IS_MSVC TRUE) + set(HOST_EXE ".exe") + set(HOST_O2 /O2) + set(HOST_I /I) + set(HOST_D /D) + set(HOST_OUT /Fe:) + # Put .obj files in a private folder to avoid collisions & root litter: + set(HOST_OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/obj") + file(MAKE_DIRECTORY "${HOST_OBJDIR}") + set(HOST_FO "/Fo$") + set(HOST_WARN "") # MSVC warnings already noisy; keep simple + # wolfSSL random on Windows needs Advapi32: + set(HOST_LINK_LIBS Advapi32.lib) + else() + # gcc or clang + set(HOST_IS_MSVC FALSE) + set(HOST_EXE "") + set(HOST_O2 -O2) + set(HOST_I -I) + set(HOST_D -D) + set(HOST_OUT -o) + set(HOST_FO "") # gcc/clang handle objs internally here + set(HOST_WARN -Wall -Wextra -Werror) + set(HOST_LINK_LIBS "") # not needed with MinGW/clang on Windows + endif() +else() + # POSIX hosts + find_program(HOST_CC NAMES gcc clang cc REQUIRED) + set(HOST_IS_MSVC FALSE) + set(HOST_EXE "") + set(HOST_O2 -O2) + set(HOST_I -I) + set(HOST_D -D) + set(HOST_OUT -o) + set(HOST_FO "") + set(HOST_WARN -Wall -Wextra -Werror) + set(HOST_LINK_LIBS "") +endif() + +message(STATUS "Host CC: ${HOST_CC}") +message(STATUS "Host compiler treated as MSVC: ${HOST_IS_MSVC}") + +# ------------------------------------------------------------------------------ +# Common includes/defines for host tools +# ------------------------------------------------------------------------------ +set(HOST_INCLUDES + ${HOST_I}${CMAKE_SOURCE_DIR}/tools/keytools + ${HOST_I}${CMAKE_SOURCE_DIR}/lib/wolfssl + ${HOST_I}${CMAKE_SOURCE_DIR}/include + ${HOST_I}${CMAKE_CURRENT_BINARY_DIR} +) +set(HOST_DEFS + ${HOST_D}WOLFSSL_USER_SETTINGS + ${HOST_D}IMAGE_HEADER_SIZE=${IMAGE_HEADER_SIZE} + ${HOST_D}DELTA_UPDATES +) + +# --- Windows unistd.h shim for MSVC host builds --- +if(CMAKE_HOST_WIN32 AND HOST_IS_MSVC) + set(HOST_SHIM_DIR "${CMAKE_CURRENT_BINARY_DIR}/host_shims") + file(MAKE_DIRECTORY "${HOST_SHIM_DIR}") + + # Minimal shims; extend if bin-assemble needs more. + file(WRITE "${HOST_SHIM_DIR}/unistd.h" [=[ +#ifndef _WIN32 +# error "This shim is for Windows/MSVC only" +#endif +#include +#include +#include +#include + +#ifndef ssize_t +# ifdef _WIN64 + typedef long long ssize_t; +# else + typedef int ssize_t; +# endif +#endif + +#ifndef unlink +# define unlink _unlink +#endif +#ifndef close +# define close _close +#endif +#ifndef read +# define read _read +#endif +#ifndef write +# define write _write +#endif +#ifndef access +# define access _access +#endif +]=]) + + # Prepend shim include so it is found first + list(INSERT HOST_INCLUDES 0 ${HOST_I}$) +endif() # Windows Host Shim + include(cmake/load_dot_config.cmake) include(cmake/utils.cmake) -include(cmake/functions.cmake) include_directories(include) include_directories(lib/wolfssl) +if(false) # my Windows + + # Cross toolchain basics + set(CMAKE_SYSTEM_NAME Generic) + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + + # Allow preset to pass the bin directory of the Arm GCC toolchain + set(ARM_GCC_BIN "" CACHE PATH "Path to Arm GNU Toolchain 'bin' folder") + + if(NOT ARM_GCC_BIN) + message(FATAL_ERROR "ARM_GCC_BIN not set. Pass it via preset cacheVariables.") + endif() + + # Normalize to CMake-style path (forward slashes) + file(TO_CMAKE_PATH "${ARM_GCC_BIN}" _ARM_GCC_BIN) + + # Point CMake compilers explicitly + set(CMAKE_C_COMPILER "${_ARM_GCC_BIN}/arm-none-eabi-gcc.exe" CACHE FILEPATH "" FORCE) + set(CMAKE_CXX_COMPILER "${_ARM_GCC_BIN}/arm-none-eabi-g++.exe" CACHE FILEPATH "" FORCE) + set(CMAKE_ASM_COMPILER "${_ARM_GCC_BIN}/arm-none-eabi-gcc.exe" CACHE FILEPATH "" FORCE) + set(CMAKE_AR "${_ARM_GCC_BIN}/arm-none-eabi-ar.exe" CACHE FILEPATH "" FORCE) + set(CMAKE_RANLIB "${_ARM_GCC_BIN}/arm-none-eabi-ranlib.exe" CACHE FILEPATH "" FORCE) + set(CMAKE_OBJCOPY "${_ARM_GCC_BIN}/arm-none-eabi-objcopy.exe" CACHE FILEPATH "" FORCE) + set(CMAKE_OBJDUMP "${_ARM_GCC_BIN}/arm-none-eabi-objdump.exe" CACHE FILEPATH "" FORCE) + set(CMAKE_SIZE "${_ARM_GCC_BIN}/arm-none-eabi-size.exe" CACHE FILEPATH "" FORCE) +endif() + + +#--------------------------------------------------------------------------------------------- +# There are different configuration modes: +# +# - Command-line options +# - Using a .config file. See load_dot_config() +# - Using CMake Presets. (preferred, use cacheVariables from CMakePresets.json) +#--------------------------------------------------------------------------------------------- + # Where should configuration values come from? # dot : parse .config via load_dot_config() # preset : use cacheVariables from CMakePresets.json @@ -67,10 +240,10 @@ if(WOLFBOOT_CONFIG_MODE STREQUAL "dot") load_dot_config("${CMAKE_SOURCE_DIR}/.config") elseif(WOLFBOOT_CONFIG_MODE STREQUAL "preset") - message(STATUS "Config mode: preset (using cacheVariables; skipping .config)") + message(STATUS "Config mode: preset (using cacheVariables; skipping .config)") else() - message(STATUS "Not using .config nor CMakePresets.json for WOLFBOOT_CONFIG_MODE.") + message(STATUS "Not using .config nor CMakePresets.json for WOLFBOOT_CONFIG_MODE.") endif() @@ -189,7 +362,7 @@ if(NOT DEFINED PULL_LINKER_DEFINES AND NOT DEFINED BUILD_TEST_APPS) endif() endif() -# unset cache variables Variables that need to be accessed by the gen_wolfboot_platform_target cmake +# unset cache variables variables that need to be accessed by the gen_wolfboot_platform_target cmake # function called from the parent cmake project are added to the cache so that they can be accessed # anywhere in the project unset(WOLFBOOT_DEFS CACHE) @@ -219,29 +392,64 @@ set(WOLFBOOT_SOURCES include/loader.h include/image.h src/string.c src/image.c) list(APPEND WOLFBOOT_SOURCES src/loader.c) -# build bin-assemble tool -set(BINASSEMBLE ${CMAKE_CURRENT_BINARY_DIR}/bin-assemble) -add_custom_command( - OUTPUT ${BINASSEMBLE} - COMMAND gcc tools/bin-assemble/bin-assemble.c -o ${BINASSEMBLE} - WORKING_DIRECTORY ${WOLFBOOT_ROOT} - COMMENT "Generating bin-assemble tool") +if(0) + # build bin-assemble tool + set(BINASSEMBLE ${CMAKE_CURRENT_BINARY_DIR}/bin-assemble) + add_custom_command( + OUTPUT "${BINASSEMBLE}" + COMMAND gcc tools/bin-assemble/bin-assemble.c -o "${BINASSEMBLE}" + WORKING_DIRECTORY "${WOLFBOOT_ROOT}" + COMMENT "Generating bin-assemble tool") + + add_custom_target(binAssemble DEPENDS "${BINASSEMBLE}") + + # ----------------------------------------------------------------------------- + # Toolchain Specifications + # ----------------------------------------------------------------------------- + + if(ARCH STREQUAL "ARM") + include(cmake/toolchain_arm-none-eabi.cmake) + elseif(ARCH STREQUAL "AARCH64") + include(cmake/toolchain_aarch64-none-elf.cmake) + endif() +else() + # build bin-assemble tool Windows + set(BINASSEMBLE ${CMAKE_CURRENT_BINARY_DIR}/bin-assemble${HOST_EXE}) + set(BINASSEMBLE_OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/obj_bin_assemble") + + add_custom_command( + OUTPUT "${BINASSEMBLE}" + COMMAND "${CMAKE_COMMAND}" -E make_directory ${BINASSEMBLE_OBJDIR} + COMMAND "${HOST_CC}" ${HOST_O2} ${HOST_WARN} + ${HOST_INCLUDES} # <-- needed for unistd.h shim + ${HOST_FO} # /Fo$ # isolate objs + ${HOST_OUT}$ + $ + ${HOST_LINK_LIBS} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + COMMENT "Building bin-assemble tool" + ) + add_custom_target(binAssemble DEPENDS ${BINASSEMBLE}) -add_custom_target(binAssemble DEPENDS ${BINASSEMBLE}) -# ----------------------------------------------------------------------------- -# Toolchain Specifications -# ----------------------------------------------------------------------------- -if(ARCH STREQUAL "ARM") - include(cmake/toolchain_arm-none-eabi.cmake) -elseif(ARCH STREQUAL "AARCH64") - include(cmake/toolchain_aarch64-none-elf.cmake) + #----------------------------------------------------------------------------------------- + # Toolchain Specifications + #----------------------------------------------------------------------------------------- + if(NOT CMAKE_C_COMPILER) + # Ensure include only once + if(ARCH STREQUAL "ARM") + include(cmake/toolchain_arm-none-eabi.cmake) + elseif(ARCH STREQUAL "AARCH64") + include(cmake/toolchain_aarch64-none-elf.cmake) + endif() + endif() + endif() -# ----------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- # Architecture/CPU configuration -# ----------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- set(UPDATE_SOURCES src/update_flash.c) # Default flash offset @@ -332,9 +540,9 @@ if(${WOLFBOOT_TARGET} STREQUAL "x86_64_efi") set(UPDATE_SOURCES src/update_ram.c) endif() -# ----------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- # DSA Settings -# ----------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- if(SIGN STREQUAL "NONE") list(APPEND KEYTOOL_OPTIONS --no-sign) message(STATUS "Image signing disabled") @@ -510,6 +718,10 @@ list(APPEND WOLFBOOT_DEFS ${SIGN_OPTIONS}) list(APPEND WOLFBOOT_COMPILE_OPTIONS -Wstack-usage=${STACK_USAGE} -Wno-unused) +#--------------------------------------------------------------------------------------------- +# +#--------------------------------------------------------------------------------------------- + if(PULL_LINKER_DEFINES) list(APPEND WOLFBOOT_DEFS PULL_LINKER_DEFINES) endif() @@ -689,22 +901,38 @@ target_sources(wolfboothal PRIVATE include/hal.h hal/${WOLFBOOT_TARGET}.c ${WOLF # --- HAL for STM32L4 (only the pieces we need) --- if(WOLFBOOT_TARGET STREQUAL "stm32l4") - set(HAL_BASE "/mnt/c/Users/gojimmypi/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx") - set(HAL_DRV "${HAL_BASE}/STM32L4xx_HAL_Driver") - set(HAL_CMSIS_DEV "${HAL_BASE}/CMSIS_HAL/Device/ST/STM32L4xx/Include") - set(HAL_CMSIS_CORE "${HAL_BASE}/CMSIS_HAL/Include") - set(HAL_TEMPLATE_INC "${HAL_BASE}/VendorSamples/L4/Projects/B-L475E-IOT01A/Templates/Inc") + if(CMAKE_HOST_WIN32 AND IS_DIRECTORY "${LIB_STM32L4_WINDOWS}" ) + message(STATUS "Win32 Path found: ${LIB_STM32L4_WINDOWS}") + set(HAL_BASE "${LIB_STM32L4_WINDOWS}") + elseif(IS_DIRECTORY "${LIB_STM32L4_WSL}") + message(STATUS "WSL Path found: ${LIB_STM32L4_WSL}") + set(HAL_BASE "${LIB_STM32L4_WSL}") + else() + message(STATUS "STM32L4 Path not found") + set(HAL_BASE "") + endif() + + if(true) + + set(HAL_DRV "${HAL_BASE}/STM32L4xx_HAL_Driver") + set(HAL_CMSIS_DEV "${HAL_BASE}/CMSIS_HAL/Device/ST/STM32L4xx/Include") + set(HAL_CMSIS_CORE "${HAL_BASE}/CMSIS_HAL/Include") + set(HAL_TEMPLATE_INC "${HAL_BASE}/VendorSamples/L4/Projects/B-L475E-IOT01A/Templates/Inc") + endif() + message(STATUS "HAL_DRV=${HAL_DRV}") add_library(stm32l4_hal STATIC ${HAL_DRV}/Src/stm32l4xx_hal.c ${HAL_DRV}/Src/stm32l4xx_hal_flash.c ${HAL_DRV}/Src/stm32l4xx_hal_flash_ex.c + ${HAL_DRV}/Src/stm32l4xx_hal_cortex.c # add more modules later if you get missing symbols, e.g. RCC/GPIO/etc: # ${HAL_DRV}/Src/stm32l4xx_hal_rcc.c # ${HAL_DRV}/Src/stm32l4xx_hal_gpio.c ) - target_include_directories(stm32l4_hal PUBLIC + target_include_directories(stm32l4_hal BEFORE PUBLIC + ${WOLFBOOT_ROOT}/hal ${HAL_DRV}/Inc ${HAL_CMSIS_DEV} ${HAL_CMSIS_CORE} @@ -714,7 +942,7 @@ if(WOLFBOOT_TARGET STREQUAL "stm32l4") target_compile_definitions(stm32l4_hal PUBLIC USE_HAL_DRIVER STM32L475xx - # If your stm32l4xx_hal_conf.h doesnt enable FLASH, you can force it: + # If your stm32l4xx_hal_conf.h doesn't enable FLASH, you can force it: # HAL_FLASH_MODULE_ENABLED ) @@ -729,15 +957,131 @@ target_include_directories(wolfboothal PRIVATE ${WOLFBOOT_ROOT} include) target_compile_options(wolfboothal PRIVATE ${WOLFBOOT_COMPILE_OPTIONS} ${EXTRA_COMPILE_OPTIONS}) message(STATUS "Using C Keytools") -set(SIGN_TOOL ${CMAKE_CURRENT_BINARY_DIR}/sign) -set(KEYGEN_TOOL ${CMAKE_CURRENT_BINARY_DIR}/keygen) + +#--------------------------------------------------------------------------------------------- +# define sources/flags BEFORE the custom commands that use them +#--------------------------------------------------------------------------------------------- +list( + APPEND + KEYTOOL_SOURCES + src/delta.c + lib/wolfssl/wolfcrypt/src/asn.c + lib/wolfssl/wolfcrypt/src/aes.c + lib/wolfssl/wolfcrypt/src/ecc.c + lib/wolfssl/wolfcrypt/src/coding.c + lib/wolfssl/wolfcrypt/src/chacha.c + lib/wolfssl/wolfcrypt/src/ed25519.c + lib/wolfssl/wolfcrypt/src/ed448.c + lib/wolfssl/wolfcrypt/src/fe_operations.c + lib/wolfssl/wolfcrypt/src/ge_operations.c + lib/wolfssl/wolfcrypt/src/fe_448.c + lib/wolfssl/wolfcrypt/src/ge_448.c + lib/wolfssl/wolfcrypt/src/hash.c + lib/wolfssl/wolfcrypt/src/logging.c + lib/wolfssl/wolfcrypt/src/memory.c + lib/wolfssl/wolfcrypt/src/random.c + lib/wolfssl/wolfcrypt/src/rsa.c + lib/wolfssl/wolfcrypt/src/sp_int.c + lib/wolfssl/wolfcrypt/src/sp_c32.c + lib/wolfssl/wolfcrypt/src/sp_c64.c + lib/wolfssl/wolfcrypt/src/sha3.c + lib/wolfssl/wolfcrypt/src/sha256.c + lib/wolfssl/wolfcrypt/src/sha512.c + lib/wolfssl/wolfcrypt/src/tfm.c + lib/wolfssl/wolfcrypt/src/wc_port.c + lib/wolfssl/wolfcrypt/src/wolfmath.c + lib/wolfssl/wolfcrypt/src/dilithium.c + lib/wolfssl/wolfcrypt/src/wc_lms.c + lib/wolfssl/wolfcrypt/src/wc_lms_impl.c + lib/wolfssl/wolfcrypt/src/wc_xmss.c + lib/wolfssl/wolfcrypt/src/wc_xmss_impl.c +) + +set(KEYTOOL_SOURCES_ABS ${KEYTOOL_SOURCES}) +list(TRANSFORM KEYTOOL_SOURCES_ABS PREPEND ${CMAKE_SOURCE_DIR}/) + +list(APPEND KEYTOOL_FLAGS + -Wall + -Wextra + -Werror + -Itools/keytools + -DWOLFSSL_USER_SETTINGS + -Ilib/wolfssl/ + -Iinclude + -I${CMAKE_CURRENT_BINARY_DIR} + -O2 + -DIMAGE_HEADER_SIZE=${IMAGE_HEADER_SIZE} + -DDELTA_UPDATES +) + + +#--------------------------------------------------------------------------------------------- +# sign tool +#--------------------------------------------------------------------------------------------- +set(SIGN_TOOL ${CMAKE_CURRENT_BINARY_DIR}/sign${HOST_EXE}) +set(SIGN_OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/obj_sign") +if( "${HOST_EXE}" STREQUAL "") + set(HOST_FO_SIGN "") # No /Fo for most environments +else() + # isolate objs only for Windows (.exe) + set(HOST_FO_SIGN "/Fo$") +endif() + + add_custom_command( + OUTPUT ${SIGN_TOOL} + COMMAND "${CMAKE_COMMAND}" -E make_directory ${SIGN_OBJDIR} + COMMAND "${HOST_CC}" ${HOST_O2} ${HOST_WARN} + ${HOST_INCLUDES} ${HOST_DEFS} + ${HOST_FO_SIGN} # /Fo$ # ${HOST_FO_SIGN} + $ + ${KEYTOOL_SOURCES_ABS} + ${HOST_OUT}$ + ${HOST_LINK_LIBS} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + COMMENT "Building signing tool" + ) + +add_custom_target(keytools ALL DEPENDS ${SIGN_TOOL} ${KEYGEN_TOOL}) +set(SIGN_TOOL ${SIGN_TOOL} CACHE INTERNAL "") + +#--------------------------------------------------------------------------------------------- +# keygen +#--------------------------------------------------------------------------------------------- +set(KEYGEN_TOOL ${CMAKE_CURRENT_BINARY_DIR}/keygen${HOST_EXE}) +set(KEYGEN_OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/obj_keygen") +if( "${HOST_EXE}" STREQUAL "") + set(HOST_FO_KEYGEN "") # No /Fo for most environments +else() + # isolate objs only for Windows (.exe) + set(HOST_FO_KEYGEN "/Fo$") +endif() + +add_custom_command( + OUTPUT ${KEYGEN_TOOL} + COMMAND "${CMAKE_COMMAND}" -E make_directory ${KEYGEN_OBJDIR} + COMMAND "${HOST_CC}" ${HOST_O2} ${HOST_WARN} + ${HOST_INCLUDES} ${HOST_DEFS} + ${HOST_FO_KEYGEN} + $ + ${KEYTOOL_SOURCES_ABS} + ${HOST_OUT}$ + ${HOST_LINK_LIBS} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Building keygen tool" +) + +add_custom_target(keygen_build DEPENDS ${KEYGEN_TOOL}) +add_dependencies(keytools keygen_build) +set(KEYGEN_TOOL ${KEYGEN_TOOL} CACHE INTERNAL "") list(APPEND WOLFBOOT_INCLUDE_DIRS ${WOLFBOOT_ROOT} ${WOLFBOOT_ROOT}/include) # set default linker script set(WOLFBOOT_LSCRIPT_TEMPLATE hal/${WOLFBOOT_TARGET}.ld) +#--------------------------------------------------------------------------------------------- # wolfcrypt +#--------------------------------------------------------------------------------------------- add_subdirectory(lib) if(BUILD_TEST_APPS OR BUILD_IMAGE) @@ -800,73 +1144,9 @@ target_include_directories(target BEFORE INTERFACE ${CMAKE_CURRENT_BINARY_DIR} l set(KEYSTORE ${CMAKE_CURRENT_BINARY_DIR}/keystore.c) -list( - APPEND - KEYTOOL_SOURCES - src/delta.c - lib/wolfssl/wolfcrypt/src/asn.c - lib/wolfssl/wolfcrypt/src/aes.c - lib/wolfssl/wolfcrypt/src/ecc.c - lib/wolfssl/wolfcrypt/src/coding.c - lib/wolfssl/wolfcrypt/src/chacha.c - lib/wolfssl/wolfcrypt/src/ed25519.c - lib/wolfssl/wolfcrypt/src/ed448.c - lib/wolfssl/wolfcrypt/src/fe_operations.c - lib/wolfssl/wolfcrypt/src/ge_operations.c - lib/wolfssl/wolfcrypt/src/fe_448.c - lib/wolfssl/wolfcrypt/src/ge_448.c - lib/wolfssl/wolfcrypt/src/hash.c - lib/wolfssl/wolfcrypt/src/logging.c - lib/wolfssl/wolfcrypt/src/memory.c - lib/wolfssl/wolfcrypt/src/random.c - lib/wolfssl/wolfcrypt/src/rsa.c - lib/wolfssl/wolfcrypt/src/sp_int.c - lib/wolfssl/wolfcrypt/src/sp_c32.c - lib/wolfssl/wolfcrypt/src/sp_c64.c - lib/wolfssl/wolfcrypt/src/sha3.c - lib/wolfssl/wolfcrypt/src/sha256.c - lib/wolfssl/wolfcrypt/src/sha512.c - lib/wolfssl/wolfcrypt/src/tfm.c - lib/wolfssl/wolfcrypt/src/wc_port.c - lib/wolfssl/wolfcrypt/src/wolfmath.c - lib/wolfssl/wolfcrypt/src/dilithium.c - lib/wolfssl/wolfcrypt/src/wc_lms.c - lib/wolfssl/wolfcrypt/src/wc_lms_impl.c - lib/wolfssl/wolfcrypt/src/wc_xmss.c - lib/wolfssl/wolfcrypt/src/wc_xmss_impl.c -) - -list( - APPEND - KEYTOOL_FLAGS - -Wall - -Wextra - -Werror - -Itools/keytools - -DWOLFSSL_USER_SETTINGS - -Ilib/wolfssl/ - -Iinclude - -I${CMAKE_CURRENT_BINARY_DIR} - -O2 - -DIMAGE_HEADER_SIZE=${IMAGE_HEADER_SIZE} - -DDELTA_UPDATES) - -add_custom_command( - OUTPUT ${SIGN_TOOL} - COMMAND gcc -o ${CMAKE_CURRENT_BINARY_DIR}/sign tools/keytools/sign.c ${KEYTOOL_SOURCES} - ${KEYTOOL_FLAGS} - WORKING_DIRECTORY ${WOLFBOOT_ROOT} - COMMENT "Building signing tool") - -add_custom_command( - OUTPUT ${KEYGEN_TOOL} - COMMAND gcc -o ${CMAKE_CURRENT_BINARY_DIR}/keygen tools/keytools/keygen.c ${KEYTOOL_SOURCES} - ${KEYTOOL_FLAGS} - WORKING_DIRECTORY ${WOLFBOOT_ROOT} - COMMENT "Building keygen tool") - -add_custom_target(keytools ALL DEPENDS ${SIGN_TOOL} ${KEYGEN_TOOL}) - +#--------------------------------------------------------------------------------------------- +# +#--------------------------------------------------------------------------------------------- if(NOT SIGN STREQUAL "NONE") add_custom_target(keystore DEPENDS ${SIGN_TOOL} ${KEYGEN_TOOL} ${KEYSTORE}) @@ -874,14 +1154,14 @@ if(NOT SIGN STREQUAL "NONE") if(NOT EXISTS ${KEYSTORE}) add_custom_command( OUTPUT ${KEYSTORE} ${WOLFBOOT_SIGNING_PRIVATE_KEY} - COMMAND ${KEYGEN_TOOL} ${KEYTOOL_OPTIONS} -g ${WOLFBOOT_SIGNING_PRIVATE_KEY} + COMMAND "${KEYGEN_TOOL}" ${KEYTOOL_OPTIONS} -g ${WOLFBOOT_SIGNING_PRIVATE_KEY} -keystoreDir ${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${WOLFBOOT_ROOT} COMMENT "Generating keystore.c and signing private key") add_custom_command( - OUTPUT ${KEYSTORE} ${WOLFBOOT_SIGNING_PRIVATE_KEY} - DEPENDS ${KEYGEN_TOOL} + OUTPUT "${KEYSTORE}" ${WOLFBOOT_SIGNING_PRIVATE_KEY} + DEPENDS "${KEYGEN_TOOL}" APPEND) endif() @@ -900,5 +1180,5 @@ target_compile_options(wolfboot PUBLIC ${EXTRA_COMPILE_OPTIONS}) target_include_directories(wolfboot PUBLIC ${WOLFBOOT_INCLUDE_DIRS}) target_link_libraries(wolfboot wolfboothal target wolfcrypt) -# dont warn on unused code +# don't warn on unused code target_compile_options(wolfboot PRIVATE -Wno-unused ${SIM_COMPILE_OPTIONS}) diff --git a/CMakePresets.json b/CMakePresets.json index 376edd56b1..0f479800c1 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -1,20 +1,67 @@ { "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 22, + "patch": 0 + }, "configurePresets": [ { "name": "base", "hidden": true, "binaryDir": "${sourceDir}/build-${presetName}" }, + { + "name": "_template-os-target", + "displayName": "_sample - target - template", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/build-windows-stm32l4", + "environment": { + "PATH": "$penv{LOCALAPPDATA}/Microsoft/WinGet/Links;C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/14.2 rel1/bin;$penv{PATH}" + }, + "cacheVariables": { + "ENV_REMINDER": "use env for cache, penv elsewhere", + "TARGET_OS": "WINDOWS", + "WOLFBOOT_CONFIG_MODE": "preset", + "VISUALGDB": "ON", + "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", + "WOLFBOOT_TARGET": "stm32l4" + } + }, { "name": "windows-stm32h7", "displayName": "Windows ARM (STM32H7)", "generator": "Ninja", "cacheVariables": { + "TARGET_OS": "WINDOWS", "WOLFBOOT_CONFIG_MODE": "preset", "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", "WOLFBOOT_TARGET": "stm32h7", - "BUILD_TEST_APPS": "yes" + "BUILD_TEST_APPS": "yes", + "ARCH": "ARM", + "SIGN": "ECC256", + "HASH": "SHA256", + "DEBUG": "OFF", + "DEBUG_UART": "OFF", + "VTOR": "ON", + "NO_ASM": "OFF", + "EXT_FLASH": "OFF", + "SPI_FLASH": "OFF", + "QSPI_FLASH": "OFF", + "OCTOSPI_FLASH": "OFF", + "ALLOW_DOWNGRADE": "OFF", + "NVM_FLASH_WRITEONCE": "OFF", + "WOLFBOOT_VERSION": "ON", + "V": "OFF", + "SPMATH": "ON", + "RAM_CODE": "OFF", + "DUALBANK_SWAP": "OFF", + "WOLFBOOT_PARTITION_SIZE": "0xD0000", + "WOLFBOOT_SECTOR_SIZE": "0x20000", + "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x8020000", + "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x80F0000", + "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x81C0000" } }, { @@ -37,6 +84,7 @@ "displayName": "Linux/WSL ARM (stm32h7)", "generator": "Ninja", "cacheVariables": { + "TARGET_OS": "LINUX", "WOLFBOOT_CONFIG_MODE": "preset", "ARCH": "ARM", "WOLFBOOT_TARGET": "stm32h7", @@ -72,10 +120,49 @@ "displayName": "Linux/WSL ARM (stm32l4)", "generator": "Ninja", "cacheVariables": { + "TARGET_OS": "LINUX", "WOLFBOOT_CONFIG_MODE": "preset", "VISUALGDB": "ON", - "VISUALGDB_BASE": "/mnt/c/Users/$env{USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx", - "CMAKE_C_STANDARD_INCLUDE_DIRECTORIES": "/mnt/c/Users/$env{USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/VendorSamples/L4/Projects/B-L475E-IOT01A/Templates/Inc", + "VISUALGDB_BASE": "/mnt/c/Users/$penv{USERNAME}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx", + "CMAKE_C_STANDARD_INCLUDE_DIRECTORIES": "/mnt/c/Users/$penv{USERNAME}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/VendorSamples/L4/Projects/B-L475E-IOT01A/Templates/Inc", + "WOLFBOOT_TARGET": "stm32l4", + "STM32L4_PART": "STM32L475xx", + "BOARD": "B-L475E-IOT01A", + "ARCH": "ARM", + "SIGN": "ECC256", + "HASH": "SHA256", + "DEBUG": "OFF", + "VTOR": "ON", + "CORTEX_M0": "OFF", + "NO_ASM": "OFF", + "EXT_FLASH": "OFF", + "SPI_FLASH": "OFF", + "ALLOW_DOWNGRADE": "OFF", + "NVM_FLASH_WRITEONCE": "ON", + "WOLFBOOT_VERSION": "OFF", + "V": "OFF", + "SPMATH": "ON", + "RAM_CODE": "OFF", + "DUALBANK_SWAP": "OFF", + "IMAGE_HEADER_SIZE": "256", + "WOLFBOOT_SECTOR_SIZE": "0x1000", + "WOLFBOOT_PARTITION_SIZE": "0x7A000", + "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x0800A000", + "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x08084000", + "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x080FE000", + "WOLFTPM": "OFF", + "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", + "BUILD_TEST_APPS": "ON" + } + }, + { + "name": "mac-stm32l4", + "displayName": "macOS ARM (STM32L4)", + "inherits": [ "base" ], + "generator": "Ninja", + "binaryDir": "${sourceDir}/build-mac-stm32l4", + "cacheVariables": { + "WOLFBOOT_CONFIG_MODE": "preset", "WOLFBOOT_TARGET": "stm32l4", "STM32L4_PART": "STM32L475xx", "BOARD": "B-L475E-IOT01A", @@ -105,28 +192,144 @@ "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", "BUILD_TEST_APPS": "ON" } + }, + { + "name": "stm32l4", + "displayName": "macOS ARM (STM32L4)", + "inherits": [ "base" ], + "generator": "Ninja", + "binaryDir": "${sourceDir}/build-stm32l4", + "cacheVariables": { + "WOLFBOOT_CONFIG_MODE": "preset", + "WOLFBOOT_TARGET": "stm32l4", + "STM32L4_PART": "STM32L475xx", + "BOARD": "B-L475E-IOT01A", + "ARCH": "ARM", + "SIGN": "ECC256", + "HASH": "SHA256", + "DEBUG": "OFF", + "VTOR": "ON", + "CORTEX_M0": "OFF", + "NO_ASM": "OFF", + "EXT_FLASH": "OFF", + "SPI_FLASH": "OFF", + "ALLOW_DOWNGRADE": "OFF", + "NVM_FLASH_WRITEONCE": "ON", + "WOLFBOOT_VERSION": "OFF", + "V": "OFF", + "SPMATH": "ON", + "RAM_CODE": "OFF", + "DUALBANK_SWAP": "OFF", + "IMAGE_HEADER_SIZE": "256", + "WOLFBOOT_SECTOR_SIZE": "0x1000", + "WOLFBOOT_PARTITION_SIZE": "0x7A000", + "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x0800A000", + "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x08084000", + "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x080FE000", + "WOLFTPM": "OFF", + "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", + "BUILD_TEST_APPS": "ON" + } + }, + { + "name": "windows-stm32l4", + "inherits": [ "base" ], + "displayName": "Windows - STM32L4 - Ninja", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build-windows-stm32l4", + "environment": { + "WindowsSdkDir": "C:/Program Files (x86)/Windows Kits/10", + "WindowsSdkVer": "10.0.26100.0", + "VCToolsInstallDir_DISABLED": "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/MSVC/14.44.35207", + "INCLUDE_DISABLED": "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include;C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/ucrt;C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/um;C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/shared;$penv{INCLUDE}", + "LIB_DISABLED": "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/x64;C:/Program Files (x86)/Windows Kits/10/Lib/10.0.26100.0/ucrt/x64;C:/Program Files (x86)/Windows Kits/10/Lib/10.0.26100.0/um/x64;$penv{LIB}", + "PATH": "$penv{LOCALAPPDATA}/Microsoft/WinGet/Links;C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/14.2 rel1/bin;$penv{PATH}" + }, + "cacheVariables": { + "TARGET_OS": "WINDOWS", + "WOLFBOOT_CONFIG_MODE": "preset", + "VISUALGDB": "ON", + "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", + "CMAKE_C_STANDARD_INCLUDE_DIRECTORIES": "c:/Users/$penv{USERNAME}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/VendorSamples/L4/Projects/B-L475E-IOT01A/Templates/Inc", + "WOLFBOOT_TARGET": "stm32l4", + "STM32L4_PART": "STM32L475xx", + "BOARD": "B-L475E-IOT01A", + "ARCH": "ARM", + "SIGN": "ECC256", + "HASH": "SHA256", + "DEBUG": "OFF", + "VTOR": "ON", + "CORTEX_M0": "OFF", + "NO_ASM": "OFF", + "EXT_FLASH": "OFF", + "SPI_FLASH": "OFF", + "ALLOW_DOWNGRADE": "OFF", + "NVM_FLASH_WRITEONCE": "ON", + "WOLFBOOT_VERSION": "OFF", + "V": "OFF", + "SPMATH": "ON", + "RAM_CODE": "OFF", + "DUALBANK_SWAP": "OFF", + "IMAGE_HEADER_SIZE": "256", + "WOLFBOOT_SECTOR_SIZE": "0x1000", + "WOLFBOOT_PARTITION_SIZE": "0x7A000", + "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x0800A000", + "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x08084000", + "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x080FE000", + "WOLFTPM": "OFF", + "BUILD_TEST_APPS": "ON" + } } ], "buildPresets": [ - { - "name": "windows-stm32h7", - "configurePreset": "windows-stm32h7", - "jobs": 0 - }, { "name": "vs-debug-trace", "configurePreset": "vs-debug-trace", - "jobs": 0 + "jobs": 4, + "verbose": true, + "targets": [ "all" ] }, { "name": "linux-stm32h7", "configurePreset": "linux-stm32h7", - "jobs": 0 + "jobs": 4, + "verbose": true, + "targets": [ "all" ] }, { "name": "linux-stm32l4", "configurePreset": "linux-stm32l4", - "jobs": 0 + "jobs": 4, + "verbose": true, + "targets": [ "all" ] + }, + { + "name": "windows-stm32h7", + "configurePreset": "windows-stm32h7", + "jobs": 4, + "verbose": true, + "targets": [ "all" ] + }, + { + "name": "windows-stm32l4", + "configurePreset": "windows-stm32l4", + "jobs": 4, + "verbose": true, + "targets": [ "all" ] + }, + { + "name": "mac-stm32l4", + "configurePreset": "mac-stm32l4", + "jobs": 4, + "verbose": true, + "targets": [ "all" ] + }, + { + "name": "stm32l4", + "configurePreset": "stm32l4", + "jobs": 4, + "verbose": true, + "targets": [ "all" ] } ] } diff --git a/CMakeUserPresets.json.sample b/CMakeUserPresets.json.sample new file mode 100644 index 0000000000..cebe0e42c2 --- /dev/null +++ b/CMakeUserPresets.json.sample @@ -0,0 +1,18 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "my-arm-bin", + "inherits": "windows-stm32l4", + "cacheVariables": { + "ARM_GCC_BIN": "C:/Tools/arm-none-eabi-14.2/bin" + } + } + ], + "buildPresets": [ + { + "name": "my-arm-bin", + "configurePreset": "my-arm-bin" + } + ] +} diff --git a/Makefile b/Makefile index 9eac3dbe01..59476dcc93 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ else endif endif -WOLFCRYPT_OBJS:= +WOLFCRYPT_OBJS?= SECURE_OBJS:= PUBLIC_KEY_OBJS:= WOLFHSM_OBJS:= @@ -147,6 +147,8 @@ else endif # ============================================================================ +-include .config + $(info WOLFCRYPT_OBJS=$(WOLFCRYPT_OBJS)) $(info MATH_OBJS=$(MATH_OBJS)) diff --git a/README.md b/README.md index 733aefe248..52c70c7f28 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,35 @@ # wolfBoot +CMake Dev Status: + +|Status | Environment | Test With +|-------| ------------------------- | -------- +| ✅ | VS 2022 | Right-Click on [CMakeLists.txt](./CMakeLists.txt), Build +| ✅ | WSL | [./my_test.sh](./my_test.sh) +| ⚠️ | Mac | [test-build-cmake-mac.yml](./github/workflows/test-build-cmake-mac.yml) +| ✅ | VS Code, Dev Prompt | Click "build" on bottom toolbar ribbon +| ✅ | DOS Prompt, Dev Prompt | [my_test.bat](./my_test.bat) +| ✅ | PowerShell, Dev Prompt | [.\my_test.bat](./my_test.bat) +| ❌ | DOS Prompt, direct launch | [my_test.bat](./my_test.bat) +| ❌ | PowerShell, direct launch | [my_test.bat](./my_test.bat) +| ❌ | VS Code, direct launch | Click "build" + +Make Dev Status: + +|Status | Environment | Test With +|-------| ------------------------- | -------- +| ? | VS 2022 | N/A (?) +| ✅ | WSL | `./wolfbuild.sh --target stm32l4` +| ⚠️ | Mac | [test-build-cmake-mac.yml](./github/workflows/test-build-cmake-mac.yml) +| ? | VS Code, Dev Prompt | N/A (?) +| ❌ | DOS Prompt, Dev Prompt | +| ❌ | PowerShell, Dev Prompt | +| ❌ | DOS Prompt, direct launch | +| ❌ | PowerShell, direct launch | +| ? | VS Code, direct launch | N/A (?) + +--- + wolfSSL Secure Bootloader ([Home page](https://www.wolfssl.com/products/wolfboot/)) wolfBoot is a portable, OS-agnostic, secure bootloader solution for 32-bit microcontrollers, @@ -84,7 +114,86 @@ make ### VS Code +Windows users may need one of these: + +- [Visual Studio 2022](https://visualstudio.microsoft.com/) +- [Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/). See `C:\Program Files(x86)\Windows kits`. + +#### Launch Stand-alone VS Code + +The MSVC kit may be needed if VS 2022 is not installed. + +Select `View` - `Command Palette`, search for CMake: Select a Compiler + +See also: CMake: Delete Cache and Reconfigure + + +#### Launch VS Code from VS 2022 Command prompt. + +Delete any existing `build` or `build-[os]-[target]` directories as needed. + +Open a VS 2022 Developer command prompt. + +From the command prompt, open the `wolfBoot.code-workspace` VS Code workspace: + +```dos +cd c:\workspace\wolfboot-%USERNAME% +code ./IDE/VSCode/wolfBoot.code-workspace +``` + +### Visual Studio IDE + +For the `Select Startup Item`, leave at default. Do not select `image`, wolfboot_name[], etc. + +Right click on `CMakeLists.txt` and select `Delete Cache and Reconfigure`. +Right click on `CMakeLists.txt` and select `Build`. + +### Visual Studio Command Prompt + +Select `View` - `Terminal` from the menu bar. + +* Configure: `cmake --preset ` +* Build: `cmake --build --preset ` + +```bash +# delete build directory +rmdir /s /q build-windows-stm32l4 + +# configure +cmake --preset windows-stm32l4 + +# build +cmake --build --preset windows-stm32l4 +``` + +If there are no devices listed in the `Manage Configurations` drop-down, ensure the `CMakePresets.json` is valid. +A single json syntax error will spoil the entire project. + +## Your own toolchain + +Create a `CMakeUserPresets.json` (ignored by git, rename `CMakeUserPresets.json.sample` ): + +```json +{ + "version": 3, + "configurePresets": [ + { + "name": "my-arm-bin", + "inherits": "windows-stm32l4", + "cacheVariables": { + "ARM_GCC_BIN": "C:/Tools/arm-none-eabi-14.2/bin" + } + } + ], + "buildPresets": [ + { + "name": "my-arm-bin", + "configurePreset": "my-arm-bin" + } + ] +} +``` ## Integrating wolfBoot in an existing project @@ -303,6 +412,83 @@ $ cmake -DWOLFBOOT_TARGET=stm32u5 -DBUILD_TEST_APPS=yes -DWOLFBOOT_PARTITION_BOO $ cmake -DWOLFBOOT_TARGET=stm32l0 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x8000 -DWOLFBOOT_SECTOR_SIZE=0x1000 -DWOLFBOOT_PARTITION_SIZE=0x10000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x18000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x28000 -DNVM_FLASH_WRITEONCE=yes .. ``` +## CMake Logic Flow + + +```mermaid +flowchart TD + %% wolfBoot CMake Build Logic Flow (GitHub-safe) + + %% === Local Dev === + A1["Start in VS 2022 / VS Code"] --> A2["Select CMake preset: windows-stm32l4 or linux-stm32l4"] + A2 --> A3{"Target preset?"} + A3 --> A4["Ensure toolchains on PATH: ARM_GCC_BIN, Ninja"] + A4 --> A5["Run: cmake --preset <name>"] + A5 --> A6["Optional: cmake --build --preset <name>"] + + %% === Configure === + A5 --> C1["Load CMakePresets.json"] + C1 --> C2["Resolve env vars: PATH, ARM_GCC_BIN, VISUALGDB"] + C2 --> C3["Apply cache vars: WOLFBOOT_TARGET, BOARD, addresses"] + C3 --> C4["Load toolchain file: toolchain_arm-none-eabi.cmake"] + C4 --> C5["Generate build system: Ninja"] + + %% === Preset-specific branches === + C5 --> B0(("Begin preset specifics")) + subgraph PS["Preset specifics"] + direction TB + + %% Windows column + subgraph BWIN["Windows: windows-stm32l4"] + direction TB + BW1["Generator: Ninja (VS 2022 or standalone)"] + BW2["Quote paths with spaces (e.g., Program Files)"] + BW3["Set ARM_GCC_BIN to Windows install path"] + BW4["Use VisualGDB include/BSP paths"] + BW5["Artifacts: .bin, .hex; optional .dfu"] + BW6["Flash: ST-Link CLI or STM32CubeProgrammer"] + BW1 --> BW2 --> BW3 --> BW4 --> BW5 --> BW6 + end + + %% Linux column + subgraph BLNX["Linux: linux-stm32l4"] + direction TB + BL1["Generator: Ninja (system package)"] + BL2["ARM_GCC_BIN in /opt or /usr/bin"] + BL3["dfu-util or stlink from package manager"] + BL4["CI-friendly paths: avoid spaces"] + BL5["Artifacts: .bin, .hex, .dfu"] + BL6["Flash: st-flash or dfu-util"] + BL1 --> BL2 --> BL3 --> BL4 --> BL5 --> BL6 + end + end + + B0 --> BW1 + B0 --> BL1 + BW6 --> BZ(("Merge")) + BL6 --> BZ + + %% === Build, Sign, Package === + BZ --> D1["Build host tools: sign, keytools"] + D1 --> D2["Compile wolfBoot core and HAL"] + D2 --> D3["Link bootloader and test apps"] + D3 --> D4["Create image header"] + D4 --> D5["Sign firmware image: ECC256, SHA256"] + D5 --> D6["Package artifacts: bin, hex, dfu"] + + %% === Deploy & CI === + D6 --> E1["Option A: Flash to device (stlink, dfu-util)"] + E1 --> E2["Run smoke tests and UART debug"] + E2 --> E3["Option B: Upload artifacts in GitHub Actions"] + E3 --> E4["CI: set up toolchains and CMake on runners"] + E4 --> E5["CI: matrix build per target preset"] + E5 --> E6["CI: archive results and report status"] + + %% === Errors (dotted refs) === + A5 -.-> X1["Preset not found or Ninja missing"] + C2 -.-> X2["Toolchain not found: fix ARM_GCC_BIN/PATH, verify VisualGDB"] + C3 -.-> X3["Address/partition mismatch: verify BOARD, flash offsets, IMAGE_HEADER_SIZE"] +``` ## Troubleshooting @@ -344,6 +530,13 @@ The error `Key algorithm mismatch. Remove old keys via 'make keysclean'` indicat Use `make keysclean` to delete keys and regenerate. +3. Cannot open compiler generated file ... Permission denied + +```text +sp_c32.c : fatal error C1083: Cannot open compiler generated file: '... sp_c32.obj': Permission denied +``` + + ## Release Notes ### v1.0 (2018-12-04) @@ -737,7 +930,7 @@ Use `make keysclean` to delete keys and regenerate. * RP2350 (Raspberry Pi Pico 2, ARM Cortex-M33 with TrustZone) * NXP MCXA153 * NXP MCXW716 - * STM32F1 series (STM32F103 "Blue Pill" board) + * STM32F1 series (STM32F103 "Blue Pill"board) * Improvements to supported targets * Xilinx UltraScale+ (ZynqMP) * Added hardware-accelerated SHA3 hashing via the CSU engine diff --git a/cmake/config_defaults.cmake b/cmake/config_defaults.cmake new file mode 100644 index 0000000000..d4af3ec2a7 --- /dev/null +++ b/cmake/config_defaults.cmake @@ -0,0 +1,92 @@ +# wolfboot/cmake/config_defaults.cmake +# +# Copyright (C) 2022 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 +# + +# This is NOT a place for device-specific project settings. For that, see CMakePresets.json + +set(FOUND_STM32L4_LIB false) +include(cmake/current_user.cmake) + +get_current_user(CURRENT_USER) +message(STATUS "Current user detected: ${CURRENT_USER}") + +set(LIB_STM32L4_WINDOWS "c:/Users/${CURRENT_USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx") +set(LIB_STM32L4_WSL "/mnt/c/Users/${CURRENT_USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx") + +if(IS_DIRECTORY "${LIB_STM32L4_WINDOWS}") + set(FOUND_STM32L4_LIB true) + message(STATUS "LIB_STM32L4_WINDOWS found: ${LIB_STM32L4_WINDOWS}") +endif() + +if(IS_DIRECTORY "${LIB_STM32L4_WSL}") + set(FOUND_STM32L4_LIB true) + message(STATUS "LIB_STM32L4_WSL found: ${LIB_STM32L4_WSL}") +endif() + +# set(ARM_GCC_BIN "") + +if(NOT FOUND_STM32L4_LIB) + include(FetchContent) + # TIP: Always pin a real tag/commit; avoid main/master. + + # Make behavior explicit & chatty while debugging + set(FETCHCONTENT_QUIET OFF) + set(FETCHCONTENT_BASE_DIR "${CMAKE_BINARY_DIR}/_deps") + + # HAL driver + message(STATUS "Fetching https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git") + FetchContent_Declare(st_hal + GIT_REPOSITORY https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git + # Pick a tag you want to lock to: + GIT_TAG v1.13.5 + GIT_SHALLOW TRUE + GIT_PROGRESS FALSE + ) + + # CMSIS device headers for L4 + message(STATUS "Fetching https://github.com/STMicroelectronics/cmsis_device_l4.git") + FetchContent_Declare(cmsis_dev + GIT_REPOSITORY https://github.com/STMicroelectronics/cmsis_device_l4.git + GIT_TAG v1.7.4 + GIT_SHALLOW TRUE + GIT_PROGRESS FALSE + ) + + # CMSIS Core headers + message(STATUS "Fetching https://github.com/ARM-software/CMSIS_5.git") + FetchContent_Declare(cmsis_core + GIT_REPOSITORY https://github.com/ARM-software/CMSIS_5.git + GIT_TAG 5.9.0 + GIT_SHALLOW TRUE + GIT_PROGRESS FALSE + ) + + FetchContent_MakeAvailable(st_hal cmsis_dev cmsis_core) + + # Map to the include structures of the fetched repos + set(HAL_DRV "${st_hal_SOURCE_DIR}") # Inc/, Src/ + set(HAL_CMSIS_DEV "${cmsis_dev_SOURCE_DIR}/Include") # device + set(HAL_CMSIS_CORE "${cmsis_core_SOURCE_DIR}/CMSIS/Core/Include") # core +endif() + +message(STATUS "config.defaults:") +message(STATUS "-- HAL_DRV: ${HAL_DRV}") +message(STATUS "-- HAL_CMSIS_DEV: ${HAL_CMSIS_DEV}") +message(STATUS "-- HAL_CMSIS_CORE:${HAL_CMSIS_CORE}") diff --git a/cmake/current_user.cmake b/cmake/current_user.cmake new file mode 100644 index 0000000000..e78ecf48b9 --- /dev/null +++ b/cmake/current_user.cmake @@ -0,0 +1,94 @@ +# wolfboot/cmake/current_user.cmake +# +# Copyright (C) 2022 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 +# +# get_current_user() +# Sets to the best guess of the current user across Windows, Linux, macOS, and WSL. + +# Example usage +# get_current_user(CURRENT_USER) +# message(STATUS "Current user detected: ${CURRENT_USER}") + +function(get_current_user OUT_VAR) + set(_user "") + + # Fast path from environment + foreach(var USER USERNAME LOGNAME) + if(DEFINED ENV{${var}} AND NOT "$ENV{${var}}" STREQUAL "") + set(_user "$ENV{${var}}") + break() + endif() + endforeach() + + # Windows specific fallbacks (native Win or WSL) + if(_user STREQUAL "") + if(WIN32 OR DEFINED ENV{WSL_DISTRO_NAME}) + # Try PowerShell first + execute_process( + COMMAND powershell -NoProfile -Command "$env:USERNAME" + OUTPUT_VARIABLE _user + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + if(_user STREQUAL "") + # Fallback to cmd.exe + execute_process( + COMMAND cmd.exe /c echo %USERNAME% + OUTPUT_VARIABLE _user + ERROR_QUIET + ) + string(REPLACE "\r" "" _user "${_user}") + string(STRIP "${_user}" _user) + endif() + endif() + endif() + + # POSIX fallbacks + if(_user STREQUAL "") + execute_process( + COMMAND id -un + OUTPUT_VARIABLE _user + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + endif() + if(_user STREQUAL "") + execute_process( + COMMAND whoami + OUTPUT_VARIABLE _user + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + endif() + + # Last resort: CI hints or placeholder + if(_user STREQUAL "") + foreach(var GITHUB_ACTOR BUILD_USER USERNAME USER LOGNAME) + if(DEFINED ENV{${var}} AND NOT "$ENV{${var}}" STREQUAL "") + set(_user "$ENV{${var}}") + break() + endif() + endforeach() + endif() + if(_user STREQUAL "") + set(_user "unknown") + endif() + + set(${OUT_VAR} "${_user}" PARENT_SCOPE) +endfunction() diff --git a/cmake/functions.cmake b/cmake/functions.cmake index 6c2e83f4d2..330b702873 100644 --- a/cmake/functions.cmake +++ b/cmake/functions.cmake @@ -55,3 +55,10 @@ function(add_option NAME HELP_STRING DEFAULT VALUES) endif() endfunction() +function(print_env VAR) + if(DEFINED ENV{${VAR}} AND NOT "$ENV{${VAR}}" STREQUAL "") + message(STATUS "${VAR} = $ENV{${VAR}}") + else() + message(STATUS "${VAR} = (not set)") + endif() +endfunction() diff --git a/cmake/load_dot_config.cmake b/cmake/load_dot_config.cmake index 76b7b92dd5..e90192868d 100644 --- a/cmake/load_dot_config.cmake +++ b/cmake/load_dot_config.cmake @@ -1,120 +1,138 @@ -# Usage: -# include(cmake/load_dot_config.cmake) -# load_dot_config("${CMAKE_SOURCE_DIR}/.config") # set normal CMake vars -# # or cache them so GUIs (e.g. Visual Studio) can see/edit them: -# load_dot_config("${CMAKE_SOURCE_DIR}/.config" CACHE_VARS) - -function(load_dot_config CONFIG_PATH) - set(_USE_CACHE OFF) - foreach(_arg IN LISTS ARGN) - if(_arg STREQUAL "CACHE_VARS") - set(_USE_CACHE ON) - endif() - endforeach() - - message(STATUS "Reading config file: ${CONFIG_PATH}") - if(NOT EXISTS "${CONFIG_PATH}") - message(FATAL_ERROR "load_dot_config: File not found: ${CONFIG_PATH}") - endif() - - # Read the entire file, normalize newlines to \n, then split into a CMake list. - file(READ "${CONFIG_PATH}" _cfg_raw) - # Normalize CRLF and CR to LF - string(REPLACE "\r\n" "\n" _cfg_raw "${_cfg_raw}") - string(REPLACE "\r" "\n" _cfg_raw "${_cfg_raw}") - # Split into a list where each element is one line - string(REPLACE "\n" ";" _cfg_lines "${_cfg_raw}") - - message(STATUS "-- Parsing lines from config file...") - foreach(_line IN LISTS _cfg_lines) - # Strip comments and whitespace - string(REGEX REPLACE "\\s*#.*$" "" _line "${_line}") - string(STRIP "${_line}" _line) - if(_line STREQUAL "") - message(STATUS "-- Skipping blank line") - continue() - endif() - message(STATUS "-- Found line: ${_line}") - - # KEY[?]=VALUE - # CMAKE_MATCH_1 = KEY, CMAKE_MATCH_2 = "?" or "", CMAKE_MATCH_3 = VALUE - # Visual guide (ASCII only): - # Group 1: Key name (...........1..........) - # Optional Space [ \t]* - # Group 2: Operand ( 2 ) - # Literal equals = - # Optional Space [ \t] - # Group 3: Value ( 3) - if(NOT _line MATCHES "^([A-Za-z_][A-Za-z0-9_]*)[ \t]*([?]?)=[ \t]*(.*)$") - message(WARNING "load_dot_config: Skipping unrecognized line: ${_line}") - continue() - endif() - set(_key "${CMAKE_MATCH_1}") # Setting name - set(_op "${CMAKE_MATCH_2}") # operand "?" or "" - set(_val "${CMAKE_MATCH_3}") # the value to - message(STATUS "-- Parsed key: ${_key}") - message(STATUS "-- Parsed op: ${_op}") - message(STATUS "-- Parsed val: ${_val}") - - # Trim value spaces - string(STRIP "${_val}" _val) - - # Remove value surrounding double quotes if present - if(_val MATCHES "^\"(.*)\"$") - set(_val "${CMAKE_MATCH_1}") - endif() - - # Expand Make-style $(VAR) to CMake env form $ENV{VAR} - # We keep $ENV{VAR} literal in the set() call so it expands now. - # Do multiple replacements if many occurrences exist. - while(_val MATCHES "\\$\\(([A-Za-z_][A-Za-z0-9_]*)\\)") - string(REGEX REPLACE "\\$\\(([A-Za-z_][A-Za-z0-9_]*)\\)" "\$ENV{\\1}" _val "${_val}") - endwhile() - - # After replacing with $ENV{...}, expand it to its actual value now. - # The "configure" trick expands env refs without touching other text. - set(_expanded "${_val}") - string(CONFIGURE "${_expanded}" _expanded @ONLY) - - # Detect prior definition - set(_already_defined FALSE) - if(DEFINED ${_key}) - set(_already_defined TRUE) - message(STATUS "-- Already defined: ${_key}=${_val}") - else() - # Check cache - get_property(_cache_type CACHE "${_key}" PROPERTY TYPE SET) - if(_cache_type) - set(_already_defined TRUE) - message(STATUS "-- Already defined (cache) ${_key}=${_val}") - endif() - endif() - - # Respect ?= (only set if not already defined) - set(_should_set TRUE) - if(_op STREQUAL "?" AND _already_defined) - set(_should_set FALSE) - endif() - - if(_should_set) - if(_USE_CACHE) - # Use STRING so values like "0x1000" stay as text; FORCE to mirror Make's "=" - # For "?=", do not FORCE to preserve user edits from cache/GUI. - if(_op STREQUAL "?") - message(STATUS "-- Cache Conditional Assignment: ${_key}=${_expanded} from ${CONFIG_PATH}") - set(${_key} "${_expanded}" CACHE STRING "Imported from ${CONFIG_PATH}") - else() - message(STATUS "-- Cache Assignment: ${_key}=${_expanded} from ${CONFIG_PATH}") - set(${_key} "${_expanded}" CACHE STRING "Imported from ${CONFIG_PATH}" FORCE) - endif() - else() - # Set variable in parent scope so caller can see value. - message(STATUS "-- Assignment: ${_key}=${_val}") - set(${_key} "${_expanded}" PARENT_SCOPE) - endif() - else() - message(STATUS "-- Skipping assignment: ${_key}=${_val}") - endif() - endforeach() - message(STATUS "-- Done processing ${CONFIG_PATH}") -endfunction() +# Copyright (C) 2022 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 +# +# Usage: +# include(cmake/load_dot_config.cmake) +# load_dot_config("${CMAKE_SOURCE_DIR}/.config") # set normal CMake vars +# # or cache them so GUIs (e.g. Visual Studio) can see/edit them: +# load_dot_config("${CMAKE_SOURCE_DIR}/.config" CACHE_VARS) + +function(load_dot_config CONFIG_PATH) + set(_USE_CACHE OFF) + foreach(_arg IN LISTS ARGN) + if(_arg STREQUAL "CACHE_VARS") + set(_USE_CACHE ON) + endif() + endforeach() + + message(STATUS "Reading config file: ${CONFIG_PATH}") + if(NOT EXISTS "${CONFIG_PATH}") + message(FATAL_ERROR "load_dot_config: File not found: ${CONFIG_PATH}") + endif() + + # Read the entire file, normalize newlines to \n, then split into a CMake list. + file(READ "${CONFIG_PATH}" _cfg_raw) + # Normalize CRLF and CR to LF + string(REPLACE "\r\n" "\n" _cfg_raw "${_cfg_raw}") + string(REPLACE "\r" "\n" _cfg_raw "${_cfg_raw}") + # Split into a list where each element is one line + string(REPLACE "\n" ";" _cfg_lines "${_cfg_raw}") + + message(STATUS "-- Parsing lines from config file...") + foreach(_line IN LISTS _cfg_lines) + # Strip comments and whitespace + string(REGEX REPLACE "\\s*#.*$" "" _line "${_line}") + string(STRIP "${_line}" _line) + if(_line STREQUAL "") + message(STATUS "-- Skipping blank line") + continue() + endif() + message(STATUS "-- Found line: ${_line}") + + # KEY[?]=VALUE + # CMAKE_MATCH_1 = KEY, CMAKE_MATCH_2 = "?" or "", CMAKE_MATCH_3 = VALUE + # Visual guide (ASCII only): + # Group 1: Key name (...........1..........) + # Optional Space [ \t]* + # Group 2: Operand ( 2 ) + # Literal equals = + # Optional Space [ \t] + # Group 3: Value ( 3) + if(NOT _line MATCHES "^([A-Za-z_][A-Za-z0-9_]*)[ \t]*([?]?)=[ \t]*(.*)$") + message(WARNING "load_dot_config: Skipping unrecognized line: ${_line}") + continue() + endif() + set(_key "${CMAKE_MATCH_1}") # Setting name + set(_op "${CMAKE_MATCH_2}") # operand "?" or "" + set(_val "${CMAKE_MATCH_3}") # the value to + message(STATUS "-- Parsed key: ${_key}") + message(STATUS "-- Parsed op: ${_op}") + message(STATUS "-- Parsed val: ${_val}") + + # Trim value spaces + string(STRIP "${_val}" _val) + + # Remove value surrounding double quotes if present + if(_val MATCHES "^\"(.*)\"$") + set(_val "${CMAKE_MATCH_1}") + endif() + + # Expand Make-style $(VAR) to CMake env form $ENV{VAR} + # We keep $ENV{VAR} literal in the set() call so it expands now. + # Do multiple replacements if many occurrences exist. + while(_val MATCHES "\\$\\(([A-Za-z_][A-Za-z0-9_]*)\\)") + string(REGEX REPLACE "\\$\\(([A-Za-z_][A-Za-z0-9_]*)\\)" "\$ENV{\\1}" _val "${_val}") + endwhile() + + # After replacing with $ENV{...}, expand it to its actual value now. + # The "configure" trick expands env refs without touching other text. + set(_expanded "${_val}") + string(CONFIGURE "${_expanded}" _expanded @ONLY) + + # Detect prior definition + set(_already_defined FALSE) + if(DEFINED ${_key}) + set(_already_defined TRUE) + message(STATUS "-- Already defined: ${_key}=${_val}") + else() + # Check cache + get_property(_cache_type CACHE "${_key}" PROPERTY TYPE SET) + if(_cache_type) + set(_already_defined TRUE) + message(STATUS "-- Already defined (cache) ${_key}=${_val}") + endif() + endif() + + # Respect ?= (only set if not already defined) + set(_should_set TRUE) + if(_op STREQUAL "?" AND _already_defined) + set(_should_set FALSE) + endif() + + if(_should_set) + if(_USE_CACHE) + # Use STRING so values like "0x1000" stay as text; FORCE to mirror Make's "=" + # For "?=", do not FORCE to preserve user edits from cache/GUI. + if(_op STREQUAL "?") + message(STATUS "-- Cache Conditional Assignment: ${_key}=${_expanded} from ${CONFIG_PATH}") + set(${_key} "${_expanded}" CACHE STRING "Imported from ${CONFIG_PATH}") + else() + message(STATUS "-- Cache Assignment: ${_key}=${_expanded} from ${CONFIG_PATH}") + set(${_key} "${_expanded}" CACHE STRING "Imported from ${CONFIG_PATH}" FORCE) + endif() + else() + # Set variable in parent scope so caller can see value. + message(STATUS "-- Assignment: ${_key}=${_val}") + set(${_key} "${_expanded}" PARENT_SCOPE) + endif() + else() + message(STATUS "-- Skipping assignment: ${_key}=${_val}") + endif() + endforeach() + message(STATUS "-- Done processing ${CONFIG_PATH}") +endfunction() diff --git a/cmake/toolchain_arm-none-eabi.cmake b/cmake/toolchain_arm-none-eabi.cmake index 4d4aa0963b..c4b96e2f31 100644 --- a/cmake/toolchain_arm-none-eabi.cmake +++ b/cmake/toolchain_arm-none-eabi.cmake @@ -1,4 +1,4 @@ -# toolchain_arm-none-eabi.cmake +# wolfboot/cmake/toolchain_arm-none-eabi.cmake # # Copyright (C) 2022 wolfSSL Inc. # @@ -21,9 +21,16 @@ set(CMAKE_SYSTEM_NAME Generic) +# Keep try-compile from attempting to run target binaries +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES ARM_GCC_BIN WOLFBOOT_TARGET) + # There needs to be a default platform or the `project()` command will fail. if(NOT DEFINED WOLFBOOT_TARGET) - set(WOLFBOOT_TARGET "stm32h7") + message(STATUS "Select a target, e.g. 'cmake --preset linux-stm32l4'") + message(FATAL_ERROR "WOLFBOOT_TARGET not set") + # set(WOLFBOOT_TARGET "stm32h7") endif() # Cortex-M CPU @@ -36,37 +43,86 @@ elseif(WOLFBOOT_TARGET STREQUAL "stm32u5") elseif(WOLFBOOT_TARGET STREQUAL "stm32h7") set(CMAKE_SYSTEM_PROCESSOR cortex-m7) set(MCPU_FLAGS "-mcpu=cortex-m7 -mthumb -mlittle-endian -mthumb-interwork") +elseif(WOLFBOOT_TARGET STREQUAL "stm32l4") + set(CMAKE_SYSTEM_PROCESSOR cortex-m4) + # L4 has FPU (single-precision). Let the toolchain pick the right libs. + set(MCPU_FLAGS "-mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard") else() set(CMAKE_SYSTEM_PROCESSOR cortex-m3) set(MCPU_FLAGS "-mcpu=cortex-m3 -mthumb -mlittle-endian -mthumb-interwork ") endif() -# ----------------------------------------------------------------------------- -# Set toolchain paths -# ----------------------------------------------------------------------------- -set(TOOLCHAIN arm-none-eabi) -set(CMAKE_CXX_STANDARD 20) +# ----- Select compilers (works on WSL/Linux and Windows) ----- +# Optional: allow an explicit bin dir +set(ARM_GCC_BIN "" CACHE PATH "Path to Arm GNU Toolchai 'bin' directory") + +if(WIN32) + if(ARM_GCC_BIN) + file(TO_CMAKE_PATH "${ARM_GCC_BIN}" _BIN) + set(CMAKE_C_COMPILER "${_BIN}/arm-none-eabi-gcc.exe" CACHE FILEPATH "" FORCE) + set(CMAKE_CXX_COMPILER "${_BIN}/arm-none-eabi-g++.exe" CACHE FILEPATH "" FORCE) + set(CMAKE_ASM_COMPILER "${_BIN}/arm-none-eabi-gcc.exe" CACHE FILEPATH "" FORCE) + else() + # Try PATH + find_program(CMAKE_C_COMPILER NAMES arm-none-eabi-gcc.exe) + find_program(CMAKE_CXX_COMPILER NAMES arm-none-eabi-g++.exe) + set(CMAKE_ASM_COMPILER "${CMAKE_C_COMPILER}" CACHE FILEPATH "" FORCE) + endif() +else() + if(ARM_GCC_BIN) + file(TO_CMAKE_PATH "${ARM_GCC_BIN}" _BIN) + set(CMAKE_C_COMPILER "${_BIN}/arm-none-eabi-gcc" CACHE FILEPATH "" FORCE) + set(CMAKE_CXX_COMPILER "${_BIN}/arm-none-eabi-g++" CACHE FILEPATH "" FORCE) + set(CMAKE_ASM_COMPILER "${_BIN}/arm-none-eabi-gcc" CACHE FILEPATH "" FORCE) + else() + find_program(CMAKE_C_COMPILER NAMES arm-none-eabi-gcc) + find_program(CMAKE_CXX_COMPILER NAMES arm-none-eabi-g++) + set(CMAKE_ASM_COMPILER "${CMAKE_C_COMPILER}" CACHE FILEPATH "" FORCE) + endif() +endif() +# Use the compiler's own include dir (Homebrew GCC may have no sysroot) execute_process( - COMMAND which ${TOOLCHAIN}-gcc - OUTPUT_VARIABLE TOOLCHAIN_GCC_PATH - OUTPUT_STRIP_TRAILING_WHITESPACE) + COMMAND ${CMAKE_C_COMPILER} -print-file-name=include + OUTPUT_VARIABLE GCC_INCLUDE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE +) +if(GCC_INCLUDE_DIR AND EXISTS "${GCC_INCLUDE_DIR}") + include_directories(SYSTEM "${GCC_INCLUDE_DIR}") +endif() # get toolchain version. CMAKE_C_COMPILER_VERSION cannot be used here since its not defined until # `project()` is run in the top-level cmake. The toolchain has to be setup before the `project` call execute_process( - COMMAND ${TOOLCHAIN}-gcc -dumpversion - OUTPUT_VARIABLE TOOLCHAIN_GCC_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE) + COMMAND ${CMAKE_C_COMPILER} -print-sysroot + OUTPUT_VARIABLE GCC_SYSROOT + OUTPUT_STRIP_TRAILING_WHITESPACE +) +if(GCC_SYSROOT) + set(CMAKE_SYSROOT "${GCC_SYSROOT}") +endif() -get_filename_component(TOOLCHAIN_BIN_DIR ${TOOLCHAIN_GCC_PATH} DIRECTORY) -get_filename_component(TOOLCHAIN_ROOT_DIR "${TOOLCHAIN_BIN_DIR}/../" DIRECTORY ABSOLUTE) -set(CMAKE_SYSROOT ${TOOLCHAIN_ROOT_DIR}/${TOOLCHAIN}) +# Some sanity checks on compiler and target OS +if(NOT CMAKE_C_COMPILER OR NOT CMAKE_CXX_COMPILER) + if("${TARGET_OS}" STREQUAL "") + message(STATUS "Warning: cmake presets should define TARGET_OS = [WINDOWS | LINUX]") + endif() + if(WIN32) + if("${TARGET_OS}" STREQUAL "LINUX") + message(FATAL_ERROR "Linux presets are not supported in Windows. Choose a different preset.") + endif() + else() + if("${TARGET_OS}" STREQUAL "Windows") + message(FATAL_ERROR "Windows presets are only supported on Windows. Choose a different preset.") + endif() + endif() + message(FATAL_ERROR "arm-none-eabi toolchain not found. Set ARM_GCC_BIN or add to PATH.") +endif() -# ----------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- # Set compiler/linker flags -#----------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- set(OBJECT_GEN_FLAGS "${MCPU_FLAGS} -Wall -Wextra -Wno-main -ffreestanding -Wno-unused -ffunction-sections -fdata-sections" ) @@ -76,19 +132,27 @@ set(CMAKE_C_FLAGS "${OBJECT_GEN_FLAGS}" CACHE INTERNAL "C Compiler options") set(CMAKE_ASM_FLAGS "${OBJECT_GEN_FLAGS}" CACHE INTERNAL "ASM Compiler options") set(CMAKE_EXE_LINKER_FLAGS "${MCPU_FLAGS} ${LD_FLAGS} -Wl,--gc-sections --specs=nano.specs --specs=nosys.specs" CACHE INTERNAL "Linker options") -#--------------------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- # Set compilers and toolchain utilities -#--------------------------------------------------------------------------------------- -set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "C Compiler") -set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-g++ CACHE INTERNAL "C++ Compiler") -set(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "ASM Compiler") -set(TOOLCHAIN_LD ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-ld CACHE INTERNAL "Toolchain linker") -set(TOOLCHAIN_AR ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc-ar CACHE INTERNAL "Toolchain archive tool") -set(TOOLCHAIN_OBJCOPY ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-objcopy CACHE INTERNAL "Toolchain objcopy tool") -set(TOOLCHAIN_OBJDUMP ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-objdump CACHE INTERNAL "Toolchain objdump tool") -set(TOOLCHAIN_SIZE ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-size CACHE INTERNAL "Toolchain object size tool") - -set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_PREFIX}/${${TOOLCHAIN}} ${CMAKE_PREFIX_PATH}) +#--------------------------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- +# Derive toolchain helper paths from the chosen compiler +#--------------------------------------------------------------------------------------------- +get_filename_component(_BIN_DIR "${CMAKE_C_COMPILER}" DIRECTORY) +if(WIN32) + set(_EXE ".exe") +else() + set(_EXE "") +endif() + + +set(TOOLCHAIN_AR "${_BIN_DIR}/arm-none-eabi-ar${_EXE}" CACHE INTERNAL "") +set(TOOLCHAIN_OBJCOPY "${_BIN_DIR}/arm-none-eabi-objcopy${_EXE}" CACHE INTERNAL "") +set(TOOLCHAIN_OBJDUMP "${_BIN_DIR}/arm-none-eabi-objdump${_EXE}" CACHE INTERNAL "") +set(TOOLCHAIN_SIZE "${_BIN_DIR}/arm-none-eabi-size${_EXE}" CACHE INTERNAL "") + + +# set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_PREFIX}/${${TOOLCHAIN}} ${CMAKE_PREFIX_PATH}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) @@ -98,7 +162,7 @@ message(STATUS "Cross-compiling using GNU arm-none-eabi toolchain") # Options for DEBUG build # -Og Enables optimizations that do not interfere with debugging. -# -g Produce debugging information in the operating system’s native format. +# -g Produce debugging information in the operating system's native format. set(CMAKE_C_FLAGS_DEBUG "-Og -g" CACHE INTERNAL "C Compiler options for debug build type") set(CMAKE_CXX_FLAGS_DEBUG "-Og -g" CACHE INTERNAL "C++ Compiler options for debug build type") set(CMAKE_ASM_FLAGS_DEBUG "-g" CACHE INTERNAL "ASM Compiler options for debug build type") diff --git a/hal/stm32l4xx_hal_conf.h b/hal/stm32l4xx_hal_conf.h index 0dd3f7690f..5e345a63f9 100644 --- a/hal/stm32l4xx_hal_conf.h +++ b/hal/stm32l4xx_hal_conf.h @@ -22,12 +22,30 @@ #ifndef __STM32L4xx_HAL_CONF_H #define __STM32L4xx_HAL_CONF_H -#define HAL_MODULE_ENABLED +#define HAL_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED -#include "stm32l4xx_hal_flash.h" -#include "stm32l4xx_hal_rcc.h" + /* Many ST examples define this in stm32l4xx_hal_conf.h */ +#ifndef TICK_INT_PRIORITY + #define TICK_INT_PRIORITY 0U +#endif + +#include "stm32l4xx_hal_def.h" + +/* Pull in headers for the enabled modules */ +#if defined(HAL_CORTEX_MODULE_ENABLED) + #include "stm32l4xx_hal_cortex.h" +#endif +#if defined(HAL_FLASH_MODULE_ENABLED) + #include "stm32l4xx_hal_flash.h" + #include "stm32l4xx_hal_flash_ex.h" +#endif +#if defined(HAL_RCC_MODULE_ENABLED) + #include "stm32l4xx_hal_rcc.h" +#endif + #define assert_param(expr) ((void)0U) #endif /* __STM32L4xx_HAL_CONF_H */ diff --git a/my_test.bat b/my_test.bat new file mode 100644 index 0000000000..d6349f727c --- /dev/null +++ b/my_test.bat @@ -0,0 +1,8 @@ +rmdir /s /q build-windows-stm32l4 + +cmake --preset windows-stm32l4 + + +:: cmake --build --preset windows-stm32l4 --parallel 4 -v + +cmake --build --preset windows-stm32l4 diff --git a/my_test.sh b/my_test.sh new file mode 100644 index 0000000000..3658da11d7 --- /dev/null +++ b/my_test.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +rm -rf ./build-windows-stm32l4 +rm -rf ./build-linux-stm32l4 + +cmake --preset linux-stm32l4 +cmake --build --preset linux-stm32l4 diff --git a/wolfBoot.code-workspace b/wolfBoot.code-workspace new file mode 100644 index 0000000000..51601f162e --- /dev/null +++ b/wolfBoot.code-workspace @@ -0,0 +1,83 @@ +{ + "folders": [ + { + "name": "wolfBoot", + "path": "./" + } + ], + "settings": { + // Drive CMake Tools from the repo root folder: + "cmake.useCMakePresets": "always", + "cmake.sourceDirectory": "${workspaceFolder:wolfBoot}", + "cmake.buildDirectory": "${workspaceFolder:wolfBoot}/build-${buildPresetName}", + + // Nice-to-haves: + "cmake.generator": "Ninja", + "cmake.configureOnOpen": true, + "cmake.loggingLevel": "info", + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", + "files.encoding": "utf8", + "files.eol": "\n" + }, + "extensions": { + "recommendations": [ + "ms-vscode.cmake-tools", + "ms-vscode.cpptools", + "marus25.cortex-debug" + ] + }, + "launch": { + "version": "0.2.0", + "configurations": [ + { + "name": "STM32L4 - OpenOCD", + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "cwd": "${workspaceFolder:wolfBoot}", + "executable": "${workspaceFolder:wolfBoot}/build-linux-stm32l4/wolfboot.elf", + "device": "STM32L475VG", + "configFiles": [ + "interface/stlink-dap.cfg", + "target/stm32l4x.cfg" + ], + "runToMain": true, + "svdFile": "${workspaceFolder:wolfBoot}/hal/stm32l4/STM32L4x.svd", + "preLaunchTask": "CMake: Build (linux-stm32l4)" + } + ] + }, + "tasks": { + "version": "2.0.0", + "tasks": [ + { + "label": "CMake: Configure (linux-stm32l4)", + "command": "cmake", + "args": ["--preset", "linux-stm32l4"], + "options": { "cwd": "${workspaceFolder:wolfBoot}" }, + "problemMatcher": [] + }, + { + "label": "CMake: Build (linux-stm32l4)", + "command": "cmake", + "args": ["--build", "--preset", "linux-stm32l4"], + "options": { "cwd": "${workspaceFolder:wolfBoot}" }, + "group": "build", + "problemMatcher": "$gcc" + }, + { + "label": "OpenOCD: Flash wolfBoot (linux-stm32l4)", + "type": "shell", + "command": "openocd", + "args": [ + "-f", "interface/stlink-dap.cfg", + "-f", "target/stm32l4x.cfg", + "-c", + "program ${workspaceFolder:wolfBoot}/build-linux-stm32l4/wolfboot.elf verify reset exit" + ], + "options": { "cwd": "${workspaceFolder:wolfBoot}" }, + "problemMatcher": [] + } + ] + } +} diff --git a/wolfbuild.sh b/wolfbuild.sh index 9ae3f5be40..01adb8b047 100644 --- a/wolfbuild.sh +++ b/wolfbuild.sh @@ -1,5 +1,10 @@ #!/bin/bash +# Reminder for WSL: +# git update-index --chmod=+x wolfbuild.sh +# git commit -m "Make wolfbuild.sh executable" +# git push + # Specify the executable shell checker you want to use: MY_SHELLCHECK="shellcheck" From a1ca06c6dd74f3580b19b6a086cb88b9b51218bb Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Sun, 12 Oct 2025 18:23:15 -0700 Subject: [PATCH 5/9] flag as executable --- wolfbuild.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 wolfbuild.sh diff --git a/wolfbuild.sh b/wolfbuild.sh old mode 100644 new mode 100755 From c35f117c2dc023e7a1a5bf13d76472ed70f41346 Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Mon, 13 Oct 2025 20:08:38 -0700 Subject: [PATCH 6/9] update from dev --- .github/workflows/test-build-cmake-mac.yml | 34 +- .../workflows/test-build-cmake-windows.yml | 22 +- CMakeLists.txt | 46 +- CMakePresets.json | 2 +- cmake/config_defaults.cmake | 73 +--- cmake/cube_ide_config.cmake | 395 ++++++++++++++++++ cmake/functions.cmake | 16 + cmake/stm32_hal_download.cmake | 80 ++++ cmake/toolchain_arm-none-eabi.cmake | 26 +- cmake/vs2022_config.cmake | 98 +++++ my_test.sh | 9 +- 11 files changed, 714 insertions(+), 87 deletions(-) create mode 100644 cmake/cube_ide_config.cmake create mode 100644 cmake/stm32_hal_download.cmake create mode 100644 cmake/vs2022_config.cmake diff --git a/.github/workflows/test-build-cmake-mac.yml b/.github/workflows/test-build-cmake-mac.yml index 92dc26bf0d..78fda599dd 100644 --- a/.github/workflows/test-build-cmake-mac.yml +++ b/.github/workflows/test-build-cmake-mac.yml @@ -23,7 +23,7 @@ jobs: with: submodules: true - - name: Cache Homebrew bottles # downloads (so retries don’t redownload) + - name: Cache Homebrew bottles # downloads (so retries don't redownload) uses: actions/cache@v4 with: path: | @@ -48,16 +48,30 @@ jobs: sleep "$throttle_delay" brew install --force-bottle ninja + # Use cask to include headers such as sleep "$throttle_delay" - brew install --force-bottle arm-none-eabi-gcc + brew install --cask gcc-arm-embedded - - name: Probe GCC sysroot (headers check) + - name: Probe ARM GCC (paths + smoke build) run: | set -euxo pipefail - SYSROOT="$(arm-none-eabi-gcc -print-sysroot)" - echo "GCC sysroot: $SYSROOT" - test -f "$SYSROOT/include/stdlib.h" || { echo "Missing stdlib.h in $SYSROOT/include"; exit 1; } - test -f "$SYSROOT/include/string.h" || { echo "Missing string.h in $SYSROOT/include"; exit 1; } + + which arm-none-eabi-gcc + arm-none-eabi-gcc --version + + echo "=== GCC search dirs ===" + arm-none-eabi-gcc -print-search-dirs + + echo "=== GCC verbose include paths (preprocess only) ===" + # This prints the built-in include search order; harmless with empty stdin. + arm-none-eabi-gcc -x c -E -v - < /dev/null || true + + echo "=== Compile a freestanding object (no stdlib headers needed) ===" + cat > hello.c <<'EOF' + int main(void) { return 0; } + EOF + arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -ffreestanding -nostdlib -c hello.c -o hello.o + ls -l hello.o - name: Configure (STM32L4) run: | @@ -71,7 +85,7 @@ jobs: - name: Presets run: | - rm -rf ./build-mac-stm32l4 + rm -rf ./build-stm32l4 - cmake --preset mac-stm32l4 - cmake --build --preset mac-stm32l4 + cmake --preset stm32l4 + cmake --build --preset stm32l4 diff --git a/.github/workflows/test-build-cmake-windows.yml b/.github/workflows/test-build-cmake-windows.yml index 524393730a..9a7b146690 100644 --- a/.github/workflows/test-build-cmake-windows.yml +++ b/.github/workflows/test-build-cmake-windows.yml @@ -73,16 +73,20 @@ jobs: shell: bash run: | # cmake runs in git bash - echo "disabled" - #BUILD_DIR="build-${{ matrix.target }}" - #cmake -S . -B "$BUILD_DIR" -G Ninja \ - # -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain_arm-none-eabi.cmake \ - # -DWOLFBOOT_CONFIG_MODE=preset \ - # -DWOLFBOOT_TARGET=${{ matrix.target }} \ - # -DBUILD_TEST_APPS=ON \ - # ${{ matrix.extra_cache }} - #echo "Configured: $BUILD_DIR" + BUILD_DIR="build-${{ matrix.target }}" + cmake -S . -B "$BUILD_DIR" -G Ninja \ + -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain_arm-none-eabi.cmake \ + -DWOLFBOOT_CONFIG_MODE=preset \ + -DWOLFBOOT_TARGET=${{ matrix.target }} \ + -DBUILD_TEST_APPS=ON \ + -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x8020000 \ + -DWOLFBOOT_SECTOR_SIZE=0x20000 \ + -DWOLFBOOT_PARTITION_SIZE=0xD0000 \ + -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x80F0000 \ + -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x81C0000 \ + ${{ matrix.extra_cache }} + echo "Configured: $BUILD_DIR" - name: Build shell: bash diff --git a/CMakeLists.txt b/CMakeLists.txt index 069eca4aaa..5241041318 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ cmake_minimum_required(VERSION 3.16) include(cmake/config_defaults.cmake) + # ------------------------------------------------------------------------------ # Initial environment checks # ------------------------------------------------------------------------------ @@ -44,6 +45,7 @@ if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") You must delete them, or cmake will refuse to work.") endif() +# This must appear before project(wolfBoot) if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) if(DEFINED WOLFBOOT_TARGET AND NOT WOLFBOOT_TARGET STREQUAL "x86_64_efi" AND @@ -54,6 +56,7 @@ if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) endif() endif() + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ project(wolfBoot) @@ -61,6 +64,18 @@ project(wolfBoot) # ------------------------------------------------------------------------------ include(cmake/functions.cmake) +# include(cmake/cube_ide_config.cmake) + +# Some OS-specific checks and configs +if(CMAKE_HOST_WIN32) + include(cmake/vs2022_config.cmake) +endif() + +if(WOLFBOOT_TARGET STREQUAL "stm32l4" AND NOT FOUND_STM32L4_LIB) + include(cmake/stm32_hal_download.cmake) +endif() + + # set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES "" CACHE STRING "" FORCE) # ---- Host compiler (for native tools only) ----------------------------------- @@ -900,6 +915,7 @@ target_sources(wolfboothal PRIVATE include/hal.h hal/${WOLFBOOT_TARGET}.c ${WOLF # --- HAL for STM32L4 (only the pieces we need) --- +# TODO move this to preset and/or cmake dir if(WOLFBOOT_TARGET STREQUAL "stm32l4") if(CMAKE_HOST_WIN32 AND IS_DIRECTORY "${LIB_STM32L4_WINDOWS}" ) message(STATUS "Win32 Path found: ${LIB_STM32L4_WINDOWS}") @@ -907,17 +923,29 @@ if(WOLFBOOT_TARGET STREQUAL "stm32l4") elseif(IS_DIRECTORY "${LIB_STM32L4_WSL}") message(STATUS "WSL Path found: ${LIB_STM32L4_WSL}") set(HAL_BASE "${LIB_STM32L4_WSL}") - else() - message(STATUS "STM32L4 Path not found") - set(HAL_BASE "") endif() - if(true) - - set(HAL_DRV "${HAL_BASE}/STM32L4xx_HAL_Driver") - set(HAL_CMSIS_DEV "${HAL_BASE}/CMSIS_HAL/Device/ST/STM32L4xx/Include") - set(HAL_CMSIS_CORE "${HAL_BASE}/CMSIS_HAL/Include") - set(HAL_TEMPLATE_INC "${HAL_BASE}/VendorSamples/L4/Projects/B-L475E-IOT01A/Templates/Inc") + # HAL_BASE "C:/Users/${CURRENT_USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx" + # +#1> [CMake] -- Found directory: C:/Users/gojimmypi/STM32Cube/Repository/STM32Cube_FW_L4_V1.18.0/Drivers/STM32L4xx_HAL_Driver (set HAL_DRV) +#1> [CMake] -- Directory not found: C:/Users/gojimmypi/STM32Cube/Repository/STM32Cube_FW_L4_V1.18.0/CMSIS_HAL/Device/ST/STM32L4xx/Include (set HAL_CMSIS_DEV) +#1> [CMake] -- Directory not found: C:/Users/gojimmypi/STM32Cube/Repository/STM32Cube_FW_L4_V1.18.0/CMSIS_HAL/Include (set HAL_CMSIS_CORE) +#1> [CMake] -- Found directory: C:/Users/gojimmypi/STM32Cube/Repository/STM32Cube_FW_L4_V1.18.0/Projects/B-L475E-IOT01A/Templates/Inc (set HAL_TEMPLATE_INC) +#1> [CMake] -- HAL_DRV=C:/Users/gojimmypi/STM32Cube/Repository/STM32Cube_FW_L4_V1.18.0/Drivers/STM32L4xx_HAL_Driver + if(NOT HAL_BASE STREQUAL "") + if(false) + # VisualGDB + set_and_echo_dir(HAL_DRV "${HAL_BASE}/Drivers/STM32L4xx_HAL_Driver") + set_and_echo_dir(HAL_CMSIS_DEV "${HAL_BASE}/CMSIS_HAL/Device/ST/STM32L4xx/Include") + set_and_echo_dir(HAL_CMSIS_CORE "${HAL_BASE}/CMSIS_HAL/Include") + set_and_echo_dir(HAL_TEMPLATE_INC "${HAL_BASE}/VendorSamples/L4/Projects/B-L475E-IOT01A/Templates/Inc") + else() + # CubeIDE + # set_and_echo_dir(HAL_DRV "${HAL_BASE}/Drivers/STM32L4xx_HAL_Driver") + # set_and_echo_dir(HAL_CMSIS_DEV "${HAL_BASE}/Drivers/CMSIS/Device/ST/STM32L4xx/Include") + # set_and_echo_dir(HAL_CMSIS_CORE "${HAL_BASE}/Drivers/CMSIS/Include") + # set_and_echo_dir(HAL_TEMPLATE_INC "${HAL_BASE}/Projects/B-L475E-IOT01A/Templates/Inc") + endif() endif() message(STATUS "HAL_DRV=${HAL_DRV}") diff --git a/CMakePresets.json b/CMakePresets.json index 0f479800c1..573488a460 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -195,7 +195,7 @@ }, { "name": "stm32l4", - "displayName": "macOS ARM (STM32L4)", + "displayName": "STM32L4", "inherits": [ "base" ], "generator": "Ninja", "binaryDir": "${sourceDir}/build-stm32l4", diff --git a/cmake/config_defaults.cmake b/cmake/config_defaults.cmake index d4af3ec2a7..a14456493b 100644 --- a/cmake/config_defaults.cmake +++ b/cmake/config_defaults.cmake @@ -22,69 +22,40 @@ # This is NOT a place for device-specific project settings. For that, see CMakePresets.json set(FOUND_STM32L4_LIB false) + include(cmake/current_user.cmake) get_current_user(CURRENT_USER) message(STATUS "Current user detected: ${CURRENT_USER}") -set(LIB_STM32L4_WINDOWS "c:/Users/${CURRENT_USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx") -set(LIB_STM32L4_WSL "/mnt/c/Users/${CURRENT_USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx") - -if(IS_DIRECTORY "${LIB_STM32L4_WINDOWS}") - set(FOUND_STM32L4_LIB true) - message(STATUS "LIB_STM32L4_WINDOWS found: ${LIB_STM32L4_WINDOWS}") -endif() - -if(IS_DIRECTORY "${LIB_STM32L4_WSL}") - set(FOUND_STM32L4_LIB true) - message(STATUS "LIB_STM32L4_WSL found: ${LIB_STM32L4_WSL}") -endif() - -# set(ARM_GCC_BIN "") -if(NOT FOUND_STM32L4_LIB) - include(FetchContent) - # TIP: Always pin a real tag/commit; avoid main/master. +# The ST CubeIDE location is searched in cmake/cube_ide_config.cmake +# Want to specify your specific STCubeIDE? Uncomment and set it here: +# set(STM32CUBEIDE_DIR "/your/path") - # Make behavior explicit & chatty while debugging - set(FETCHCONTENT_QUIET OFF) - set(FETCHCONTENT_BASE_DIR "${CMAKE_BINARY_DIR}/_deps") +if(false) + # TODO need to be more generic, in presets? + if(IS_DIRECTORY "C:/Users/${CURRENT_USER}/AppData/Local/VisualGDB") + set(LIB_STM32L4_WINDOWS "C:/Users/${CURRENT_USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx") + endif() - # HAL driver - message(STATUS "Fetching https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git") - FetchContent_Declare(st_hal - GIT_REPOSITORY https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git - # Pick a tag you want to lock to: - GIT_TAG v1.13.5 - GIT_SHALLOW TRUE - GIT_PROGRESS FALSE - ) + if(IS_DIRECTORY "/mnt/c/Users/${CURRENT_USER}/AppData/Local/VisualGDB") + set(LIB_STM32L4_WSL "/mnt/c/Users/${CURRENT_USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx") + endif() - # CMSIS device headers for L4 - message(STATUS "Fetching https://github.com/STMicroelectronics/cmsis_device_l4.git") - FetchContent_Declare(cmsis_dev - GIT_REPOSITORY https://github.com/STMicroelectronics/cmsis_device_l4.git - GIT_TAG v1.7.4 - GIT_SHALLOW TRUE - GIT_PROGRESS FALSE - ) + if(IS_DIRECTORY "${LIB_STM32L4_WINDOWS}") + set(FOUND_STM32L4_LIB true) + message(STATUS "LIB_STM32L4_WINDOWS found: ${LIB_STM32L4_WINDOWS}") + endif() - # CMSIS Core headers - message(STATUS "Fetching https://github.com/ARM-software/CMSIS_5.git") - FetchContent_Declare(cmsis_core - GIT_REPOSITORY https://github.com/ARM-software/CMSIS_5.git - GIT_TAG 5.9.0 - GIT_SHALLOW TRUE - GIT_PROGRESS FALSE - ) + if(IS_DIRECTORY "${LIB_STM32L4_WSL}") + set(FOUND_STM32L4_LIB true) + message(STATUS "LIB_STM32L4_WSL found: ${LIB_STM32L4_WSL}") + endif() +endif() - FetchContent_MakeAvailable(st_hal cmsis_dev cmsis_core) +# set(ARM_GCC_BIN "") - # Map to the include structures of the fetched repos - set(HAL_DRV "${st_hal_SOURCE_DIR}") # Inc/, Src/ - set(HAL_CMSIS_DEV "${cmsis_dev_SOURCE_DIR}/Include") # device - set(HAL_CMSIS_CORE "${cmsis_core_SOURCE_DIR}/CMSIS/Core/Include") # core -endif() message(STATUS "config.defaults:") message(STATUS "-- HAL_DRV: ${HAL_DRV}") diff --git a/cmake/cube_ide_config.cmake b/cmake/cube_ide_config.cmake new file mode 100644 index 0000000000..e263a3fabf --- /dev/null +++ b/cmake/cube_ide_config.cmake @@ -0,0 +1,395 @@ +# wolfboot/cmake/cube_ide_config.cmake +# +# Copyright (C) 2022 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 +# + +# Some logic to find the ST Cube IDE in various directories on various systems +# See also https://www.st.com/resource/en/application_note/an5952-how-to-use-cmake-in-stm32cubeide-stmicroelectronics.pdf + +# Usage: +# set(STM32CUBEIDE_DIR "C:/ST/STM32CubeIDE_1.15.0" CACHE PATH "Hint to STM32CubeIDE root") +# find_package(STM32CubeIDE REQUIRED) +# message(STATUS "STM32CubeIDE: ${STM32CUBEIDE_EXECUTABLE} (root: ${STM32CUBEIDE_ROOT}, ver: ${STM32CUBEIDE_VERSION})") + +include_guard(GLOBAL) +message(STATUS "Begin cube_ide_config.cmake") +unset(STM32CUBEIDE_ROOT CACHE) +unset(STM32CUBEIDE_FOUND CACHE) +unset(STM32CUBEIDE_VERSION CACHE) +unset(STM32CUBEIDE_EXECUTABLE CACHE) + +function(_stm32cubeide_set_from_exec PARAM_EXE) + if(NOT EXISTS "${PARAM_EXE}") + return() + endif() + set(STM32CUBEIDE_EXECUTABLE "${PARAM_EXE}" PARENT_SCOPE) + # Root: up two dirs works for Linux default; handle macOS bundle separately below. + get_filename_component(_dir "${PARAM_EXE}" DIRECTORY) + if(CMAKE_HOST_APPLE AND _dir MATCHES "\\.app/Contents/MacOS$") + get_filename_component(_root "${_dir}/../.." REALPATH) + else() + get_filename_component(_root "${_dir}/.." REALPATH) + endif() + + message(STATUS "Found STM32CUBEIDE_ROOT=${_root}") + set(STM32CUBEIDE_ROOT "${_root}" PARENT_SCOPE) + + # Version extract from directory names like STM32CubeIDE_1.15.0 + file(TO_CMAKE_PATH "${_root}" _root_norm) + get_filename_component(_leaf "${_root_norm}" NAME) # e.g. "STM32CubeIDE_1.14.1" + + set(_ver "") + set(_mark "STM32CubeIDE_") + string(FIND "${_leaf}" "${_mark}" _pos) + if(NOT _pos EQUAL -1) + string(LENGTH "${_mark}" _mlen) + math(EXPR _start "${_pos} + ${_mlen}") + string(SUBSTRING "${_leaf}" ${_start} -1 _ver_raw) + string(STRIP "${_ver_raw}" _ver) + endif() + + if(_ver) # e.g. "1.14.1" + # set both locally and in parent scope for immediate logging + export + set(STM32CUBEIDE_VERSION "${_ver}") + set(STM32CUBEIDE_VERSION "${_ver}" PARENT_SCOPE) + message(NOTICE "Found STM32CUBEIDE_VERSION=${_ver}") + else() + message(VERBOSE "Could not derive version (leaf='${_leaf}', root='${_root_norm}')") + endif() +endfunction() + +# Finds the newest STM32Cube L4 firmware folder under the standard Repository path. +# Usage: +# find_newest_stm32cube_fw_l4(OUT_DIR OUT_VER) +# After the call: +# OUT_DIR = full path to the newest STM32Cube_FW_L4_Vx.y.z directory +# OUT_VER = version string x.y.z +# +# Optional inputs that you may predefine before calling: +# CURRENT_USER Used only on Windows if USERPROFILE is not set +# STM32CUBE_REPO_HINT Override the Repository root folder if you know it already +# +# Examples: +# find_newest_stm32cube_fw_l4(STM32CUBE_L4_ROOT STM32CUBE_L4_VERSION) +# message(STATUS "STM32Cube L4 root: ${STM32CUBE_L4_ROOT} (version ${STM32CUBE_L4_VERSION})") +function(find_newest_stm32cube_fw_l4 OUT_DIR OUT_VER) + set(_repo_root "") + + # 1) If the caller provided a direct hint, use it + if(DEFINED STM32CUBE_REPO_HINT AND EXISTS "${STM32CUBE_REPO_HINT}") + set(_repo_root "${STM32CUBE_REPO_HINT}") + else() + # 2) Build the default path based on platform + if(CMAKE_HOST_WIN32) + # Prefer USERPROFILE if available + set(_userprofile "$ENV{USERPROFILE}") + if(_userprofile STREQUAL "") + # Fallback to C:/Users/ + if(NOT DEFINED CURRENT_USER OR CURRENT_USER STREQUAL "") + set(_env_user "$ENV{USERNAME}") + if(NOT _env_user STREQUAL "") + set(CURRENT_USER "${_env_user}") + endif() + endif() + if(DEFINED CURRENT_USER AND NOT CURRENT_USER STREQUAL "") + set(_repo_root "C:/Users/${CURRENT_USER}/STM32Cube/Repository") + endif() + else() + # Convert backslashes to forward slashes for CMake path sanity + file(TO_CMAKE_PATH "${_userprofile}" _userprofile_cmake) + set(_repo_root "${_userprofile_cmake}/STM32Cube/Repository") + endif() + else() + # macOS and Linux + set(_home "$ENV{HOME}") + if(NOT _home STREQUAL "") + file(TO_CMAKE_PATH "${_home}" _home_cmake) + set(_repo_root "${_home_cmake}/STM32Cube/Repository") + endif() + endif() + endif() + + # Validate we have a repository root + if(_repo_root STREQUAL "" OR NOT EXISTS "${_repo_root}") + set(${OUT_DIR} "" PARENT_SCOPE) + set(${OUT_VER} "" PARENT_SCOPE) + message(STATUS "STM32Cube Repository not found. Checked: ${_repo_root}") + return() + endif() + + # 3) Glob STM32Cube L4 folders + file(GLOB _candidates + LIST_DIRECTORIES true + "${_repo_root}/STM32Cube_FW_L4_V*" + ) + + if(_candidates STREQUAL "") + set(${OUT_DIR} "" PARENT_SCOPE) + set(${OUT_VER} "" PARENT_SCOPE) + message(STATUS "No STM32Cube L4 packages found under: ${_repo_root}") + return() + endif() + + # 4) Pick the highest semantic version using CMake's VERSION comparison + set(_best_dir "") + set(_best_ver "") + + foreach(_dir IN LISTS _candidates) + get_filename_component(_name "${_dir}" NAME) + # Expect names like STM32Cube_FW_L4_V1.17.2 + # Extract the numeric version after the V + string(REGEX MATCH "STM32Cube_FW_L4_V([0-9]+\\.[0-9]+\\.[0-9]+)" _m "${_name}") + if(_m) + # Capture group 1 is the version x.y.z + string(REGEX REPLACE "STM32Cube_FW_L4_V" "" _ver "${_m}") + if(_best_ver STREQUAL "" OR _best_ver VERSION_LESS _ver) + set(_best_ver "${_ver}") + set(_best_dir "${_dir}") + endif() + endif() + endforeach() + + if(_best_dir STREQUAL "") + set(${OUT_DIR} "" PARENT_SCOPE) + set(${OUT_VER} "" PARENT_SCOPE) + message(STATUS "STM32Cube L4 directories found but no valid version pattern matched under: ${_repo_root}") + return() + endif() + + # 5) Return results + set(${OUT_DIR} "${_best_dir}" PARENT_SCOPE) + set(${OUT_VER} "${_best_ver}" PARENT_SCOPE) + message(STATUS "Found newest STM32Cube L4: ${_best_dir} (version ${_best_ver})") +endfunction() # find_newest_stm32cube_fw_l4 + + +# 1) Hints from environment or cache +set(_HINTS "") +if(DEFINED ENV{STM32CUBEIDE_DIR}) + message(STATUS "Found env STM32CUBEIDE_DIR=$ENV{STM32CUBEIDE_DIR}") + list(APPEND _HINTS "$ENV{STM32CUBEIDE_DIR}") +endif() + +if(DEFINED STM32CUBEIDE_DIR) + message(STATUS "Found STM32CUBEIDE_DIR=${STM32CUBEIDE_DIR}") + list(APPEND _HINTS "${STM32CUBEIDE_DIR}") +endif() + +if(DEFINED ENV{STM32CUBEIDE_ROOT}) + message(STATUS "Found env STM32CUBEIDE_ROOT=$ENV{STM32CUBEIDE_ROOT}") + list(APPEND _HINTS "$ENV{STM32CUBEIDE_ROOT}") +endif() + +if(DEFINED STM32CUBEIDE_ROOT) + message(STATUS "Found STM32CUBEIDE_ROOT=${STM32CUBEIDE_ROOT}") + list(APPEND _HINTS "${STM32CUBEIDE_ROOT}") +endif() + +foreach(h ${_HINTS}) + message(STATUS "Looking for STM32CubeIDE.exe in ${h}") + if(CMAKE_HOST_WIN32) + if(EXISTS "${h}/STM32CubeIDE.exe") + _stm32cubeide_set_from_exec("${h}/STM32CubeIDE.exe") + endif() + elseif(CMAKE_HOST_APPLE) + if(EXISTS "${h}/STM32CubeIDE.app/Contents/MacOS/STM32CubeIDE") + _stm32cubeide_set_from_exec("${h}/STM32CubeIDE.app/Contents/MacOS/STM32CubeIDE") + elseif(EXISTS "${h}/Contents/MacOS/STM32CubeIDE") + _stm32cubeide_set_from_exec("${h}/Contents/MacOS/STM32CubeIDE") + endif() + else() + if(EXISTS "${h}/stm32cubeide") + _stm32cubeide_set_from_exec("${h}/stm32cubeide") + endif() + endif() +endforeach() + +# 2) PATH search +if(NOT STM32CUBEIDE_EXECUTABLE) + if(CMAKE_HOST_WIN32) + find_program(_CUBE_EXE NAMES "STM32CubeIDE.exe") + elseif(CMAKE_HOST_APPLE OR CMAKE_HOST_UNIX) + find_program(_CUBE_EXE NAMES "stm32cubeide") + endif() + if(_CUBE_EXE) + _stm32cubeide_set_from_exec("${_CUBE_EXE}") + endif() +endif() + +# 3) OS-specific probing +if(NOT STM32CUBEIDE_EXECUTABLE) + if(CMAKE_HOST_WIN32) + # Try Registry: uninstall entries often expose InstallLocation + # 64-bit and 32-bit views + foreach(_HK + "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" + "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall") + execute_process(COMMAND reg query ${_HK} /f STM32CubeIDE /s + OUTPUT_VARIABLE _reg + ERROR_VARIABLE _reg_err + RESULT_VARIABLE _reg_rc) + if(_reg_rc EQUAL 0 AND _reg MATCHES "InstallLocation\\s+REG_SZ\\s+([^\r\n]+)") + string(REGEX REPLACE ".*InstallLocation\\s+REG_SZ\\s+([^\r\n]+).*" "\\1" _loc "${_reg}") + string(REPLACE "\\" "/" _loc "${_loc}") + if(EXISTS "${_loc}/STM32CubeIDE.exe") + _stm32cubeide_set_from_exec("${_loc}/STM32CubeIDE.exe") + endif() + endif() + endforeach() + + # Common default roots + if(NOT STM32CUBEIDE_EXECUTABLE) + file(GLOB _candidates + "C:/ST/STM32CubeIDE_*" + "C:/Program Files/STMicroelectronics/STM32CubeIDE*" + "C:/Program Files (x86)/STMicroelectronics/STM32CubeIDE*") + + if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.7") + list(SORT _candidates COMPARE NATURAL ORDER DESCENDING) + else() + list(SORT _candidates) + list(REVERSE _candidates) + endif() + + foreach(_this_c ${_candidates}) + message(STATUS "Looking at ${_this_c}") + if(EXISTS "${_this_c}/STM32CubeIDE.exe") + message(STATUS "Found ${_this_c}/STM32CubeIDE.exe") + _stm32cubeide_set_from_exec("${_this_c}/STM32CubeIDE.exe") + break() + endif() + + if(EXISTS "${_this_c}/STM32CubeIDE/STM32CubeIDE.exe") + message(STATUS "Found ${_this_c}/STM32CubeIDE/STM32CubeIDE.exe") + _stm32cubeide_set_from_exec("${_this_c}/STM32CubeIDE/STM32CubeIDE.exe") + break() + endif() + endforeach() + endif() + + elseif(CMAKE_HOST_APPLE) + # Standard Applications folder + if(EXISTS "/Applications/STM32CubeIDE.app/Contents/MacOS/STM32CubeIDE") + _stm32cubeide_set_from_exec("/Applications/STM32CubeIDE.app/Contents/MacOS/STM32CubeIDE") + else() + # Fall back: scan *.app names + file(GLOB _apps "/Applications/STM32CubeIDE*.app") + + if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.7") + list(SORT _apps COMPARE NATURAL ORDER DESCENDING) + else() + list(SORT _apps) + list(REVERSE _apps) + endif() + + foreach(app ${_apps}) + if(EXISTS "${app}/Contents/MacOS/STM32CubeIDE") + _stm32cubeide_set_from_exec("${app}/Contents/MacOS/STM32CubeIDE") + break() + endif() + endforeach() + + # Spotlight as last resort + if(NOT STM32CUBEIDE_EXECUTABLE) + execute_process(COMMAND mdfind "kMDItemCFBundleIdentifier == com.st.stm32cubeide" + OUTPUT_VARIABLE _mdfind RESULT_VARIABLE _mdrc) + if(_mdrc EQUAL 0 AND _mdfind) + string(REGEX MATCH ".*\\.app" _app "${_mdfind}") + if(_app AND EXISTS "${_app}/Contents/MacOS/STM32CubeIDE") + _stm32cubeide_set_from_exec("${_app}/Contents/MacOS/STM32CubeIDE") + endif() + endif() + endif() + endif() + + else() # Linux + # Desktop file -> Exec path + if(EXISTS "/usr/share/applications/stm32cubeide.desktop") + file(READ "/usr/share/applications/stm32cubeide.desktop" _desk) + string(REGEX MATCH "Exec=([^ \n\r]+)" _m "${_desk}") + if(_m) + string(REGEX REPLACE "Exec=([^ \n\r]+).*" "\\1" _exec "${_desk}") + # Resolve symlink if any + execute_process(COMMAND bash -lc "readlink -f \"${_exec}\"" OUTPUT_VARIABLE _rl RESULT_VARIABLE _rc) + if(_rc EQUAL 0) + string(STRIP "${_rl}" _rls) + if(EXISTS "${_rls}") + _stm32cubeide_set_from_exec("${_rls}") + endif() + elseif(EXISTS "${_exec}") + _stm32cubeide_set_from_exec("${_exec}") + endif() + endif() + endif() + + # Typical install roots under /opt + if(NOT STM32CUBEIDE_EXECUTABLE) + file(GLOB _candidates "/opt/st/stm32cubeide_*") + + if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.7") + list(SORT _candidates COMPARE NATURAL ORDER DESCENDING) + else() + list(SORT _candidates) + list(REVERSE _candidates) + endif() + + foreach(c ${_candidates}) + if(EXISTS "${c}/stm32cubeide") + _stm32cubeide_set_from_exec("${c}/stm32cubeide") + break() + endif() + endforeach() + endif() + endif() # Windows or Mac else Linux +endif() # !STM32CUBEIDE_EXECUTABLE + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(STM32CubeIDE + REQUIRED_VARS STM32CUBEIDE_EXECUTABLE STM32CUBEIDE_ROOT + FAIL_MESSAGE "STM32CubeIDE not found. Set STM32CUBEIDE_DIR or add it to PATH." +) + +if(STM32CUBEIDE_EXECUTABLE) + message(STATUS "Found STM32 CubeIDE: ${STM32CUBEIDE_EXECUTABLE}") + set(STM32CUBEIDE_FOUND TRUE) +else() + message(STATUS "Not found: STM32 CubeIDE") +endif() + +# The CubeIDE version likely does not match FW version: +# C:\Users\${CURRENT_USER}\STM32Cube\Repository\STM32Cube_FW_L4_V1.18.0\Drivers\STM32L4xx_HAL_Driver +# C:/Users/${CURRENT_USER}/STM32Cube/Repository/STM32Cube_FW_L4_V1.14.1/Drivers/ + +find_newest_stm32cube_fw_l4(STM32CUBE_L4_ROOT STM32CUBE_L4_VERSION) +set(STM32_HAL_DIR "${STM32CUBE_L4_ROOT}/Drivers/STM32L4xx_HAL_Driver") +set(CMSIS_DIR "${STM32CUBE_L4_ROOT}/Drivers/CMSIS") + +if(STM32CUBE_L4_VERSION) + set(HAL_BASE "${STM32CUBE_L4_ROOT}") + if(IS_DIRECTORY "${HAL_BASE}") + message(STATUS "Found HAL_BASE=${HAL_BASE}") + set(FOUND_STM32L4_LIB true) + else() + message(STATUS "Not found expected HAL_BASE=${HAL_BASE}") + endif() +endif() + +mark_as_advanced(STM32CUBEIDE_EXECUTABLE STM32CUBEIDE_ROOT STM32CUBEIDE_VERSION) +message(STATUS "End cube_ide_config.cmake") diff --git a/cmake/functions.cmake b/cmake/functions.cmake index 330b702873..ff3f44f4b8 100644 --- a/cmake/functions.cmake +++ b/cmake/functions.cmake @@ -62,3 +62,19 @@ function(print_env VAR) message(STATUS "${VAR} = (not set)") endif() endfunction() + +# Sets to . +# If points to an existing directory, prints a STATUS message. +function(set_and_echo_dir var_name value_expr) + set(_val "${value_expr}") + # Export to caller's scope + set(${var_name} "${_val}" PARENT_SCOPE) + + if(IS_DIRECTORY "${_val}") + message(STATUS "set ${var_name}; Found directory: ${_val}") + else() + message(STATUS "set ${var_name}; Directory not found: ${_val}") + endif() +endfunction() + +set(functions_cmake_loaded true) diff --git a/cmake/stm32_hal_download.cmake b/cmake/stm32_hal_download.cmake new file mode 100644 index 0000000000..af06c60758 --- /dev/null +++ b/cmake/stm32_hal_download.cmake @@ -0,0 +1,80 @@ +# wolfboot/cmake/stm32_hal_download.cmake +# +# Copyright (C) 2022 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 +# + +# If not found: +# The CubeIDE +# VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32 +# +# ... then download HAL files as needed + +if(NOT functions_cmake_loaded) + include(cmake/functions.cmake) +endif() + +if(WOLFBOOT_TARGET STREQUAL "stm32l4") + if(FOUND_STM32L4_LIB) + message(STATUS "stm32_hal_download.cmake skipped, already found STM32 HAL lib.") + else() + include(FetchContent) + # TIP: Always pin a real tag/commit; avoid main/master. + + # Make behavior explicit & chatty while debugging + set(FETCHCONTENT_QUIET OFF) + set(FETCHCONTENT_BASE_DIR "${CMAKE_BINARY_DIR}/_deps") + + # HAL driver + message(STATUS "Fetching https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git") + FetchContent_Declare(st_hal + GIT_REPOSITORY https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git + # Pick a tag you want to lock to: + GIT_TAG v1.13.5 + GIT_SHALLOW TRUE + GIT_PROGRESS FALSE + ) + + # CMSIS device headers for L4 + message(STATUS "Fetching https://github.com/STMicroelectronics/cmsis_device_l4.git") + FetchContent_Declare(cmsis_dev + GIT_REPOSITORY https://github.com/STMicroelectronics/cmsis_device_l4.git + GIT_TAG v1.7.4 + GIT_SHALLOW TRUE + GIT_PROGRESS FALSE + ) + + # CMSIS Core headers + message(STATUS "Fetching https://github.com/ARM-software/CMSIS_5.git") + FetchContent_Declare(cmsis_core + GIT_REPOSITORY https://github.com/ARM-software/CMSIS_5.git + GIT_TAG 5.9.0 + GIT_SHALLOW TRUE + GIT_PROGRESS FALSE + ) + + FetchContent_MakeAvailable(st_hal cmsis_dev cmsis_core) + + # Map to the include structures of the fetched repos + message("stm32_hal_download.cmake setting hal directories:") + set_and_echo_dir(HAL_BASE "${st_hal_SOURCE_DIR}") + set_and_echo_dir(HAL_DRV "${st_hal_SOURCE_DIR}") # Inc/, Src/ + set_and_echo_dir(HAL_CMSIS_DEV "${cmsis_dev_SOURCE_DIR}/Include") # device + set_and_echo_dir(HAL_CMSIS_CORE "${cmsis_core_SOURCE_DIR}/CMSIS/Core/Include") # core + endif() +endif() diff --git a/cmake/toolchain_arm-none-eabi.cmake b/cmake/toolchain_arm-none-eabi.cmake index c4b96e2f31..b76b56c44e 100644 --- a/cmake/toolchain_arm-none-eabi.cmake +++ b/cmake/toolchain_arm-none-eabi.cmake @@ -34,6 +34,7 @@ if(NOT DEFINED WOLFBOOT_TARGET) endif() # Cortex-M CPU +# TODO move to presets if(WOLFBOOT_TARGET STREQUAL "stm32l0") set(CMAKE_SYSTEM_PROCESSOR cortex-m0) set(MCPU_FLAGS "-mcpu=cortex-m0 -mthumb -mlittle-endian -mthumb-interwork ") @@ -56,7 +57,7 @@ endif() # Optional: allow an explicit bin dir set(ARM_GCC_BIN "" CACHE PATH "Path to Arm GNU Toolchai 'bin' directory") -if(WIN32) +if(CMAKE_HOST_WIN32) if(ARM_GCC_BIN) file(TO_CMAKE_PATH "${ARM_GCC_BIN}" _BIN) set(CMAKE_C_COMPILER "${_BIN}/arm-none-eabi-gcc.exe" CACHE FILEPATH "" FORCE) @@ -64,8 +65,21 @@ if(WIN32) set(CMAKE_ASM_COMPILER "${_BIN}/arm-none-eabi-gcc.exe" CACHE FILEPATH "" FORCE) else() # Try PATH - find_program(CMAKE_C_COMPILER NAMES arm-none-eabi-gcc.exe) - find_program(CMAKE_CXX_COMPILER NAMES arm-none-eabi-g++.exe) + find_program(CMAKE_C_COMPILER NAMES arm-none-eabi-gcc.exe + HINTS + "C:/Program Files/Ninja" + "C:/SysGCC/arm-eabi/bin" + "C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/14.2 rel1/bin" + "C:/ST/STM32CubeIDE_1.14.1/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.11.3.rel1.win32_1.1.100.202309141235/tools/bin" + ) + find_program(CMAKE_CXX_COMPILER NAMES arm-none-eabi-g++.exe + HINTS + "C:/Program Files/Ninja" + "C:/SysGCC/arm-eabi/bin" + "C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/14.2 rel1/bin" + "C:/ST/STM32CubeIDE_1.14.1/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.11.3.rel1.win32_1.1.100.202309141235/tools/bin" + ) + set(CMAKE_ASM_COMPILER "${CMAKE_C_COMPILER}" CACHE FILEPATH "" FORCE) endif() else() @@ -75,6 +89,7 @@ else() set(CMAKE_CXX_COMPILER "${_BIN}/arm-none-eabi-g++" CACHE FILEPATH "" FORCE) set(CMAKE_ASM_COMPILER "${_BIN}/arm-none-eabi-gcc" CACHE FILEPATH "" FORCE) else() + # Assume Mac / Linux is in path. No hints. find_program(CMAKE_C_COMPILER NAMES arm-none-eabi-gcc) find_program(CMAKE_CXX_COMPILER NAMES arm-none-eabi-g++) set(CMAKE_ASM_COMPILER "${CMAKE_C_COMPILER}" CACHE FILEPATH "" FORCE) @@ -104,11 +119,12 @@ endif() # Some sanity checks on compiler and target OS +# TODO remove OS specific presets if(NOT CMAKE_C_COMPILER OR NOT CMAKE_CXX_COMPILER) if("${TARGET_OS}" STREQUAL "") message(STATUS "Warning: cmake presets should define TARGET_OS = [WINDOWS | LINUX]") endif() - if(WIN32) + if(CMAKE_HOST_WIN32) if("${TARGET_OS}" STREQUAL "LINUX") message(FATAL_ERROR "Linux presets are not supported in Windows. Choose a different preset.") endif() @@ -139,7 +155,7 @@ set(CMAKE_EXE_LINKER_FLAGS "${MCPU_FLAGS} ${LD_FLAGS} -Wl,--gc-sections --specs= # Derive toolchain helper paths from the chosen compiler #--------------------------------------------------------------------------------------------- get_filename_component(_BIN_DIR "${CMAKE_C_COMPILER}" DIRECTORY) -if(WIN32) +if(CMAKE_HOST_WIN32) set(_EXE ".exe") else() set(_EXE "") diff --git a/cmake/vs2022_config.cmake b/cmake/vs2022_config.cmake new file mode 100644 index 0000000000..b5249c3ec7 --- /dev/null +++ b/cmake/vs2022_config.cmake @@ -0,0 +1,98 @@ +# Raw inputs copied from your Developer Prompt +set(WIN_DEV_PATH_RAW [=[ +C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\bin\HostX86\x86;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\VC\VCPackages;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\bin\Roslyn;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\;C:\Program Files (x86)\HTML Help Workshop;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Team Tools\DiagnosticsHub\Collector;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\Extensions\Microsoft\CodeCoverage.Console;C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\\x86;C:\Program Files (x86)\Windows Kits\10\bin\\x86;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\\MSBuild\Current\Bin\amd64;C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\;C:\Program Files (x86)\VMware\VMware Workstation\bin\;C:\Program Files\Microsoft\jdk-11.0.16.101-hotspot\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\Git\cmd;C:\SysGCC\esp32-master\tools\riscv32-esp-elf\esp-15.2.0_20250920\riscv32-esp-elf\bin;C:\SysGCC\esp32-master\tools\xtensa-esp-elf\esp-15.2.0_20250920\xtensa-esp-elf\bin;C:\Program Files (x86)\VMware\VMware Workstation\bin\;C:\Program Files\Microsoft\jdk-11.0.16.101-hotspot\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\Git\cmd;C:\Users\gojimmypi\AppData\Local\Microsoft\WindowsApps;C:\Users\gojimmypi\AppData\Local\Programs\Microsoft VS Code\bin;C:\ST\STM32CubeIDE_1.14.1\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.1.100.202311100844\tools\bin;C:\Program Files\Git\usr\bin\;C:\Users\gojimmypi\.dotnet\tools;C:\SysGCC\esp32-master\tools\riscv32-esp-elf\esp-13.2.0_20240530\riscv32-esp-elf\bin;C:\Users\gojimmypi\AppData\Local\Microsoft\WinGet\Packages\Ninja-build.Ninja_Microsoft.Winget.Source_8wekyb3d8bbwe;;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\VC\Linux\bin\ConnectionManagerExe +]=]) + +set(WIN_DEV_INCLUDE_RAW [=[ +C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\include;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\ATLMFC\include;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\VS\include;C:\Program Files (x86)\Windows Kits\10\include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\um;C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\shared;C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\winrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\cppwinrt;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um +]=]) + +set(WIN_DEV_LIB_RAW [=[ +C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\ATLMFC\lib\x86;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\lib\x86;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x86;C:\Program Files (x86)\Windows Kits\10\lib\10.0.26100.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\\lib\10.0.26100.0\\um\x86 +]=]) + + + +# Normalize a raw path token: strip quotes/whitespace, convert to CMake-style slashes +function(_normalize_path _out _in) + set(_p "${_in}") + string(REPLACE "\"" "" _p "${_p}") + string(STRIP "${_p}" _p) + + # Convert backslashes to forward slashes for CMake + file(TO_CMAKE_PATH "${_p}" _p) + + # Drop a single trailing slash to stabilize dedupe + if(_p MATCHES ".+/$") + string(REGEX REPLACE "/$" "" _p "${_p}") + endif() + set(${_out} "${_p}" PARENT_SCOPE) +endfunction() + +# Build a clean env-style variable from a raw ;-separated list +# Usage: +# build_env_from_dirs(PATH ) +# build_env_from_dirs(INCLUDE ) +# build_env_from_dirs(LIB ) +# +# Produces: +# _LIST -> CMake list of existing, deduplicated, normalized dirs +# _STRING -> Same, joined with ';' suitable for an env var +function(build_env_from_dirs NAME) + set(_seen ) + set(_final ) + + foreach(_raw IN LISTS ARGN) + if(_raw STREQUAL "") + continue() + endif() + + _normalize_path(_p "${_raw}") + if(_p STREQUAL "") + continue() + endif() + + if(IS_DIRECTORY "${_p}") + list(FIND _seen "${_p}" _idx) + if(_idx EQUAL -1) + list(APPEND _final "${_p}") + list(APPEND _seen "${_p}") + endif() + else() + # Uncomment for troubleshooting + # message(STATUS "[${NAME}] Skipping missing: ${_p}") + endif() + endforeach() + + list(JOIN _final ";" _joined) + set(${NAME}_LIST "${_final}" PARENT_SCOPE) + set(${NAME}_STRING "${_joined}" PARENT_SCOPE) +endfunction() # build_env_from_dirs + +# Only helpful if Visual Studio is installed +# Note VS2022 is installed by default in GitHub workflow `runs-on: windows-latest` +if(IS_DIRECTORY "C:/Program Files/Microsoft Visual Studio/") + message(STATUS "Found C:/Program Files/Microsoft Visual Studio/") + # Build the CMake equivalents + build_env_from_dirs(PATH ${WIN_DEV_PATH_RAW}) + build_env_from_dirs(INCLUDE ${WIN_DEV_INCLUDE_RAW}) + build_env_from_dirs(LIB ${WIN_DEV_LIB_RAW}) +else() + message(STATUS "Visual Studio not found, skipping VS2022_config.cmake") +endif() + +# Results: +# PATH_LIST / PATH_STRING +# INCLUDE_LIST / INCLUDE_STRING +# LIB_LIST / LIB_STRING + +# Optional: export to the environment for tools launched by CMake +# set(ENV{Path} "${PATH_STRING}") +# set(ENV{INCLUDE} "${INCLUDE_STRING}") +# set(ENV{LIB} "${LIB_STRING}") + +# Optional: integrate with CMake search variables +# list(PREPEND CMAKE_PREFIX_PATH ${PATH_LIST}) +# list(PREPEND CMAKE_PROGRAM_PATH ${PATH_LIST}) +# list(PREPEND CMAKE_INCLUDE_PATH ${INCLUDE_LIST}) +# list(PREPEND CMAKE_LIBRARY_PATH ${LIB_LIST}) diff --git a/my_test.sh b/my_test.sh index 3658da11d7..d77e7aa2d5 100644 --- a/my_test.sh +++ b/my_test.sh @@ -1,7 +1,12 @@ #!/bin/bash +echo "Remove prior build directories..." rm -rf ./build-windows-stm32l4 rm -rf ./build-linux-stm32l4 +rm -rf ./build-stm32l4 -cmake --preset linux-stm32l4 -cmake --build --preset linux-stm32l4 +echo "cmake --preset stm32l4" + cmake --preset stm32l4 + +echo "cmake --build --preset stm32l4" + cmake --build --preset stm32l4 From 32e46e68d2f4712d758fb7b69398e13d90a5331e Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Thu, 16 Oct 2025 16:40:10 -0700 Subject: [PATCH 7/9] update from dev branch --- .editorconfig | 5 + .../workflows/test-build-cmake-dot-config.yml | 102 ++++ .github/workflows/test-build-cmake-mac.yml | 13 +- .github/workflows/test-build-cmake-script.yml | 14 +- .../workflows/test-build-cmake-windows.yml | 60 +- .github/workflows/test-build-cmake.yml | 4 +- .gitignore | 13 + .vscode/launch.json | 2 +- .vscode/tasks.json | 12 +- CMakeLists.txt | 107 ++-- CMakePresets.json | 261 ++++----- IDE/VSCode/.vscode/launch.json | 21 - IDE/VSCode/.vscode/settings.json | 10 - IDE/VSCode/.vscode/tasks.json | 35 -- IDE/VSCode/README.md | 71 ++- IDE/VisualGDB/README.md | 19 +- IDE/VisualStudio/README.md | 44 ++ IDE/Windows/README.md | 29 + README.md | 286 +++------- .../CMakeUserPresets.json.sample | 34 +- cmake/README.md | 514 ++++++++++++++++++ cmake/config_defaults.cmake | 51 +- cmake/cube_ide_config.cmake | 27 +- cmake/current_user.cmake | 16 +- cmake/downloads/README.md | 21 + cmake/downloads/stm32l4.cmake | 39 ++ cmake/functions.cmake | 22 +- cmake/load_dot_config.cmake | 16 +- cmake/stm32_hal_download.cmake | 211 +++++-- cmake/toolchain_aarch64-none-elf.cmake | 14 +- cmake/toolchain_arm-none-eabi.cmake | 13 +- cmake/utils.cmake | 13 + cmake/visualgdb_config.cmake | 93 ++++ cmake/vs2022_config.cmake | 38 ++ cmake/wolfboot.cmake | 12 + config/examples/README.md | 16 +- docs/CMake.md | 3 + docs/README.md | 33 ++ docs/STM32.md | 123 +++++ my_test.bat | 8 - my_test.sh | 12 - test-app/CMakeLists.txt | 2 +- tools/keytools/sign.c | 6 +- tools/scripts/cmake_dev_prompt_test.bat | 79 +++ tools/scripts/cmake_dot_config.sh | 83 +++ tools/scripts/cmake_test.bat | 80 +++ tools/scripts/cmake_test.sh | 49 ++ .../scripts/config2presets.py | 130 ++++- tools/scripts/wolfboot_build.sh | 306 +++++++++++ wolfBoot.code-workspace | 16 +- wolfbuild.sh | 123 ----- 51 files changed, 2486 insertions(+), 825 deletions(-) create mode 100644 .github/workflows/test-build-cmake-dot-config.yml delete mode 100644 IDE/VSCode/.vscode/launch.json delete mode 100644 IDE/VSCode/.vscode/settings.json delete mode 100644 IDE/VSCode/.vscode/tasks.json create mode 100644 IDE/VisualStudio/README.md create mode 100644 IDE/Windows/README.md rename CMakeUserPresets.json.sample => cmake/CMakeUserPresets.json.sample (83%) create mode 100644 cmake/README.md create mode 100644 cmake/downloads/README.md create mode 100644 cmake/downloads/stm32l4.cmake create mode 100644 cmake/visualgdb_config.cmake create mode 100644 docs/CMake.md create mode 100644 docs/README.md create mode 100644 docs/STM32.md delete mode 100644 my_test.bat delete mode 100644 my_test.sh create mode 100644 tools/scripts/cmake_dev_prompt_test.bat create mode 100644 tools/scripts/cmake_dot_config.sh create mode 100644 tools/scripts/cmake_test.bat create mode 100644 tools/scripts/cmake_test.sh rename config2presets.py => tools/scripts/config2presets.py (50%) create mode 100644 tools/scripts/wolfboot_build.sh delete mode 100755 wolfbuild.sh diff --git a/.editorconfig b/.editorconfig index 8138f66086..c38f7b7d43 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,3 +4,8 @@ root = true charset = utf-8 end_of_line = lf insert_final_newline = true + +[*.md] +charset = utf-8-bom +end_of_line = lf +insert_final_newline = true diff --git a/.github/workflows/test-build-cmake-dot-config.yml b/.github/workflows/test-build-cmake-dot-config.yml new file mode 100644 index 0000000000..7bf30ae8c4 --- /dev/null +++ b/.github/workflows/test-build-cmake-dot-config.yml @@ -0,0 +1,102 @@ +name: wolfboot CMake (.config) +on: + push: + branches: [ '*' ] + pull_request: + branches: [ '*' ] +jobs: + wolfboot_dot_config_test: + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Workaround for sources.list + run: | + # Replace sources + + set -euxo pipefail + + # Peek (what repos are active now) + apt-cache policy + grep -RInE '^(deb|Types|URIs)' /etc/apt || true + + # Enable nullglob so *.list/*.sources that don't exist don't break sed + shopt -s nullglob + + echo "Replace sources.list (legacy)" + sudo sed -i \ + -e "s|https\?://azure\.archive\.ubuntu\.com/ubuntu/?|http://mirror.arizona.edu/ubuntu/|g" \ + /etc/apt/sources.list || true + + echo "Replace sources.list.d/*.list (legacy)" + for f in /etc/apt/sources.list.d/*.list; do + sudo sed -i \ + -e "s|https\?://azure\.archive\.ubuntu\.com/ubuntu/?|http://mirror.arizona.edu/ubuntu/|g" \ + "$f" + done + + echo "Replace sources.list.d/*.sources (deb822)" + for f in /etc/apt/sources.list.d/*.sources; do + sudo sed -i \ + -e "s|https\?://azure\.archive\.ubuntu\.com/ubuntu/?|http://mirror.arizona.edu/ubuntu/|g" \ + -e "s|https\?://azure\.archive\.ubuntu\.com|http://mirror.arizona.edu|g" \ + "$f" + done + + echo "Fix /etc/apt/apt-mirrors.txt (used by URIs: mirror+file:...)" + if grep -qE '^[[:space:]]*https?://azure\.archive\.ubuntu\.com/ubuntu/?' /etc/apt/apt-mirrors.txt; then + # Replace azure with our mirror (idempotent) + sudo sed -i 's|https\?://azure\.archive\.ubuntu\.com/ubuntu/|http://mirror.arizona.edu/ubuntu/|g' /etc/apt/apt-mirrors.txt + fi + + # Peek (verify changes) + grep -RIn "azure.archive.ubuntu.com" /etc/apt || true + grep -RInE '^(deb|Types|URIs)' /etc/apt || true + echo "--- apt-mirrors.txt ---" + cat /etc/apt/apt-mirrors.txt || true + + + - name: Install requirements + run: | + # Run system updates and install toolchain + sudo apt-get update + sudo apt-get install -y gcc-arm-none-eabi gcc-powerpc-linux-gnu cmake + + - name: Run dot-config examples + run: | + # Sample .config cmake test + + set -euo pipefail + + LOG_FILE="run.log" + KEYWORD="Config mode: dot" + echo "Saving output to $LOG_FILE" + + echo "Fetch stm32h7 example .config" + cp ./config/examples/stm32h7.config ./.config + ls .config + cat .config + echo "" + + echo "Clean" + rm -rf ./build-stm32h7 + + # Here we should see the .config file values read and displayed: + cmake -S . -B build-stm32h7 \ + -DUSE_DOT_CONFIG=ON \ + -DWOLFBOOT_TARGET=stm32h7 2>&1 | tee "$LOG_FILE" + + # Config dot-config mode + if grep -q -- "$KEYWORD" "$LOG_FILE"; then + echo "Keyword found: $KEYWORD" + else + echo "Keyword not found: $KEYWORD" >&2 + exit 1 + fi + + # Sample build + cmake --build build-stm32h7 -j diff --git a/.github/workflows/test-build-cmake-mac.yml b/.github/workflows/test-build-cmake-mac.yml index 78fda599dd..989cfc3552 100644 --- a/.github/workflows/test-build-cmake-mac.yml +++ b/.github/workflows/test-build-cmake-mac.yml @@ -12,6 +12,11 @@ jobs: runs-on: macos-14 timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + target: [stm32l4, stm32h7, stm32c0, stm32g0] + env: HOMEBREW_NO_AUTO_UPDATE: "1" # avoid updating taps during install HOMEBREW_NO_ANALYTICS: "1" @@ -83,9 +88,9 @@ jobs: # -DBUILD_TEST_APPS=ON \ # -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain_arm-none-eabi.cmake - - name: Presets + - name: Cmake Configure & Build Preset (${{ matrix.target }}) run: | - rm -rf ./build-stm32l4 + rm -rf ./build-${{ matrix.target }} - cmake --preset stm32l4 - cmake --build --preset stm32l4 + cmake --preset ${{ matrix.target }} + cmake --build --preset ${{ matrix.target }} diff --git a/.github/workflows/test-build-cmake-script.yml b/.github/workflows/test-build-cmake-script.yml index e17a48a991..191d4ff249 100644 --- a/.github/workflows/test-build-cmake-script.yml +++ b/.github/workflows/test-build-cmake-script.yml @@ -1,11 +1,11 @@ -name: Wolfboot CMake Script +name: wolfboot CMake Script on: push: branches: [ '*' ] pull_request: branches: [ '*' ] jobs: - cmake_automated_test: + wolfboot_build_script_test: runs-on: ubuntu-latest timeout-minutes: 15 @@ -65,8 +65,12 @@ jobs: sudo apt-get update sudo apt-get install -y gcc-arm-none-eabi gcc-powerpc-linux-gnu cmake - - name: Run wolfbuild script + - name: Run wolfboot_build script run: | rm -rf ./build - ./wolfbuild.sh --CLEAN "linux-stm32l4" - ./wolfbuild.sh --target "linux-stm32l4" + + ./tools/scripts/wolfboot_build.sh --CLEAN "stm32l4" + ./tools/scripts/wolfboot_build.sh --target "stm32l4" + + ./tools/scripts/wolfboot_build.sh --CLEAN "stm32g0" + ./tools/scripts/wolfboot_build.sh --target "stm32g0" diff --git a/.github/workflows/test-build-cmake-windows.yml b/.github/workflows/test-build-cmake-windows.yml index 9a7b146690..3752fa1a50 100644 --- a/.github/workflows/test-build-cmake-windows.yml +++ b/.github/workflows/test-build-cmake-windows.yml @@ -6,9 +6,12 @@ on: pull_request: branches: [ "*" ] +permissions: + contents: read + jobs: windows-cmake: - name: Build on Windows (CMake + Ninja) + name: Build on Windows runs-on: windows-latest timeout-minutes: 20 @@ -18,6 +21,7 @@ jobs: target: - stm32l4 - stm32h7 + - stm32g0 include: # Optional per-target cache variables you might want to pass later. # Keep empty for now to avoid guessing addresses. @@ -25,6 +29,8 @@ jobs: extra_cache: "" - target: stm32h7 extra_cache: "" + - target: stm32g0 + extra_cache: "" steps: - name: Checkout (with submodules) @@ -32,17 +38,29 @@ jobs: with: submodules: true + # Lock down network/runner + # See https://github.com/step-security/harden-runner/releases + - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a + with: + egress-policy: block + allowed-endpoints: > + developer.arm.com, + armkeil.blob.core.windows.net, + github.com, objects.githubusercontent.com, api.github.com + # ARM GCC toolchain (adds the bin dir to PATH) - name: Set up ARM none-eabi GCC 14.x uses: carlosperate/arm-none-eabi-gcc-action@v1 with: - version: "14.2.Rel1" # <-- use 'release', not 'version' + release: "14.2.Rel1" # <-- use 'release', not 'version' path-env-var: ARM_NONE_EABI_GCC_PATH # CMake + Ninja are preinstalled on windows-latest, but verify & print versions - name: Tool versions shell: bash run: | + # Show some key toolchain versions + echo "Compiler versions:" arm-none-eabi-gcc --version echo @@ -55,45 +73,27 @@ jobs: echo "MSVC (via vswhere):" cmd.exe /c "\"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe\" -latest -products * -requires Microsoft.Component.MSBuild -property installationVersion" - - name: Build via cmd inline - shell: cmd - run: | - if exist build-windows-stm32l4 rmdir /s /q build-windows-stm32l4 - cmake --preset windows-stm32l4 - cmake --build --preset windows-stm32l4 --parallel %NUMBER_OF_PROCESSORS% - - - name: Build via batch (cmd) - shell: cmd + - name: List Presets + shell: bash run: | - :: # Call my_test.bat + # Check available presets in CMakePresets.json - call my_test.bat + cmake -S . -B build-list --list-presets=configure - - name: Configure (CMake + Ninja) + - name: Configure Preset "${{ matrix.target }}" shell: bash run: | # cmake runs in git bash - BUILD_DIR="build-${{ matrix.target }}" - cmake -S . -B "$BUILD_DIR" -G Ninja \ - -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain_arm-none-eabi.cmake \ - -DWOLFBOOT_CONFIG_MODE=preset \ - -DWOLFBOOT_TARGET=${{ matrix.target }} \ - -DBUILD_TEST_APPS=ON \ - -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x8020000 \ - -DWOLFBOOT_SECTOR_SIZE=0x20000 \ - -DWOLFBOOT_PARTITION_SIZE=0xD0000 \ - -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x80F0000 \ - -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x81C0000 \ - ${{ matrix.extra_cache }} - echo "Configured: $BUILD_DIR" - - - name: Build + cmake --preset "${{ matrix.target }}" + echo "Configured: ${{ matrix.target }}" + + - name: Build "${{ matrix.target }}" shell: bash run: | # cmake runs in git bash BUILD_DIR="build-${{ matrix.target }}" - cmake --build "$BUILD_DIR" --parallel + cmake --build "build-${{ matrix.target }}" --parallel # Optional: show interesting artifacts - name: List build outputs diff --git a/.github/workflows/test-build-cmake.yml b/.github/workflows/test-build-cmake.yml index b72dea367a..673a78f99a 100644 --- a/.github/workflows/test-build-cmake.yml +++ b/.github/workflows/test-build-cmake.yml @@ -111,5 +111,5 @@ jobs: - name: Run wolfbuild script run: | rm -rf ./build - ./wolfbuild.sh --CLEAN "linux-stm32l4" - ./wolfbuild.sh --target "linux-stm32l4" + ./tools/scripts/wolfboot_build.sh --CLEAN "stm32l4" + ./tools/scripts/wolfboot_build.sh --target "stm32l4" diff --git a/.gitignore b/.gitignore index e7d512e398..8f860bba51 100644 --- a/.gitignore +++ b/.gitignore @@ -144,6 +144,9 @@ IDE/IAR/Release build/ CMakeFiles/ CMakeCache.txt +# User specific presets should never be included. +# See docs: https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html +/**/CMakeUserPresets.json # Stage 1 stage1/loader_stage1.ld @@ -267,3 +270,13 @@ language.settings.xml /**/build /**/build-** +/IDE/VisualGDB +/commit_squash.sh +/evars.txt +/evars_non_dev.txt +/gpg_refresh.sh +/IDE/VisualStudio/EmbeddedProject1 +/IDE/VisualStudio/wolfboot +/.gitignore.wip +/run.log +/stm32.mak diff --git a/.vscode/launch.json b/.vscode/launch.json index 14ec097716..060d945aec 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,7 +7,7 @@ "request": "launch", "servertype": "openocd", "cwd": "${workspaceFolder:wolfBoot}", - "executable": "${workspaceFolder:wolfBoot}/build-linux-stm32l4/wolfboot.elf", + "executable": "${workspaceFolder:wolfBoot}/build-stm32l4/wolfboot.elf", "device": "STM32L475VG", "configFiles": [ "interface/stlink-dap.cfg", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index f20b19f787..7f6bf44fed 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -2,22 +2,22 @@ "version": "2.0.0", "tasks": [ { - "label": "CMake: Configure (linux-stm32l4)", + "label": "CMake: Configure (stm32l4)", "command": "cmake", - "args": [ "--preset", "linux-stm32l4" ], + "args": [ "--preset", "stm32l4" ], "options": { "cwd": "${workspaceFolder:wolfBoot}" }, "problemMatcher": [] }, { - "label": "CMake: Build (linux-stm32l4)", + "label": "CMake: Build (stm32l4)", "command": "cmake", - "args": [ "--build", "--preset", "linux-stm32l4" ], + "args": [ "--build", "--preset", "stm32l4" ], "options": { "cwd": "${workspaceFolder:wolfBoot}" }, "group": "build", "problemMatcher": "$gcc" }, { - "label": "OpenOCD: Flash wolfBoot (linux-stm32l4)", + "label": "OpenOCD: Flash wolfBoot (stm32l4)", "type": "shell", "command": "openocd", "args": [ @@ -26,7 +26,7 @@ "-f", "target/stm32l4x.cfg", "-c", - "program ${workspaceFolder:wolfBoot}/build-linux-stm32l4/wolfboot.elf verify reset exit" + "program ${workspaceFolder:wolfBoot}/build-stm32l4/wolfboot.elf verify reset exit" ], "options": { "cwd": "${workspaceFolder:wolfBoot}" }, "problemMatcher": [] diff --git a/CMakeLists.txt b/CMakeLists.txt index 9aaa14ced3..c3511f0f6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,10 +32,9 @@ cmake_minimum_required(VERSION 3.16) include(cmake/config_defaults.cmake) - -# ------------------------------------------------------------------------------ +#--------------------------------------------------------------------------------------------- # Initial environment checks -# ------------------------------------------------------------------------------ +#--------------------------------------------------------------------------------------------- if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") message( FATAL_ERROR @@ -57,28 +56,55 @@ if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) endif() -# ------------------------------------------------------------------------------ -# ------------------------------------------------------------------------------ +#--------------------------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- project(wolfBoot) -# ------------------------------------------------------------------------------ -# ------------------------------------------------------------------------------ +#--------------------------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- include(cmake/functions.cmake) +include(cmake/utils.cmake) -# include(cmake/cube_ide_config.cmake) +# Windows users may prefer VisualGDB +if(DETECT_VISUALGDB) + message(STATUS "VisualGDB detection active: cmake/visualgdb_config.cmake") + include(cmake/visualgdb_config.cmake) +endif() # Some OS-specific checks and configs -if(CMAKE_HOST_WIN32) +if(CMAKE_HOST_WIN32 AND DETECT_VS2022 AND NOT FOUND_HAL_BASE) + message(STATUS "Visual Studio 2022 detection active: make/vs2022_config.cmakee") include(cmake/vs2022_config.cmake) endif() -if(WOLFBOOT_TARGET STREQUAL "stm32l4" AND NOT FOUND_STM32L4_LIB) - include(cmake/stm32_hal_download.cmake) +# If not VisualGDB, perhaps ST CubeIDE? +if(DETECT_CUBEIDE AND NOT FOUND_HAL_BASE) + include(cmake/cube_ide_config.cmake) endif() +# If still not found, download: +if(NOT FOUND_HAL_BASE AND ENABLE_HAL_DOWNLOAD) + if(WOLFBOOT_TARGET MATCHES "^stm32") + include(cmake/stm32_hal_download.cmake) + else() + message(STATUS "WARNING: HAL not found and download not available for ${WOLFBOOT_TARGET}") + endif() +endif() -# set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES "" CACHE STRING "" FORCE) +if(USE_DOT_CONFIG) + message(STATUS "USE_DOT_CONFIG is enabled") + include(cmake/load_dot_config.cmake) +else() + message(STATUS "No .config files will be read; USE_DOT_CONFIG is disabled") +endif() -# ---- Host compiler (for native tools only) ----------------------------------- +# Edit to stop CMake from appending any "standard" C include paths that it thinks your toolchain/platform needs +# Brute force, not recommended, ymmv. +if(false) + set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES "" CACHE STRING "" FORCE) +endif() + +#------------------- Host compiler (for native tools only) ----------------------------------- +#--------------------------------------------------------------------------------------------- # Build-time tools (bin-assemble/sign/keygen) must compile for the HOST. if (CMAKE_HOST_WIN32) # Prefer gcc/clang on Windows so POSIX-y headers (unistd.h) are available. @@ -135,9 +161,9 @@ endif() message(STATUS "Host CC: ${HOST_CC}") message(STATUS "Host compiler treated as MSVC: ${HOST_IS_MSVC}") -# ------------------------------------------------------------------------------ +#--------------------------------------------------------------------------------------------- # Common includes/defines for host tools -# ------------------------------------------------------------------------------ +#--------------------------------------------------------------------------------------------- set(HOST_INCLUDES ${HOST_I}${CMAKE_SOURCE_DIR}/tools/keytools ${HOST_I}${CMAKE_SOURCE_DIR}/lib/wolfssl @@ -194,13 +220,10 @@ if(CMAKE_HOST_WIN32 AND HOST_IS_MSVC) list(INSERT HOST_INCLUDES 0 ${HOST_I}$) endif() # Windows Host Shim - -include(cmake/load_dot_config.cmake) -include(cmake/utils.cmake) - include_directories(include) include_directories(lib/wolfssl) +# TODO if(false) # my Windows # Cross toolchain basics @@ -418,9 +441,10 @@ if(0) add_custom_target(binAssemble DEPENDS "${BINASSEMBLE}") - # ----------------------------------------------------------------------------- + #----------------------------------------------------------------------------------------- # Toolchain Specifications - # ----------------------------------------------------------------------------- + #----------------------------------------------------------------------------------------- + if(ARCH STREQUAL "ARM") include(cmake/toolchain_arm-none-eabi.cmake) @@ -826,9 +850,9 @@ list(APPEND WOLFBOOT_SOURCES ${UPDATE_SOURCES}) list(TRANSFORM WOLFBOOT_SOURCES PREPEND ${WOLFBOOT_ROOT}/) -# ----------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- # Hash settings -# ----------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- if(HASH STREQUAL "SHA256") list(APPEND WOLFBOOT_DEFS WOLFBOOT_HASH_SHA256) message(STATUS "Using SHA256 hash") @@ -844,9 +868,9 @@ if(HASH STREQUAL "SHA3") list(APPEND KEYTOOL_OPTIONS --sha3) endif() -# ----------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- # wolfboot HAL -# ----------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------------- # Default SPI driver name set(SPI_TARGET ${WOLFBOOT_TARGET}) @@ -914,40 +938,11 @@ target_sources(wolfboothal PRIVATE include/hal.h hal/${WOLFBOOT_TARGET}.c ${WOLF ${PARTITION_SOURCE}) +#--------------------------------------------------------------------------------------------- # --- HAL for STM32L4 (only the pieces we need) --- +#--------------------------------------------------------------------------------------------- # TODO move this to preset and/or cmake dir if(WOLFBOOT_TARGET STREQUAL "stm32l4") - if(CMAKE_HOST_WIN32 AND IS_DIRECTORY "${LIB_STM32L4_WINDOWS}" ) - message(STATUS "Win32 Path found: ${LIB_STM32L4_WINDOWS}") - set(HAL_BASE "${LIB_STM32L4_WINDOWS}") - elseif(IS_DIRECTORY "${LIB_STM32L4_WSL}") - message(STATUS "WSL Path found: ${LIB_STM32L4_WSL}") - set(HAL_BASE "${LIB_STM32L4_WSL}") - endif() - - # HAL_BASE "C:/Users/${CURRENT_USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx" - # -#1> [CMake] -- Found directory: C:/Users/gojimmypi/STM32Cube/Repository/STM32Cube_FW_L4_V1.18.0/Drivers/STM32L4xx_HAL_Driver (set HAL_DRV) -#1> [CMake] -- Directory not found: C:/Users/gojimmypi/STM32Cube/Repository/STM32Cube_FW_L4_V1.18.0/CMSIS_HAL/Device/ST/STM32L4xx/Include (set HAL_CMSIS_DEV) -#1> [CMake] -- Directory not found: C:/Users/gojimmypi/STM32Cube/Repository/STM32Cube_FW_L4_V1.18.0/CMSIS_HAL/Include (set HAL_CMSIS_CORE) -#1> [CMake] -- Found directory: C:/Users/gojimmypi/STM32Cube/Repository/STM32Cube_FW_L4_V1.18.0/Projects/B-L475E-IOT01A/Templates/Inc (set HAL_TEMPLATE_INC) -#1> [CMake] -- HAL_DRV=C:/Users/gojimmypi/STM32Cube/Repository/STM32Cube_FW_L4_V1.18.0/Drivers/STM32L4xx_HAL_Driver - if(NOT HAL_BASE STREQUAL "") - if(false) - # VisualGDB - set_and_echo_dir(HAL_DRV "${HAL_BASE}/Drivers/STM32L4xx_HAL_Driver") - set_and_echo_dir(HAL_CMSIS_DEV "${HAL_BASE}/CMSIS_HAL/Device/ST/STM32L4xx/Include") - set_and_echo_dir(HAL_CMSIS_CORE "${HAL_BASE}/CMSIS_HAL/Include") - set_and_echo_dir(HAL_TEMPLATE_INC "${HAL_BASE}/VendorSamples/L4/Projects/B-L475E-IOT01A/Templates/Inc") - else() - # CubeIDE - # set_and_echo_dir(HAL_DRV "${HAL_BASE}/Drivers/STM32L4xx_HAL_Driver") - # set_and_echo_dir(HAL_CMSIS_DEV "${HAL_BASE}/Drivers/CMSIS/Device/ST/STM32L4xx/Include") - # set_and_echo_dir(HAL_CMSIS_CORE "${HAL_BASE}/Drivers/CMSIS/Include") - # set_and_echo_dir(HAL_TEMPLATE_INC "${HAL_BASE}/Projects/B-L475E-IOT01A/Templates/Inc") - endif() - endif() - message(STATUS "HAL_DRV=${HAL_DRV}") add_library(stm32l4_hal STATIC ${HAL_DRV}/Src/stm32l4xx_hal.c diff --git a/CMakePresets.json b/CMakePresets.json index 573488a460..3d9b2986e2 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -12,63 +12,34 @@ "binaryDir": "${sourceDir}/build-${presetName}" }, { - "name": "_template-os-target", + "name": "stm32", + "hidden": true, + "cacheVariables": { + "ST_CMSIS_CORE_TAG": "5.9.0" + } + }, + { + "name": "_template-target", "displayName": "_sample - target - template", "hidden": true, "generator": "Ninja", - "binaryDir": "${sourceDir}/build-windows-stm32l4", + "binaryDir": "${sourceDir}/build-template", "environment": { "PATH": "$penv{LOCALAPPDATA}/Microsoft/WinGet/Links;C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/14.2 rel1/bin;$penv{PATH}" }, "cacheVariables": { "ENV_REMINDER": "use env for cache, penv elsewhere", - "TARGET_OS": "WINDOWS", "WOLFBOOT_CONFIG_MODE": "preset", "VISUALGDB": "ON", "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", "WOLFBOOT_TARGET": "stm32l4" } }, - { - "name": "windows-stm32h7", - "displayName": "Windows ARM (STM32H7)", - "generator": "Ninja", - "cacheVariables": { - "TARGET_OS": "WINDOWS", - "WOLFBOOT_CONFIG_MODE": "preset", - "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", - "WOLFBOOT_TARGET": "stm32h7", - "BUILD_TEST_APPS": "yes", - "ARCH": "ARM", - "SIGN": "ECC256", - "HASH": "SHA256", - "DEBUG": "OFF", - "DEBUG_UART": "OFF", - "VTOR": "ON", - "NO_ASM": "OFF", - "EXT_FLASH": "OFF", - "SPI_FLASH": "OFF", - "QSPI_FLASH": "OFF", - "OCTOSPI_FLASH": "OFF", - "ALLOW_DOWNGRADE": "OFF", - "NVM_FLASH_WRITEONCE": "OFF", - "WOLFBOOT_VERSION": "ON", - "V": "OFF", - "SPMATH": "ON", - "RAM_CODE": "OFF", - "DUALBANK_SWAP": "OFF", - "WOLFBOOT_PARTITION_SIZE": "0xD0000", - "WOLFBOOT_SECTOR_SIZE": "0x20000", - "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x8020000", - "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x80F0000", - "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x81C0000" - } - }, { "name": "vs-debug-trace", "displayName": "VS Debug Trace (STM32H7)", "inherits": [ - "linux-stm32h7" + "stm32h7" ], "binaryDir": "${sourceDir}/out/build/${presetName}", "cacheVariables": { @@ -79,15 +50,21 @@ } }, { - "name": "linux-stm32h7", - "inherits": [ "base" ], - "displayName": "Linux/WSL ARM (stm32h7)", + "name": "stm32h7", + "displayName": "STM32H7", + "inherits": [ + "base", + "stm32" + ], "generator": "Ninja", "cacheVariables": { - "TARGET_OS": "LINUX", "WOLFBOOT_CONFIG_MODE": "preset", - "ARCH": "ARM", + "ST_HAL_TAG": "v1.10.6", + "ST_CMSIS_TAG": "v1.7.4", + "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", "WOLFBOOT_TARGET": "stm32h7", + "BUILD_TEST_APPS": "yes", + "ARCH": "ARM", "SIGN": "ECC256", "HASH": "SHA256", "DEBUG": "OFF", @@ -109,22 +86,21 @@ "WOLFBOOT_SECTOR_SIZE": "0x20000", "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x8020000", "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x80F0000", - "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x81C0000", - "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", - "BUILD_TEST_APPS": "ON" + "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x81C0000" } }, { - "name": "linux-stm32l4", - "inherits": [ "base" ], - "displayName": "Linux/WSL ARM (stm32l4)", + "name": "stm32l4", + "displayName": "STM32L4", + "inherits": [ + "base", + "stm32" + ], "generator": "Ninja", + "binaryDir": "${sourceDir}/build-stm32l4", "cacheVariables": { - "TARGET_OS": "LINUX", + "WOLFBOOT_DOWNLOADS_CMAKE": "${sourceDir}/cmake/downloads/stm32l4.cmake", "WOLFBOOT_CONFIG_MODE": "preset", - "VISUALGDB": "ON", - "VISUALGDB_BASE": "/mnt/c/Users/$penv{USERNAME}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx", - "CMAKE_C_STANDARD_INCLUDE_DIRECTORIES": "/mnt/c/Users/$penv{USERNAME}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/VendorSamples/L4/Projects/B-L475E-IOT01A/Templates/Inc", "WOLFBOOT_TARGET": "stm32l4", "STM32L4_PART": "STM32L475xx", "BOARD": "B-L475E-IOT01A", @@ -156,23 +132,26 @@ } }, { - "name": "mac-stm32l4", - "displayName": "macOS ARM (STM32L4)", - "inherits": [ "base" ], + "name": "stm32c0", + "displayName": "STM32C0", + "inherits": [ + "base", + "stm32" + ], "generator": "Ninja", - "binaryDir": "${sourceDir}/build-mac-stm32l4", + "binaryDir": "${sourceDir}/build-stm32c0", "cacheVariables": { - "WOLFBOOT_CONFIG_MODE": "preset", - "WOLFBOOT_TARGET": "stm32l4", - "STM32L4_PART": "STM32L475xx", - "BOARD": "B-L475E-IOT01A", + "ST_HAL_TAG": "v1.4.0", + "ST_CMSIS_TAG": "v1.3.0", "ARCH": "ARM", - "SIGN": "ECC256", + "WOLFBOOT_TARGET": "stm32c0", + "SIGN": "ED25519", "HASH": "SHA256", "DEBUG": "OFF", "VTOR": "ON", - "CORTEX_M0": "OFF", + "CORTEX_M0": "ON", "NO_ASM": "OFF", + "NO_MPU": "ON", "EXT_FLASH": "OFF", "SPI_FLASH": "OFF", "ALLOW_DOWNGRADE": "OFF", @@ -180,86 +159,55 @@ "WOLFBOOT_VERSION": "OFF", "V": "OFF", "SPMATH": "ON", - "RAM_CODE": "OFF", "DUALBANK_SWAP": "OFF", - "IMAGE_HEADER_SIZE": "256", - "WOLFBOOT_SECTOR_SIZE": "0x1000", - "WOLFBOOT_PARTITION_SIZE": "0x7A000", - "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x0800A000", - "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x08084000", - "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x080FE000", - "WOLFTPM": "OFF", + "RAM_CODE": "OFF", + "WOLFBOOT_PARTITION_SIZE": "0x2000", + "WOLFBOOT_SECTOR_SIZE": "0x800", + "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x08002800", + "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x08005000", + "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x08007800", "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", - "BUILD_TEST_APPS": "ON" + "BUILD_TEST_APPS": "ON", + "WOLFBOOT_CONFIG_MODE": "preset" } }, { - "name": "stm32l4", - "displayName": "STM32L4", - "inherits": [ "base" ], + "name": "stm32f1", + "displayName": "Linux/WSL ARM (stm32f1)", "generator": "Ninja", - "binaryDir": "${sourceDir}/build-stm32l4", + "binaryDir": "${sourceDir}/build-stm32f1", "cacheVariables": { - "WOLFBOOT_CONFIG_MODE": "preset", - "WOLFBOOT_TARGET": "stm32l4", - "STM32L4_PART": "STM32L475xx", - "BOARD": "B-L475E-IOT01A", "ARCH": "ARM", - "SIGN": "ECC256", + "WOLFBOOT_TARGET": "stm32f1", + "SIGN": "ED25519", "HASH": "SHA256", - "DEBUG": "OFF", - "VTOR": "ON", - "CORTEX_M0": "OFF", - "NO_ASM": "OFF", - "EXT_FLASH": "OFF", - "SPI_FLASH": "OFF", - "ALLOW_DOWNGRADE": "OFF", - "NVM_FLASH_WRITEONCE": "ON", - "WOLFBOOT_VERSION": "OFF", - "V": "OFF", + "VTOR": "OFF", "SPMATH": "ON", - "RAM_CODE": "OFF", - "DUALBANK_SWAP": "OFF", - "IMAGE_HEADER_SIZE": "256", - "WOLFBOOT_SECTOR_SIZE": "0x1000", - "WOLFBOOT_PARTITION_SIZE": "0x7A000", - "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x0800A000", - "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x08084000", - "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x080FE000", - "WOLFTPM": "OFF", + "DISABLE_BACKUP": "OFF", + "NVM_FLASH_WRITEONCE": "ON", + "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x08003000", + "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x08009400", + "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x0800F800", + "WOLFBOOT_PARTITION_SIZE": "0x6400", + "WOLFBOOT_SECTOR_SIZE": "0x400", "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", - "BUILD_TEST_APPS": "ON" + "BUILD_TEST_APPS": "ON", + "WOLFBOOT_CONFIG_MODE": "preset" } }, { - "name": "windows-stm32l4", - "inherits": [ "base" ], - "displayName": "Windows - STM32L4 - Ninja", + "name": "stm32g0", + "displayName": "stm32g0", "generator": "Ninja", - "binaryDir": "${sourceDir}/build-windows-stm32l4", - "environment": { - "WindowsSdkDir": "C:/Program Files (x86)/Windows Kits/10", - "WindowsSdkVer": "10.0.26100.0", - "VCToolsInstallDir_DISABLED": "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/MSVC/14.44.35207", - "INCLUDE_DISABLED": "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/MSVC/14.44.35207/include;C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/ucrt;C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/um;C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/shared;$penv{INCLUDE}", - "LIB_DISABLED": "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/MSVC/14.44.35207/lib/x64;C:/Program Files (x86)/Windows Kits/10/Lib/10.0.26100.0/ucrt/x64;C:/Program Files (x86)/Windows Kits/10/Lib/10.0.26100.0/um/x64;$penv{LIB}", - "PATH": "$penv{LOCALAPPDATA}/Microsoft/WinGet/Links;C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/14.2 rel1/bin;$penv{PATH}" - }, + "binaryDir": "${sourceDir}/build-stm32g0", "cacheVariables": { - "TARGET_OS": "WINDOWS", - "WOLFBOOT_CONFIG_MODE": "preset", - "VISUALGDB": "ON", - "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", - "CMAKE_C_STANDARD_INCLUDE_DIRECTORIES": "c:/Users/$penv{USERNAME}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/VendorSamples/L4/Projects/B-L475E-IOT01A/Templates/Inc", - "WOLFBOOT_TARGET": "stm32l4", - "STM32L4_PART": "STM32L475xx", - "BOARD": "B-L475E-IOT01A", "ARCH": "ARM", - "SIGN": "ECC256", + "WOLFBOOT_TARGET": "stm32g0", + "SIGN": "ED25519", "HASH": "SHA256", "DEBUG": "OFF", "VTOR": "ON", - "CORTEX_M0": "OFF", + "CORTEX_M0": "ON", "NO_ASM": "OFF", "EXT_FLASH": "OFF", "SPI_FLASH": "OFF", @@ -268,16 +216,16 @@ "WOLFBOOT_VERSION": "OFF", "V": "OFF", "SPMATH": "ON", - "RAM_CODE": "OFF", + "RAM_CODE": "ON", "DUALBANK_SWAP": "OFF", - "IMAGE_HEADER_SIZE": "256", - "WOLFBOOT_SECTOR_SIZE": "0x1000", - "WOLFBOOT_PARTITION_SIZE": "0x7A000", - "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x0800A000", - "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x08084000", - "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x080FE000", - "WOLFTPM": "OFF", - "BUILD_TEST_APPS": "ON" + "WOLFBOOT_PARTITION_SIZE": "0xB000", + "WOLFBOOT_SECTOR_SIZE": "0x800", + "WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x08008000", + "WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x08013000", + "WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x0801E000", + "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", + "BUILD_TEST_APPS": "ON", + "WOLFBOOT_CONFIG_MODE": "preset" } } ], @@ -287,49 +235,54 @@ "configurePreset": "vs-debug-trace", "jobs": 4, "verbose": true, - "targets": [ "all" ] - }, - { - "name": "linux-stm32h7", - "configurePreset": "linux-stm32h7", - "jobs": 4, - "verbose": true, - "targets": [ "all" ] + "targets": [ + "all" + ] }, { - "name": "linux-stm32l4", - "configurePreset": "linux-stm32l4", + "name": "stm32c0", + "configurePreset": "stm32c0", "jobs": 4, "verbose": true, - "targets": [ "all" ] + "targets": [ + "all" + ] }, { - "name": "windows-stm32h7", - "configurePreset": "windows-stm32h7", + "name": "stm32f1", + "configurePreset": "stm32f1", "jobs": 4, "verbose": true, - "targets": [ "all" ] + "targets": [ + "all" + ] }, { - "name": "windows-stm32l4", - "configurePreset": "windows-stm32l4", + "name": "stm32g0", + "configurePreset": "stm32g0", "jobs": 4, "verbose": true, - "targets": [ "all" ] + "targets": [ + "all" + ] }, { - "name": "mac-stm32l4", - "configurePreset": "mac-stm32l4", + "name": "stm32h7", + "configurePreset": "stm32h7", "jobs": 4, "verbose": true, - "targets": [ "all" ] + "targets": [ + "all" + ] }, { "name": "stm32l4", "configurePreset": "stm32l4", "jobs": 4, "verbose": true, - "targets": [ "all" ] + "targets": [ + "all" + ] } ] } diff --git a/IDE/VSCode/.vscode/launch.json b/IDE/VSCode/.vscode/launch.json deleted file mode 100644 index 9126709f05..0000000000 --- a/IDE/VSCode/.vscode/launch.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": "STM32L4 - OpenOCD", - "type": "cortex-debug", - "request": "launch", - "servertype": "openocd", - "cwd": "${workspaceFolder:wolfBoot}", - "executable": "${workspaceFolder:wolfBoot}/build-linux-stm32l4/wolfboot.elf", - "device": "STM32L475VG", - "configFiles": [ - "interface/stlink-dap.cfg", - "target/stm32l4x.cfg" - ], - "runToMain": true, - "svdFile": "${workspaceFolder:wolfBoot}/hal/stm32l4/STM32L4x.svd", - "preLaunchTask": "CMake: Build (linux-stm32l4)" - } - ] -} diff --git a/IDE/VSCode/.vscode/settings.json b/IDE/VSCode/.vscode/settings.json deleted file mode 100644 index 74419f2aa0..0000000000 --- a/IDE/VSCode/.vscode/settings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "cmake.useCMakePresets": "always", - "cmake.buildDirectory": "${workspaceFolder}/build-${buildPresetName}", - "cmake.configureOnOpen": true, - "cmake.generator": "Ninja", - "cmake.loggingLevel": "info", - "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", - "files.encoding": "utf8", - "files.eol": "\n" -} diff --git a/IDE/VSCode/.vscode/tasks.json b/IDE/VSCode/.vscode/tasks.json deleted file mode 100644 index 65aff45aec..0000000000 --- a/IDE/VSCode/.vscode/tasks.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "CMake: Configure (linux-stm32l4)", - "command": "cmake", - "args": [ "--preset", "linux-stm32l4" ], - "options": { "cwd": "${workspaceFolder:wolfBoot}" }, - "problemMatcher": [] - }, - { - "label": "CMake: Build (linux-stm32l4)", - "command": "cmake", - "args": [ "--build", "--preset", "linux-stm32l4" ], - "options": { "cwd": "${workspaceFolder:wolfBoot}" }, - "group": "build", - "problemMatcher": "$gcc" - }, - { - "label": "OpenOCD: Flash wolfBoot (linux-stm32l4)", - "type": "shell", - "command": "openocd", - "args": [ - "-f", - "interface/stlink-dap.cfg", - "-f", - "target/stm32l4x.cfg", - "-c", - "program ${workspaceFolder:wolfBoot}/build-linux-stm32l4/wolfboot.elf verify reset exit" - ], - "options": { "cwd": "${workspaceFolder:wolfBoot}" }, - "problemMatcher": [] - } - ] -} diff --git a/IDE/VSCode/README.md b/IDE/VSCode/README.md index 5123cd5a63..8dcbe0bdc9 100644 --- a/IDE/VSCode/README.md +++ b/IDE/VSCode/README.md @@ -1,2 +1,71 @@ -# VS Code wolfBoot Project +# VS Code wolfBoot Project +CMake presets are support in VS Code. See also details in the [cmake/README.md](../../cmake/README). + +Open the `WOLFBOOT_ROOT`[wolfBoot.code-workspace](../../wolfBoot.code-workspace) in VSCode. + +For example, select `STM32L4` wait for CMake to finish, then click `build`. The `output` pane might be not visible. Grab frame to expand up: + +image

+ +## Additional Settings + +See the [cmake/config_defaults.cmake](../../cmake/config_defaults.cmake) file. Of particular interest +are some environment configuration settings: + +```cmake +# Environments are detected in this order: +set(DETECT_VISUALGDB true) +set(DETECT_CUBEIDE true) +set(DETECT_VS2022 true) + +# Enable HAL download only implemented for TMS devices at this time. +# See [WOLFBOOT_ROOT]/cmake/stm32_hal_download.cmake +# and [WOLFBOOT_ROOT]/cmake/downloads/stm32_hal_download.cmake +set(ENABLE_HAL_DOWNLOAD true) +set(FOUND_HAL_BASE false) + +# optionally use .config files; See CMakePresets.json instead +set(USE_DOT_CONFIG false) +``` + +## Requirements + +### VS Code extensions + +- CMake Tools (ms-vscode.cmake-tools) +- C/C++ (ms-vscode.cpptools) +- Cortex-Debug (marus25.cortex-debug) + +### Build tools + +#### WSL path: + +cmake, ninja-build, gcc-arm-none-eabi, openocd + +#### Windows path: + +Windows path: CMake, Ninja, Arm GNU Toolchain, OpenOCD (or ST’s OpenOCD) + +Install via PowerShell (will need to restart VSCode): + +```ps +winget install --id Ninja-build.Ninja -e + + +# winget install -e --id Arm.GnuArmEmbeddedToolchain + +winget install -e --id Arm.GnuArmEmbeddedToolchain --override "/S /D=C:\Tools\arm-gnu-toolchain-14.2.rel1" +# reopen VS / terminal so PATH refreshes + +# Confirm +ninja --version + +Get-Command arm-none-eabi-gcc +``` + +If already installed, uninstall: + +``` +winget uninstall -e --id Arm.GnuArmEmbeddedToolchain +``` diff --git a/IDE/VisualGDB/README.md b/IDE/VisualGDB/README.md index 053bc49b17..7c0cf4bdbe 100644 --- a/IDE/VisualGDB/README.md +++ b/IDE/VisualGDB/README.md @@ -1,6 +1,23 @@ -# VisualGDB SDK wolfBoot Project +# VisualGDB SDK wolfBoot Project +See the [cmake/config_defaults.cmake](../../cmake/config_defaults.cmake) file. Of particular interest +are some environment configuration settings, in particular the `DETECT_VISUALGDB`: +```cmake +# Environments are detected in this order: +set(DETECT_VISUALGDB true) +set(DETECT_CUBEIDE true) +set(DETECT_VS2022 true) + +# Enable HAL download only implemented for TMS devices at this time. +# See [WOLFBOOT_ROOT]/cmake/stm32_hal_download.cmake +# and [WOLFBOOT_ROOT]/cmake/downloads/stm32_hal_download.cmake +set(ENABLE_HAL_DOWNLOAD true) +set(FOUND_HAL_BASE false) + +# optionally use .config files; See CMakePresets.json instead +set(USE_DOT_CONFIG false) +``` ## Required include files diff --git a/IDE/VisualStudio/README.md b/IDE/VisualStudio/README.md new file mode 100644 index 0000000000..5d7f7f5364 --- /dev/null +++ b/IDE/VisualStudio/README.md @@ -0,0 +1,44 @@ +# wolfboot Visual Studio + +Users of Visual Studio can open the `WOLFBOOT_ROOT` directory without the need for a project file. + +Visual Studio is "cmake-aware" and recognizes the [CMakePresets.json](../../CMakePresets.json) + +Select a device from the ribbon bar, shown here for the `stm32l4` + +image

+ + +From `Solution Explorer`, right-click `CmakeLists.txt` and then select `Configure wolfBoot`. + +image

+ +To build, follow the same steps to right click, and select `Build`. + +View the CMake and Build messages in the `Output` Window. Noter the dropdown to select view: + +image

+ +## Additional Configuration Defaults + +See the [cmake/config_defaults.cmake](../../cmake/config_defaults.cmake) file. Of particular interest +are some environment configuration settings, in particular the `DETECT_VISUALGDB`: + +```cmake +# Environments are detected in this order: +set(DETECT_VISUALGDB true) +set(DETECT_CUBEIDE true) +set(DETECT_VS2022 true) + +# Enable HAL download only implemented for TMS devices at this time. +# See [WOLFBOOT_ROOT]/cmake/stm32_hal_download.cmake +# and [WOLFBOOT_ROOT]/cmake/downloads/stm32_hal_download.cmake +set(ENABLE_HAL_DOWNLOAD true) +set(FOUND_HAL_BASE false) + +# optionally use .config files; See CMakePresets.json instead +set(USE_DOT_CONFIG false) +``` + + +For more details, see the [cmake/README](../../cmake/README.md) file. diff --git a/IDE/Windows/README.md b/IDE/Windows/README.md new file mode 100644 index 0000000000..0174e100d5 --- /dev/null +++ b/IDE/Windows/README.md @@ -0,0 +1,29 @@ +# wolfboot for Windows + +A variety of Windows-based solutions exist. Here are notes for a no-IDE build on Windows from a DOS prompt. + +See also: + +- [VS Code](../VSCode/README.md) +- [Visual Studio](../VisualStudio/README.md) + +# Example + +See the [WOLFBOOT_ROOT/tools/scripts/cmake_test.bat](../../tools/scripts/cmake_test.bat) using cmake: + +```dos +rmdir /s /q build-stm32l4 + +cmake --preset stm32l4 +cmake --build --preset stm32l4 +``` + +## Troubleshooting + +This error is typically caused by anti-virus software locking a file during build. + +Consider excluding the build directory or executable from anti-virus scan. + +```test +build-stm32l4\bin-assemble.exe - The process cannot access the file because it is being used by another process. +``` diff --git a/README.md b/README.md index 52c70c7f28..3f2e76c5b3 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,38 @@ -# wolfBoot +# wolfBoot -CMake Dev Status: +Some interim notes on progress in various environments: + +## CMake Dev Status: |Status | Environment | Test With |-------| ------------------------- | -------- | ✅ | VS 2022 | Right-Click on [CMakeLists.txt](./CMakeLists.txt), Build -| ✅ | WSL | [./my_test.sh](./my_test.sh) -| ⚠️ | Mac | [test-build-cmake-mac.yml](./github/workflows/test-build-cmake-mac.yml) +| ✅ | WSL | [./tools/scripts/cmake_test.sh](./tools/scripts/cmake_test.sh) +| ✅ | Mac | [test-build-cmake-mac.yml](./github/workflows/test-build-cmake-mac.yml) | ✅ | VS Code, Dev Prompt | Click "build" on bottom toolbar ribbon -| ✅ | DOS Prompt, Dev Prompt | [my_test.bat](./my_test.bat) -| ✅ | PowerShell, Dev Prompt | [.\my_test.bat](./my_test.bat) -| ❌ | DOS Prompt, direct launch | [my_test.bat](./my_test.bat) -| ❌ | PowerShell, direct launch | [my_test.bat](./my_test.bat) -| ❌ | VS Code, direct launch | Click "build" +| ✅ | DOS Prompt, Dev Prompt | [.\tools\scripts\cmake_dev_prompt_test.bat](./tools/scripts/cmake_dev_prompt_test.bat) +| ✅ | PowerShell, Dev Prompt | [.\tools\scripts\cmake_dev_prompt_test.bat](./tools/scripts/cmake_dev_prompt_test.bat) +| ✅ | DOS Prompt, direct launch | [.\tools\scripts\cmake_test.bat](./tools/scripts/cmake_test.bat) (needs toolchain path) +| ✅ | PowerShell, direct launch | [.\tools\scripts\cmake_test.bat](./tools/scripts/cmake_test.bat) (needs toolchain path) +| ✅ | VS Code, direct launch | Click "build" -Make Dev Status: +## Make Dev Status: |Status | Environment | Test With |-------| ------------------------- | -------- | ? | VS 2022 | N/A (?) -| ✅ | WSL | `./wolfbuild.sh --target stm32l4` +| ✅ | WSL | `./tools/scripts/wolfboot_build.sh --target stm32l4` | ⚠️ | Mac | [test-build-cmake-mac.yml](./github/workflows/test-build-cmake-mac.yml) | ? | VS Code, Dev Prompt | N/A (?) -| ❌ | DOS Prompt, Dev Prompt | +| ❌ | DOS Prompt, Dev Prompt | | ❌ | PowerShell, Dev Prompt | | ❌ | DOS Prompt, direct launch | -| ❌ | PowerShell, direct launch | -| ? | VS Code, direct launch | N/A (?) +| ❌ | PowerShell, direct launch | +| ? | VS Code, direct launch | N/A (?) --- -wolfSSL Secure Bootloader ([Home page](https://www.wolfssl.com/products/wolfboot/)) +wolfSSL Secure Bootloader ([Home page](https://www.wolfssl.com/products/wolfboot/), [Manual](https://www.wolfssl.com/documentation/manuals/wolfboot/), [wolfBoot-examples](https://github.com/wolfSSL/wolfBoot-examples)) wolfBoot is a portable, OS-agnostic, secure bootloader solution for 32-bit microcontrollers, relying on wolfCrypt for firmware authentication, providing firmware update mechanisms. @@ -73,127 +75,7 @@ The bootloader consists of the following components: ### Linux -Ensure the proper toolchain is installed. The default [Makefile](./Makefile) needs at least the `gcc-arm-none-eabi`. - -```bash -sudo apt update -sudo apt install -y build-essential gcc-arm-none-eabi binutils-arm-none-eabi -# optional (often handy): gdb-multiarch or gdb-arm-none-eabi -arm-none-eabi-gcc --version # should print the version -``` - -The device manufacturer toolchain _also_ needs to be installed. For example without the [STM32CubeIDE Software](https://www.st.com/en/development-tools/stm32cubeide.html), -errors like this will otherwise be encountered: - -``` - [CC ARM] hal/stm32l4.o -hal/stm32l4.c:24:10: fatal error: stm32l4xx_hal.h: No such file or directory - 24 | #include "stm32l4xx_hal.h" - | ^~~~~~~~~~~~~~~~~ -``` - -## Quick Start - -```bash -git clone https://github.com/gojimmypi/wolfBoot.git -cd wolfBoot -git submodule update --init - -## Use make -# edit your .config or copy from config/examples -make - -## OR ## - -# use cmake via wolfbuild.sh script: - -./wolfbuild.sh --CLEAN -./wolfbuild.sh --CLEAN stm32h7 -./wolfbuild.sh --target stm32h7 -``` - -### VS Code - -Windows users may need one of these: - -- [Visual Studio 2022](https://visualstudio.microsoft.com/) -- [Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/). See `C:\Program Files(x86)\Windows kits`. - -#### Launch Stand-alone VS Code - -The MSVC kit may be needed if VS 2022 is not installed. - -Select `View` - `Command Palette`, search for CMake: Select a Compiler - -See also: CMake: Delete Cache and Reconfigure - - -#### Launch VS Code from VS 2022 Command prompt. - -Delete any existing `build` or `build-[os]-[target]` directories as needed. - -Open a VS 2022 Developer command prompt. - -From the command prompt, open the `wolfBoot.code-workspace` VS Code workspace: - -```dos -cd c:\workspace\wolfboot-%USERNAME% -code ./IDE/VSCode/wolfBoot.code-workspace -``` - -### Visual Studio IDE - -For the `Select Startup Item`, leave at default. Do not select `image`, wolfboot_name[], etc. - -Right click on `CMakeLists.txt` and select `Delete Cache and Reconfigure`. - -Right click on `CMakeLists.txt` and select `Build`. - -### Visual Studio Command Prompt - -Select `View` - `Terminal` from the menu bar. - -* Configure: `cmake --preset ` -* Build: `cmake --build --preset ` - -```bash -# delete build directory -rmdir /s /q build-windows-stm32l4 - -# configure -cmake --preset windows-stm32l4 - -# build -cmake --build --preset windows-stm32l4 -``` - -If there are no devices listed in the `Manage Configurations` drop-down, ensure the `CMakePresets.json` is valid. -A single json syntax error will spoil the entire project. - -## Your own toolchain - -Create a `CMakeUserPresets.json` (ignored by git, rename `CMakeUserPresets.json.sample` ): - -```json -{ - "version": 3, - "configurePresets": [ - { - "name": "my-arm-bin", - "inherits": "windows-stm32l4", - "cacheVariables": { - "ARM_GCC_BIN": "C:/Tools/arm-none-eabi-14.2/bin" - } - } - ], - "buildPresets": [ - { - "name": "my-arm-bin", - "configurePreset": "my-arm-bin" - } - ] -} -``` +Ensure the proper toolchain is installed. See the [docs](./docs/README.md) for platform-specific details. ## Integrating wolfBoot in an existing project @@ -276,7 +158,57 @@ make keytools make ``` -### CMake +### CMake - Presets + +This section explains how to build wolfBoot using CMake Presets. +Presets let you keep repeatable build settings in a single JSON file ([CMakePresets.json](./CMakePresets.json)) so +you can configure and build with short, memorable commands like: + +``` +cmake --list-presets +cmake --preset stm32l4 +cmake --build --preset stm32l4 +``` + +See the `WOLFBOOT_ROOT`/[config_defaults.cmake](./config_defaults.cmake) file. + +#### Convert existing `.config` to CMake Presets + +The [tools/scripts/config2presets.py](./tools/scripts/config2presets.py) script cam +convert existing [config/examples](./config/examples) to CMake presets. + +For example: + +```python +python3 ./tools/scripts/config2presets.py ./config/examples/stm32h7.config +``` + +#### Tips & Gotchas + +Out-of-source enforced: wolfBoot’s CMakeLists.txt blocks in-source builds; +presets default to `build-${presetName}` anyway. + +Toolchain auto-select: If `WOLFBOOT_TARGET` is not x86_64_efi or sim, +CMAKE_TOOLCHAIN_FILE defaults to `cmake/toolchain_arm-none-eabi.cmake`. + +Windows host tools: When HOST_CC is `cl.exe`, CMakeLists.txt creates a +lightweight `unistd.h` shim and adjusts flags—no manual changes needed. + +`$penv` vs `$env`: Use `$penv{VAR}` in environment to append to the existing +process environment (keeps your PATH). `$env{VAR}` replaces it. + +Visual Studio / VS Code: Both detect presets automatically; +select the preset from the status bar or CMake menu, then build. + +`--fresh`: Re-configure from scratch without deleting the build directory. + +For further details, see the [cmake/README](./cmake/README.md) + +### CMake - Read .config file + +See [cmake/README](./cmake/README.md#build-with-cmake-using-config-files). + +### CMake - Command-line Settings To build using CMake, create a `build` directory and run `cmake` with the target platform as well as values for the partition size and address variables. To build the test-apps, run with `-DBUILD_TEST_APPS=yes`. To use the wolfCrypt-py keytools, run @@ -412,84 +344,6 @@ $ cmake -DWOLFBOOT_TARGET=stm32u5 -DBUILD_TEST_APPS=yes -DWOLFBOOT_PARTITION_BOO $ cmake -DWOLFBOOT_TARGET=stm32l0 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x8000 -DWOLFBOOT_SECTOR_SIZE=0x1000 -DWOLFBOOT_PARTITION_SIZE=0x10000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x18000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x28000 -DNVM_FLASH_WRITEONCE=yes .. ``` -## CMake Logic Flow - - -```mermaid -flowchart TD - %% wolfBoot CMake Build Logic Flow (GitHub-safe) - - %% === Local Dev === - A1["Start in VS 2022 / VS Code"] --> A2["Select CMake preset: windows-stm32l4 or linux-stm32l4"] - A2 --> A3{"Target preset?"} - A3 --> A4["Ensure toolchains on PATH: ARM_GCC_BIN, Ninja"] - A4 --> A5["Run: cmake --preset <name>"] - A5 --> A6["Optional: cmake --build --preset <name>"] - - %% === Configure === - A5 --> C1["Load CMakePresets.json"] - C1 --> C2["Resolve env vars: PATH, ARM_GCC_BIN, VISUALGDB"] - C2 --> C3["Apply cache vars: WOLFBOOT_TARGET, BOARD, addresses"] - C3 --> C4["Load toolchain file: toolchain_arm-none-eabi.cmake"] - C4 --> C5["Generate build system: Ninja"] - - %% === Preset-specific branches === - C5 --> B0(("Begin preset specifics")) - subgraph PS["Preset specifics"] - direction TB - - %% Windows column - subgraph BWIN["Windows: windows-stm32l4"] - direction TB - BW1["Generator: Ninja (VS 2022 or standalone)"] - BW2["Quote paths with spaces (e.g., Program Files)"] - BW3["Set ARM_GCC_BIN to Windows install path"] - BW4["Use VisualGDB include/BSP paths"] - BW5["Artifacts: .bin, .hex; optional .dfu"] - BW6["Flash: ST-Link CLI or STM32CubeProgrammer"] - BW1 --> BW2 --> BW3 --> BW4 --> BW5 --> BW6 - end - - %% Linux column - subgraph BLNX["Linux: linux-stm32l4"] - direction TB - BL1["Generator: Ninja (system package)"] - BL2["ARM_GCC_BIN in /opt or /usr/bin"] - BL3["dfu-util or stlink from package manager"] - BL4["CI-friendly paths: avoid spaces"] - BL5["Artifacts: .bin, .hex, .dfu"] - BL6["Flash: st-flash or dfu-util"] - BL1 --> BL2 --> BL3 --> BL4 --> BL5 --> BL6 - end - end - - B0 --> BW1 - B0 --> BL1 - BW6 --> BZ(("Merge")) - BL6 --> BZ - - %% === Build, Sign, Package === - BZ --> D1["Build host tools: sign, keytools"] - D1 --> D2["Compile wolfBoot core and HAL"] - D2 --> D3["Link bootloader and test apps"] - D3 --> D4["Create image header"] - D4 --> D5["Sign firmware image: ECC256, SHA256"] - D5 --> D6["Package artifacts: bin, hex, dfu"] - - %% === Deploy & CI === - D6 --> E1["Option A: Flash to device (stlink, dfu-util)"] - E1 --> E2["Run smoke tests and UART debug"] - E2 --> E3["Option B: Upload artifacts in GitHub Actions"] - E3 --> E4["CI: set up toolchains and CMake on runners"] - E4 --> E5["CI: matrix build per target preset"] - E5 --> E6["CI: archive results and report status"] - - %% === Errors (dotted refs) === - A5 -.-> X1["Preset not found or Ninja missing"] - C2 -.-> X2["Toolchain not found: fix ARM_GCC_BIN/PATH, verify VisualGDB"] - C3 -.-> X3["Address/partition mismatch: verify BOARD, flash offsets, IMAGE_HEADER_SIZE"] -``` - ## Troubleshooting 1. Python errors when signing a key: @@ -930,7 +784,7 @@ sp_c32.c : fatal error C1083: Cannot open compiler generated file: '... sp_c32.o * RP2350 (Raspberry Pi Pico 2, ARM Cortex-M33 with TrustZone) * NXP MCXA153 * NXP MCXW716 - * STM32F1 series (STM32F103 "Blue Pill"board) + * STM32F1 series (STM32F103 "Blue Pill"board) * Improvements to supported targets * Xilinx UltraScale+ (ZynqMP) * Added hardware-accelerated SHA3 hashing via the CSU engine diff --git a/CMakeUserPresets.json.sample b/cmake/CMakeUserPresets.json.sample similarity index 83% rename from CMakeUserPresets.json.sample rename to cmake/CMakeUserPresets.json.sample index cebe0e42c2..cd71553104 100644 --- a/CMakeUserPresets.json.sample +++ b/cmake/CMakeUserPresets.json.sample @@ -1,18 +1,18 @@ -{ - "version": 3, - "configurePresets": [ - { - "name": "my-arm-bin", - "inherits": "windows-stm32l4", - "cacheVariables": { - "ARM_GCC_BIN": "C:/Tools/arm-none-eabi-14.2/bin" - } - } - ], - "buildPresets": [ - { - "name": "my-arm-bin", - "configurePreset": "my-arm-bin" - } - ] +{ + "version": 3, + "configurePresets": [ + { + "name": "my-arm-bin", + "inherits": "stm32l4", + "cacheVariables": { + "ARM_GCC_BIN": "C:/Tools/arm-none-eabi-14.2/bin" + } + } + ], + "buildPresets": [ + { + "name": "my-arm-bin", + "configurePreset": "my-arm-bin" + } + ] } diff --git a/cmake/README.md b/cmake/README.md new file mode 100644 index 0000000000..015b805a24 --- /dev/null +++ b/cmake/README.md @@ -0,0 +1,514 @@ +# wolfBoot Cmake + +See the local [config_defaults.cmake](./config_defaults.cmake) file. Of particular interest +are some environment configuration settings: + +```cmake +# Environments are detected in this order: +set(DETECT_VISUALGDB true) +set(DETECT_CUBEIDE true) +set(DETECT_VS2022 true) + +# Enable HAL download only implemented for TMS devices at this time. +# See [WOLFBOOT_ROOT]/cmake/stm32_hal_download.cmake +# and [WOLFBOOT_ROOT]/cmake/downloads/stm32_hal_download.cmake +set(ENABLE_HAL_DOWNLOAD true) +set(FOUND_HAL_BASE false) + +# optionally use .config files; See CMakePresets.json instead +set(USE_DOT_CONFIG false) +``` + +## cmake directory overview + +- [../CMakeLists.txt](../CMakeLists.txt) - Top-level CMake entry that configures the wolfBoot build. +Used to initialize the project, include cmake/wolfboot.cmake, set options, and define targets. +This file is where `project()` is declared and where toolchain logic or preset imports begin. + +- [../CMakePresets.json](../CMakePresets.json) - OS-agnostic CMake preset definitions. +Used by `cmake --preset {name}` and `cmake --build --preset {name}` to apply consistent settings. +Centralizes toolchain paths, target names, build directories, and key cache variables such as: +`{ "CMAKE_TOOLCHAIN_FILE": "cmake/toolchain_arm-none-eabi.cmake", "WOLFBOOT_TARGET": "stm32l4" }`. + +- [../CMakeSettings.json](../CMakeSettings.json) - Visual Studio integration file. +Maps Visual Studio configurations (Debug, Release) to existing CMake presets. +Controls IntelliSense, environment variables, and the preset shown in the VS CMake toolbar. + +- [CMakeUserPresets.json.sample](./CMakeUserPresets.json.sample) - Example local overrides for user-specific paths and options. Copy to `CMakeUserPresets.json` in the `WOLFBOOT_ROOT` directory and customize. Not committed. Copy to `WOLFBOOT_ROOT` and remove the `.sample` suffix. + +- [config_defaults.cmake](./config_defaults.cmake) - Default cache values and feature toggles used when presets or .config do not provide them. + +- [cube_ide_config.cmake](./cube_ide_config.cmake) - Optional STM32CubeIDE integration. Maps CubeIDE variables or project layout into CMake context. + +- [current_user.cmake](./current_user.cmake) - Cross-platform detection of the current user for path composition and cache hints. + +- [downloads](./downloads) - Series-specific scripts and docs for fetching STM32 HAL and CMSIS artifacts on demand. + +- [functions.cmake](./functions.cmake) - Reusable helper functions for path checks, argument validation, status output, and small build utilities. + +- [load_dot_config.cmake](./load_dot_config.cmake) - Imports legacy `.config` values from Makefile-based builds into modern CMake cache variables. + +- [stm32_hal_download.cmake](./stm32_hal_download.cmake) - Common download logic used by downloads/stm32*.cmake modules to fetch HAL and CMSIS. + +- [toolchain_aarch64-none-elf.cmake](./toolchain_aarch64-none-elf.cmake) - Bare-metal AArch64 toolchain configuration for 64-bit ARM targets. + +- [toolchain_arm-none-eabi.cmake](./toolchain_arm-none-eabi.cmake) - Main Cortex-M cross toolchain config. Disables try-run, standardizes flags, and sets compilers. + +- [utils.cmake](./utils.cmake) - Lightweight utilities shared by other modules. Path normalization, small helpers, and logging wrappers. + +- [visualgdb_config.cmake](./visualgdb_config.cmake) - VisualGDB quality-of-life settings for Windows builds that use Sysprogs BSPs. + +- [vs2022_config.cmake](./vs2022_config.cmake) - Visual Studio 2022 integration hints. Keeps generator and environment consistent with VS CMake. + +- [wolfboot.cmake](./wolfboot.cmake) - wolfBoot CMake glue: targets, include directories, compile definitions, and link rules. + +- [downloads/README.md](./downloads/README.md) - Notes for the downloads subsystem and expected directory layout. + +- [downloads/stm32l4.cmake](./downloads/stm32l4.cmake) - STM32L4 fetch script for HAL and CMSIS. + +--- + +### Build with cmake using `.config` files + +Presets are preferred, see below. + +To use `.config` files instead of presets, + +```bash +# cd your [WOLFBOOT_ROOT] + +# Backup current config +mv ./.config ./.config.bak + +# Get an example config +cp ./config/examples/stm32h7.config ./.config + +# Call cmake with -DUSE_DOT_CONFIG=ON +cmake -S . -B build-stm32h7 -DUSE_DOT_CONFIG=ON + +# Sample build +cmake --build build-stm32h7 -j +``` + +The output should look contain text like this: + +```text +-- Found a .config file, will parse +-- Config mode: dot (.config cache) +-- Loading config from: /mnt/c/workspace/wolfBoot-gojimmypi +-- Reading config file: /mnt/c/workspace/wolfBoot-gojimmypi/.config +-- -- Parsing lines from config file... +-- -- Found line: ARCH?=ARM +-- -- Parsed key: ARCH +-- -- Parsed op: ? +-- -- Parsed val: ARM +-- -- Assignment: ARCH=ARM +-- -- Found line: TARGET?=stm32h7 +-- -- Parsed key: TARGET +-- -- Parsed op: ? +-- -- Parsed val: stm32h7 +-- -- Assignment: TARGET=stm32h7 +-- -- Found line: SIGN?=ECC256 +-- -- Parsed key: SIGN +-- -- Parsed op: ? +-- -- Parsed val: ECC256 + ...etc... +``` + +Calling `cmake` with an existing `.config` file will default to dot-config mode. + +```bash +ls .config +cmake -S . -B build-stm32h7 +``` + +Specify additional directories, for example the STM32L4: + +```bash +cmake -S . -B build-stm32l4 -DUSE_DOT_CONFIG=ON \ + -DHAL_DRV="${VG_BASE}/Drivers/STM32L4xx_HAL_Driver" \ + -DHAL_CMSIS_DEV="${VG_BASE}/Drivers/CMSIS/Device/ST/STM32L4xx/Include" \ + -DHAL_CMSIS_CORE="${VG_BASE}/Drivers/CMSIS/Include" \ + -DHAL_TEMPLATE_INC="${VG_BASE}/Drivers/STM32L4xx_HAL_Driver/Inc" + +cmake --build build-stm32l4 -j +``` + +### Build presets + +Each configure preset has a matching build preset with jobs=4, verbose=true, and targets=["all"]. + +Example commands: + +```bash +cmake --preset stm32l4 +cmake --build --preset stm32l4 + +cmake --preset stm32h7 +cmake --build --preset stm32h7 +``` + + +From the [docs for CMake Presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html): + +>"Added in version 3.19. +> +>One problem that CMake users often face is sharing settings with other people for common ways to configure +a project. This may be done to support CI builds, or for users who frequently use the same build. CMake +supports two main files, `CMakePresets.json` and `CMakeUserPresets.json`, that allow users to specify common +configure options and share them with others. CMake also supports files included with the include field. +> +>`CMakePresets.json` and` CMakeUserPresets.json` live in the project's root directory. They both have +exactly the same format, and both are optional (though at least one must be present if `--preset` is +specified). `CMakePresets.json` is meant to specify project-wide build details, while `CMakeUserPresets.json` +is meant for developers to specify their own local build details. +> +>CMakePresets.json may be checked into a version control system, and `CMakeUserPresets.json` should NOT be +checked in. For example, if a project is using Git, `CMakePresets.json` may be tracked, and +`CMakeUserPresets.json` should be added to the .gitignore." + +## Troubleshooting + +The wrong toolchain is being used, or a target was not specified + +``` +Error: no such instruction: `isb' +``` + + +## CMake Logic Flow + +Simplified Diagram: + +```mermaid +flowchart TD + +S[Start] --> B0{In-source build?} +B0 -- yes --> BX[FATAL_ERROR no in-source builds] +B0 -- no --> T0{Toolchain file set?} +T0 -- no --> T1{Target set and not x86_64_efi or sim?} +T1 -- yes --> T2[Set toolchain arm-none-eabi] +T1 -- no --> PRJ[project wolfBoot] +T0 -- yes --> PRJ + +PRJ --> CFG{Config source} +CFG -- dot --> C1[load dotconfig] +CFG -- preset --> C2[use presets] +CFG -- neither --> C3[use cache or CLI] + +C1 --> TA +C2 --> TA +C3 --> TA +TA{Target and sector size set?} +TA -- no --> TEe[FATAL_ERROR required vars] +TA -- yes --> AR{Resolve ARCH} + +AR --> PARTQ{Need partition vars} +PARTQ --> PART{not PULL_LINKER_DEFINES and not BUILD_TEST_APPS} +PART -- yes --> PV{All partition vars set} +PV -- no --> PVe[FATAL_ERROR partition vars] +PV -- yes --> OK1[OK] +PART -- no --> OK1 + +OK1 --> HOST[Detect host compiler and flags] +HOST --> TOOLS[Build sign keygen bin-assemble] +TOOLS --> X0{Cross compiler set} +X0 -- no --> XSEL{ARCH} +XSEL -- ARM --> XARM[include ARM toolchain] +XSEL -- AARCH64 --> XA64[include AARCH64 toolchain] +XSEL -- x86_64 or sim --> XNONE[no cross include] +X0 -- yes --> XNONE + +XNONE --> A0{ARCH specifics} +A0 -- ARM --> A1[boot_arm freestanding stm32 tweaks] +A0 -- x86_64 --> A2[boot_x86_64] +A0 -- AARCH64 --> A3[aarch64 sources and defs] + +A0 --> EFIQ{Target is x86_64_efi} +EFIQ -- yes --> EFI[GNU EFI settings update via RAM] +EFIQ -- no --> UDF[Default update via flash] + +UDF --> SIGN{SIGN algorithm} +EFI --> SIGN +SIGN --> S1[Apply sign options header size stack] +S1 --> FEAT{Feature flags} +FEAT --> FLASH[EXT SPI QSPI UART] +FEAT --> ENC[AES128 AES256 CHACHA] +FEAT --> MISC[ALLOW_DOWNGRADE NO_MPU FLAGS_HOME FLAGS_INVERT] +FEAT --> DELTA[DELTA_UPDATES optional] +FEAT --> ARMOR[ARMORED optional] + +ARMOR --> HASH{HASH} +DELTA --> HASH +MISC --> HASH +ENC --> HASH +FLASH --> HASH +HASH --> H1[Add hash defs and keytool flags] + +H1 --> HAL[Select SPI UART drivers DEBUG_UART] +HAL --> MATH{Math options} +MATH --> LIBS[Build user_settings wolfboothal wolfcrypt] +LIBS --> IMG{Build image or tests} +IMG -- yes --> TAPP[add test app] +IMG -- no --> VARS[configure target header cache vars] +TAPP --> VARS +VARS --> KEY{SIGN not none} +KEY -- yes --> KEYGEN[keystore and public key] +KEY -- no --> WL +KEYGEN --> WL +WL[Build wolfboot and link] --> DONE[Done] + +``` + +---- + +In more detail: + +```mermaid +flowchart TD + %% wolfBoot CMake Build Logic Flow (conservative syntax for VS 2022) + + %% ================================ + %% 0) Initial checks & toolchain + %% ================================ + S["Start (cmake 3.16+)\ninclude(cmake/config_defaults.cmake)"] --> I1{"In-source build?"} + I1 -- "yes" --> I1E["FATAL_ERROR:\nIn-source builds are not allowed"] + I1 -- "no" --> T0{"CMAKE_TOOLCHAIN_FILE defined?"} + T0 -- "no" --> T1{"WOLFBOOT_TARGET is set\nand not x86_64_efi or sim?"} + T1 -- "yes" --> T2["Set CMAKE_TOOLCHAIN_FILE:\ncmake/toolchain_arm-none-eabi.cmake"] + T1 -- "no" --> PRJ + T0 -- "yes" --> PRJ + + %% ================================ + %% 1) Project & host env discovery + %% ================================ + PRJ["project(wolfBoot)"] --> INC["include: cmake/functions.cmake\ninclude: cmake/utils.cmake"] + INC --> IDE0{"DETECT_VISUALGDB?"} + IDE0 -- "yes" --> IDE1["include(cmake/visualgdb_config.cmake)"] + IDE0 -- "no" --> VS0{"Windows host and DETECT_VS2022\nand NOT FOUND_HAL_BASE?"} + VS0 -- "yes" --> VS1["include(cmake/vs2022_config.cmake)"] + VS0 -- "no" --> CUBE0{"DETECT_CUBEIDE and NOT FOUND_HAL_BASE?"} + CUBE0 -- "yes" --> CUBE1["include(cmake/cube_ide_config.cmake)"] + CUBE0 -- "no" --> HALD0{"NOT FOUND_HAL_BASE and ENABLE_HAL_DOWNLOAD?"} + HALD0 -- "yes" --> HALD1{"WOLFBOOT_TARGET matches ^stm32?"} + HALD1 -- "yes" --> HALD2["include(cmake/stm32_hal_download.cmake)"] + HALD1 -- "no" --> HALWARN["WARNING:\nHAL not found and download not available"] + HALD0 -- "no" --> CFGSRC + + %% ================================ + %% 2) Config source (dot vs preset) + %% ================================ + CFGSRC{"USE_DOT_CONFIG?"} -- "yes" --> DOTINC["include(cmake/load_dot_config.cmake)"] + CFGSRC -- "no" --> DOTDIS["Info:\nNo .config files will be read"] + + DOTINC --> DOTX{"Found file ./.config?"} + DOTX -- "yes" --> DOTLOAD["WOLFBOOT_CONFIG_MODE=dot\nload_dot_config(.config)"] + DOTX -- "no" --> NODOT["Info:\nNo .config file found"] + + DOTDIS --> PRESETQ{"WOLFBOOT_CONFIG_MODE equals preset?"} + PRESETQ -- "yes" --> PRESETOK["Use cacheVariables from CMakePresets.json"] + PRESETQ -- "no" --> PRESETNONE["Info:\nNot using .config nor CMakePresets.json"] + + %% ================================ + %% 3) Target, arch, partitions + %% ================================ + subgraph TGT["Target, Arch, Partitions"] + direction TB + TGT0{"WOLFBOOT_TARGET empty?"} + TGT0 -- "yes" --> TGT1["Set WOLFBOOT_TARGET from TARGET cache var"] + TGT0 -- "no" --> TGT2["Status:\nBuilding for WOLFBOOT_TARGET"] + TGT2 --> SEC0{"WOLFBOOT_SECTOR_SIZE defined?"} + SEC0 -- "no" --> SECERR["FATAL_ERROR:\nWOLFBOOT_SECTOR_SIZE must be defined"] + SEC0 -- "yes" --> AT0["Init ARM_TARGETS list"] + AT0 --> ASEL{"Target in ARM_TARGETS?"} + ASEL -- "yes" --> ARCH_ARM["ARCH = ARM"] + ASEL -- "no" --> AX86{"Target equals x86_64_efi?"} + AX86 -- "yes" --> ARCH_X86["ARCH = x86_64"] + AX86 -- "no" --> ASIM{"Target equals sim?"} + ASIM -- "yes" --> ARCH_SIM["ARCH = sim"] + ASIM -- "no" --> AERR["FATAL_ERROR:\nUnable to configure ARCH"] + + PART0{"PULL_LINKER_DEFINES or BUILD_TEST_APPS set?"} + PART0 -- "no" --> PART1{"Require partition vars:\nPARTITION_SIZE\nBOOT_ADDRESS\nUPDATE_ADDRESS\nSWAP_ADDRESS"} + PART1 -- "no" --> PARTERR["FATAL_ERROR:\nMissing partition vars"] + PART1 -- "yes" --> PARTOK["OK:\nPartition vars present"] + PART0 -- "yes" --> PARTLK["OK:\nAddresses come from linker or tests"] + end + + %% ================================ + %% 4) Host compiler & Windows shim + %% ================================ + ARCH_ARM --> HOST + ARCH_X86 --> HOST + ARCH_SIM --> HOST + HOST["Detect HOST_CC (gcc or clang or cl)\nSet HOST flags and HOST_IS_MSVC"] --> SHIM{"Windows host and HOST_IS_MSVC?"} + SHIM -- "yes" --> SHIMON["Generate minimal unistd.h shim\nPrepend to HOST_INCLUDES"] + SHIM -- "no" --> SHIMOFF["No shim"] + + %% ================================ + %% 5) Helper tools (native) + %% ================================ + SHIMON --> TOOLS + SHIMOFF --> TOOLS + TOOLS["Build native tools with HOST_CC:\n- bin-assemble (custom)\n- sign (tools/keytools/sign.c)\n- keygen (tools/keytools/keygen.c)\nDefine KEYTOOL_SOURCES and flags"] --> TOOLSDONE["keytools ALL depends on sign and keygen"] + + %% ================================ + %% 6) Cross toolchain include (once) + %% ================================ + TOOLSDONE --> XTC{"CMAKE_C_COMPILER already set?"} + XTC -- "no" --> XTCSEL{"ARCH selection"} + XTCSEL -- "ARM" --> XARM["include(cmake/toolchain_arm-none-eabi.cmake)"] + XTCSEL -- "AARCH64" --> XA64["include(cmake/toolchain_aarch64-none-elf.cmake)"] + XTCSEL -- "x86_64 or sim" --> XNONE["No cross toolchain include"] + XTC -- "yes" --> XNONE + + %% ================================ + %% 7) Arch-specific sources and options + %% ================================ + XNONE --> ARCHO{"Which ARCH?"} + ARCHO -- "x86_64" --> AX86S["Add src/boot_x86_64.c\nIf DEBUG then add WOLFBOOT_DEBUG_EFI"] + ARCHO -- "ARM" --> AARMS["Add src/boot_arm.c\nAdd ARCH_ARM\nAdd -ffreestanding -nostartfiles -fomit-frame-pointer"] + ARCHO -- "AARCH64" --> AA64S["Add aarch64 sources\nAdd ARCH_AARCH64 NO_QNX WOLFBOOT_DUALBOOT MMU\nIf SPMATH then add sp_c32.c"] + + AX86S --> UPDS["UPDATE_SOURCES = src/update_flash.c (default)"] + AARMS --> ARMSTMS{"WOLFBOOT_TARGET specifics"} + ARMSTMS --> ARMf4{"Target stm32f4?"} + ARMf4 -- "yes" --> ARMf4set["ARCH_FLASH_OFFSET=0x08000000\nRequire CLOCK_SPEED and PLL vars\nAdd compile definitions"] + ARMSTMS --> ARMu5{"Target stm32u5?"} + ARMu5 -- "yes" --> ARMu5set["ARCH_FLASH_OFFSET=0x08000000"] + ARMSTMS --> ARMh7{"Target stm32h7?"} + ARMh7 -- "yes" --> ARMh7set["ARCH_FLASH_OFFSET=0x08000000"] + ARMSTMS --> ARMl0{"Target stm32l0?"} + ARMl0 -- "yes" --> ARMl0inv["Set FLAGS_INVERT=ON"] + AA64S --> UPDS + + UPDS --> EFIQ{"Target equals x86_64_efi?"} + EFIQ -- "yes" --> EFICONF["Set GNU EFI crt0 and lds paths\nAdd TARGET_X86_64_EFI\nSet shared linker flags\nUPDATE_SOURCES = src/update_ram.c"] + EFIQ -- "no" --> ARCHOFF["Continue"] + + %% ================================ + %% 8) DSA / signing, header size, stack + %% ================================ + ARCHOFF --> DSA{"SIGN algorithm"} + DSA -- "NONE" --> S_NONE["No signing; stack by hash\nAdd WOLFBOOT_NO_SIGN"] + DSA -- "ECC256" --> S_ECC256["KEYTOOL --ecc256; add WOLFBOOT_SIGN_ECC256\nStack depends; header >= 256"] + DSA -- "ECC384" --> S_ECC384["KEYTOOL --ecc384; add WOLFBOOT_SIGN_ECC384\nStack depends; header >= 512"] + DSA -- "ECC521" --> S_ECC521["KEYTOOL --ecc521; add WOLFBOOT_SIGN_ECC521\nStack depends; header >= 512"] + DSA -- "ED25519" --> S_ED25519["KEYTOOL --ed25519; add WOLFBOOT_SIGN_ED25519\nStack default 5000; header >= 256"] + DSA -- "ED448" --> S_ED448["KEYTOOL --ed448; add WOLFBOOT_SIGN_ED448\nStack 1024 or 4376; header >= 512"] + DSA -- "RSA2048" --> S_RSA2048["KEYTOOL --rsa2048; add WOLFBOOT_SIGN_RSA2048\nStack varies; header >= 512"] + DSA -- "RSA4096" --> S_RSA4096["KEYTOOL --rsa4096; add WOLFBOOT_SIGN_RSA4096\nStack varies; header >= 1024"] + + S_NONE --> DSA_APPLY + S_ECC256 --> DSA_APPLY + S_ECC384 --> DSA_APPLY + S_ECC521 --> DSA_APPLY + S_ED25519 --> DSA_APPLY + S_ED448 --> DSA_APPLY + S_RSA2048 --> DSA_APPLY + S_RSA4096 --> DSA_APPLY + + DSA_APPLY["Append IMAGE_HEADER_SIZE and SIGN_OPTIONS to WOLFBOOT_DEFS\nAdd -Wstack-usage and -Wno-unused"] --> FLAGS + + %% ================================ + %% 9) Feature flags and encryption + %% ================================ + FLAGS{"Apply feature toggles"} --> F_PULL["If PULL_LINKER_DEFINES then add def"] + FLAGS --> F_RAM["If RAM_CODE then add def"] + FLAGS --> F_FHOME["If FLAGS_HOME then add FLAGS_HOME=1"] + FLAGS --> F_FINV["If FLAGS_INVERT then add WOLFBOOT_FLAGS_INVERT=1"] + FLAGS --> F_SPI["If SPI_FLASH or QSPI_FLASH or OCTOSPI_FLASH or UART_FLASH\nthen set EXT_FLASH and add sources"] + FLAGS --> F_ENC{"ENCRYPT enabled?"} + F_ENC -- "yes" --> F_ENCSEL{"Select AES128 or AES256 or CHACHA"} + F_ENCSEL --> F_AES128["Add ENCRYPT_WITH_AES128; EXT_ENCRYPTED=1"] + F_ENCSEL --> F_AES256["Add ENCRYPT_WITH_AES256; EXT_ENCRYPTED=1"] + F_ENCSEL --> F_CHACHA["Default CHACHA; add ENCRYPT_WITH_CHACHA and HAVE_CHACHA\nEXT_ENCRYPTED=1"] + FLAGS --> F_DOWN["If ALLOW_DOWNGRADE then add def"] + FLAGS --> F_WO["If NVM_FLASH_WRITEONCE then add def"] + FLAGS --> F_NOBKP["If DISABLE_BACKUP then add def"] + FLAGS --> F_NOMPU["If NO_MPU then add WOLFBOOT_NO_MPU"] + FLAGS --> F_VER{"WOLFBOOT_VERSION defined?"} + F_VER -- "no" --> F_VERSET["Set WOLFBOOT_VERSION=1"] + F_VER -- "yes" --> F_VEROK["Keep version"] + + %% ================================ + %% 10) Delta updates and armored + %% ================================ + F_VEROK --> DELTA{"DELTA_UPDATES enabled?"} + F_VERSET --> DELTA + DELTA -- "yes" --> DELTAON["Add src/delta.c and DELTA_UPDATES\nIf DELTA_BLOCK_SIZE defined then add def"] + DELTA -- "no" --> ARMOR{"ARMORED enabled?"} + ARMOR -- "yes" --> ARMORON["Add WOLFBOOT_ARMORED"] + ARMOR -- "no" --> NEXT0 + + DELTAON --> NEXT0 + ARMORON --> NEXT0 + + %% ================================ + %% 11) Hash selection + %% ================================ + NEXT0 --> HASH{"HASH selection"} + HASH -- "SHA256" --> H256["Add WOLFBOOT_HASH_SHA256"] + HASH -- "SHA384" --> H384["Add WOLFBOOT_HASH_SHA384; KEYTOOL --sha384"] + HASH -- "SHA3" --> H3["Add WOLFBOOT_HASH_SHA3_384; KEYTOOL --sha3"] + + %% ================================ + %% 12) HAL and drivers + %% ================================ + H256 --> HAL + H384 --> HAL + H3 --> HAL + HAL["SPI_TARGET and UART_TARGET default to WOLFBOOT_TARGET\nIf target is STM32 in list then SPI_TARGET=stm32"] --> HALDRV{"Drivers enabled?"} + HALDRV -- "SPI_FLASH" --> DSPIS["Add spi driver and src/spi_flash.c"] + HALDRV -- "QSPI_FLASH" --> DQSPIS["Add spi driver and src/qspi_flash.c"] + HALDRV -- "UART_FLASH" --> DUART["Add uart driver and src/uart_flash.c"] + HALDRV -- "none" --> HALNEXT["No external flash drivers"] + HALDRV --> DBGQ{"DEBUG_UART enabled?"} + DBGQ -- "yes" --> DBGON["Add DEBUG_UART and uart driver path"] + DBGQ -- "no" --> DBGOFF["No debug uart"] + + %% ================================ + %% 13) Math options (wolfSSL) + %% ================================ + DBGOFF --> MATH + DBGON --> MATH + MATH{"SPMATH / SPMATHALL"} --> MALL["If SPMATHALL then add WOLFSSL_SP_MATH_ALL"] + MATH --> MFAST["If neither then add USE_FAST_MATH"] + MATH --> MNONE["If only SPMATH then no extra def"] + + %% ================================ + %% 14) Build HAL libs and wolfcrypt + %% ================================ + MALL --> LIBS0 + MFAST --> LIBS0 + MNONE --> LIBS0 + LIBS0["add_library(user_settings INTERFACE)\nadd_library(wolfboothal)"] --> STM32L4Q{"Target equals stm32l4?"} + STM32L4Q -- "yes" --> L4HAL["Create stm32l4_hal subset\nLink into wolfboothal"] + STM32L4Q -- "no" --> L4SKIP["Skip stm32l4 subset"] + L4HAL --> CRYPT + L4SKIP --> CRYPT + CRYPT["add_subdirectory(lib) for wolfcrypt"] --> BUILDIMG{"BUILD_TEST_APPS or BUILD_IMAGE?"} + BUILDIMG -- "yes" --> ADDAPP["Print status and add_subdirectory(test-app)"] + BUILDIMG -- "no" --> VARS + + %% ================================ + %% 15) Cache vars, target.h, target iface + %% ================================ + ADDAPP --> VARS + VARS["Set INTERNAL cache vars\nconfigure_file target.h\nadd_library(target INTERFACE)"] --> KEYGENQ{"SIGN is not NONE?"} + + %% ================================ + %% 16) Keystore generation and public key lib + %% ================================ + KEYGENQ -- "yes" --> KEYGEN["add_custom_target(keystore)\nIf keystore.c missing then run keygen"] + KEYGENQ -- "no" --> KEYGENSKIP["Skip keystore and public_key"] + KEYGEN --> PUBKEY["add_library(public_key)\nUse generated keystore.c\nLink target"] + KEYGENSKIP --> WBLIB + + %% ================================ + %% 17) Final libraries + %% ================================ + PUBKEY --> WBLIB + WBLIB["add_library(wolfboot)\nAdd src/libwolfboot.c and flash sources\nApply WOLFBOOT_DEFS and include dirs\nLink wolfboothal target wolfcrypt\nAdd -Wno-unused and SIM_COMPILE_OPTIONS"] --> DONE["Done"] + +``` diff --git a/cmake/config_defaults.cmake b/cmake/config_defaults.cmake index a14456493b..c2aab58991 100644 --- a/cmake/config_defaults.cmake +++ b/cmake/config_defaults.cmake @@ -1,6 +1,6 @@ # wolfboot/cmake/config_defaults.cmake # -# Copyright (C) 2022 wolfSSL Inc. +# Copyright (C) 2025 wolfSSL Inc. # # This file is part of wolfBoot. # @@ -21,7 +21,31 @@ # This is NOT a place for device-specific project settings. For that, see CMakePresets.json -set(FOUND_STM32L4_LIB false) +# Ensure this file is only included and initialized once +if(CMAKE_VERSION VERSION_LESS 3.10) + # Fallback path for older CMake + if(DEFINED CONFIG_DEFAULTS_CMAKE_INCLUDED) + return() + endif() +else() + include_guard(GLOBAL) +endif() + + + +# Environments are detected in this order: +set(DETECT_VISUALGDB true) +set(DETECT_CUBEIDE true) +set(DETECT_VS2022 true) + +# Enable HAL download only implemented for TMS devices at this time. +# See [WOLFBOOT_ROOT]/cmake/stm32_hal_download.cmake +# and [WOLFBOOT_ROOT]/cmake/downloads/stm32_hal_download.cmake +set(ENABLE_HAL_DOWNLOAD true) +set(FOUND_HAL_BASE false) + +# optionally use .config files; See CMakePresets.json instead +set(USE_DOT_CONFIG false) include(cmake/current_user.cmake) @@ -33,27 +57,6 @@ message(STATUS "Current user detected: ${CURRENT_USER}") # Want to specify your specific STCubeIDE? Uncomment and set it here: # set(STM32CUBEIDE_DIR "/your/path") -if(false) - # TODO need to be more generic, in presets? - if(IS_DIRECTORY "C:/Users/${CURRENT_USER}/AppData/Local/VisualGDB") - set(LIB_STM32L4_WINDOWS "C:/Users/${CURRENT_USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx") - endif() - - if(IS_DIRECTORY "/mnt/c/Users/${CURRENT_USER}/AppData/Local/VisualGDB") - set(LIB_STM32L4_WSL "/mnt/c/Users/${CURRENT_USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/STM32L4xxxx") - endif() - - if(IS_DIRECTORY "${LIB_STM32L4_WINDOWS}") - set(FOUND_STM32L4_LIB true) - message(STATUS "LIB_STM32L4_WINDOWS found: ${LIB_STM32L4_WINDOWS}") - endif() - - if(IS_DIRECTORY "${LIB_STM32L4_WSL}") - set(FOUND_STM32L4_LIB true) - message(STATUS "LIB_STM32L4_WSL found: ${LIB_STM32L4_WSL}") - endif() -endif() - # set(ARM_GCC_BIN "") @@ -61,3 +64,5 @@ message(STATUS "config.defaults:") message(STATUS "-- HAL_DRV: ${HAL_DRV}") message(STATUS "-- HAL_CMSIS_DEV: ${HAL_CMSIS_DEV}") message(STATUS "-- HAL_CMSIS_CORE:${HAL_CMSIS_CORE}") + +set(CONFIG_DEFAULTS_CMAKE_INCLUDED TRUE) diff --git a/cmake/cube_ide_config.cmake b/cmake/cube_ide_config.cmake index e263a3fabf..f762b2f4b7 100644 --- a/cmake/cube_ide_config.cmake +++ b/cmake/cube_ide_config.cmake @@ -1,6 +1,6 @@ # wolfboot/cmake/cube_ide_config.cmake # -# Copyright (C) 2022 wolfSSL Inc. +# Copyright (C) 2025 wolfSSL Inc. # # This file is part of wolfBoot. # @@ -27,7 +27,19 @@ # find_package(STM32CubeIDE REQUIRED) # message(STATUS "STM32CubeIDE: ${STM32CUBEIDE_EXECUTABLE} (root: ${STM32CUBEIDE_ROOT}, ver: ${STM32CUBEIDE_VERSION})") -include_guard(GLOBAL) +# Ensure this file is only included and initialized once +if(CMAKE_VERSION VERSION_LESS 3.10) + # Fallback path for older CMake + if(DEFINED CUBE_IDE_CONFIG_CMAKE_INCLUDED) + return() + endif() +else() + include_guard(GLOBAL) +endif() + +# Exclude entire file unless DETECT_CUBEIDE is set to true +if(DETECT_CUBEIDE) + message(STATUS "Begin cube_ide_config.cmake") unset(STM32CUBEIDE_ROOT CACHE) unset(STM32CUBEIDE_FOUND CACHE) @@ -385,11 +397,20 @@ if(STM32CUBE_L4_VERSION) set(HAL_BASE "${STM32CUBE_L4_ROOT}") if(IS_DIRECTORY "${HAL_BASE}") message(STATUS "Found HAL_BASE=${HAL_BASE}") - set(FOUND_STM32L4_LIB true) + set(FOUND_HAL_BASE true) + # CubeIDE + set_and_echo_dir(HAL_DRV "${HAL_BASE}/Drivers/STM32L4xx_HAL_Driver") + set_and_echo_dir(HAL_CMSIS_DEV "${HAL_BASE}/Drivers/CMSIS/Device/ST/STM32L4xx/Include") + set_and_echo_dir(HAL_CMSIS_CORE "${HAL_BASE}/Drivers/CMSIS/Include") + set_and_echo_dir(HAL_TEMPLATE_INC "${HAL_BASE}/Projects/B-L475E-IOT01A/Templates/Inc") else() message(STATUS "Not found expected HAL_BASE=${HAL_BASE}") endif() endif() mark_as_advanced(STM32CUBEIDE_EXECUTABLE STM32CUBEIDE_ROOT STM32CUBEIDE_VERSION) + +set(CUBE_IDE_CONFIG_CMAKE_INCLUDED TRUE) message(STATUS "End cube_ide_config.cmake") + +endif() # DETECT_CUBEIDE diff --git a/cmake/current_user.cmake b/cmake/current_user.cmake index e78ecf48b9..19a3c6f52d 100644 --- a/cmake/current_user.cmake +++ b/cmake/current_user.cmake @@ -1,6 +1,6 @@ -# wolfboot/cmake/current_user.cmake +# wolfboot/cmake/current_user.cmake # -# Copyright (C) 2022 wolfSSL Inc. +# Copyright (C) 2025 wolfSSL Inc. # # This file is part of wolfBoot. # @@ -25,6 +25,16 @@ # get_current_user(CURRENT_USER) # message(STATUS "Current user detected: ${CURRENT_USER}") +# Ensure this file is only included and initialized once +if(CMAKE_VERSION VERSION_LESS 3.10) + # Fallback path for older CMake, and anything else that wants to detect is loaded + if(DEFINED CURRENT_USER_CMAKE_INCLUDED) + return() + endif() +else() + include_guard(GLOBAL) +endif() + function(get_current_user OUT_VAR) set(_user "") @@ -92,3 +102,5 @@ function(get_current_user OUT_VAR) set(${OUT_VAR} "${_user}" PARENT_SCOPE) endfunction() + +set(CURRENT_USER_CMAKE_INCLUDED true) diff --git a/cmake/downloads/README.md b/cmake/downloads/README.md new file mode 100644 index 0000000000..81e7b682be --- /dev/null +++ b/cmake/downloads/README.md @@ -0,0 +1,21 @@ +# wolbBoot CMake Downloads + +Device-specific supplemental download specifications. + +Include in `CmakePresets.json` via the `WOLFBOOT_DOWNLOADS_CMAKE` + +``` +"cacheVariables": { + "WOLFBOOT_DOWNLOADS_CMAKE": "${sourceDir}/cmake/downloads/my_dependency.cmake" +} +``` + +Format for `my_dependency.cmake` entries: + +``` +add_download( + NAME some_name + URL https://github.com/some/repo.git + TAG 5.9.0 +) +``` diff --git a/cmake/downloads/stm32l4.cmake b/cmake/downloads/stm32l4.cmake new file mode 100644 index 0000000000..0900963ed3 --- /dev/null +++ b/cmake/downloads/stm32l4.cmake @@ -0,0 +1,39 @@ +# wolfboot/cmake/downloads/stm32l4.cmake +# +# Copyright (C) 2025 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 +# + +# The STM32L4 is known to need additional HAL source files: +add_download( + NAME st_hal + URL https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git + TAG v1.13.5 +) + +add_download( + NAME cmsis_dev + URL https://github.com/STMicroelectronics/cmsis_device_l4.git + TAG v1.7.4 +) + +add_download( + NAME cmsis_core + URL https://github.com/ARM-software/CMSIS_5.git + TAG 5.9.0 +) diff --git a/cmake/functions.cmake b/cmake/functions.cmake index 9025494b02..ea3930a9a2 100644 --- a/cmake/functions.cmake +++ b/cmake/functions.cmake @@ -1,4 +1,4 @@ -# functions.cmake +# wolfboot/cmake/functions.cmake # # Copyright (C) 2025 wolfSSL Inc. # @@ -18,6 +18,17 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA +# Ensure this file is only included and initialized once +if(CMAKE_VERSION VERSION_LESS 3.10) + # Fallback path for older CMake, and anything else that wants to detect is loaded + if(DEFINED FUNCTIONS_CMAKE_INCLUDED) + return() + endif() + set(FUNCTIONS_CMAKE_INCLUDED TRUE) +else() + include_guard(GLOBAL) +endif() + function(override_cache VAR VAL) get_property(VAR_STRINGS CACHE ${VAR} PROPERTY STRINGS) LIST(FIND VAR_STRINGS ${VAL} CK) @@ -71,10 +82,13 @@ function(set_and_echo_dir var_name value_expr) set(${var_name} "${_val}" PARENT_SCOPE) if(IS_DIRECTORY "${_val}") - message(STATUS "set ${var_name}; Found directory: ${_val}") + message(STATUS "-- set ${var_name}; Found directory: ${_val}") else() - message(STATUS "set ${var_name}; Directory not found: ${_val}") + message(STATUS "-- Warning: set ${var_name}") + message(STATUS "-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + message(STATUS "-- Directory not found: ${_val}") + message(STATUS "-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") endif() endfunction() -set(functions_cmake_loaded true) +set(FUNCTIONS_CMAKE_INCLUDED true) diff --git a/cmake/load_dot_config.cmake b/cmake/load_dot_config.cmake index e90192868d..4a58408292 100644 --- a/cmake/load_dot_config.cmake +++ b/cmake/load_dot_config.cmake @@ -1,4 +1,6 @@ -# Copyright (C) 2022 wolfSSL Inc. +# wolfboot/cmake/load_dot_config.cmake +# +# Copyright (C) 2025 wolfSSL Inc. # # This file is part of wolfBoot. # @@ -22,6 +24,16 @@ # # or cache them so GUIs (e.g. Visual Studio) can see/edit them: # load_dot_config("${CMAKE_SOURCE_DIR}/.config" CACHE_VARS) +# Ensure this file is only included and initialized once +if(CMAKE_VERSION VERSION_LESS 3.10) + # Fallback path for older CMake, and anything else that wants to detect is loaded + if(DEFINED LOAD_DOT_CONFIG_CMAKE_INCLUDED) + return() + endif() +else() + include_guard(GLOBAL) +endif() + function(load_dot_config CONFIG_PATH) set(_USE_CACHE OFF) foreach(_arg IN LISTS ARGN) @@ -136,3 +148,5 @@ function(load_dot_config CONFIG_PATH) endforeach() message(STATUS "-- Done processing ${CONFIG_PATH}") endfunction() + +set(LOAD_DOT_CONFIG_CMAKE_INCLUDED TRUE) diff --git a/cmake/stm32_hal_download.cmake b/cmake/stm32_hal_download.cmake index af06c60758..4df82a17ca 100644 --- a/cmake/stm32_hal_download.cmake +++ b/cmake/stm32_hal_download.cmake @@ -1,6 +1,6 @@ # wolfboot/cmake/stm32_hal_download.cmake # -# Copyright (C) 2022 wolfSSL Inc. +# Copyright (C) 2025 wolfSSL Inc. # # This file is part of wolfBoot. # @@ -20,61 +20,178 @@ # # If not found: -# The CubeIDE -# VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32 +# 1) The CubeIDE +# 2) VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32 +# 3) User-specified # -# ... then download HAL files as needed +# ... then download HAL files as needed: -if(NOT functions_cmake_loaded) - include(cmake/functions.cmake) +# Ensure this file is only included and initialized once +if(CMAKE_VERSION VERSION_LESS 3.10) + # Fallback path for older CMake, and anything else that wants to detect is loaded + if(DEFINED STM32_HAL_DOWNLOAD_CMAKE_INCLUDED) + return() + endif() +else() + include_guard(GLOBAL) endif() -if(WOLFBOOT_TARGET STREQUAL "stm32l4") - if(FOUND_STM32L4_LIB) - message(STATUS "stm32_hal_download.cmake skipped, already found STM32 HAL lib.") + +if(ENABLE_HAL_DOWNLOAD) # Entire file wrapper + include(FetchContent) + + + if(NOT FUNCTIONS_CMAKE_INCLUDED) + include(cmake/functions.cmake) + endif() + + # Accumulators for the DSL + set(_DL_NAMES) + set(_DL_URLS) + set(_DL_TAGS) + + # Mini DSL + function(add_download) + cmake_parse_arguments(AD "" "" "NAME;URL;TAG" ${ARGN}) + if(NOT AD_NAME) + message(FATAL_ERROR "add_download requires NAME") + endif() + if(NOT AD_URL) + message(FATAL_ERROR "add_download requires URL") + endif() + if(NOT AD_TAG) + set(AD_TAG "master") + endif() + + list(APPEND _DL_NAMES "${AD_NAME}") + list(APPEND _DL_URLS "${AD_URL}") + list(APPEND _DL_TAGS "${AD_TAG}") + + set(_DL_NAMES "${_DL_NAMES}" PARENT_SCOPE) + set(_DL_URLS "${_DL_URLS}" PARENT_SCOPE) + set(_DL_TAGS "${_DL_TAGS}" PARENT_SCOPE) + endfunction() + + set(DOWNLOADS_FOUND false) + # If a downloads list is provided, include it + if(DEFINED WOLFBOOT_DOWNLOADS_CMAKE) + if(EXISTS "${WOLFBOOT_DOWNLOADS_CMAKE}") + message(STATUS "Including downloads list: ${WOLFBOOT_DOWNLOADS_CMAKE}") + include("${WOLFBOOT_DOWNLOADS_CMAKE}") + set(DOWNLOADS_FOUND true) + else() + # If there's a defined download, the file specified needs to exist! + message(FATAL_ERROR "WOLFBOOT_DOWNLOADS_CMAKE enabled but file now found: ${WOLFBOOT_DOWNLOADS_CMAKE}") + endif() else() - include(FetchContent) - # TIP: Always pin a real tag/commit; avoid main/master. - - # Make behavior explicit & chatty while debugging - set(FETCHCONTENT_QUIET OFF) - set(FETCHCONTENT_BASE_DIR "${CMAKE_BINARY_DIR}/_deps") - - # HAL driver - message(STATUS "Fetching https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git") - FetchContent_Declare(st_hal - GIT_REPOSITORY https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git - # Pick a tag you want to lock to: - GIT_TAG v1.13.5 - GIT_SHALLOW TRUE - GIT_PROGRESS FALSE - ) + message(STATUS "No WOLFBOOT_DOWNLOADS_CMAKE and no builtin defaults for target: ${WOLFBOOT_TARGET}. Skipping auto downloads.") + endif() # WOLFBOOT_DOWNLOADS_CMAKE + + # Fallback: The stm32l4 trio is known to be needed, so hard-coded here: + if(WOLFBOOT_TARGET STREQUAL "stm32l4" AND (NOT DOWNLOADS_FOUND)) + message(STATUS "WARNING not downloads found for known target needing them: stm32l4" ) - # CMSIS device headers for L4 - message(STATUS "Fetching https://github.com/STMicroelectronics/cmsis_device_l4.git") - FetchContent_Declare(cmsis_dev - GIT_REPOSITORY https://github.com/STMicroelectronics/cmsis_device_l4.git - GIT_TAG v1.7.4 - GIT_SHALLOW TRUE - GIT_PROGRESS FALSE + add_download( + NAME st_hal + URL https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git + TAG v1.13.5 + ) + add_download( + NAME cmsis_dev + URL https://github.com/STMicroelectronics/cmsis_device_l4.git + TAG v1.7.4 ) + add_download( + NAME cmsis_core + URL https://github.com/ARM-software/CMSIS_5.git + TAG 5.9.0 + ) + endif() + + + # Validate lists are aligned + list(LENGTH _DL_NAMES _n1) + list(LENGTH _DL_URLS _n2) + list(LENGTH _DL_TAGS _n3) + if(NOT (_n1 EQUAL _n2 AND _n1 EQUAL _n3)) + message(FATAL_ERROR "add_download internal list length mismatch: names=${_n1} urls=${_n2} tags=${_n3}") + endif() + + # Nothing to do + if(_n1 EQUAL 0) + set(STM32_HAL_DOWNLOAD_CMAKE_INCLUDED TRUE) + #--------------------------------------------------------------------------------------------- + message(STATUS "No files found needing to be downloaded. If needed, configure WOLFBOOT_DOWNLOADS_CMAKE") + return() + #--------------------------------------------------------------------------------------------- + endif() - # CMSIS Core headers - message(STATUS "Fetching https://github.com/ARM-software/CMSIS_5.git") - FetchContent_Declare(cmsis_core - GIT_REPOSITORY https://github.com/ARM-software/CMSIS_5.git - GIT_TAG 5.9.0 - GIT_SHALLOW TRUE - GIT_PROGRESS FALSE + # Fetch loop + set(FETCHCONTENT_QUIET OFF) + set(FETCHCONTENT_BASE_DIR "${CMAKE_BINARY_DIR}/_deps") + + set(_ALL_NAMES) + math(EXPR _last "${_n1} - 1") + foreach(i RANGE 0 ${_last}) + list(GET _DL_NAMES ${i} _name) + list(GET _DL_URLS ${i} _url) + list(GET _DL_TAGS ${i} _tag) + + message(STATUS "Fetching ${_url} (tag ${_tag})") + FetchContent_Declare(${_name} + GIT_REPOSITORY "${_url}" + GIT_TAG "${_tag}" + GIT_SHALLOW TRUE + GIT_PROGRESS FALSE ) + list(APPEND _ALL_NAMES "${_name}") + endforeach() - FetchContent_MakeAvailable(st_hal cmsis_dev cmsis_core) + if(_ALL_NAMES) + FetchContent_MakeAvailable(${_ALL_NAMES}) + endif() - # Map to the include structures of the fetched repos - message("stm32_hal_download.cmake setting hal directories:") - set_and_echo_dir(HAL_BASE "${st_hal_SOURCE_DIR}") - set_and_echo_dir(HAL_DRV "${st_hal_SOURCE_DIR}") # Inc/, Src/ - set_and_echo_dir(HAL_CMSIS_DEV "${cmsis_dev_SOURCE_DIR}/Include") # device - set_and_echo_dir(HAL_CMSIS_CORE "${cmsis_core_SOURCE_DIR}/CMSIS/Core/Include") # core + # st_hal + FetchContent_GetProperties(st_hal) # ensures *_SOURCE_DIR vars are available + if(DEFINED st_hal_SOURCE_DIR AND EXISTS "${st_hal_SOURCE_DIR}") + set_and_echo_dir(HAL_BASE "${st_hal_SOURCE_DIR}") + set_and_echo_dir(HAL_DRV "${st_hal_SOURCE_DIR}") + else() + message(FATAL_ERROR "st_hal source dir not found; expected after FetchContent.") endif() -endif() + + # cmsis_dev + FetchContent_GetProperties(cmsis_dev) + if(DEFINED cmsis_dev_SOURCE_DIR AND EXISTS "${cmsis_dev_SOURCE_DIR}") + set_and_echo_dir(HAL_CMSIS_DEV "${cmsis_dev_SOURCE_DIR}/Include") + else() + message(FATAL_ERROR "cmsis_dev source dir not found.") + endif() + + # cmsis_core + FetchContent_GetProperties(cmsis_core) + if(DEFINED cmsis_core_SOURCE_DIR AND EXISTS "${cmsis_core_SOURCE_DIR}") + set_and_echo_dir(HAL_CMSIS_CORE "${cmsis_core_SOURCE_DIR}/CMSIS/Core/Include") + else() + message(FATAL_ERROR "cmsis_core source dir not found.") + endif() + + + # Map include directories when known names are fetched + # Adjust or extend this block if you add more components + if(TARGET st_hal) + set_and_echo_dir(HAL_BASE "${st_hal_SOURCE_DIR}") + set_and_echo_dir(HAL_DRV "${st_hal_SOURCE_DIR}") + endif() + + if(TARGET cmsis_dev) + set_and_echo_dir(HAL_CMSIS_DEV "${cmsis_dev_SOURCE_DIR}/Include") + endif() + + if(TARGET cmsis_core) + set_and_echo_dir(HAL_CMSIS_CORE "${cmsis_core_SOURCE_DIR}/CMSIS/Core/Include") + endif() + +endif() #ENABLE_HAL_DOWNLOAD + +set(STM32_HAL_DOWNLOAD_CMAKE_INCLUDED true) diff --git a/cmake/toolchain_aarch64-none-elf.cmake b/cmake/toolchain_aarch64-none-elf.cmake index 4c3de5c546..9218590b74 100644 --- a/cmake/toolchain_aarch64-none-elf.cmake +++ b/cmake/toolchain_aarch64-none-elf.cmake @@ -18,11 +18,21 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA +# Ensure this file is only included and initialized once +if(CMAKE_VERSION VERSION_LESS 3.10) + # Fallback path for older CMake + if(DEFINED TOOLCHAIN_AARCH64_NONE_ELF_CMAKE_INCLUDED) + return() + endif() +else() + include_guard(GLOBAL) +endif() set(CMAKE_SYSTEM_NAME Generic) # There needs to be a default platform or the `project()` command will fail. if(NOT DEFINED WOLFBOOT_TARGET) + message(STATUS "WOLFBOOT_TARGET not set, defaulting to stm32h7") set(WOLFBOOT_TARGET "stm32h7") endif() @@ -86,7 +96,7 @@ message(STATUS "Cross-compiling using GNU aarch64-none-elf toolchain") # Options for DEBUG build # -Og Enables optimizations that do not interfere with debugging. -# -g Produce debugging information in the operating system’s native format. +# -g Produce debugging information in the operating system’s native format. set(CMAKE_C_FLAGS_DEBUG "-Og -g" CACHE INTERNAL "C Compiler options for debug build type") set(CMAKE_CXX_FLAGS_DEBUG "-Og -g" CACHE INTERNAL "C++ Compiler options for debug build type") set(CMAKE_ASM_FLAGS_DEBUG "-g" CACHE INTERNAL "ASM Compiler options for debug build type") @@ -112,3 +122,5 @@ set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG -flto -Wl,-flto" CACHE INTERNAL set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -flto -Wl,-flto" CACHE INTERNAL "C++ Compiler options for minimum size release build type") set(CMAKE_ASM_FLAGS_MINSIZEREL "" CACHE INTERNAL "ASM Compiler options for minimum size release build type") set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-flto -Wl,-flto" CACHE INTERNAL "Linker options for minimum size release build type") + +set(TOOLCHAIN_AARCH64_NONE_ELF_CMAKE_INCLUDED true) diff --git a/cmake/toolchain_arm-none-eabi.cmake b/cmake/toolchain_arm-none-eabi.cmake index 65ff63fcba..bc31a6c89f 100644 --- a/cmake/toolchain_arm-none-eabi.cmake +++ b/cmake/toolchain_arm-none-eabi.cmake @@ -18,6 +18,15 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA +# Ensure this file is only included and initialized once +if(CMAKE_VERSION VERSION_LESS 3.10) + # Fallback path for older CMake + if(DEFINED TOOLCHAIN_ARM_NONE_EABI_CMAKE_INCLUDED) + return() + endif() +else() + include_guard(GLOBAL) +endif() set(CMAKE_SYSTEM_NAME Generic) @@ -28,7 +37,7 @@ set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES ARM_GCC_BIN WOLFBOOT_TARGET) # There needs to be a default platform or the `project()` command will fail. if(NOT DEFINED WOLFBOOT_TARGET) - message(STATUS "Select a target, e.g. 'cmake --preset linux-stm32l4'") + message(STATUS "Select a target, e.g. 'cmake --preset stm32l4'") message(FATAL_ERROR "WOLFBOOT_TARGET not set") # set(WOLFBOOT_TARGET "stm32h7") endif() @@ -204,3 +213,5 @@ set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG -flto -Wl,-flto" CACHE INTERNAL set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -flto -Wl,-flto" CACHE INTERNAL "C++ Compiler options for minimum size release build type") set(CMAKE_ASM_FLAGS_MINSIZEREL "" CACHE INTERNAL "ASM Compiler options for minimum size release build type") set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-flto -Wl,-flto" CACHE INTERNAL "Linker options for minimum size release build type") + +set(TOOLCHAIN_ARM_NONE_EABI_CMAKE_INCLUDED true) diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 60e2bbf6c1..58838fc82f 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -18,6 +18,17 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + +# Ensure this file is only included and initialized once +if(CMAKE_VERSION VERSION_LESS 3.10) + # Fallback path for older CMake + if(DEFINED UTILS_CMAKE_INCLUDED) + return() + endif() +else() + include_guard(GLOBAL) +endif() + # -------------------------------------------------------------------------------------------------- # Utility for properly installing a file output regardless of if the current configuration is multi # config or not @@ -72,3 +83,5 @@ macro(gen_bin_target_outputs TARGET) # Add top level target for all MCU standard outputs add_custom_target(${FILENAME}_outputs ALL DEPENDS ${TARGET_OUTPUTS}) endmacro() + +set(UTILS_CMAKE_INCLUDED true) diff --git a/cmake/visualgdb_config.cmake b/cmake/visualgdb_config.cmake new file mode 100644 index 0000000000..24fad6534b --- /dev/null +++ b/cmake/visualgdb_config.cmake @@ -0,0 +1,93 @@ +# wolfboot/cmake/visualgdb_config.cmake +# +# Copyright (C) 2025 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 +# + +# See wolfboot/cmake/config_defaults.cmake + +# Ensure this file is only included and initialized once +if(CMAKE_VERSION VERSION_LESS 3.10) + # Fallback path for older CMake + if(DEFINED VISUALGDB_CONFIG_CMAKE_INCLUDED) + return() + endif() +else() + include_guard(GLOBAL) +endif() + +# VisualGDB toolchains are installed automatically with the product +# or can be found at: https://gnutoolchains.com/download/ + +if(DETECT_VISUALGDB) + message(STATUS "Begin VisualGDB detection...") + # TODO needs to be more generic, perhaps in presets? + + if("${WOLFBOOT_TARGET}" STREQUAL "" ) + message(STATUS "WOLFBOOT_TARGET is not defined") + else() + string(STRIP "${WOLFBOOT_TARGET}" _target_trimmed) + string(TOUPPER "${_target_trimmed}" WOLFBOOT_TARGET_DIR) + if(WOLFBOOT_TARGET_DIR MATCHES "^STM32") + message(STATUS "Starts with STM32, will look for ${WOLFBOOT_TARGET_DIR}") + else() + message(STATUS "WARNING: target not yet supported: ${WOLFBOOT_TARGET}") + endif() + endif() + + if("${HAL_BASE}" STREQUAL "") + message(STATUS "HAL_BASE not yet found, searching VisualGDB...") + + # VisualDGB files can be used from Windows: + if(IS_DIRECTORY "C:/Users/${CURRENT_USER}/AppData/Local/VisualGDB") + set(LIB_STM32_WINDOWS "C:/Users/${CURRENT_USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/${WOLFBOOT_TARGET_DIR}xxxx") + if(IS_DIRECTORY "${LIB_STM32_WINDOWS}") + set(FOUND_HAL_BASE true) + message(STATUS "LIB_STM32_WINDOWS found: ${LIB_STM32_WINDOWS}") + set_and_echo_dir(HAL_BASE "${LIB_STM32_WINDOWS}") + endif() + endif() + + # VisualDGB files can also be used from WSL: + if(IS_DIRECTORY "/mnt/c/Users/${CURRENT_USER}/AppData/Local/VisualGDB") + set(LIB_STM32_WSL "/mnt/c/Users/${CURRENT_USER}/AppData/Local/VisualGDB/EmbeddedBSPs/arm-eabi/com.sysprogs.arm.stm32/${WOLFBOOT_TARGET_DIR}xxxx") + if(IS_DIRECTORY "${LIB_STM32_WSL}") + set(FOUND_HAL_BASE true) + message(STATUS "LIB_STM32_WSL found: ${LIB_STM32_WSL}") + set_and_echo_dir(HAL_BASE "${LIB_STM32_WSL}") + endif() + endif() + + if("${HAL_BASE}" STREQUAL "") + message(STATUS "VisualGDB detection could not set HAL_BASE") + else() + # VisualGDB + set_and_echo_dir(HAL_DRV "${HAL_BASE}/${WOLFBOOT_TARGET_DIR}xx_HAL_Driver") + set_and_echo_dir(HAL_CMSIS_DEV "${HAL_BASE}/CMSIS_HAL/Device/ST/${WOLFBOOT_TARGET_DIR}xx/Include") + set_and_echo_dir(HAL_CMSIS_CORE "${HAL_BASE}/CMSIS_HAL/Include") + # In VisualGDB, the samples are in the parent from the HAL_BASE + # set_and_echo_dir(HAL_TEMPLATE_INC "${HAL_BASE}/../VendorSamples/L4/Projects/B-L475E-IOT01A/Templates/Inc") + endif() + else() + message(STATUS "Skipped VisualGDB, found HAL_BASE=${HAL_BASE}") + endif() + + message(STATUS "Completed VisualGDB detection.") +endif() # if visualgdb_config.cmake + +set(VISUALGDB_CONFIG_CMAKE_INCLUDED TRUE) diff --git a/cmake/vs2022_config.cmake b/cmake/vs2022_config.cmake index b5249c3ec7..3b6e7e749f 100644 --- a/cmake/vs2022_config.cmake +++ b/cmake/vs2022_config.cmake @@ -1,3 +1,37 @@ +# wolfboot/cmake/vs2022_config.cmake +# +# Copyright (C) 2025 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 +# + +# Ensure this file is only included and initialized once +if(CMAKE_VERSION VERSION_LESS 3.10) + # Fallback path for older CMake + if(DEFINED VS2022_CONFIG_CMAKE_INCLUDED) + return() + endif() +else() + include_guard(GLOBAL) +endif() + +# See cmake/config_defaults.cmake for environment config and detection preferences. +if(DETECT_VS2022) + # Raw inputs copied from your Developer Prompt set(WIN_DEV_PATH_RAW [=[ C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\bin\HostX86\x86;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\VC\VCPackages;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\bin\Roslyn;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\;C:\Program Files (x86)\HTML Help Workshop;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Team Tools\DiagnosticsHub\Collector;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\Extensions\Microsoft\CodeCoverage.Console;C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\\x86;C:\Program Files (x86)\Windows Kits\10\bin\\x86;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\\MSBuild\Current\Bin\amd64;C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\;C:\Program Files (x86)\VMware\VMware Workstation\bin\;C:\Program Files\Microsoft\jdk-11.0.16.101-hotspot\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\Git\cmd;C:\SysGCC\esp32-master\tools\riscv32-esp-elf\esp-15.2.0_20250920\riscv32-esp-elf\bin;C:\SysGCC\esp32-master\tools\xtensa-esp-elf\esp-15.2.0_20250920\xtensa-esp-elf\bin;C:\Program Files (x86)\VMware\VMware Workstation\bin\;C:\Program Files\Microsoft\jdk-11.0.16.101-hotspot\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\Git\cmd;C:\Users\gojimmypi\AppData\Local\Microsoft\WindowsApps;C:\Users\gojimmypi\AppData\Local\Programs\Microsoft VS Code\bin;C:\ST\STM32CubeIDE_1.14.1\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.1.100.202311100844\tools\bin;C:\Program Files\Git\usr\bin\;C:\Users\gojimmypi\.dotnet\tools;C:\SysGCC\esp32-master\tools\riscv32-esp-elf\esp-13.2.0_20240530\riscv32-esp-elf\bin;C:\Users\gojimmypi\AppData\Local\Microsoft\WinGet\Packages\Ninja-build.Ninja_Microsoft.Winget.Source_8wekyb3d8bbwe;;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\VC\Linux\bin\ConnectionManagerExe @@ -96,3 +130,7 @@ endif() # list(PREPEND CMAKE_PROGRAM_PATH ${PATH_LIST}) # list(PREPEND CMAKE_INCLUDE_PATH ${INCLUDE_LIST}) # list(PREPEND CMAKE_LIBRARY_PATH ${LIB_LIST}) + +endif() # DETECT_VS2022 + +set(VS2022_CONFIG_CMAKE_INCLUDED true) diff --git a/cmake/wolfboot.cmake b/cmake/wolfboot.cmake index cae75bf9f5..9c94741617 100644 --- a/cmake/wolfboot.cmake +++ b/cmake/wolfboot.cmake @@ -18,6 +18,16 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA +# Ensure this file is only included and initialized once +if(CMAKE_VERSION VERSION_LESS 3.10) + # Fallback path for older CMake + if(DEFINED WOLFBOOT_CMAKE_INCLUDED) + return() + endif() +else() + include_guard(GLOBAL) +endif() + include(${CMAKE_CURRENT_LIST_DIR}/utils.cmake) set(VERSION ${WOLFBOOT_VERSION}) @@ -119,3 +129,5 @@ function(gen_wolfboot_factory_image PLATFORM_NAME TARGET) multiconfigfileinstall(${BOOTLOADER_OUTPUTS} bin) endfunction() + +set(WOLFBOOT_CMAKE_INCLUDED true) diff --git a/config/examples/README.md b/config/examples/README.md index 495d11e7e8..b65ec3dea8 100644 --- a/config/examples/README.md +++ b/config/examples/README.md @@ -1,4 +1,4 @@ -# Config Example Files +# Config Example Files This directory contains example `.config` presets for various target devices. @@ -13,5 +13,17 @@ See the [CMakePresets.json](../../CMakePresets.json) file. Config files can be added or updated to the `CMakePresets.json` like this: ```bash -python3 config2presets.py ./config/examples/stm32h7.config +python3 ./tools/scripts/config2presets.py ./config/examples/stm32h7.config + +# then test it: + +./tools/scripts/wolfboot_build.sh --target stm32h7 +``` + +## Troubleshooting + +The wrong toolchain is being used, or a target was not specified + +``` +Error: no such instruction: `isb' ``` diff --git a/docs/CMake.md b/docs/CMake.md new file mode 100644 index 0000000000..6f156f8ddd --- /dev/null +++ b/docs/CMake.md @@ -0,0 +1,3 @@ +# wolfBoot CMake + +See the [`WOLFBOOT_ROOT`/cmake/README.md](../cmake/README.md) file. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..3ecd13c5e6 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,33 @@ +## wolfBoot Docs and Platform-Specific Details + +See also: [wolfBoot Product Overview](https://www.wolfssl.com/products/wolfboot/) and [wolfBoot Manual](https://www.wolfssl.com/documentation/manuals/wolfboot/). + + +- [**API.md**](./API.md) - Overview of wolfBoot public APIs and how to use them. +- [**ata_security.md**](./ata_security.md) - ATA security features (lock/unlock, passwords) and wolfBoot integration. +- [**azure_keyvault.md**](./azure_keyvault.md) - Using Azure Key Vault for key management and signing with wolfBoot. +- [**CMake.md**](./CMake.md) - CMake-based build setup, presets, toolchains, and tips for building wolfBoot. +- [**compile.md**](./compile.md) - How to build/compile wolfBoot (toolchains, options, typical steps). +- [**encrypted_partitions.md**](./encrypted_partitions.md) - Creating and managing encrypted firmware/data partitions. +- [**firmware_image.md**](./firmware_image.md) - wolfBoot firmware image format, layout, and metadata. +- [**firmware_update.md**](./firmware_update.md) - Update flow: slots, verification, rollback, and recovery. +- [**flash-OTP.md**](./flash-OTP.md) - Using One-Time Programmable (OTP) regions in flash for secure data. +- [**flash_partitions.md**](./flash_partitions.md) - Flash partitioning schemes and configuration guidance. +- [**HAL.md**](./HAL.md) - Hardware Abstraction Layer notes and porting considerations. +- [**keystore.md**](./keystore.md) - Keystore design, key storage, and access strategies. +- [**lib.md**](./lib.md) - Using wolfBoot as a library and linking/integration guidance. +- [**Loader.md**](./Loader.md) - Loader/secondary stage behavior and handoff to application. +- [**measured_boot.md**](./measured_boot.md) - Measured boot concepts and recording measurements (e.g., PCRs). +- [**png/**](./png) - Folder of images/diagrams referenced by the documentation. +- [**PQ.md**](./PQ.md) - Post-quantum algorithms and PQC support in wolfBoot. +- [**README.md**](./README.md) - Overview and index of the documentation set. +- [**remote_flash.md**](./remote_flash.md) - Working with external/remote flash (SPI/QSPI, mapping, access). +- [**Renesas.md**](./Renesas.md) - Notes and specifics for Renesas platforms/ports. +- [**Signing.md**](./Signing.md) - Keys, signatures, and the image signing workflow. +- [**STM32-TZ.md**](./STM32-TZ.md) - STM32 TrustZone (Armv8-M) setup and usage with wolfBoot. +- [**STM32.md**](./STM32.md) - STM32 platform notes, options, and integration tips. +- [**Targets.md**](./Targets.md) - Supported targets and platform-specific configuration. +- [**TPM.md**](./TPM.md) - TPM integration, measured boot, and attestation flows. +- [**wolfHSM.md**](./wolfHSM.md) - Integrating wolfHSM with wolfBoot for secure key operations. + + diff --git a/docs/STM32.md b/docs/STM32.md new file mode 100644 index 0000000000..afbb6931d7 --- /dev/null +++ b/docs/STM32.md @@ -0,0 +1,123 @@ +## wolfBoot for STM32 devices + +The default [Makefile](../Makefile) needs at least the `gcc-arm-none-eabi`. + +```bash +sudo apt update +sudo apt install -y build-essential gcc-arm-none-eabi binutils-arm-none-eabi +# optional (often handy): gdb-multiarch or gdb-arm-none-eabi +arm-none-eabi-gcc --version # should print the version +``` + +The device manufacturer toolchain _also_ needs to be installed. For example without the [STM32CubeIDE Software](https://www.st.com/en/development-tools/stm32cubeide.html), +errors like this will otherwise be encountered: + +``` + [CC ARM] hal/stm32l4.o +hal/stm32l4.c:24:10: fatal error: stm32l4xx_hal.h: No such file or directory + 24 | #include "stm32l4xx_hal.h" + | ^~~~~~~~~~~~~~~~~ +``` + +## Quick Start + +```bash +git clone https://github.com/wolfssl/wolfBoot.git +cd wolfBoot +git submodule update --init + +## Use make +# edit your .config or copy from config/examples +make + +## OR ## + +# use cmake via wolfbuild.sh script: + +./tools/scripts/wolfboot_build.sh --CLEAN +./tools/scripts/wolfboot_build.sh --CLEAN stm32h7 +./tools/scripts/wolfboot_build.sh --target stm32h7 +``` + +### VS Code + +Windows users may need one of these: + +- [Visual Studio 2022](https://visualstudio.microsoft.com/) +- [Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/). See `C:\Program Files(x86)\Windows kits`. + +#### Launch Stand-alone VS Code + +The MSVC kit may be needed if VS 2022 is not installed. + +Select `View` - `Command Palette`, search for CMake: Select a Compiler + +See also: CMake: Delete Cache and Reconfigure + + +#### Launch VS Code from VS 2022 Command prompt. + +Delete any existing `build` or `build-[target]` directories as needed. + +Open a VS 2022 Developer command prompt. + +From the command prompt, open the `wolfBoot.code-workspace` VS Code workspace: + +```dos +cd c:\workspace\wolfboot-%USERNAME% +code ./IDE/VSCode/wolfBoot.code-workspace +``` + +### Visual Studio IDE + +For the `Select Startup Item`, leave at default. Do not select `image`, wolfboot_name[], etc. + +Right click on `CMakeLists.txt` and select `Delete Cache and Reconfigure`. + +Right click on `CMakeLists.txt` and select `Build`. + +### Visual Studio Command Prompt + +Select `View` - `Terminal` from the menu bar. + +* Configure: `cmake --preset ` +* Build: `cmake --build --preset ` + +```bash +# delete build directory +rmdir /s /q build-stm32l4 + +# configure +cmake --preset stm32l4 + +# build +cmake --build --preset stm32l4 +``` + +If there are no devices listed in the `Manage Configurations` drop-down, ensure the `CMakePresets.json` is valid. +A single json syntax error will spoil the entire project. + +## Your own toolchain + +Create a `CMakeUserPresets.json` (ignored by git, see and rename `cmake/CMakeUserPresets.json.sample` ): + +```json +{ + "version": 3, + "configurePresets": [ + { + "name": "my-arm-bin", + "inherits": "stm32l4", + "cacheVariables": { + "ARM_GCC_BIN": "C:/Tools/arm-none-eabi-14.2/bin" + } + } + ], + "buildPresets": [ + { + "name": "my-arm-bin", + "configurePreset": "my-arm-bin" + } + ] +} +``` diff --git a/my_test.bat b/my_test.bat deleted file mode 100644 index d6349f727c..0000000000 --- a/my_test.bat +++ /dev/null @@ -1,8 +0,0 @@ -rmdir /s /q build-windows-stm32l4 - -cmake --preset windows-stm32l4 - - -:: cmake --build --preset windows-stm32l4 --parallel 4 -v - -cmake --build --preset windows-stm32l4 diff --git a/my_test.sh b/my_test.sh deleted file mode 100644 index d77e7aa2d5..0000000000 --- a/my_test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -echo "Remove prior build directories..." -rm -rf ./build-windows-stm32l4 -rm -rf ./build-linux-stm32l4 -rm -rf ./build-stm32l4 - -echo "cmake --preset stm32l4" - cmake --preset stm32l4 - -echo "cmake --build --preset stm32l4" - cmake --build --preset stm32l4 diff --git a/test-app/CMakeLists.txt b/test-app/CMakeLists.txt index 353514d475..a0b8a12911 100644 --- a/test-app/CMakeLists.txt +++ b/test-app/CMakeLists.txt @@ -1,4 +1,4 @@ -# CMakeLists.txt +# wolfboot test-app/CMakeLists.txt # # Copyright (C) 2025 wolfSSL Inc. # diff --git a/tools/keytools/sign.c b/tools/keytools/sign.c index 712b1c8bac..fafd3ab4e4 100644 --- a/tools/keytools/sign.c +++ b/tools/keytools/sign.c @@ -2830,9 +2830,9 @@ int main(int argc, char** argv) } printf("Input image: %s\n", CMD.image_file); printf("Selected cipher: %s\n", sign_str); - printf("Selected hash : %s\n", hash_str); + printf("Selected hash: %s\n", hash_str); if (CMD.sign != NO_SIGN) { - printf("Private key: %s\n", CMD.key_file); + printf("Private key: %s\n", CMD.key_file); } if (CMD.hybrid) { printf("Secondary cipher: %s\n", secondary_sign_str); @@ -2853,7 +2853,7 @@ int main(int argc, char** argv) if (CMD.encrypt) { printf("Encrypted output: %s\n", CMD.output_encrypted_image_file); } - printf("Target partition id : %hu ", CMD.partition_id); + printf("Target partition id: %hu ", CMD.partition_id); if (CMD.partition_id == HDR_IMG_TYPE_WOLFBOOT) printf("(bootloader)"); printf("\n"); diff --git a/tools/scripts/cmake_dev_prompt_test.bat b/tools/scripts/cmake_dev_prompt_test.bat new file mode 100644 index 0000000000..67a6e4f130 --- /dev/null +++ b/tools/scripts/cmake_dev_prompt_test.bat @@ -0,0 +1,79 @@ +::!/cmd/batch +:: +:: cmake_dev_prompt_test.bat +:: +:: Some cmake tests from a VS 2022 dev prompt +:: +:: We start in /tools/scripts, but build two directories up: from wolfBoot root +:: +:: Example: +:: C:\workspace\wolfBoot>.\tools\scripts\cmake_dev_prompt_test.bat +:: +@echo off +setlocal enableextensions enabledelayedexpansion + +rem === Resolve script path/dir === +set "SCRIPT_PATH=%~f0" +for %%I in ("%~dp0") do set "SCRIPT_DIR=%%~fI" + +rem === Repo root is parent of /tools/scripts === +for %%I in ("%SCRIPT_DIR%\..\..") do set "REPO_ROOT=%%~fI" + +rem === Caller’s current directory === +for %%I in ("%CD%") do set "CALLER_CWD=%%~fI" + +rem === (Optional) Normalize to physical paths via PowerShell to resolve junctions/symlinks === +rem call :physpath "%SCRIPT_DIR%" SCRIPT_DIR_P +rem call :physpath "%REPO_ROOT%" REPO_ROOT_P +rem call :physpath "%CALLER_CWD%" CALLER_CWD_P +set "SCRIPT_DIR_P=%SCRIPT_DIR%" +set "REPO_ROOT_P=%REPO_ROOT%" +set "CALLER_CWD_P=%CALLER_CWD%" + +rem === Print only if caller CWD is neither nor \scripts === +if /I "%CALLER_CWD_P%"=="%REPO_ROOT_P%" goto after_print +if /I "%CALLER_CWD_P%"=="%REPO_ROOT_P%\scripts" goto after_print + +echo Caller CWD = %CALLER_CWD_P% +echo SCRIPT_DIR = %SCRIPT_DIR_P% +echo REPO_ROOT = %REPO_ROOT_P% + +:after_print +rem === Always work from repo root === +pushd "%REPO_ROOT_P%" || goto :err +echo Starting %~nx0 from %CD% + +:: Is CMake installed? +where cmake >nul 2>&1 +if errorlevel 1 ( + echo This test should be run from a VS2022 dev prompt. + echo Error: CMake is not installed or not found in path. + goto err +) + + +echo Remove prior build directories... +if exist "build-stm32l4" rmdir /s /q "build-stm32l4" || goto :err + + +:: Begin tests and examples + +cmake --preset stm32l4 + + +:: cmake --build --preset stm32l4 --parallel 4 -v + +cmake --build --preset stm32l4 + +:: Deleting immediately may cause an anti-virus file-locking problem +:: rmdir /s /q build-stm32l4 + +goto done + +:err +echo Failed +exit /b 1 + +:done +echo Done. +exit /b 0 diff --git a/tools/scripts/cmake_dot_config.sh b/tools/scripts/cmake_dot_config.sh new file mode 100644 index 0000000000..c0a787fca6 --- /dev/null +++ b/tools/scripts/cmake_dot_config.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# cmake_dot_config.sh +# +# Example for using cmake with .config +# +# Reminder for WSL: +# git update-index --chmod=+x wolfboot_build.sh +# git commit -m "Make wolfboot_build.sh executable" +# git push + +# Specify the executable shell checker you want to use: +MY_SHELLCHECK="shellcheck" + +# Check if the executable is available in the PATH +if command -v "$MY_SHELLCHECK" >/dev/null 2>&1; then + # Run your command here + shellcheck "$0" || exit 1 +else + echo "$MY_SHELLCHECK is not installed. Please install it if changes to this script have been made." +fi + +set -euo pipefail + +# Begin common dir init, for /tools/scripts +# Resolve this script's absolute path and its directories +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +SCRIPT_PATH="${SCRIPT_DIR}/$(basename -- "${BASH_SOURCE[0]}")" +REPO_ROOT="$(cd -- "${SCRIPT_DIR}/../.." && pwd)" + +# Normalize to physical paths (no symlinks, no trailing slashes) +# SCRIPT_DIR_P="$(cd -- "$SCRIPT_DIR" && pwd -P)" +REPO_ROOT_P="$(cd -- "$REPO_ROOT" && pwd -P)" +CALLER_CWD_P="$(pwd -P)" # where the user ran the script from + +# Print only if caller's cwd is neither REPO_ROOT nor REPO_ROOT/scripts +case "$CALLER_CWD_P" in + "$REPO_ROOT_P" | "$REPO_ROOT_P"/scripts) + : # silent + ;; + *) + echo "Script paths:" + echo "-- SCRIPT_PATH =$SCRIPT_PATH" + echo "-- SCRIPT_DIR =$SCRIPT_DIR" + echo "-- REPO_ROOT =$REPO_ROOT" + ;; +esac + +# Always work from the repo root, regardless of where the script was invoked +cd -- "$REPO_ROOT_P" || { printf 'Failed to cd to: %s\n' "$REPO_ROOT_P" >&2; exit 1; } +echo "Starting $0 from $(pwd -P)" + +# End common dir init + +# Regardless of where launches, we should not be at pwd=WOLFBOOT_ROOT + +# Set some logging params +LOG_FILE="run.log" +KEYWORD="Config mode: dot" +echo "Saving output to $LOG_FILE" + +echo "Fetch stm32h7 example .config" +cp ./config/examples/stm32h7.config ./.config +ls .config +cat .config +echo "" + +echo "Clean" +rm -rf ./build-stm32h7 +cmake -S . -B build-stm32h7 \ + -DUSE_DOT_CONFIG=ON \ + -DWOLFBOOT_TARGET=stm32h7 2>&1 | tee "$LOG_FILE" >/dev/tty + +# Config dot-config mode +if grep -q -- "$KEYWORD" "$LOG_FILE"; then + echo "Keyword found: $KEYWORD" +else + echo "Keyword not found: $KEYWORD" >&2 + exit 1 +fi + +# Sample build +cmake --build build-stm32h7 -j diff --git a/tools/scripts/cmake_test.bat b/tools/scripts/cmake_test.bat new file mode 100644 index 0000000000..f54ea546ac --- /dev/null +++ b/tools/scripts/cmake_test.bat @@ -0,0 +1,80 @@ +::!/cmd/batch +:: +:: cmake_test.bat +:: +:: Unlike the cmake_dev_prompt_test.bat that is expected to run in a VS 2022 Dev Prompt +:: This test manually sets paths to cmake and include files (also assumes VS 2022 is installed, but can be any suitable path) + +set "Path=C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\bin\HostX86\x86;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\VC\VCPackages;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\bin\Roslyn;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\;C:\Program Files (x86)\HTML Help Workshop;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Team Tools\DiagnosticsHub\Collector;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\Extensions\Microsoft\CodeCoverage.Console;C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\\x86;C:\Program Files (x86)\Windows Kits\10\bin\\x86;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\\MSBuild\Current\Bin\amd64;C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\;C:\Program Files (x86)\VMware\VMware Workstation\bin\;C:\Program Files\Microsoft\jdk-11.0.16.101-hotspot\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\Git\cmd;C:\SysGCC\esp32-master\tools\riscv32-esp-elf\esp-15.2.0_20250920\riscv32-esp-elf\bin;C:\SysGCC\esp32-master\tools\xtensa-esp-elf\esp-15.2.0_20250920\xtensa-esp-elf\bin;C:\Program Files (x86)\VMware\VMware Workstation\bin\;C:\Program Files\Microsoft\jdk-11.0.16.101-hotspot\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\Git\cmd;C:\Users\gojimmypi\AppData\Local\Microsoft\WindowsApps;C:\Users\gojimmypi\AppData\Local\Programs\Microsoft VS Code\bin;C:\ST\STM32CubeIDE_1.14.1\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.1.100.202311100844\tools\bin;C:\Program Files\Git\usr\bin\;C:\Users\gojimmypi\.dotnet\tools;C:\SysGCC\esp32-master\tools\riscv32-esp-elf\esp-13.2.0_20240530\riscv32-esp-elf\bin;C:\Users\gojimmypi\AppData\Local\Microsoft\WinGet\Packages\Ninja-build.Ninja_Microsoft.Winget.Source_8wekyb3d8bbwe;;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\VC\Linux\bin\ConnectionManagerExe" +set "INCLUDE=C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\include;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\ATLMFC\include;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\VS\include;C:\Program Files (x86)\Windows Kits\10\include\10.0.26100.0\ucrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\um;C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\shared;C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\winrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\cppwinrt;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" +set "LIB=C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\ATLMFC\lib\x86;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\lib\x86;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x86;C:\Program Files (x86)\Windows Kits\10\lib\10.0.26100.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\\lib\10.0.26100.0\\um\x86" + +:: We start in /tools/scripts, but build two directories up: from wolfBoot root + +:: Begin common start directory detection +@echo off +setlocal enableextensions enabledelayedexpansion + +rem === Resolve script path/dir === +set "SCRIPT_PATH=%~f0" +for %%I in ("%~dp0") do set "SCRIPT_DIR=%%~fI" + +rem === Repo root is parent of /tools/scripts === +for %%I in ("%SCRIPT_DIR%\..\..") do set "REPO_ROOT=%%~fI" + +rem === Caller’s current directory === +for %%I in ("%CD%") do set "CALLER_CWD=%%~fI" + +rem === (Optional) Normalize to physical paths via PowerShell to resolve junctions/symlinks === +rem call :physpath "%SCRIPT_DIR%" SCRIPT_DIR_P +rem call :physpath "%REPO_ROOT%" REPO_ROOT_P +rem call :physpath "%CALLER_CWD%" CALLER_CWD_P +set "SCRIPT_DIR_P=%SCRIPT_DIR%" +set "REPO_ROOT_P=%REPO_ROOT%" +set "CALLER_CWD_P=%CALLER_CWD%" + +rem === Print only if caller CWD is neither nor \scripts === +if /I "%CALLER_CWD_P%"=="%REPO_ROOT_P%" goto after_print +if /I "%CALLER_CWD_P%"=="%REPO_ROOT_P%\scripts" goto after_print + +echo Caller CWD = %CALLER_CWD_P% +echo SCRIPT_DIR = %SCRIPT_DIR_P% +echo REPO_ROOT = %REPO_ROOT_P% + +:after_print +rem === Always work from repo root === +pushd "%REPO_ROOT_P%" || goto :err +echo Starting %~nx0 from %CD% +:: End common start directory detection + + +:: Is CMake installed? +where cmake >nul 2>&1 +if errorlevel 1 ( + echo This test should be run from a VS2022 dev prompt. + echo Error: CMake is not installed or not found in path. + goto err +) + + + +rmdir /s /q build-stm32l4 + +cmake --preset stm32l4 + + +:: cmake --build --preset stm32l4 --parallel 4 -v + +cmake --build --preset stm32l4 + +goto done + +:err +popd +echo Failed. +exit /b 1 + +:done +popd +echo Done. +exit /b 0 diff --git a/tools/scripts/cmake_test.sh b/tools/scripts/cmake_test.sh new file mode 100644 index 0000000000..bcc7aa2410 --- /dev/null +++ b/tools/scripts/cmake_test.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Specify the executable shell checker you want to use: +MY_SHELLCHECK="shellcheck" + +# Check if the executable is available in the PATH +if command -v "$MY_SHELLCHECK" >/dev/null 2>&1; then + # Run your command here + shellcheck "$0" || exit 1 +else + echo "$MY_SHELLCHECK is not installed. Please install it if changes to this script have been made." +fi + +# Resolve this script's absolute path and its directories +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +SCRIPT_PATH="${SCRIPT_DIR}/$(basename -- "${BASH_SOURCE[0]}")" +REPO_ROOT="$(cd -- "${SCRIPT_DIR}/../../" && pwd)" + +# Normalize to physical paths (no symlinks, no trailing slashes) +# SCRIPT_DIR_P="$(cd -- "$SCRIPT_DIR" && pwd -P)" +REPO_ROOT_P="$(cd -- "$REPO_ROOT" && pwd -P)" +CALLER_CWD_P="$(pwd -P)" # <— where the user ran the script from + +# Print only if caller's cwd is neither REPO_ROOT nor REPO_ROOT/scripts +case "$CALLER_CWD_P" in + "$REPO_ROOT_P" | "$REPO_ROOT_P"/scripts) + : # silent + ;; + *) + echo "Script paths:" + echo "-- SCRIPT_PATH =$SCRIPT_PATH" + echo "-- SCRIPT_DIR =$SCRIPT_DIR" + echo "-- REPO_ROOT =$REPO_ROOT" + ;; +esac + +# Always work from the repo root, regardless of where the script was invoked +cd -- "$REPO_ROOT_P" || { printf 'Failed to cd to: %s\n' "$REPO_ROOT_P" >&2; exit 1; } +echo "Starting $0 from $(pwd -P)" + + +echo "Remove prior build directories..." +rm -rf ./build-stm32l4 + +echo "cmake --preset stm32l4" + cmake --preset stm32l4 + +echo "cmake --build --preset stm32l4" + cmake --build --preset stm32l4 diff --git a/config2presets.py b/tools/scripts/config2presets.py similarity index 50% rename from config2presets.py rename to tools/scripts/config2presets.py index 1b40ec5c58..0677285bbb 100644 --- a/config2presets.py +++ b/tools/scripts/config2presets.py @@ -1,6 +1,13 @@ #!/usr/bin/env python3 + +# Adds .config file to CMakePresets.json +# +# Example: +# python3 ./tools/scripts/config2presets.py ./config/examples/stm32h7.config + import argparse, json, os, re, sys from collections import OrderedDict +from pathlib import Path COMMENT_RE = re.compile(r"\s*(#.*)?$") LINE_RE = re.compile(r'^([A-Za-z_][A-Za-z0-9_]*)\s*\??=\s*(.*)$') @@ -8,26 +15,31 @@ BOOL_TRUE = {"1", "on", "true", "yes", "y"} BOOL_FALSE = {"0", "off", "false", "no", "n"} + def normalize_bool(s: str): v = s.strip().lower() - if v in BOOL_TRUE: return "ON" - if v in BOOL_FALSE: return "OFF" + if v in BOOL_TRUE: + return "ON" + if v in BOOL_FALSE: + return "OFF" return None -def parse_config(path: str): + +def parse_config(path: Path): kv = OrderedDict() - with open(path, "r", encoding="utf-8") as f: + with path.open("r", encoding="utf-8") as f: for ln in f: if COMMENT_RE.fullmatch(ln): continue m = LINE_RE.match(ln.rstrip("\n")) if not m: - # skip silently; load_dot_config warns + # skip silently; load_dot_config warns elsewhere continue key, val = m.group(1), m.group(2).strip() kv[key] = val return kv + def choose_target(kv): # Prefer explicit wolfBoot var; else accept TARGET if present if "WOLFBOOT_TARGET" in kv and kv["WOLFBOOT_TARGET"]: @@ -36,6 +48,7 @@ def choose_target(kv): return kv["TARGET"] return "custom" + def to_cache_vars(kv): cache = OrderedDict() for k, v in kv.items(): @@ -49,28 +62,33 @@ def to_cache_vars(kv): cache[k] = nb if nb is not None else v return cache + def ensure_base_vars(cache, toolchain_path): # Always ensure toolchain file is set cache.setdefault("CMAKE_TOOLCHAIN_FILE", toolchain_path) - # Your build typically wants this on + # Typically desired cache.setdefault("BUILD_TEST_APPS", "ON") # Force preset mode when generating from .config into presets cache["WOLFBOOT_CONFIG_MODE"] = "preset" return cache + def make_preset_name(target): - return f"linux-{target}" + return f"{target}" + def make_binary_dir(source_dir, target): return os.path.join(source_dir, f"build-{target}") -def load_existing_presets(presets_path): + +def load_existing_presets(presets_path: Path): try: - with open(presets_path, "r", encoding="utf-8") as f: + with presets_path.open("r", encoding="utf-8") as f: return json.load(f) except FileNotFoundError: return None + def merge_preset(doc, cfg_preset, bld_preset): if doc is None: return { @@ -81,33 +99,90 @@ def merge_preset(doc, cfg_preset, bld_preset): # If file has newer schema that your CMake can't handle, you can still append, # but CMake 3.22.1 will choke. We keep the existing version as-is. - if "configurePresets" not in doc: doc["configurePresets"] = [] - if "buildPresets" not in doc: doc["buildPresets"] = [] + if "configurePresets" not in doc: + doc["configurePresets"] = [] + if "buildPresets" not in doc: + doc["buildPresets"] = [] # Replace presets with same name doc["configurePresets"] = [p for p in doc["configurePresets"] if p.get("name") != cfg_preset["name"]] + [cfg_preset] doc["buildPresets"] = [p for p in doc["buildPresets"] if p.get("name") != bld_preset["name"]] + [bld_preset] return doc + def main(): ap = argparse.ArgumentParser(description="Generate or merge a CMakePresets.json from a .config file") - ap.add_argument("config", help="Path to .config") - ap.add_argument("--toolchain", default="cmake/toolchain_arm-none-eabi.cmake", help="Path to toolchain file (relative to repo)") - ap.add_argument("--presets", default="CMakePresets.json", help="Path to CMakePresets.json to create/merge") - ap.add_argument("--generator", default="Ninja", help="CMake generator") - ap.add_argument("--preset-name", default=None, help="Override preset name") - ap.add_argument("--binary-dir", default=None, help="Override binaryDir") - ap.add_argument("--display-name", default=None, help="Override displayName") + ap.add_argument("config", + help="Path to .config (relative to your current directory if not absolute)") + ap.add_argument("--toolchain", + default="cmake/toolchain_arm-none-eabi.cmake", + help="Path to toolchain file (relative to repo root if not absolute)") + ap.add_argument("--presets", + default="CMakePresets.json", + help="Path to CMakePresets.json to create/merge (relative to repo root if not absolute)") + ap.add_argument("--generator", + default="Ninja", + help="CMake generator") + ap.add_argument("--preset-name", + default=None, + help="Override preset name") + ap.add_argument("--binary-dir", + default=None, + help="Override binaryDir") + ap.add_argument("--display-name", + default=None, + help="Override displayName") args = ap.parse_args() - kv = parse_config(args.config) + # Begin common dir init, for /tools/scripts + script_path = Path(__file__).resolve() + script_dir = script_path.parent.resolve() + + # repo root is parent of tools/scripts → go up two levels + repo_root = (script_dir / ".." / "..").resolve() + + caller_cwd = Path.cwd().resolve() + + # Print only if caller's current working directory is neither REPO_ROOT nor REPO_ROOT/tools/scripts + if caller_cwd != repo_root and caller_cwd != (repo_root / "tools" / "scripts"): + print("Script paths:") + print(f"-- SCRIPT_PATH = {script_path}") + print(f"-- SCRIPT_DIR = {script_dir}") + print(f"-- REPO_ROOT = {repo_root}") + + # Always work from the repo root, regardless of where the script was invoked + try: + os.chdir(repo_root) + except OSError as e: + print(f"Failed to cd to: {repo_root}\n{e}", file=sys.stderr) + sys.exit(1) + print(f"Starting {script_path} from {Path.cwd().resolve()}") + # End common dir init + + # Resolve paths: + # - config: relative to caller's CWD (so user can pass local relative paths naturally) + # - toolchain/presets: relative to repo root (we already chdir there) + config_path = Path(args.config) + if not config_path.is_absolute(): + config_path = (caller_cwd / config_path).resolve() + + toolchain_path = Path(args.toolchain) + if not toolchain_path.is_absolute(): + toolchain_path = (repo_root / toolchain_path).resolve() + + presets_path = Path(args.presets) + if not presets_path.is_absolute(): + presets_path = (repo_root / presets_path).resolve() + + kv = parse_config(config_path) if not kv: - print("No settings parsed from .config", file=sys.stderr) + print(f"No settings parsed from .config: {config_path}", file=sys.stderr) sys.exit(2) target = choose_target(kv) cache = to_cache_vars(kv) - cache = ensure_base_vars(cache, args.toolchain) + # Use forward slashes in JSON for better CMake portability + cache = ensure_base_vars(cache, toolchain_path.as_posix()) # Build preset objects source_dir = "${sourceDir}" # CMake variable; leave literal @@ -125,26 +200,27 @@ def main(): bld_preset = OrderedDict([ ("name", preset_name), ("configurePreset", preset_name), - ("jobs", 0), + ("jobs", 4), + ("verbose", True), + ("targets", ["all"]), ]) # Ensure schema v3 unless existing file says otherwise - doc = load_existing_presets(args.presets) + doc = load_existing_presets(presets_path) if doc is None: doc = {"version": 3} - - # If existing file has version >3, we *keep it*, but remember your CMake 3.22 understands v3 only. if "version" not in doc: doc["version"] = 3 result = merge_preset(doc, cfg_preset, bld_preset) # Pretty-print with stable key order - with open(args.presets, "w", encoding="utf-8") as f: + with presets_path.open("w", encoding="utf-8") as f: json.dump(result, f, indent=2) f.write("\n") - print(f"Updated {args.presets} with preset '{preset_name}' targeting '{target}'") + print(f"Updated {presets_path} with preset '{preset_name}' targeting '{target}'") + if __name__ == "__main__": main() diff --git a/tools/scripts/wolfboot_build.sh b/tools/scripts/wolfboot_build.sh new file mode 100644 index 0000000000..99ee496341 --- /dev/null +++ b/tools/scripts/wolfboot_build.sh @@ -0,0 +1,306 @@ +#!/bin/bash + +# wolfboot_build.sh +# +# ./tools/scripts/wolfboot_build.sh --CLEAN [your target] +# ./tools/scripts/wolfboot_build.sh --target [your target] +# ./tools/scripts/wolfboot_build.sh --flash [your target] +# +# Options: +# Set WOLFBOOT_CLEAN_STRICT=1 to error is any other build directories found +# +# Reminder for WSL: +# git update-index --chmod=+x wolfboot_build.sh +# git commit -m "Make wolfboot_build.sh executable" +# git push + +# Specify the executable shell checker you want to use: +MY_SHELLCHECK="shellcheck" + +# Check if the executable is available in the PATH +if command -v "$MY_SHELLCHECK" >/dev/null 2>&1; then + # Run your command here + shellcheck "$0" || exit 1 +else + echo "$MY_SHELLCHECK is not installed. Please install it if changes to this script have been made." +fi + +# Begin common dir init, for /tools/scripts +# Resolve this script's absolute path and its directories +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +SCRIPT_PATH="${SCRIPT_DIR}/$(basename -- "${BASH_SOURCE[0]}")" +REPO_ROOT="$(cd -- "${SCRIPT_DIR}/../.." && pwd)" + +# Normalize to physical paths (no symlinks, no trailing slashes) +# SCRIPT_DIR_P="$(cd -- "$SCRIPT_DIR" && pwd -P)" +REPO_ROOT_P="$(cd -- "$REPO_ROOT" && pwd -P)" +CALLER_CWD_P="$(pwd -P)" # where the user ran the script from + +# Print only if caller's cwd is neither REPO_ROOT nor REPO_ROOT/scripts +case "$CALLER_CWD_P" in + "$REPO_ROOT_P" | "$REPO_ROOT_P"/scripts) + : # silent + ;; + *) + echo "Script paths:" + echo "-- SCRIPT_PATH =$SCRIPT_PATH" + echo "-- SCRIPT_DIR =$SCRIPT_DIR" + echo "-- REPO_ROOT =$REPO_ROOT" + ;; +esac + +# Always work from the repo root, regardless of where the script was invoked +cd -- "$REPO_ROOT_P" || { printf 'Failed to cd to: %s\n' "$REPO_ROOT_P" >&2; exit 1; } +echo "Starting $0 from $(pwd -P)" + +# End common dir init + +# find_stm32_tool: locate STM32CubeProgrammer tools (e.g., STM32_Programmer_CLI, STLinkUpgrade) +# Usage: +# find_stm32_tool STM32_Programmer_CLI # prints full path, returns 0 if found +# find_stm32_tool STLinkUpgrade # finds .exe on WSL/Windows or .jar on macOS/Linux +# find_stm32_tool STM32_Programmer_CLI STLink_CLI # tries each name until one is found +# +# Optional environment override: +# export STM32CUBE_PROGRAMMER_ROOT="/path/to/STM32CubeProgrammer" +# # (either the install root or its bin/ directory) +# +# ---------- Examples ---------- +# Find the CLI on any platform: +# cli_path="$(find_stm32_tool STM32_Programmer_CLI)" || { echo "CLI not found"; exit 1; } +# echo "CLI: $cli_path" + +# Find the STLink upgrader (exe on WSL/Windows, jar on macOS/Linux): +# upg_path="$(find_stm32_tool STLinkUpgrade STLinkUpgrade.jar)" || { echo "Upgrader not found"; exit 1; } +# echo "Upgrader: $upg_path" + +find_stm32_tool() { + if [ "$#" -lt 1 ]; then + echo "Usage: find_stm32_tool [alt_name ...]" >&2 + return 2 + fi + + # Build candidate bin directories (order matters) + _bins=() + + # 1) User override + if [ -n "$STM32CUBE_PROGRAMMER_ROOT" ]; then + if [ -d "$STM32CUBE_PROGRAMMER_ROOT/bin" ]; then + _bins+=("$STM32CUBE_PROGRAMMER_ROOT/bin") + fi + if [ -d "$STM32CUBE_PROGRAMMER_ROOT" ] && { [ -x "$STM32CUBE_PROGRAMMER_ROOT/STM32_Programmer_CLI" ] || [ -x "$STM32CUBE_PROGRAMMER_ROOT/STM32_Programmer_CLI.exe" ]; }; then + _bins+=("$STM32CUBE_PROGRAMMER_ROOT") + fi + fi + + # 2) WSL/Windows (common default) + if [ -d "/mnt/c" ]; then + _bins+=( + "/mnt/c/Program Files/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin" + "/mnt/c/Program Files (x86)/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin" + ) + fi + + # 3) macOS .app bundle paths + _mac_app="/Applications/STMicroelectronics/STM32Cube/STM32CubeProgrammer/STM32CubeProgrammer.app" + if [ -d "$_mac_app" ]; then + # Most recent distributions place binaries here: + _bins+=("$_mac_app/Contents/Resources/bin") + # Some older guides/installers used this: + _bins+=("$_mac_app/Contents/MacOs/bin") + fi + + # 4) Linux / macOS common install locations + _bins+=( + "$HOME/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin" + "/usr/local/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin" + "/opt/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin" + ) + + # Deduplicate while preserving order + _uniq_bins=() + for d in "${_bins[@]}"; do + _seen=0 + for u in "${_uniq_bins[@]}"; do + [ "$u" = "$d" ] && _seen=1 && break + done + [ "$_seen" -eq 0 ] && _uniq_bins+=("$d") + done + + # Try each requested name across all candidate directories. + for name in "$@"; do + for dir in "${_uniq_bins[@]}"; do + [ -d "$dir" ] || continue + + # Candidates to test (with and without .exe) + cand1="$dir/$name" + cand2="$dir/$name.exe" + + # Special-case: STLinkUpgrade may be shipped as a .jar on macOS/Linux + cand3="$dir/${name%.jar}.jar" + + # Prefer native executable if present + if [ -x "$cand1" ]; then + printf "%s\n" "$cand1" + return 0 + fi + if [ -x "$cand2" ]; then + printf "%s\n" "$cand2" + return 0 + fi + # Jar isn't -x by default; accept it if it exists and is readable + if [ -r "$cand3" ] && { [ "${name%.jar}" = "STLinkUpgrade" ] || [ "$name" = "STLinkUpgrade.jar" ]; }; then + printf "%s\n" "$cand3" + return 0 + fi + done + done + + # Not found + return 1 +} + +#--------------------------------------------------------------------------------------------- +# +#--------------------------------------------------------------------------------------------- +if [ $# -gt 0 ]; then + THIS_OPERATION="$1" + + TARGET="$2" + if [ "$TARGET" = "" ]; then + echo "No target specified" + fi + + if [ "$THIS_OPERATION" = "--CLEAN" ]; then + if [ "$TARGET" = "" ]; then + echo "Clean... (build)" + rm -rf ./build + if [ -e ./build ]; then + echo "ERROR: ./build still exists after rm -rf" >&2 + exit 1 + fi + else + echo "Clean... (build-$TARGET)" + rm -rf "./build-$TARGET" + if [ -e "./build-$TARGET" ]; then + echo "ERROR: ./build-$TARGET still exists after rm -rf" >&2 + exit 1 + fi + fi + + # Any other build directories? + # Warn if others remain, but don't fail unless strict is requested + shopt -s nullglob + others=() + for d in build-*; do + # skip generic build dir (if any) and the one we just removed + [ "$d" = "build" ] && continue + [ "$d" = "build-$TARGET" ] && continue + others+=("$d") + done + + if ((${#others[@]})); then + printf 'Note: Found %d other build directory target(s):\n' "${#others[@]}" + printf '%s\n' "${others[@]}" + if [ -n "$WOLFBOOT_CLEAN_STRICT" ]; then + echo "Failing because WOLFBOOT_CLEAN_STRICT is set." + exit 1 + fi + else + echo 'Success: No other build-[target] directories found.' + fi + exit 0 + fi + + if [ "$THIS_OPERATION" = "--target" ]; then + TARGET="$2" + echo "Set target: $TARGET" + fi + + if [ "$THIS_OPERATION" = "--stlink-upgrade" ]; then + echo "ST-Link upgrade!" + CLI="$(find_stm32_tool STLinkUpgrade)" || { echo "CLI not found"; exit 1; } + if [ -f "$CLI" ]; then + echo "Found stlink upgrade tool: $CLI" + else + echo "CLI=$CLI" + echo "STLinkUpgrade.exe not found, exiting" + exit 2 + fi + + # Run STLinkUpgrade.exe + "$CLI" + status=$? + if [ "$status" -eq 0 ]; then + echo "OK: command succeeded" + else + echo "Failed: command exited with status $status" + fi + exit "$status" + fi + + if [ "$THIS_OPERATION" = "--flash" ]; then + echo "Flash Target=$TARGET" + CLI="$(find_stm32_tool STM32_Programmer_CLI)" || { echo "CLI not found"; exit 1; } + if [ -f "$CLI" ]; then + echo "Found STM32 flasher: $CLI" + else + echo "CLI=$CLI" + echo "STM32_Programmer_CLI.exe not found, exiting" + exit 2 + fi + + WOLFBOOT_BIN="build-$TARGET/test-app/wolfboot_$TARGET.bin" + echo Checking "WOLFBOOT_BIN=$WOLFBOOT_BIN" + if [ ! -f "$WOLFBOOT_BIN" ]; then + echo "Missing: $WOLFBOOT_BIN (build first: cmake --build --preset \"$TARGET\")" + exit 2 + fi + IMAGE_WOLFBOOT=$(wslpath -w "$WOLFBOOT_BIN") + "$CLI" -c port=SWD mode=UR freq=400 -w "$IMAGE_WOLFBOOT" 0x08000000 -v + + SIGNED="build-$TARGET/test-app/image_v1_signed.bin" + echo "Checking SIGNED=$SIGNED" + if [ ! -f "$SIGNED" ]; then + echo "Missing: $SIGNED (try: cmake --build --preset \"$TARGET\" --target test-app)" + exit 2 + fi + + BOOT_ADDR=0x0800A000 # your wolfBoot BOOT address + IMAGE_SIGNED=$(wslpath -w "$SIGNED") + echo "IMAGE_SIGNED=$IMAGE_SIGNED" + + # SWD via ST-LINK (Windows handles the USB) + "$CLI" -c port=SWD mode=UR freq=400 -w "$IMAGE_SIGNED" "$BOOT_ADDR" -v -hardRst + status=$? + if [ "$status" -eq 0 ]; then + echo "OK: command succeeded" + else + echo "Failed: command exited with status $status" + fi + exit "$status" + fi +fi + +if [ "$TARGET" = "" ]; then + echo "Please specify a target." + echo "" + echo " $0 --CLEAN [your target]" + echo " $0 --target [your target]" + echo " $0 --flash [your target]" + echo "" + cmake -S . -B build --list-presets=configure + exit 1 +fi + +echo "cmake --preset $TARGET" + cmake --preset "$TARGET" + +echo "cmake --build --preset $TARGET -j" + cmake --build --preset "$TARGET" -j + +# Reminder: Manual build +# mkdir -p build +# cd build +# cmake -DWOLFBOOT_TARGET=stm32h7 -DBUILD_TEST_APPS=yes -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x8020000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_SIZE=0xD0000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x80F0000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x81C0000 .. +# make diff --git a/wolfBoot.code-workspace b/wolfBoot.code-workspace index 51601f162e..6aee7c3f7b 100644 --- a/wolfBoot.code-workspace +++ b/wolfBoot.code-workspace @@ -35,7 +35,7 @@ "request": "launch", "servertype": "openocd", "cwd": "${workspaceFolder:wolfBoot}", - "executable": "${workspaceFolder:wolfBoot}/build-linux-stm32l4/wolfboot.elf", + "executable": "${workspaceFolder:wolfBoot}/build-stm32l4/wolfboot.elf", "device": "STM32L475VG", "configFiles": [ "interface/stlink-dap.cfg", @@ -43,7 +43,7 @@ ], "runToMain": true, "svdFile": "${workspaceFolder:wolfBoot}/hal/stm32l4/STM32L4x.svd", - "preLaunchTask": "CMake: Build (linux-stm32l4)" + "preLaunchTask": "CMake: Build (stm32l4)" } ] }, @@ -51,29 +51,29 @@ "version": "2.0.0", "tasks": [ { - "label": "CMake: Configure (linux-stm32l4)", + "label": "CMake: Configure (stm32l4)", "command": "cmake", - "args": ["--preset", "linux-stm32l4"], + "args": ["--preset", "stm32l4"], "options": { "cwd": "${workspaceFolder:wolfBoot}" }, "problemMatcher": [] }, { - "label": "CMake: Build (linux-stm32l4)", + "label": "CMake: Build (stm32l4)", "command": "cmake", - "args": ["--build", "--preset", "linux-stm32l4"], + "args": ["--build", "--preset", "stm32l4"], "options": { "cwd": "${workspaceFolder:wolfBoot}" }, "group": "build", "problemMatcher": "$gcc" }, { - "label": "OpenOCD: Flash wolfBoot (linux-stm32l4)", + "label": "OpenOCD: Flash wolfBoot (stm32l4)", "type": "shell", "command": "openocd", "args": [ "-f", "interface/stlink-dap.cfg", "-f", "target/stm32l4x.cfg", "-c", - "program ${workspaceFolder:wolfBoot}/build-linux-stm32l4/wolfboot.elf verify reset exit" + "program ${workspaceFolder:wolfBoot}/build-stm32l4/wolfboot.elf verify reset exit" ], "options": { "cwd": "${workspaceFolder:wolfBoot}" }, "problemMatcher": [] diff --git a/wolfbuild.sh b/wolfbuild.sh deleted file mode 100755 index 01adb8b047..0000000000 --- a/wolfbuild.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/bin/bash - -# Reminder for WSL: -# git update-index --chmod=+x wolfbuild.sh -# git commit -m "Make wolfbuild.sh executable" -# git push - -# Specify the executable shell checker you want to use: -MY_SHELLCHECK="shellcheck" - -# Check if the executable is available in the PATH -if command -v "$MY_SHELLCHECK" >/dev/null 2>&1; then - # Run your command here - shellcheck "$0" || exit 1 -else - echo "$MY_SHELLCHECK is not installed. Please install it if changes to this script have been made." -fi - -if [ $# -gt 0 ]; then - THIS_OPERATION="$1" - - TARGET="$2" - if [ "$TARGET" = "" ]; then - echo "No target specified" - fi - - if [ "$THIS_OPERATION" = "--CLEAN" ]; then - if [ "$TARGET" = "" ]; then - echo "Clean... (build)" - rm -rf ./build - else - echo "Clean... (build-$TARGET)" - rm -rf "./build-$TARGET" - fi - - # Any other build directories? - shopt -s nullglob - dirs=(build-*/) - if ((${#dirs[@]})); then - printf 'Warning: Found %d other build directory target(s):\n' "${#dirs[@]}" - printf '\n' - printf '%s\n' "${dirs[@]%/}" - printf '\n' - echo "Try: $0 --CLEAN [target]" - exit 1 - else - echo 'Success: No other build-[target] directories found.' - exit 0 - fi - fi - - if [ "$THIS_OPERATION" = "--target" ]; then - TARGET="$2" - echo "Set target: $TARGET" - fi - - if [ "$THIS_OPERATION" = "--stlink-upgrade" ]; then - echo "ST-Link upgrade!" - CLI="/mnt/c/Program Files/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STLinkUpgrade.exe" - - "$CLI" - status=$? - if [ "$status" -eq 0 ]; then - echo "OK: command succeeded" - else - echo "Failed: command exited with status $status" - fi - exit "$status" - fi - - if [ "$THIS_OPERATION" = "--flash" ]; then - CLI="/mnt/c/Program Files/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STM32_Programmer_CLI.exe" - - WOLFBOOT_BIN="build-linux-stm32l4/test-app/wolfboot_stm32l4.bin" - if [ ! -f "$WOLFBOOT_BIN" ]; then - echo "Missing: $WOLFBOOT_BIN (build first: cmake --build --preset \"$TARGET\")" - exit 2 - fi - IMAGE_WOLFBOOT=$(wslpath -w "$WOLFBOOT_BIN") - "$CLI" -c port=SWD mode=UR freq=400 -w "$IMAGE_WOLFBOOT" 0x08000000 -v - - SIGNED="build-$TARGET/test-app/image_v1_signed.bin" - if [ ! -f "$SIGNED" ]; then - echo "Missing: $SIGNED (try: cmake --build --preset \"$TARGET\" --target test-app)" - exit 2 - fi - - BOOT_ADDR=0x0800A000 # your wolfBoot BOOT address - IMAGE_SIGNED=$(wslpath -w "$SIGNED") - echo "IMAGE_SIGNED=$IMAGE_SIGNED" - - # SWD via ST-LINK (Windows handles the USB) - "$CLI" -c port=SWD mode=UR freq=400 -w "$IMAGE_SIGNED" "$BOOT_ADDR" -v -hardRst - status=$? - if [ "$status" -eq 0 ]; then - echo "OK: command succeeded" - else - echo "Failed: command exited with status $status" - fi - exit "$status" - fi -fi - -if [ "$TARGET" = "" ]; then - echo "Please specify a target." - echo "" - echo " $0 --target [your target]" - echo "" - cmake -S . -B build --list-presets=configure - exit 1 -fi - -echo "cmake --preset $TARGET" - cmake --preset "$TARGET" - -echo "cmake --build --preset $TARGET -j" - cmake --build --preset "$TARGET" -j - -# Reminder: Manual build -# mkdir -p build -# cd build -# cmake -DWOLFBOOT_TARGET=stm32h7 -DBUILD_TEST_APPS=yes -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x8020000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_SIZE=0xD0000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x80F0000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x81C0000 .. -# make From 183bfde9121ea29835b76d5deb144c08a549696c Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Thu, 16 Oct 2025 16:56:54 -0700 Subject: [PATCH 8/9] wolfboot_build cmake script --- tools/scripts/wolfboot_build.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tools/scripts/wolfboot_build.sh diff --git a/tools/scripts/wolfboot_build.sh b/tools/scripts/wolfboot_build.sh old mode 100644 new mode 100755 From b13b81971beed4c4d5e63a47b9257cbdc678c26a Mon Sep 17 00:00:00 2001 From: gojimmypi Date: Thu, 16 Oct 2025 17:08:57 -0700 Subject: [PATCH 9/9] special char cleanup --- IDE/VSCode/README.md | 2 +- INSTALL.md | 8 ++++---- README.md | 2 +- cmake/toolchain_aarch64-none-elf.cmake | 2 +- docs/PQ.md | 4 ++-- docs/Signing.md | 6 +++--- tools/scripts/cmake_test.sh | 2 +- tools/scripts/config2presets.py | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/IDE/VSCode/README.md b/IDE/VSCode/README.md index 8dcbe0bdc9..54ddca38e7 100644 --- a/IDE/VSCode/README.md +++ b/IDE/VSCode/README.md @@ -45,7 +45,7 @@ cmake, ninja-build, gcc-arm-none-eabi, openocd #### Windows path: -Windows path: CMake, Ninja, Arm GNU Toolchain, OpenOCD (or ST’s OpenOCD) +Windows path: CMake, Ninja, Arm GNU Toolchain, OpenOCD (or ST's OpenOCD) Install via PowerShell (will need to restart VSCode): diff --git a/INSTALL.md b/INSTALL.md index 4ebe75a880..133fa1a89c 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,4 +1,4 @@ -# wolfBoot Setup Instructions +# wolfBoot Setup Instructions ## Gathering Sources @@ -40,7 +40,7 @@ wolfBoot -> src -> image.c (crypto verify/hash) -> loader.c (main) - -> libwolfboot.c (User application API’s) + -> libwolfboot.c (User application API's) -> update_*.c (flash/ram wolfBoot_start) -> test-app (example applications) -> tools @@ -68,14 +68,14 @@ The signing key used goes into wolfBoot root (example `rsa4096.der`). make ``` -The “make [target]” +The `make [target]` * `keytools`: Build the C version of the key tools * `wolfboot.bin`: Build the .elf and .bin version of the bootloader only * `test-app/image.bin`: Builds the test application * `test-app/image_v1_signed.bin`: Builds the test application signed with version 1 * `factory.bin`: Builds bootloader and test application signed and appended together -Note: Default is “factory.bin” +Note: Default is `factory.bin` ## Building with Cross Compile diff --git a/README.md b/README.md index 3f2e76c5b3..91dd689848 100644 --- a/README.md +++ b/README.md @@ -784,7 +784,7 @@ sp_c32.c : fatal error C1083: Cannot open compiler generated file: '... sp_c32.o * RP2350 (Raspberry Pi Pico 2, ARM Cortex-M33 with TrustZone) * NXP MCXA153 * NXP MCXW716 - * STM32F1 series (STM32F103 "Blue Pill"board) + * STM32F1 series (STM32F103 "Blue Pill" board) * Improvements to supported targets * Xilinx UltraScale+ (ZynqMP) * Added hardware-accelerated SHA3 hashing via the CSU engine diff --git a/cmake/toolchain_aarch64-none-elf.cmake b/cmake/toolchain_aarch64-none-elf.cmake index 9218590b74..7155e16ba8 100644 --- a/cmake/toolchain_aarch64-none-elf.cmake +++ b/cmake/toolchain_aarch64-none-elf.cmake @@ -96,7 +96,7 @@ message(STATUS "Cross-compiling using GNU aarch64-none-elf toolchain") # Options for DEBUG build # -Og Enables optimizations that do not interfere with debugging. -# -g Produce debugging information in the operating system’s native format. +# -g Produce debugging information in the operating system's native format. set(CMAKE_C_FLAGS_DEBUG "-Og -g" CACHE INTERNAL "C Compiler options for debug build type") set(CMAKE_CXX_FLAGS_DEBUG "-Og -g" CACHE INTERNAL "C++ Compiler options for debug build type") set(CMAKE_ASM_FLAGS_DEBUG "-g" CACHE INTERNAL "ASM Compiler options for debug build type") diff --git a/docs/PQ.md b/docs/PQ.md index 9eb0caa268..a6b2a1cb89 100644 --- a/docs/PQ.md +++ b/docs/PQ.md @@ -1,4 +1,4 @@ -# Post-Quantum Signatures +# Post-Quantum Signatures wolfBoot is continuously adding support for post-quantum (PQ) signature algorithms as they mature. At present, support has been added for three NIST @@ -95,7 +95,7 @@ tradeoff. Stateful HBS schemes are based on the security of their underlying hash functions and Merkle trees, which are not expected to be broken by the advent of cryptographically relevant quantum computers. For this reason they have -been recommended by both NIST SP 800-208, and the NSA’s CNSA 2.0 suite. +been recommended by both NIST SP 800-208, and the NSA's CNSA 2.0 suite. See these links for more info on stateful HBS support and wolfSSL/wolfCrypt: - https://www.wolfssl.com/documentation/manuals/wolfssl/appendix07.html#post-quantum-stateful-hash-based-signatures diff --git a/docs/Signing.md b/docs/Signing.md index 8f78520d11..28e255e54a 100644 --- a/docs/Signing.md +++ b/docs/Signing.md @@ -1,4 +1,4 @@ -# wolfBoot Key Tools +# wolfBoot Key Tools `keygen` and `sign` are two command line tools to be used on a PC (or automated server) environment to manage wolfBoot private keys and sign the initial @@ -178,14 +178,14 @@ is provided: `BASE_SIGNED_IMG.BIN` and the new image signed starting from `IMAGE.BIN`. The result is stored in a file ending in `_signed_diff.bin`. -The compression scheme used is Bentley–McIlroy. +The compression scheme used is Bentley-McIlroy. Options: * `--no-base-sha` : Avoid adding the sha of the base image to the manifest header. By default, the sign tool appends the sha of the base image to the manifest header, so wolfBoot will refuse to start a delta update if the sha does not match the one of the existing image. However, this takes up 32 to 48 bytes extra in the - manifest header, so this option is available to provide compatibility on + manifest header, so this option is available to provide compatibility on existing installations without this feature, where the header size does not allow to accommodate the field diff --git a/tools/scripts/cmake_test.sh b/tools/scripts/cmake_test.sh index bcc7aa2410..c7753c2c82 100644 --- a/tools/scripts/cmake_test.sh +++ b/tools/scripts/cmake_test.sh @@ -19,7 +19,7 @@ REPO_ROOT="$(cd -- "${SCRIPT_DIR}/../../" && pwd)" # Normalize to physical paths (no symlinks, no trailing slashes) # SCRIPT_DIR_P="$(cd -- "$SCRIPT_DIR" && pwd -P)" REPO_ROOT_P="$(cd -- "$REPO_ROOT" && pwd -P)" -CALLER_CWD_P="$(pwd -P)" # <— where the user ran the script from +CALLER_CWD_P="$(pwd -P)" # where the user ran the script from # Print only if caller's cwd is neither REPO_ROOT nor REPO_ROOT/scripts case "$CALLER_CWD_P" in diff --git a/tools/scripts/config2presets.py b/tools/scripts/config2presets.py index 0677285bbb..0dd96c4478 100644 --- a/tools/scripts/config2presets.py +++ b/tools/scripts/config2presets.py @@ -138,7 +138,7 @@ def main(): script_path = Path(__file__).resolve() script_dir = script_path.parent.resolve() - # repo root is parent of tools/scripts → go up two levels + # repo root is parent of tools/scripts - go up two levels repo_root = (script_dir / ".." / "..").resolve() caller_cwd = Path.cwd().resolve()