From 8108b3dc065997c5814ed57568bd7f3672392d95 Mon Sep 17 00:00:00 2001 From: charles Date: Tue, 19 Aug 2025 23:59:46 +0800 Subject: [PATCH] feat: porting for vscode develop env --- .gitignore | 1 + .vscode/launch.json | 72 ++++ CMakeLists.txt | 316 ++++++++++++++++++ CMakePresets.json | 59 ++++ bmd380_bootloader.code-workspace | 12 + app_config.h => bootloader/inc/app_config.h | 0 .../inc/custom_board.h | 0 .../inc/nrf_crypto_allocator.h | 0 sdk_config.h => bootloader/inc/sdk_config.h | 0 .../src/dfu_public_key.c | 0 bootloader/src/main.c | 222 ++++++++++++ bootloader/src/syscalls.c | 31 ++ cmake/arm-none-eabi-gcc.cmake | 47 +++ .../secure_bootloader_gcc_nrf52.ld | 0 main.c | 231 ------------- 15 files changed, 760 insertions(+), 231 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 CMakeLists.txt create mode 100644 CMakePresets.json create mode 100644 bmd380_bootloader.code-workspace rename app_config.h => bootloader/inc/app_config.h (100%) rename custom_board.h => bootloader/inc/custom_board.h (100%) rename nrf_crypto_allocator.h => bootloader/inc/nrf_crypto_allocator.h (100%) rename sdk_config.h => bootloader/inc/sdk_config.h (100%) rename dfu_public_key.c => bootloader/src/dfu_public_key.c (100%) create mode 100644 bootloader/src/main.c create mode 100644 bootloader/src/syscalls.c create mode 100644 cmake/arm-none-eabi-gcc.cmake rename secure_bootloader_gcc_nrf52.ld => linkscripts/secure_bootloader_gcc_nrf52.ld (100%) delete mode 100644 main.c diff --git a/.gitignore b/.gitignore index df003a1..f17b32e 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,4 @@ Thumbs.db /.visualgdb/ /.vs/ *.vgdbsettings.*.user +/build/ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e00eb1c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,72 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "cwd": "${workspaceRoot}", + "executable": "${command:cmake.launchTargetPath}", + "name": "(Ubuntu) launch & debug", + "request": "launch", + "type": "cortex-debug", + "servertype": "jlink", + "serverpath": "/opt/SEGGER/JLink/JLinkGDBServerCLExe", + "serverArgs": [ + "-halt", + "-ir", + "-vd", + "-strict", + ], + "rttConfig": { + "enabled": true, + "address": "auto", + "decoders": [ + { + "label": "", + "port": 0, + "type": "console" + } + ], + }, + "armToolchainPath": "/opt/arm-none-eabi/bin", + "device": "NRF52840_XXAA", + "interface": "swd", + "svdFile": "${workspaceRoot}/../bmd380_sdk/modules/nrfx/mdk/nrf52840.svd", + "runToEntryPoint": "main", + "preLaunchTask": "CMake: build" + }, + { + "cwd": "${workspaceRoot}", + "executable": "${command:cmake.launchTargetPath}", + "name": "(Windows) launch & debug", + "request": "launch", + "type": "cortex-debug", + "servertype": "jlink", + "serverpath": "C:/Program Files/SEGGER/JLink/JLinkGDBServerCL.exe", + "serverArgs": [ + "-halt", + "-ir", + "-vd", + "-strict", + ], + "rttConfig": { + "enabled": true, + "address": "auto", + "decoders": [ + { + "label": "", + "port": 0, + "type": "console" + } + ], + }, + "armToolchainPath": "/opt/arm-none-eabi/bin", + "device": "NRF52840_XXAA", + "interface": "swd", + "svdFile": "${workspaceRoot}/../bmd380_sdk/modules/nrfx/mdk/nrf52840.svd", + "runToEntryPoint": "main", + "preLaunchTask": "CMake: build" + }, + ] +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2370357 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,316 @@ +cmake_minimum_required(VERSION 3.15.0) + +# ========================== +# Toolchain Setup +# ========================== +set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/arm-none-eabi-gcc.cmake) + +# ========================== +# Project Setup +# ========================== +project(elite_bootlaoder VERSION 0.1.0 LANGUAGES C ASM) + +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) + +set(EXECUTABLE ${PROJECT_NAME}.elf) +set(NRF_SDK_DIR ${CMAKE_SOURCE_DIR}/../bmd380_sdk) +set(NRF_SDK_LINKER_DIR ${NRF_SDK_DIR}/modules/nrfx/mdk) +set(SD_LINKER_DIR ${CMAKE_SOURCE_DIR}/SoftdeviceLibraries/hard) +set(LINKER_FILE ${CMAKE_SOURCE_DIR}/linkscripts/secure_bootloader_gcc_nrf52.ld) + +# ========================== +# Compiler Flags and Defines +# ========================== +set(COMMON_COMPILE_OPT + -mcpu=cortex-m4 + -mfpu=fpv4-sp-d16 + -mfloat-abi=hard + -mthumb + -fdata-sections + -ffunction-sections + -Wall -Os -g3 + -Wno-unused-variable + -Wno-pointer-sign + -Wno-array-bounds +) + +set(COMMON_COMPILE_DEF + -DDEBUG=1 + -DBLE_STACK_SUPPORT_REQD + -DBOARD_CUSTOM + -DDEBUG_NRF + -DFLOAT_ABI_HARD + -DNRF52840_XXAA + -DNRF_DFU_SETTINGS_VERSION=2 + -DNRF_DFU_SVCI_ENABLED + -DNRF_SD_BLE_API_VERSION=7 + -DS140 + -DSOFTDEVICE_PRESENT + -DSVC_INTERFACE_CALL_AS_NORMAL_FUNCTION + -DUSE_APP_CONFIG + -DAPP_TIMER_V2 + -DAPP_TIMER_V2_RTC1_ENABLED + -DBL_SETTINGS_ACCESS_ONLY + -DCONFIG_GPIO_AS_PINRESET + -DNRF_DFU_TRANSPORT_BLE=1 + -D__HEAP_SIZE=8192 + -D__STACK_SIZE=8192 +) + +set(COMMON_COMPILE_INC + ## Timing & Events + ${NRF_SDK_DIR}/components/libraries/delay + ${NRF_SDK_DIR}/components/libraries/led_softblink + ${NRF_SDK_DIR}/components/libraries/low_power_pwm + ${NRF_SDK_DIR}/components/libraries/scheduler + ${NRF_SDK_DIR}/components/libraries/timer + + ## Others + ${NRF_SDK_DIR}/components/libraries/experimental_section_vars + ${NRF_SDK_DIR}/components/libraries/ringbuf + ${NRF_SDK_DIR}/components/libraries/slip + ${NRF_SDK_DIR}/components/libraries/svc + + ## Boards + ${NRF_SDK_DIR}/bmd380_sdk/components/boards + ${NRF_SDK_DIR}/components/boards + + ## BLE + ${NRF_SDK_DIR}/components/ble/common + + ## External + ${NRF_SDK_DIR}/external/fprintf + ${NRF_SDK_DIR}/external/nano-pb + ${NRF_SDK_DIR}/external/nrf_cc310_bl/include + ${NRF_SDK_DIR}/external/segger_rtt + ${NRF_SDK_DIR}/external/utf_converter + + ## USB + ${NRF_SDK_DIR}/components/libraries/usbd + ${NRF_SDK_DIR}/components/libraries/usbd/class/cdc + ${NRF_SDK_DIR}/components/libraries/usbd/class/cdc/acm + + ## Crypto + ${NRF_SDK_DIR}/components/libraries/crypto + ${NRF_SDK_DIR}/components/libraries/crypto/backend/cc310 + ${NRF_SDK_DIR}/components/libraries/crypto/backend/cc310_bl + ${NRF_SDK_DIR}/components/libraries/crypto/backend/cifra + ${NRF_SDK_DIR}/components/libraries/crypto/backend/mbedtls + ${NRF_SDK_DIR}/components/libraries/crypto/backend/micro_ecc + ${NRF_SDK_DIR}/components/libraries/crypto/backend/nrf_hw + ${NRF_SDK_DIR}/components/libraries/crypto/backend/nrf_sw + ${NRF_SDK_DIR}/components/libraries/crypto/backend/oberon + ${NRF_SDK_DIR}/components/libraries/crypto/backend/optiga + + ## Bootloader + ${CMAKE_SOURCE_DIR}/bootloader/inc + ${NRF_SDK_DIR}/components/libraries/bootloader + ${NRF_SDK_DIR}/components/libraries/bootloader/ble_dfu + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu + + ## Utility + ${NRF_SDK_DIR}/components/libraries/crc32 + ${NRF_SDK_DIR}/components/libraries/fstorage + ${NRF_SDK_DIR}/components/libraries/sortlist + ${NRF_SDK_DIR}/components/libraries/strerror + + ## Log + ${NRF_SDK_DIR}/components/libraries/log + ${NRF_SDK_DIR}/components/libraries/log/src + + ## Toolchain + ${ARM_TOOLCHAIN_DIR}/../arm-none-eabi/include + ${NRF_SDK_DIR}/components/toolchain/cmsis/include + + ## Core Libs + ${NRF_SDK_DIR}/components/libraries/atomic + ${NRF_SDK_DIR}/components/libraries/atomic_fifo + ${NRF_SDK_DIR}/components/libraries/balloc + ${NRF_SDK_DIR}/components/libraries/memobj + ${NRF_SDK_DIR}/components/libraries/mutex + ${NRF_SDK_DIR}/components/libraries/util + + ## NRFX + ${NRF_SDK_DIR}/integration/nrfx + ${NRF_SDK_DIR}/integration/nrfx/legacy + ${NRF_SDK_DIR}/modules/nrfx + ${NRF_SDK_DIR}/modules/nrfx/drivers/include + ${NRF_SDK_DIR}/modules/nrfx/hal + ${NRF_SDK_DIR}/modules/nrfx/mdk + + ## SoftDevice + ${NRF_SDK_DIR}/components/softdevice/common + ${NRF_SDK_DIR}/components/softdevice/mbr/headers + ${NRF_SDK_DIR}/components/softdevice/s140/headers + ${NRF_SDK_DIR}/components/softdevice/s140/headers/nrf52 +) + +# ========================== +# Configuration Interface +# ========================== +add_library(prj_config INTERFACE) +target_include_directories(prj_config INTERFACE ${COMMON_COMPILE_INC}) +target_compile_definitions(prj_config INTERFACE ${COMMON_COMPILE_DEF}) +target_compile_options(prj_config INTERFACE ${COMMON_COMPILE_OPT}) + + +# ========================== +# Subdirectories +# ========================== + +# ========================== +# Source Files +# ========================== +set(STARTUP_SRC + ${NRF_SDK_DIR}/modules/nrfx/mdk/gcc_startup_nrf52840.S + ${NRF_SDK_DIR}/modules/nrfx/mdk/system_nrf52.c +) + +file(GLOB_RECURSE BOOTLOADER_SOURCES "bootloader/*.c") + +# ========================== +# Executable and Linker +# ========================== +add_executable(${EXECUTABLE} + ${STARTUP_SRC} + ${BOOTLOADER_SOURCES} + + ### Bootloader (DFU) + ${NRF_SDK_DIR}/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/dfu-cc.pb.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/nrf_dfu.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/nrf_dfu_flash.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/nrf_dfu_mbr.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/nrf_dfu_settings.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/nrf_dfu_settings_svci.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/nrf_dfu_svci.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/nrf_dfu_svci_handler.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/nrf_dfu_transport.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/nrf_dfu_utils.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/nrf_dfu_validation.c + ${NRF_SDK_DIR}/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c + ${NRF_SDK_DIR}/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_usb.c + ${NRF_SDK_DIR}/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c + + ### Bootloader Core + ${NRF_SDK_DIR}/components/libraries/bootloader/nrf_bootloader.c + ${NRF_SDK_DIR}/components/libraries/bootloader/nrf_bootloader_app_start.c + ${NRF_SDK_DIR}/components/libraries/bootloader/nrf_bootloader_app_start_final.c + ${NRF_SDK_DIR}/components/libraries/bootloader/nrf_bootloader_dfu_timers.c + ${NRF_SDK_DIR}/components/libraries/bootloader/nrf_bootloader_fw_activation.c + ${NRF_SDK_DIR}/components/libraries/bootloader/nrf_bootloader_info.c + ${NRF_SDK_DIR}/components/libraries/bootloader/nrf_bootloader_wdt.c + + ### USBD + ${NRF_SDK_DIR}/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c + ${NRF_SDK_DIR}/components/libraries/usbd/app_usbd.c + ${NRF_SDK_DIR}/components/libraries/usbd/app_usbd_string_desc.c + ${NRF_SDK_DIR}/components/libraries/usbd/app_usbd_serial_num.c + ${NRF_SDK_DIR}/components/libraries/usbd/app_usbd_core.c + + ### Crypto + ${NRF_SDK_DIR}/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.c + ${NRF_SDK_DIR}/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.c + ${NRF_SDK_DIR}/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.c + ${NRF_SDK_DIR}/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_init.c + ${NRF_SDK_DIR}/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.c + ${NRF_SDK_DIR}/components/libraries/crypto/nrf_crypto_ecc.c + ${NRF_SDK_DIR}/components/libraries/crypto/nrf_crypto_ecdsa.c + ${NRF_SDK_DIR}/components/libraries/crypto/nrf_crypto_hash.c + ${NRF_SDK_DIR}/components/libraries/crypto/nrf_crypto_init.c + ${NRF_SDK_DIR}/components/libraries/crypto/nrf_crypto_shared.c + + ### Core Libraries + ${NRF_SDK_DIR}/components/libraries/atomic/nrf_atomic.c + ${NRF_SDK_DIR}/components/libraries/atomic_fifo/nrf_atfifo.c + ${NRF_SDK_DIR}/components/libraries/balloc/nrf_balloc.c + ${NRF_SDK_DIR}/components/libraries/crc32/crc32.c + ${NRF_SDK_DIR}/components/libraries/experimental_section_vars/nrf_section_iter.c + ${NRF_SDK_DIR}/components/libraries/fstorage/nrf_fstorage.c + ${NRF_SDK_DIR}/components/libraries/fstorage/nrf_fstorage_nvmc.c + ${NRF_SDK_DIR}/components/libraries/fstorage/nrf_fstorage_sd.c + ${NRF_SDK_DIR}/components/libraries/led_softblink/led_softblink.c + ${NRF_SDK_DIR}/components/libraries/low_power_pwm/low_power_pwm.c + ${NRF_SDK_DIR}/components/libraries/memobj/nrf_memobj.c + ${NRF_SDK_DIR}/components/libraries/ringbuf/nrf_ringbuf.c + ${NRF_SDK_DIR}/components/libraries/scheduler/app_scheduler.c + ${NRF_SDK_DIR}/components/libraries/sortlist/nrf_sortlist.c + ${NRF_SDK_DIR}/components/libraries/strerror/nrf_strerror.c + ${NRF_SDK_DIR}/components/libraries/svc/nrf_svc_handler.c + ${NRF_SDK_DIR}/components/libraries/timer/app_timer2.c + ${NRF_SDK_DIR}/components/libraries/timer/drv_rtc.c + ${NRF_SDK_DIR}/components/libraries/util/app_util_platform.c + ${NRF_SDK_DIR}/components/libraries/util/nrf_assert.c + + ### Logging + ${NRF_SDK_DIR}/components/libraries/log/src/nrf_log_backend_rtt.c + ${NRF_SDK_DIR}/components/libraries/log/src/nrf_log_backend_serial.c + ${NRF_SDK_DIR}/components/libraries/log/src/nrf_log_default_backends.c + ${NRF_SDK_DIR}/components/libraries/log/src/nrf_log_frontend.c + ${NRF_SDK_DIR}/components/libraries/log/src/nrf_log_str_formatter.c + + ### External Libraries + ${NRF_SDK_DIR}/external/fprintf/nrf_fprintf.c + ${NRF_SDK_DIR}/external/fprintf/nrf_fprintf_format.c + ${NRF_SDK_DIR}/external/nano-pb/pb_common.c + ${NRF_SDK_DIR}/external/nano-pb/pb_decode.c + ${NRF_SDK_DIR}/external/segger_rtt/SEGGER_RTT.c + ${NRF_SDK_DIR}/components/libraries/slip/slip.c + + ### HAL/Drivers + ${NRF_SDK_DIR}/integration/nrfx/legacy/nrf_drv_clock.c + ${NRF_SDK_DIR}/integration/nrfx/legacy/nrf_drv_power.c + ${NRF_SDK_DIR}/modules/nrfx/drivers/src/nrfx_clock.c + ${NRF_SDK_DIR}/modules/nrfx/drivers/src/nrfx_usbd.c + ${NRF_SDK_DIR}/modules/nrfx/drivers/src/nrfx_power.c + ${NRF_SDK_DIR}/modules/nrfx/hal/nrf_nvmc.c + ${NRF_SDK_DIR}/modules/nrfx/soc/nrfx_atomic.c + + ### SoftDevice & Board + ${NRF_SDK_DIR}/components/boards/boards.c + ${NRF_SDK_DIR}/components/softdevice/common/nrf_sdh.c + ${NRF_SDK_DIR}/components/softdevice/common/nrf_sdh_ble.c + ${NRF_SDK_DIR}/components/softdevice/common/nrf_sdh_soc.c + ${NRF_SDK_DIR}/components/ble/common/ble_srv_common.c +) + +target_link_options(${EXECUTABLE} PRIVATE + -T${LINKER_FILE} + -L${LINKER_DIR} + -L${SD_LINKER_DIR} + -L${NRF_SDK_LINKER_DIR} + -L${NRF_SDK_DIR}/external/nrf_cc310_bl/lib/cortex-m4/hard-float + -mcpu=cortex-m4 + -mfpu=fpv4-sp-d16 + -mfloat-abi=hard + -mthumb + --specs=nano.specs + --specs=nosys.specs + -Wl,-Map=${PROJECT_NAME}.map,--cref + -Wl,--gc-sections + -Xlinker -print-memory-usage -Xlinker +) + +target_link_libraries(${EXECUTABLE} PRIVATE + prj_config + c + nrf_cc310_bl_0.9.13 +) + + +# Optional: Print executable size as part of the post build process +add_custom_command(TARGET ${EXECUTABLE} + POST_BUILD + COMMAND ${CMAKE_SIZE} ${EXECUTABLE}) + +# Optional: Create hex, bin and S-Record files after the build +add_custom_command(TARGET ${EXECUTABLE} + POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -O srec --srec-len=64 ${EXECUTABLE} ${PROJECT_NAME}.s19 + COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE} ${PROJECT_NAME}.hex + COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE} ${PROJECT_NAME}.bin +) \ No newline at end of file diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..2f2f4d6 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,59 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "default", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/${presetName}", + "cacheVariables": { + } + }, + { + "name": "Debug", + "inherits": "default", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "RelWithDebInfo", + "inherits": "default", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "Release", + "inherits": "default", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "MinSizeRel", + "inherits": "default", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "MinSizeRel" + } + } + ], + "buildPresets": [ + { + "name": "Debug", + "configurePreset": "Debug" + }, + { + "name": "RelWithDebInfo", + "configurePreset": "RelWithDebInfo" + }, + { + "name": "Release", + "configurePreset": "Release" + }, + { + "name": "MinSizeRel", + "configurePreset": "MinSizeRel" + } + ] +} \ No newline at end of file diff --git a/bmd380_bootloader.code-workspace b/bmd380_bootloader.code-workspace new file mode 100644 index 0000000..99471a2 --- /dev/null +++ b/bmd380_bootloader.code-workspace @@ -0,0 +1,12 @@ +{ + "folders": [ + { + "name": "bmd380_bootloader", + "path": "." + }, + { + "path": "../bmd380_sdk" + } + ], + "settings": {} +} \ No newline at end of file diff --git a/app_config.h b/bootloader/inc/app_config.h similarity index 100% rename from app_config.h rename to bootloader/inc/app_config.h diff --git a/custom_board.h b/bootloader/inc/custom_board.h similarity index 100% rename from custom_board.h rename to bootloader/inc/custom_board.h diff --git a/nrf_crypto_allocator.h b/bootloader/inc/nrf_crypto_allocator.h similarity index 100% rename from nrf_crypto_allocator.h rename to bootloader/inc/nrf_crypto_allocator.h diff --git a/sdk_config.h b/bootloader/inc/sdk_config.h similarity index 100% rename from sdk_config.h rename to bootloader/inc/sdk_config.h diff --git a/dfu_public_key.c b/bootloader/src/dfu_public_key.c similarity index 100% rename from dfu_public_key.c rename to bootloader/src/dfu_public_key.c diff --git a/bootloader/src/main.c b/bootloader/src/main.c new file mode 100644 index 0000000..d3d38e6 --- /dev/null +++ b/bootloader/src/main.c @@ -0,0 +1,222 @@ +/** + * Copyright (c) 2016 - 2020, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be + * reverse engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +/** @file + * + * @defgroup bootloader_secure_ble main.c + * @{ + * @ingroup dfu_bootloader_api + * @brief Bootloader project main file for secure DFU. + * + */ + +#include "app_error.h" +#include "app_error_weak.h" +#include "app_timer.h" +#include "boards.h" +#include "led_softblink.h" +#include "nrf_bootloader.h" +#include "nrf_bootloader_app_start.h" +#include "nrf_bootloader_dfu_timers.h" +#include "nrf_bootloader_info.h" +#include "nrf_clock.h" +#include "nrf_delay.h" +#include "nrf_dfu.h" +#include "nrf_dfu_utils.h" +#include "nrf_log.h" +#include "nrf_log_ctrl.h" +#include "nrf_log_default_backends.h" +#include "nrf_mbr.h" +#include + +/* Timer used to blink LED on DFU progress. */ +APP_TIMER_DEF(m_dfu_progress_led_timer); + +static void on_error(void) { + NRF_LOG_FINAL_FLUSH(); + +#if NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT) + // To allow the buffer to be flushed by the host. + nrf_delay_ms(100); +#endif +#ifdef NRF_DFU_DEBUG_VERSION + NRF_BREAKPOINT_COND; +#endif + NVIC_SystemReset(); +} + +void app_error_handler(uint32_t error_code, uint32_t line_num, + const uint8_t *p_file_name) { + NRF_LOG_ERROR("%s:%d", p_file_name, line_num); + on_error(); +} + +void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) { + NRF_LOG_ERROR("Received a fault! id: 0x%08x, pc: 0x%08x, info: 0x%08x", id, + pc, info); + on_error(); +} + +void app_error_handler_bare(uint32_t error_code) { + NRF_LOG_ERROR("Received an error: 0x%08x!", error_code); + on_error(); +} + +static void dfu_progress_led_timeout_handler(void *p_context) { + app_timer_id_t timer = (app_timer_id_t)p_context; + + uint32_t err_code = app_timer_start( + timer, APP_TIMER_TICKS(DFU_LED_CONFIG_PROGRESS_BLINK_MS), p_context); + APP_ERROR_CHECK(err_code); + + bsp_board_led_invert(BSP_BOARD_LED_1); +} + +/** + * @brief Function notifies certain events in DFU process. + */ +static void dfu_observer(nrf_dfu_evt_type_t evt_type) { + static bool timer_created = false; + uint32_t err_code; + + if (!timer_created) { + err_code = + app_timer_create(&m_dfu_progress_led_timer, APP_TIMER_MODE_SINGLE_SHOT, + dfu_progress_led_timeout_handler); + APP_ERROR_CHECK(err_code); + timer_created = true; + } + + switch (evt_type) { + case NRF_DFU_EVT_DFU_FAILED: + case NRF_DFU_EVT_DFU_ABORTED: + err_code = led_softblink_stop(); + APP_ERROR_CHECK(err_code); + + err_code = app_timer_stop(m_dfu_progress_led_timer); + APP_ERROR_CHECK(err_code); + + err_code = led_softblink_start(BSP_LED_0_MASK | BSP_LED_1_MASK); + APP_ERROR_CHECK(err_code); + + break; + case NRF_DFU_EVT_DFU_INITIALIZED: { + bsp_board_init(BSP_INIT_LEDS); + + if (!nrf_clock_lf_is_running()) { + nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART); + } + err_code = app_timer_init(); + APP_ERROR_CHECK(err_code); + + led_sb_init_params_t led_sb_init_param = + LED_SB_INIT_DEFAULT_PARAMS(BSP_LED_0_MASK | BSP_LED_1_MASK); + + uint32_t ticks = + APP_TIMER_TICKS(DFU_LED_CONFIG_TRANSPORT_INACTIVE_BREATH_MS); + led_sb_init_param.p_leds_port = BSP_LED_1_PORT; + led_sb_init_param.on_time_ticks = ticks; + led_sb_init_param.off_time_ticks = ticks; + led_sb_init_param.duty_cycle_max = 255; + + err_code = led_softblink_init(&led_sb_init_param); + APP_ERROR_CHECK(err_code); + + err_code = led_softblink_start(BSP_LED_0_MASK | BSP_LED_1_MASK); + APP_ERROR_CHECK(err_code); + break; + } + case NRF_DFU_EVT_TRANSPORT_ACTIVATED: { + uint32_t ticks = APP_TIMER_TICKS(DFU_LED_CONFIG_TRANSPORT_ACTIVE_BREATH_MS); + led_softblink_off_time_set(ticks); + led_softblink_on_time_set(ticks); + break; + } + case NRF_DFU_EVT_TRANSPORT_DEACTIVATED: { + uint32_t ticks = APP_TIMER_TICKS(DFU_LED_CONFIG_PROGRESS_BLINK_MS); + err_code = led_softblink_stop(); + APP_ERROR_CHECK(err_code); + + err_code = app_timer_start(m_dfu_progress_led_timer, ticks, + m_dfu_progress_led_timer); + APP_ERROR_CHECK(err_code); + + break; + } + default: + break; + } +} + +/**@brief Function for application main entry. */ +int main(void) { + uint32_t ret_val; + + // Must happen before flash protection is applied, since it edits a protected + // page. + nrf_bootloader_mbr_addrs_populate(); + + // Protect MBR and bootloader code from being overwritten. + ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE); + APP_ERROR_CHECK(ret_val); + ret_val = + nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR, BOOTLOADER_SIZE); + APP_ERROR_CHECK(ret_val); + + (void)NRF_LOG_INIT(nrf_bootloader_dfu_timer_counter_get); + + NRF_LOG_DEFAULT_BACKENDS_INIT(); + + NRF_LOG_INFO("Inside main"); + + ret_val = nrf_bootloader_init(dfu_observer); + APP_ERROR_CHECK(ret_val); + + NRF_LOG_FLUSH(); + + NRF_LOG_ERROR("After main, should never be reached."); + NRF_LOG_FLUSH(); + + APP_ERROR_CHECK_BOOL(false); +} + +/** + * @} + */ diff --git a/bootloader/src/syscalls.c b/bootloader/src/syscalls.c new file mode 100644 index 0000000..9510f58 --- /dev/null +++ b/bootloader/src/syscalls.c @@ -0,0 +1,31 @@ +#include "SEGGER_RTT.h" + +#include +#include + +int _read(int file, char *ptr, int len) { + errno = ENOSYS; + return -1; +} + +int _write(int file, const char *ptr, int len) { + SEGGER_RTT_Write(0, ptr, len); + return len; +} + +int _close(int file) { + errno = ENOSYS; + return -1; +} + +int _lseek(int file, int ptr, int dir) { + errno = ENOSYS; + return -1; +} + +int _fstat(int file, struct stat *st) { + st->st_mode = S_IFCHR; + return 0; +} + +int _isatty(int file) { return 1; } \ No newline at end of file diff --git a/cmake/arm-none-eabi-gcc.cmake b/cmake/arm-none-eabi-gcc.cmake new file mode 100644 index 0000000..6a8da18 --- /dev/null +++ b/cmake/arm-none-eabi-gcc.cmake @@ -0,0 +1,47 @@ +# Call Cmake from the 'build' subfolder with the command below. +# For using Make: +# cmake -DCMAKE_MAKE_PROGRAM=make.exe -DCMAKE_TOOLCHAIN_FILE="arm-none-eabi-gcc.cmake" -G "Unix Makefiles" .. +# followed by +# 'make' or 'cmake --build .' to build it +# +# For using Ninja: +# cmake -DCMAKE_MAKE_PROGRAM=ninja.exe -DCMAKE_TOOLCHAIN_FILE="arm-none-eabi-gcc.cmake" -G "Ninja" .. +# followed by +# 'ninja' or 'cmake --build .' to build it + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR arm) + +if(CMAKE_HOST_WIN32) + set(EXECUTESUFFIX ".exe") + set(ARM_TOOLCHAIN_DIR "C:/SysGCC/arm-eabi/bin") +elseif(CMAKE_HOST_UNIX) + set(EXECUTESUFFIX "") + if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin") + message(STATUS "Running on macOS") + set(ARM_TOOLCHAIN_DIR "/opt/homebrew/bin") + elseif(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Linux") + message(STATUS "Running on Linux (likely Ubuntu)") + set(ARM_TOOLCHAIN_DIR "/opt/arm-none-eabi/bin") + endif() +else() + message(WARNING "Unknown host OS: ${CMAKE_HOST_SYSTEM_NAME}") +endif() + +set(BINUTILS_PATH ${ARM_TOOLCHAIN_DIR}) + +set(TOOLCHAIN_PREFIX arm-none-eabi-) + +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(CMAKE_C_COMPILER ${ARM_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}gcc${EXECUTESUFFIX}) +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_CXX_COMPILER ${ARM_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}g++${EXECUTESUFFIX}) +set(CMAKE_LINKER ${ARM_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}ld${EXECUTESUFFIX}) +set(CMAKE_OBJCOPY ${ARM_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}objcopy${EXECUTESUFFIX} CACHE INTERNAL "objcopy tool") +set(CMAKE_SIZE ${ARM_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}size${EXECUTESUFFIX} CACHE INTERNAL "size tool") + +set(CMAKE_FIND_ROOT_PATH ${BINUTILS_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) diff --git a/secure_bootloader_gcc_nrf52.ld b/linkscripts/secure_bootloader_gcc_nrf52.ld similarity index 100% rename from secure_bootloader_gcc_nrf52.ld rename to linkscripts/secure_bootloader_gcc_nrf52.ld diff --git a/main.c b/main.c deleted file mode 100644 index ed4782a..0000000 --- a/main.c +++ /dev/null @@ -1,231 +0,0 @@ -/** - * Copyright (c) 2016 - 2020, Nordic Semiconductor ASA - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ -/** @file - * - * @defgroup bootloader_secure_ble main.c - * @{ - * @ingroup dfu_bootloader_api - * @brief Bootloader project main file for secure DFU. - * - */ - -#include -#include "boards.h" -#include "nrf_mbr.h" -#include "nrf_bootloader.h" -#include "nrf_bootloader_app_start.h" -#include "nrf_bootloader_dfu_timers.h" -#include "nrf_dfu.h" -#include "nrf_log.h" -#include "nrf_log_ctrl.h" -#include "nrf_log_default_backends.h" -#include "app_error.h" -#include "app_error_weak.h" -#include "nrf_bootloader_info.h" -#include "nrf_dfu_utils.h" -#include "led_softblink.h" -#include "app_timer.h" -#include "nrf_delay.h" -#include "nrf_clock.h" - -/* Timer used to blink LED on DFU progress. */ -APP_TIMER_DEF(m_dfu_progress_led_timer); - -static void on_error(void) -{ - NRF_LOG_FINAL_FLUSH(); - -#if NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT) - // To allow the buffer to be flushed by the host. - nrf_delay_ms(100); -#endif -#ifdef NRF_DFU_DEBUG_VERSION - NRF_BREAKPOINT_COND; -#endif - NVIC_SystemReset(); -} - - -void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name) -{ - NRF_LOG_ERROR("%s:%d", p_file_name, line_num); - on_error(); -} - - -void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) -{ - NRF_LOG_ERROR("Received a fault! id: 0x%08x, pc: 0x%08x, info: 0x%08x", id, pc, info); - on_error(); -} - - -void app_error_handler_bare(uint32_t error_code) -{ - NRF_LOG_ERROR("Received an error: 0x%08x!", error_code); - on_error(); -} - -static void dfu_progress_led_timeout_handler(void * p_context) -{ - app_timer_id_t timer = (app_timer_id_t)p_context; - - uint32_t err_code = app_timer_start(timer, - APP_TIMER_TICKS(DFU_LED_CONFIG_PROGRESS_BLINK_MS), - p_context); - APP_ERROR_CHECK(err_code); - - bsp_board_led_invert(BSP_BOARD_LED_1); -} - -/** - * @brief Function notifies certain events in DFU process. - */ -static void dfu_observer(nrf_dfu_evt_type_t evt_type) -{ - static bool timer_created = false; - uint32_t err_code; - - if (!timer_created) - { - err_code = app_timer_create(&m_dfu_progress_led_timer, - APP_TIMER_MODE_SINGLE_SHOT, - dfu_progress_led_timeout_handler); - APP_ERROR_CHECK(err_code); - timer_created = true; - } - - switch (evt_type) - { - case NRF_DFU_EVT_DFU_FAILED: - case NRF_DFU_EVT_DFU_ABORTED: - err_code = led_softblink_stop(); - APP_ERROR_CHECK(err_code); - - err_code = app_timer_stop(m_dfu_progress_led_timer); - APP_ERROR_CHECK(err_code); - - err_code = led_softblink_start(BSP_LED_0_MASK | BSP_LED_1_MASK); - APP_ERROR_CHECK(err_code); - - break; - case NRF_DFU_EVT_DFU_INITIALIZED: - { - bsp_board_init(BSP_INIT_LEDS); - - if (!nrf_clock_lf_is_running()) - { - nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART); - } - err_code = app_timer_init(); - APP_ERROR_CHECK(err_code); - - led_sb_init_params_t led_sb_init_param = LED_SB_INIT_DEFAULT_PARAMS(BSP_LED_0_MASK | BSP_LED_1_MASK); - - uint32_t ticks = APP_TIMER_TICKS(DFU_LED_CONFIG_TRANSPORT_INACTIVE_BREATH_MS); - led_sb_init_param.p_leds_port = BSP_LED_1_PORT; - led_sb_init_param.on_time_ticks = ticks; - led_sb_init_param.off_time_ticks = ticks; - led_sb_init_param.duty_cycle_max = 255; - - err_code = led_softblink_init(&led_sb_init_param); - APP_ERROR_CHECK(err_code); - - err_code = led_softblink_start(BSP_LED_0_MASK | BSP_LED_1_MASK); - APP_ERROR_CHECK(err_code); - break; - } - case NRF_DFU_EVT_TRANSPORT_ACTIVATED: - { - uint32_t ticks = APP_TIMER_TICKS(DFU_LED_CONFIG_TRANSPORT_ACTIVE_BREATH_MS); - led_softblink_off_time_set(ticks); - led_softblink_on_time_set(ticks); - break; - } - case NRF_DFU_EVT_TRANSPORT_DEACTIVATED: - { - uint32_t ticks = APP_TIMER_TICKS(DFU_LED_CONFIG_PROGRESS_BLINK_MS); - err_code = led_softblink_stop(); - APP_ERROR_CHECK(err_code); - - err_code = app_timer_start(m_dfu_progress_led_timer, ticks, m_dfu_progress_led_timer); - APP_ERROR_CHECK(err_code); - - break; - } - default: - break; - } -} - -/**@brief Function for application main entry. */ -int main(void) -{ - uint32_t ret_val; - - // Must happen before flash protection is applied, since it edits a protected page. - nrf_bootloader_mbr_addrs_populate(); - - // Protect MBR and bootloader code from being overwritten. - ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE); - APP_ERROR_CHECK(ret_val); - ret_val = nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR, BOOTLOADER_SIZE); - APP_ERROR_CHECK(ret_val); - - (void) NRF_LOG_INIT(nrf_bootloader_dfu_timer_counter_get); - - NRF_LOG_DEFAULT_BACKENDS_INIT(); - - NRF_LOG_INFO("Inside main"); - - ret_val = nrf_bootloader_init(dfu_observer); - APP_ERROR_CHECK(ret_val); - - NRF_LOG_FLUSH(); - - NRF_LOG_ERROR("After main, should never be reached."); - NRF_LOG_FLUSH(); - - APP_ERROR_CHECK_BOOL(false); -} - -/** - * @} - */