diff --git a/docs/config_options/BOOT_MODE.md b/docs/config_options/BOOT_MODE.md index 67e327f..24ca7d0 100644 --- a/docs/config_options/BOOT_MODE.md +++ b/docs/config_options/BOOT_MODE.md @@ -26,5 +26,5 @@ platformio.ini: ```ini [env:my_env] # ... -board_build.ld_args.boot_mode = secondary +board_build.boot_mode = secondary ``` diff --git a/docs/config_options/LINKER_SCRIPT.md b/docs/config_options/LINKER_SCRIPT.md index 9d3905b..f36e5a3 100644 --- a/docs/config_options/LINKER_SCRIPT.md +++ b/docs/config_options/LINKER_SCRIPT.md @@ -1,17 +1,16 @@ # Linker Script Configuration -the linker script can be configured in the platformio environment using options in `board_build`. -options are **directly** passed to the linker script using the `--defsym` option. +the linker script can be configured in the platformio environment using options in `board_build` and `board_upload`. -| option | description | default value | -| ------------- | ------------------------------------- | ------------- | -| `flash_start` | the start address of the flash memory | `0x0` | -| `flash_size` | the size of the flash memory | `256K` | -| `boot_mode` | firmware boot mode | `primary` | -| `preprocess` | enable linker script preprocessing | `true` | +| option | description | default value | +| ----------------------- | ------------------------------------- | ------------- | +| `upload.offset_address` | the start address of the flash memory | `0x0` | +| `upload.maximum_size` | the size of the flash memory | `262144` | +| `build.boot_mode` | firmware boot mode | `primary` | +| `build.ld_preprocess` | enable linker script preprocessing | `true` | > [!TIP] -> the `flash_size` option describes the **total** size of the flash memory in bytes. +> the `upload.maximum_size` option describes the **total** size of the flash memory in bytes. > do not subtract the bootloader size from the flash size, as this is done automatically by the build script. > [!NOTE] @@ -35,9 +34,9 @@ platformio.ini: ```ini [env:my_env] # ... -board_build.ld_args.flash_start = 0x0000C000 -board_build.ld_args.flash_size = 256K -board_build.ld_args.boot_mode = primary +board_upload.offset_address = 0x0000C000 +board_upload.maximum_size = 262144 +board_build.boot_mode = primary ``` @@ -45,12 +44,10 @@ board.json: ```json { // ... - "build": { - // ... - "ld_args": { - "flash_start": "0x00000000", - "flash_size": "256K" - } + "upload": { + "maximum_size": 262144, + "maximum_ram_size": 192512, + "offset_address": "0xc000" } } ``` diff --git a/docs/patches/hc32f46x_param.ld.patch b/docs/patches/hc32f46x_param.ld.patch index 2af61e7..2f8ceac 100644 --- a/docs/patches/hc32f46x_param.ld.patch +++ b/docs/patches/hc32f46x_param.ld.patch @@ -78,7 +78,7 @@ index fc0136c..ea9a833 100644 OTP (rx): ORIGIN = 0x03000C00, LENGTH = 1020 RAM (rwx): ORIGIN = 0x1FFF8000, LENGTH = 188K RET_RAM (rwx): ORIGIN = 0x200F0000, LENGTH = 4K -@@ -28,18 +88,30 @@ ENTRY(Reset_Handler) +@@ -28,18 +88,31 @@ ENTRY(Reset_Handler) SECTIONS { @@ -107,8 +107,9 @@ index fc0136c..ea9a833 100644 + /* ICG: 0x400 - 0x41F*/ + .icg_sec : + { ++ ASSERT(. == (ORIGIN(FLASH) + 0x400), "icg_sec alignment issue"); + KEEP(*(.icg_sec)); -+ . = 0x420; ++ ASSERT(. == (ORIGIN(FLASH) + 0x420), "icg_sec alignment issue"); + } >FLASH + #endif + @@ -116,7 +117,7 @@ index fc0136c..ea9a833 100644 .text : { . = ALIGN(4); -@@ -172,12 +244,14 @@ SECTIONS +@@ -172,12 +245,14 @@ SECTIONS __end__ = .; PROVIDE(end = .); PROVIDE(_end = .); @@ -133,7 +134,7 @@ index fc0136c..ea9a833 100644 . = ALIGN(8); __StackTop = .; } >RAM -@@ -197,4 +271,10 @@ SECTIONS +@@ -197,4 +272,10 @@ SECTIONS __RamEnd = ORIGIN(RAM) + LENGTH(RAM); ASSERT(__StackTop <= __RamEnd, "region RAM overflowed with stack") diff --git a/ld/hc32f46x_param.ld b/ld/hc32f46x_param.ld index ea9a833..684f469 100644 --- a/ld/hc32f46x_param.ld +++ b/ld/hc32f46x_param.ld @@ -106,8 +106,9 @@ SECTIONS /* ICG: 0x400 - 0x41F*/ .icg_sec : { + ASSERT(. == (ORIGIN(FLASH) + 0x400), "icg_sec alignment issue"); KEEP(*(.icg_sec)); - . = 0x420; + ASSERT(. == (ORIGIN(FLASH) + 0x420), "icg_sec alignment issue"); } >FLASH #endif diff --git a/tools/platformio/platformio-build-ddl.py b/tools/platformio/platformio-build-ddl.py index 5fca8db..42561ae 100644 --- a/tools/platformio/platformio-build-ddl.py +++ b/tools/platformio/platformio-build-ddl.py @@ -3,6 +3,7 @@ Device Driver Libraries for the HC32F460 series of microcontrollers """ import os +import sys import re from os.path import isdir, join @@ -23,6 +24,49 @@ assert isdir(FRAMEWORK_DIR) assert isdir(DDL_DIR) +def apply_legacy_ld_args() -> dict: + """ + Get legacy linker script parameters (build.ld_args.x) from board manifest and write to new keys (upload.x) + """ + flash_start = board.get("build.ld_args.flash_start", None) + if not flash_start == None: + # parse flash start (hex, convert to int) + flash_start = int(flash_start, 16) + + board._manifest["upload"]["offset_address"] = flash_start + sys.stderr.write("Warning: you appear to be using legacy option 'build.ld_args.flash_start'! Use 'upload.offset_address' instead.\n") + + + flash_size = board.get("build.ld_args.flash_size", None) + if not flash_size == None: + # parse flash size (K or M suffix, convert to bytes) + if flash_size[-1] == "K": + flash_size = int(flash_size[:-1]) * 1024 + elif flash_size[-1] == "M": + flash_size = int(flash_size[:-1]) * 1024 * 1024 + else: + flash_size = int(flash_size) + + board._manifest["upload"]["maximum_size"] = flash_size + sys.stderr.write("Warning: you appear to be using legacy option 'build.ld_args.flash_size'! Use 'upload.maximum_size' instead.\n") + + + boot_mode = board.get("build.ld_args.boot_mode", None) + if not boot_mode == None: + # parse boot mode + # 0 / 1 / "primary" = primary boot mode + # 2 / "secondary" = secondary boot mode + if boot_mode in ["0", "1", "primary"]: + boot_mode = "primary" + elif boot_mode in ["2", "secondary"]: + boot_mode = "secondary" + else: + raise ValueError("legacy boot_mode must be 0/1/'primary' or 2/'secondary'!") + + board._manifest["build"]["boot_mode"] = boot_mode + sys.stderr.write("Warning: you appear to be using legacy option 'build.ld_args.boot_mode'! Use 'build.boot_mode' instead.\n") + + def get_ld_args() -> dict: """ Get linker script parameters from the board manifest @@ -30,21 +74,16 @@ def get_ld_args() -> dict: :return: dict with flash_start, flash_size and boot_mode """ + apply_legacy_ld_args() + # get parameters from board manifest - flash_start = board.get("build.ld_args.flash_start", "0x0") - flash_size = board.get("build.ld_args.flash_size", "256K") - boot_mode = board.get("build.ld_args.boot_mode", "1") + flash_start = board.get("upload.offset_address", 0) + flash_size = board.get("upload.maximum_size", 262144) + boot_mode = board.get("build.boot_mode", "primary") # parse flash start (hex, convert to int) - flash_start = int(flash_start, 16) - - # parse flash size (K or M suffix, convert to bytes) - if flash_size[-1] == "K": - flash_size = int(flash_size[:-1]) * 1024 - elif flash_size[-1] == "M": - flash_size = int(flash_size[:-1]) * 1024 * 1024 - else: - flash_size = int(flash_size) + if isinstance(flash_start, str): + flash_start = int(flash_start, 16) if flash_start.startswith("0x") else int(flash_start) # calculate and check usable flash size flash_size_usable = flash_size - flash_start @@ -56,14 +95,14 @@ def get_ld_args() -> dict: board._manifest["upload"]["maximum_size"] = flash_size_usable # parse boot mode - # 0 / 1 / "primary" = primary boot mode - # 2 / "secondary" = secondary boot mode - if boot_mode in ["0", "1", "primary"]: + # "primary" = primary boot mode + # "secondary" = secondary boot mode + if boot_mode in ["primary"]: boot_mode = 1 - elif boot_mode in ["2", "secondary"]: + elif boot_mode in ["secondary"]: boot_mode = 2 else: - raise ValueError("boot_mode must be 0/1/'primary' or 2/'secondary'!") + raise ValueError("boot_mode must be 'primary' or 'secondary'!") # boot_mode must be primary if flash_start is 0 if flash_start == 0 and boot_mode != 1: @@ -89,8 +128,8 @@ def preprocess_ld_script(): # either from the board manifest, or the default one ld_script_source = board.get("build.ldscript", join(FRAMEWORK_DIR, "ld", "hc32f46x_param.ld")) - # allow disabling preprocessing using board_build.ld_args.preprocess - if board.get("build.ld_args.preprocess", "true") == "true": + # allow disabling preprocessing using board_build.ld_preprocess + if board.get("build.ld_preprocess", "true") == "true": # preprocess the linker script # output will be written to $BUILD_DIR/PROGNAME.ld ld_script_target = join("$BUILD_DIR", "${PROGNAME}.ld")