Scaffold bootloader project with TODO checklist
New project under bootloader/ with the same structure as color_switcher: Dockerfile, docker-compose, modular CMake, and APP_BOOT + SYS_ECU stub components. Reuses common/ submodules for MCU_UART, MCU_USB, HAL_COM, STD_TYPES. TODO.md lists all open design decisions (interface, protocol, flash layout, entry trigger, integrity checks, flash strategy) and the implementation tasks that depend on them.
This commit is contained in:
parent
b62a86bdc7
commit
4f1199a3e6
@ -19,6 +19,7 @@ git submodule update --init --recursive
|
|||||||
| Project | Description | Target Board |
|
| Project | Description | Target Board |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| [color_switcher](color_switcher/) | Interactive color-switching firmware with USB-CDC serial commands and WS2812B LED control via PIO | Waveshare RP2040-Zero |
|
| [color_switcher](color_switcher/) | Interactive color-switching firmware with USB-CDC serial commands and WS2812B LED control via PIO | Waveshare RP2040-Zero |
|
||||||
|
| [bootloader](bootloader/) | Custom firmware bootloader — receives updates over UART/USB, writes to flash, jumps to app | RP2040 (any board) |
|
||||||
|
|
||||||
## Shared Components (git submodules)
|
## Shared Components (git submodules)
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ pico/
|
|||||||
│ ├── MCU_PIO/ # generic PIO driver + ws2812.pio
|
│ ├── MCU_PIO/ # generic PIO driver + ws2812.pio
|
||||||
│ ├── HAL_COM/ # communication abstraction
|
│ ├── HAL_COM/ # communication abstraction
|
||||||
│ └── HAL_LED/ # LED strip abstraction
|
│ └── HAL_LED/ # LED strip abstraction
|
||||||
|
├── bootloader/ # project: custom firmware bootloader
|
||||||
├── color_switcher/ # project: WS2812B color switcher
|
├── color_switcher/ # project: WS2812B color switcher
|
||||||
│ ├── cmake/ # modular CMake build system
|
│ ├── cmake/ # modular CMake build system
|
||||||
│ ├── src/ # project-specific components (APP_CLSW, SYS_ECU)
|
│ ├── src/ # project-specific components (APP_CLSW, SYS_ECU)
|
||||||
|
|||||||
24
bootloader/CLAUDE.md
Normal file
24
bootloader/CLAUDE.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project
|
||||||
|
|
||||||
|
Custom bootloader for the Raspberry Pi Pico (RP2040). Receives firmware over a communication interface, writes to flash, and jumps to the main application.
|
||||||
|
|
||||||
|
## Build System
|
||||||
|
|
||||||
|
All builds run inside Docker — no local toolchain required.
|
||||||
|
|
||||||
|
- `docker compose run --rm pico-build bash /scripts/build.sh` — compile the firmware
|
||||||
|
- `./flash.sh bootloader` — flash to Pico (from repo root)
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
- `src/APP_BOOT/{inc,prg,cfg}/` — bootloader application logic (firmware receive, flash write, app jump)
|
||||||
|
- `src/SYS_ECU/{inc,prg,cfg}/` — system orchestrator (init sequence, main loop)
|
||||||
|
- Shared components from `common/` (STD_TYPES, MCU_UART, MCU_USB, HAL_COM, etc.)
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
Same as the repo-level CLAUDE.md — MISRA-C style, STD_TYPES, Hungarian naming, descriptive comments, no magic numbers.
|
||||||
23
bootloader/Dockerfile
Normal file
23
bootloader/Dockerfile
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Base image: Ubuntu 24.04 for ARM cross-compilation toolchain
|
||||||
|
FROM ubuntu:24.04
|
||||||
|
|
||||||
|
# Install cross-compilation dependencies + clangd for dev container intellisense
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
cmake \
|
||||||
|
gcc-arm-none-eabi \
|
||||||
|
libnewlib-arm-none-eabi \
|
||||||
|
build-essential \
|
||||||
|
git \
|
||||||
|
python3 \
|
||||||
|
clangd \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Clone the Pico SDK with submodules (TinyUSB, etc.)
|
||||||
|
RUN git clone https://github.com/raspberrypi/pico-sdk.git /opt/pico-sdk \
|
||||||
|
&& cd /opt/pico-sdk \
|
||||||
|
&& git submodule update --init
|
||||||
|
|
||||||
|
# Tell CMake where to find the Pico SDK
|
||||||
|
ENV PICO_SDK_PATH=/opt/pico-sdk
|
||||||
|
|
||||||
|
WORKDIR /project
|
||||||
26
bootloader/README.md
Normal file
26
bootloader/README.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Bootloader
|
||||||
|
|
||||||
|
A custom bootloader for the Raspberry Pi Pico (RP2040). Receives firmware updates over a communication interface, writes to flash, and jumps to the main application.
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
**Scaffolded — not yet implemented.** See `TODO.md` for the design decisions and implementation tasks.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- [Docker](https://docs.docker.com/get-docker/) and Docker Compose
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd bootloader/
|
||||||
|
docker compose run --rm pico-build bash /scripts/build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Flashing
|
||||||
|
|
||||||
|
From the repo root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./flash.sh bootloader
|
||||||
|
```
|
||||||
61
bootloader/TODO.md
Normal file
61
bootloader/TODO.md
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# Bootloader — Design Decisions & TODO
|
||||||
|
|
||||||
|
## Open Design Decisions
|
||||||
|
|
||||||
|
These must be resolved before implementation begins:
|
||||||
|
|
||||||
|
### 1. Firmware update interface
|
||||||
|
- [ ] UART only
|
||||||
|
- [ ] USB-CDC only
|
||||||
|
- [ ] Both (selectable via config or auto-detect)
|
||||||
|
- **Notes:** We have MCU_UART and MCU_USB in common/ ready to use via HAL_COM.
|
||||||
|
|
||||||
|
### 2. Transfer protocol
|
||||||
|
- [ ] Custom simple protocol (length + CRC32 + raw binary)
|
||||||
|
- [ ] XMODEM / YMODEM (standard, many terminal tools support it)
|
||||||
|
- [ ] Custom framed protocol (start byte, length, payload, CRC, end byte)
|
||||||
|
- **Notes:** Custom is simplest to implement. XMODEM is widely supported by serial tools.
|
||||||
|
|
||||||
|
### 3. Flash memory layout
|
||||||
|
- [ ] Define bootloader size (e.g., first 16 KB, 32 KB, or 64 KB of flash)
|
||||||
|
- [ ] Define application start address
|
||||||
|
- [ ] Define metadata region (app version, CRC, valid flag)
|
||||||
|
- **Notes:** RP2040 has 2 MB flash. Pico SDK linker script needs modification to place the bootloader and app at different addresses.
|
||||||
|
|
||||||
|
### 4. Bootloader entry trigger
|
||||||
|
- [ ] Always enter bootloader, wait N seconds for firmware, then jump to app
|
||||||
|
- [ ] Check a GPIO pin (button held = stay in bootloader)
|
||||||
|
- [ ] Check a magic value in flash/RAM (set by the application to request update)
|
||||||
|
- [ ] Combination: check button first, then magic value, then jump to app
|
||||||
|
- **Notes:** "Button + timeout" is the most user-friendly approach.
|
||||||
|
|
||||||
|
### 5. Application jump mechanism
|
||||||
|
- [ ] Read the app's vector table at the app start address
|
||||||
|
- [ ] Set the MSP (main stack pointer) from the vector table
|
||||||
|
- [ ] Jump to the reset handler from the vector table
|
||||||
|
- **Notes:** Standard Cortex-M0+ boot sequence. Need to disable interrupts and peripherals before jumping.
|
||||||
|
|
||||||
|
### 6. Integrity verification
|
||||||
|
- [ ] CRC32 check on the received firmware before writing to flash
|
||||||
|
- [ ] CRC32 check on the stored application before jumping (boot-time validation)
|
||||||
|
- [ ] Signature verification (stretch goal — not needed for initial version)
|
||||||
|
|
||||||
|
### 7. Flash write strategy
|
||||||
|
- [ ] Erase + write as chunks arrive (streaming)
|
||||||
|
- [ ] Buffer entire firmware in RAM, then erase + write at once (limited by RAM size)
|
||||||
|
- [ ] Dual-bank: write to alternate region, swap on success (A/B update)
|
||||||
|
- **Notes:** Streaming is most memory-efficient. A/B is safest (rollback on failure) but uses 2x flash.
|
||||||
|
|
||||||
|
## Implementation Tasks
|
||||||
|
|
||||||
|
Once design decisions are made:
|
||||||
|
|
||||||
|
- [ ] Create linker scripts (bootloader.ld, application.ld) with correct flash regions
|
||||||
|
- [ ] Implement APP_BOOT_enuInit — check entry trigger, decide boot vs update mode
|
||||||
|
- [ ] Implement firmware receive via HAL_COM (protocol parsing, CRC validation)
|
||||||
|
- [ ] Implement flash write using Pico SDK hardware_flash API
|
||||||
|
- [ ] Implement application jump (disable interrupts, set MSP, branch to reset handler)
|
||||||
|
- [ ] Implement boot-time app validation (CRC check before jumping)
|
||||||
|
- [ ] Modify color_switcher's linker script to start at the app address (not 0x10000000)
|
||||||
|
- [ ] Test: flash bootloader, then send color_switcher firmware over UART/USB
|
||||||
|
- [ ] Test: corrupt firmware scenario — bootloader should stay in update mode
|
||||||
28
bootloader/cmake/CMakeLists.txt
Normal file
28
bootloader/cmake/CMakeLists.txt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# Top-level CMakeLists.txt for the bootloader project
|
||||||
|
# ============================================================================
|
||||||
|
# Same phase-ordered structure as color_switcher.
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
|
get_filename_component(PROJECT_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE)
|
||||||
|
|
||||||
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake_config)
|
||||||
|
|
||||||
|
include(project_config)
|
||||||
|
include(mcu_config)
|
||||||
|
|
||||||
|
mcu_init()
|
||||||
|
|
||||||
|
project(${PROJECT_NAME}
|
||||||
|
VERSION ${PROJECT_VERSION}
|
||||||
|
LANGUAGES ${PROJECT_LANGUAGES})
|
||||||
|
|
||||||
|
mcu_sdk_config()
|
||||||
|
|
||||||
|
include(sources_config)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
mcu_link_target(${PROJECT_NAME})
|
||||||
34
bootloader/cmake/cmake_config/mcu_config.cmake
Normal file
34
bootloader/cmake/cmake_config/mcu_config.cmake
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# mcu_config.cmake — RP2040 / Pico SDK configuration for the bootloader
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Step 1/3: called BEFORE project() — bootstrap the Pico SDK toolchain
|
||||||
|
macro(mcu_init)
|
||||||
|
include(${CMAKE_SOURCE_DIR}/pico_sdk_import.cmake)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# Step 2/3: called AFTER project() — register SDK targets
|
||||||
|
macro(mcu_sdk_config)
|
||||||
|
set(CMAKE_C_STANDARD ${PROJECT_C_STANDARD})
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
pico_sdk_init()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# Step 3/3: called AFTER add_executable() — link SDK libs + configure target
|
||||||
|
function(mcu_link_target target)
|
||||||
|
# Libraries needed by the bootloader.
|
||||||
|
# hardware_flash is critical — the bootloader writes firmware to flash.
|
||||||
|
target_link_libraries(${target} PRIVATE
|
||||||
|
pico_stdlib
|
||||||
|
hardware_uart
|
||||||
|
hardware_dma
|
||||||
|
hardware_flash
|
||||||
|
)
|
||||||
|
|
||||||
|
# Route stdio over USB-CDC for bootloader status messages
|
||||||
|
pico_enable_stdio_usb(${target} 1)
|
||||||
|
pico_enable_stdio_uart(${target} 0)
|
||||||
|
|
||||||
|
# Generate .uf2 for initial bootloader flashing via BOOTSEL
|
||||||
|
pico_add_extra_outputs(${target})
|
||||||
|
endfunction()
|
||||||
11
bootloader/cmake/cmake_config/project_config.cmake
Normal file
11
bootloader/cmake/cmake_config/project_config.cmake
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# project_config.cmake — Bootloader project identity and language settings
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
set(PROJECT_NAME Bootloader_PICO)
|
||||||
|
set(PROJECT_VERSION 0.1.0)
|
||||||
|
set(PROJECT_LANGUAGES C CXX ASM)
|
||||||
|
set(PROJECT_C_STANDARD 11)
|
||||||
|
|
||||||
|
# Generate compile_commands.json for clangd intellisense
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
37
bootloader/cmake/cmake_config/sources_config.cmake
Normal file
37
bootloader/cmake/cmake_config/sources_config.cmake
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# sources_config.cmake — Source files and include paths for the bootloader
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
set(COMMON_DIR "${PROJECT_ROOT_DIR}/../common")
|
||||||
|
|
||||||
|
# Collect .c files from project src/ and common submodules
|
||||||
|
file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS
|
||||||
|
"${PROJECT_ROOT_DIR}/src/*.c"
|
||||||
|
"${COMMON_DIR}/STD_TYPES/*.c"
|
||||||
|
"${COMMON_DIR}/MCU_UART/*.c"
|
||||||
|
"${COMMON_DIR}/MCU_USB/*.c"
|
||||||
|
"${COMMON_DIR}/HAL_COM/*.c")
|
||||||
|
|
||||||
|
set(PROJECT_INCLUDE_DIRS
|
||||||
|
# Common components (git submodules)
|
||||||
|
${COMMON_DIR}/STD_TYPES/inc
|
||||||
|
|
||||||
|
${COMMON_DIR}/MCU_UART/inc
|
||||||
|
${COMMON_DIR}/MCU_UART/prg
|
||||||
|
${COMMON_DIR}/MCU_UART/cfg
|
||||||
|
|
||||||
|
${COMMON_DIR}/MCU_USB/inc
|
||||||
|
${COMMON_DIR}/MCU_USB/prg
|
||||||
|
${COMMON_DIR}/MCU_USB/cfg
|
||||||
|
|
||||||
|
${COMMON_DIR}/HAL_COM/inc
|
||||||
|
${COMMON_DIR}/HAL_COM/prg
|
||||||
|
${COMMON_DIR}/HAL_COM/cfg
|
||||||
|
|
||||||
|
# Project-specific components
|
||||||
|
${PROJECT_ROOT_DIR}/src/APP_BOOT/inc
|
||||||
|
${PROJECT_ROOT_DIR}/src/APP_BOOT/prg
|
||||||
|
${PROJECT_ROOT_DIR}/src/APP_BOOT/cfg
|
||||||
|
|
||||||
|
${PROJECT_ROOT_DIR}/src/SYS_ECU/prg
|
||||||
|
)
|
||||||
121
bootloader/cmake/pico_sdk_import.cmake
Normal file
121
bootloader/cmake/pico_sdk_import.cmake
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
|
||||||
|
|
||||||
|
# This can be dropped into an external project to help locate this SDK
|
||||||
|
# It should be include()ed prior to project()
|
||||||
|
|
||||||
|
# Copyright 2020 (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
||||||
|
# following conditions are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
|
||||||
|
# disclaimer.
|
||||||
|
#
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
|
||||||
|
# disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
|
||||||
|
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
|
||||||
|
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
|
||||||
|
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
|
||||||
|
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_TAG} AND (NOT PICO_SDK_FETCH_FROM_GIT_TAG))
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT_TAG $ENV{PICO_SDK_FETCH_FROM_GIT_TAG})
|
||||||
|
message("Using PICO_SDK_FETCH_FROM_GIT_TAG from environment ('${PICO_SDK_FETCH_FROM_GIT_TAG}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (PICO_SDK_FETCH_FROM_GIT AND NOT PICO_SDK_FETCH_FROM_GIT_TAG)
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT_TAG "master")
|
||||||
|
message("Using master as default value for PICO_SDK_FETCH_FROM_GIT_TAG")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT_TAG "${PICO_SDK_FETCH_FROM_GIT_TAG}" CACHE FILEPATH "release tag for SDK")
|
||||||
|
|
||||||
|
if (NOT PICO_SDK_PATH)
|
||||||
|
if (PICO_SDK_FETCH_FROM_GIT)
|
||||||
|
include(FetchContent)
|
||||||
|
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
|
||||||
|
if (PICO_SDK_FETCH_FROM_GIT_PATH)
|
||||||
|
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||||
|
endif ()
|
||||||
|
FetchContent_Declare(
|
||||||
|
pico_sdk
|
||||||
|
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
|
||||||
|
GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (NOT pico_sdk)
|
||||||
|
message("Downloading Raspberry Pi Pico SDK")
|
||||||
|
# GIT_SUBMODULES_RECURSE was added in 3.17
|
||||||
|
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
|
||||||
|
FetchContent_Populate(
|
||||||
|
pico_sdk
|
||||||
|
QUIET
|
||||||
|
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
|
||||||
|
GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG}
|
||||||
|
GIT_SUBMODULES_RECURSE FALSE
|
||||||
|
|
||||||
|
SOURCE_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-src
|
||||||
|
BINARY_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-build
|
||||||
|
SUBBUILD_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-subbuild
|
||||||
|
)
|
||||||
|
else ()
|
||||||
|
FetchContent_Populate(
|
||||||
|
pico_sdk
|
||||||
|
QUIET
|
||||||
|
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
|
||||||
|
GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG}
|
||||||
|
|
||||||
|
SOURCE_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-src
|
||||||
|
BINARY_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-build
|
||||||
|
SUBBUILD_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-subbuild
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
|
||||||
|
endif ()
|
||||||
|
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
|
||||||
|
else ()
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||||
|
if (NOT EXISTS ${PICO_SDK_PATH})
|
||||||
|
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||||
|
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
|
||||||
|
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
|
||||||
|
|
||||||
|
include(${PICO_SDK_INIT_CMAKE_FILE})
|
||||||
13
bootloader/docker-compose.yml
Normal file
13
bootloader/docker-compose.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Docker Compose for the bootloader project.
|
||||||
|
# Same structure as color_switcher — shared build script + common submodules.
|
||||||
|
|
||||||
|
services:
|
||||||
|
pico-build:
|
||||||
|
build: .
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- .:/project
|
||||||
|
- ../common:/common
|
||||||
|
- ../build.sh:/scripts/build.sh
|
||||||
|
|
||||||
|
command: sleep infinity
|
||||||
9
bootloader/src/APP_BOOT/cfg/APP_BOOT_cfg.c
Normal file
9
bootloader/src/APP_BOOT/cfg/APP_BOOT_cfg.c
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File: APP_BOOT_cfg.c
|
||||||
|
* Component: APP_BOOT
|
||||||
|
* Description: Configuration definitions for the bootloader application.
|
||||||
|
*
|
||||||
|
* Layer: Application - configuration
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "APP_BOOT_cfg.h"
|
||||||
18
bootloader/src/APP_BOOT/cfg/APP_BOOT_cfg.h
Normal file
18
bootloader/src/APP_BOOT/cfg/APP_BOOT_cfg.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File: APP_BOOT_cfg.h
|
||||||
|
* Component: APP_BOOT
|
||||||
|
* Description: Configuration header for the bootloader application.
|
||||||
|
* Will hold flash layout addresses, timeout values,
|
||||||
|
* entry trigger config, etc.
|
||||||
|
*
|
||||||
|
* Layer: Application - configuration
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef APP_BOOT_CFG_H
|
||||||
|
#define APP_BOOT_CFG_H
|
||||||
|
|
||||||
|
#include "STD_TYPES.h"
|
||||||
|
|
||||||
|
/* TODO: define flash layout, timeouts, entry trigger config */
|
||||||
|
|
||||||
|
#endif /* APP_BOOT_CFG_H */
|
||||||
20
bootloader/src/APP_BOOT/inc/APP_BOOT.h
Normal file
20
bootloader/src/APP_BOOT/inc/APP_BOOT.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File: APP_BOOT.h
|
||||||
|
* Component: APP_BOOT
|
||||||
|
* Description: Public interface for the bootloader application.
|
||||||
|
* Handles firmware receive, flash write, integrity check,
|
||||||
|
* and application jump.
|
||||||
|
*
|
||||||
|
* Layer: Application
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef APP_BOOT_H
|
||||||
|
#define APP_BOOT_H
|
||||||
|
|
||||||
|
#include "STD_TYPES.h"
|
||||||
|
|
||||||
|
STD_tenuResult APP_BOOT_enuInit(void);
|
||||||
|
|
||||||
|
void APP_BOOT_vRunnable(void);
|
||||||
|
|
||||||
|
#endif /* APP_BOOT_H */
|
||||||
27
bootloader/src/APP_BOOT/prg/APP_BOOT_prg.c
Normal file
27
bootloader/src/APP_BOOT/prg/APP_BOOT_prg.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File: APP_BOOT_prg.c
|
||||||
|
* Component: APP_BOOT
|
||||||
|
* Description: Bootloader application logic — stub implementation.
|
||||||
|
* See TODO.md for the design decisions needed before
|
||||||
|
* implementing the actual bootloader behavior.
|
||||||
|
*
|
||||||
|
* Layer: Application
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "APP_BOOT.h"
|
||||||
|
#include "APP_BOOT_priv.h"
|
||||||
|
#include "APP_BOOT_cfg.h"
|
||||||
|
|
||||||
|
STD_tenuResult APP_BOOT_enuInit(void)
|
||||||
|
{
|
||||||
|
STD_tenuResult enuResultLoc = STD_OK;
|
||||||
|
|
||||||
|
/* TODO: check bootloader entry trigger (button, magic value, etc.) */
|
||||||
|
|
||||||
|
return enuResultLoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void APP_BOOT_vRunnable(void)
|
||||||
|
{
|
||||||
|
/* TODO: firmware receive state machine, flash write, app jump */
|
||||||
|
}
|
||||||
15
bootloader/src/APP_BOOT/prg/APP_BOOT_priv.h
Normal file
15
bootloader/src/APP_BOOT/prg/APP_BOOT_priv.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File: APP_BOOT_priv.h
|
||||||
|
* Component: APP_BOOT
|
||||||
|
* Description: Private header for the bootloader application.
|
||||||
|
*
|
||||||
|
* Layer: Application - internal use only
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef APP_BOOT_PRIV_H
|
||||||
|
#define APP_BOOT_PRIV_H
|
||||||
|
|
||||||
|
#include "APP_BOOT.h"
|
||||||
|
#include "APP_BOOT_cfg.h"
|
||||||
|
|
||||||
|
#endif /* APP_BOOT_PRIV_H */
|
||||||
37
bootloader/src/SYS_ECU/prg/SYS_ECU.c
Normal file
37
bootloader/src/SYS_ECU/prg/SYS_ECU.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* File: SYS_ECU.c
|
||||||
|
* Component: SYS_ECU
|
||||||
|
* Description: Bootloader system orchestrator. Init sequence + main loop.
|
||||||
|
*
|
||||||
|
* Layer: System (top of the stack)
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "STD_TYPES.h"
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
|
||||||
|
#include "MCU_USB.h"
|
||||||
|
#include "HAL_COM.h"
|
||||||
|
#include "APP_BOOT.h"
|
||||||
|
|
||||||
|
static void vInitAll(void)
|
||||||
|
{
|
||||||
|
/* MCU layer */
|
||||||
|
MCU_USB_enuInit();
|
||||||
|
|
||||||
|
/* HAL layer */
|
||||||
|
HAL_COM_enuInit();
|
||||||
|
|
||||||
|
/* Application layer */
|
||||||
|
APP_BOOT_enuInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
vInitAll();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
APP_BOOT_vRunnable();
|
||||||
|
sleep_ms(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user