Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .changesets/refactor-linker-script.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
release: major
summary: Refactor linker script, startup code, and memory model with unified copy/zero tables, configurable ITCM, and weak BoardInit

## Implemented

### Linker Script (`LinkerScript.ld`)
- **Unified copy table**: all initialized data sections (ISR vector, ITCM code, `.data`, `.dtcm_rodata`, D1/D2/D3 NC and cached data/rodata) are copied from FLASH to RAM by a single generic loop in `Reset_Handler`. No more hand-written copy per section.
- **Unified zero table**: all BSS sections (DTCM `.bss`, D1/D2/D3 NC and cached BSS) are zero-initialized by the same generic mechanism.
- **Configurable ITCM**: `__ITCM_SIZE` and `__ITCM_BUILD` macros (passed via C preprocessor `-D` at build time) control ITCM size and whether `.text` is placed in ITCM instead of FLASH.
- **ISR vector always in ITCM**: the interrupt vector table is unconditionally placed in ITCMRAM and copied at startup.
- **DTCM constants**: `.dtcm_rodata` section for constants explicitly placed in DTCM (via `DTCM_RODATA` / `DTCM_RODATA_INLINE` macros), initialized from FLASH by the copy table.
- **Initialized data for all memory domains**: D1, D2, D3 each have non-cached and cached data/rodata sections (`>RAM_Dx AT> FLASH`) copied by the copy table.
- **Null-pointer guard**: 32-byte MPU region at `0x00000000` (NO_ACCESS) catches runtime null dereferences. Vector table relocated to a 1024-byte aligned location after the 32 security bytes, loaded in VTOR via `.null_guard` NOLOAD section. Region 12 > region 11 → takes priority.
- **LMA collision guard**: `BYTE(0)` in every `AT> FLASH` section prevents empty sections from clustering at the same PhysAddr, suppressing STM32_Programmer "overlapping segments" warnings.

### Startup Code (`StartupCode.s`)
- Replaced per-section manual copy with generic copy-table loop (`__copy_table_start` → `__copy_table_end`).
- Replaced per-section manual BSS zeroing with generic zero-table loop (`__zero_table_start` → `__zero_table_end`).
- Removed `Reset_Handler` reliance on hardcoded section symbols; everything is table-driven.
- Calls `weak BoardInit()` between `SystemInit` and global constructors, allowing early hardware initialization from C++.

### System / Board Init (`System.c`)
- Moved from template-project to ST-LIB so all projects benefit.
- Provides `weak BoardInit()` and `weak ConfigurationChecker()` — user overrides in firmware.

### MPU (`MPU.hpp`)
- Fixed `MPUDomain::Instance::as()` and `construct()`: `Request::e` → `Target.e` for valid constexpr member access.
- Fixed `static_assert` logic: `is_nc && volatile` → `!is_nc || volatile` (cached buffers no longer trigger the assert).
- Added null-pointer guard region (region 12, `0x00000000`, 32 bytes, NO_ACCESS).
- Inline specifiers for all `*_INLINE` macros (since inline things are placed in special COMDAT sections that must be separate one from another and everything else).

## Not implemented (left as weak symbols)
- `ConfigurationChecker`: a function to validate ITCM size and other build-time configuration at runtime. User can define it to add custom startup checks.

## Migration guide (template-project)
The corresponding template-project PR adapts `BoardInit` to the new weak function contract, and changes the CMAKE as needed. See the template-project for details.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ add_library(${STLIB_LIBRARY} OBJECT
$<$<AND:$<BOOL:${CMAKE_CROSSCOMPILING}>,$<BOOL:${USE_ETHERNET}>>:${HALAL_C_ETH_PHY}>


$<$<BOOL:${CMAKE_CROSSCOMPILING}>:${CMAKE_CURRENT_LIST_DIR}/System.c>
$<$<BOOL:${CMAKE_CROSSCOMPILING}>:${CPP_UTILITIES_C}>
$<$<BOOL:${CMAKE_CROSSCOMPILING}>:${CPP_UTILITIES_CPP}>

Expand Down
278 changes: 208 additions & 70 deletions Inc/HALAL/Models/MPU.hpp

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions Inc/HALAL/Services/ADC/ADC.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@

#include "HALAL/Models/Pin.hpp"
#ifdef SIM_ON
#define STLIB_ADC_DMA_BUFFER_ATTR
#define STLIB_ADC_DMA_BUFFER_ATTR(x) inline
#else
#include "HALAL/Models/MPU.hpp"
#define STLIB_ADC_DMA_BUFFER_ATTR D1_NC
#define STLIB_ADC_DMA_BUFFER_ATTR(x) D2_NC_BSS_INLINE(x)
#endif

using std::array;
Expand Down Expand Up @@ -780,8 +780,8 @@ struct ADCDomain {
"ADC DMA buffer size exceeds max_instances"
);

alignas(32) STLIB_ADC_DMA_BUFFER_ATTR
static inline uint16_t dma_buffer_pool[total_dma_slots > 0 ? total_dma_slots : 1]{};
alignas(32) static uint16_t STLIB_ADC_DMA_BUFFER_ATTR(dma_buffer_pool
) dma_buffer_pool[total_dma_slots > 0 ? total_dma_slots : 1]{};

static constexpr bool is_resolved_config(const Config& cfg) {
return cfg.peripheral != Peripheral::AUTO && cfg.channel != Channel::AUTO;
Expand Down
18 changes: 9 additions & 9 deletions Inc/HALAL/Services/DFSDM/DFSDM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "HALAL/Models/DMA/DMA2.hpp"
#include "HALAL/Models/MPU.hpp"

#define STLIB_DFSDM_DMA_BUFFER_ATTR D1_NC
#define STLIB_DFSDM_DMA_BUFFER_ATTR(x) D2_NC_BSS_INLINE(x)

#define Oversampling_MAX 1024
#define Oversampling_MAX_Filter_4 215
Expand Down Expand Up @@ -992,14 +992,14 @@ struct DFSDM_CHANNEL_DOMAIN {
sizes.filter0 + sizes.filter1 + sizes.filter2 + sizes.filter3;

// Filter Buffers
alignas(32) STLIB_DFSDM_DMA_BUFFER_ATTR
static inline int32_t Buffer_Filter0[sizes.filter0 > 0 ? sizes.filter0 : 1]{};
alignas(32) STLIB_DFSDM_DMA_BUFFER_ATTR
static inline int32_t Buffer_Filter1[sizes.filter1 > 0 ? sizes.filter1 : 1]{};
alignas(32) STLIB_DFSDM_DMA_BUFFER_ATTR
static inline int32_t Buffer_Filter2[sizes.filter2 > 0 ? sizes.filter2 : 1]{};
alignas(32) STLIB_DFSDM_DMA_BUFFER_ATTR
static inline int32_t Buffer_Filter3[sizes.filter3 > 0 ? sizes.filter3 : 1]{};
alignas(32) STLIB_DFSDM_DMA_BUFFER_ATTR(Buffer_Filter0
) static int32_t Buffer_Filter0[sizes.filter0 > 0 ? sizes.filter0 : 1]{};
alignas(32) STLIB_DFSDM_DMA_BUFFER_ATTR(Buffer_Filter1
) static int32_t Buffer_Filter1[sizes.filter1 > 0 ? sizes.filter1 : 1]{};
alignas(32) STLIB_DFSDM_DMA_BUFFER_ATTR(Buffer_Filter2
) static int32_t Buffer_Filter2[sizes.filter2 > 0 ? sizes.filter2 : 1]{};
alignas(32) STLIB_DFSDM_DMA_BUFFER_ATTR(Buffer_Filter3
) static int32_t Buffer_Filter3[sizes.filter3 > 0 ? sizes.filter3 : 1]{};

static inline std::array<Instance, N> instances{};

Expand Down
1 change: 1 addition & 0 deletions Inc/MockedDrivers/stm32h7xx_hal_mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,7 @@ enum {
#define MPU_REGION_NUMBER8 (0x08U)
#define MPU_REGION_NUMBER10 (0x0AU)
#define MPU_REGION_NUMBER11 (0x0BU)
#define MPU_REGION_NUMBER12 (0x0CU)

#define MPU_REGION_ENABLE (0x01U)
#define MPU_REGION_SIZE_4GB (0x1FU)
Expand Down
7 changes: 7 additions & 0 deletions Inc/ST-LIB.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,3 +385,10 @@ template <BoardFaultPolicy FaultPolicyT, auto&... devs> struct Board {
};

} // namespace ST_LIB

/**
* @brief This is a function that gets called early in the startup process,
* before the global constructors and main() are called.
* It is responsible for initializing the hardware and peripherals
*/
extern "C" void BoardInit(void);
Loading
Loading