Skip to content

Commit

Permalink
Merge pull request #12 from shadow578/add/ldargs-refactor
Browse files Browse the repository at this point in the history
use `board.upload` instead of ld_args
  • Loading branch information
shadow578 authored May 12, 2024
2 parents e055830 + c918048 commit 67c488a
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 43 deletions.
2 changes: 1 addition & 1 deletion docs/config_options/BOOT_MODE.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ platformio.ini:
```ini
[env:my_env]
# ...
board_build.ld_args.boot_mode = secondary
board_build.boot_mode = secondary
```
33 changes: 15 additions & 18 deletions docs/config_options/LINKER_SCRIPT.md
Original file line number Diff line number Diff line change
@@ -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]
Expand All @@ -35,22 +34,20 @@ 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
```


board.json:
```json
{
// ...
"build": {
// ...
"ld_args": {
"flash_start": "0x00000000",
"flash_size": "256K"
}
"upload": {
"maximum_size": 262144,
"maximum_ram_size": 192512,
"offset_address": "0xc000"
}
}
```
9 changes: 5 additions & 4 deletions docs/patches/hc32f46x_param.ld.patch
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -107,16 +107,17 @@ 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
+
+ /* append all other FLASH sections after */
.text :
{
. = ALIGN(4);
@@ -172,12 +244,14 @@ SECTIONS
@@ -172,12 +245,14 @@ SECTIONS
__end__ = .;
PROVIDE(end = .);
PROVIDE(_end = .);
Expand All @@ -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")
Expand Down
3 changes: 2 additions & 1 deletion ld/hc32f46x_param.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
77 changes: 58 additions & 19 deletions tools/platformio/platformio-build-ddl.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -23,28 +24,66 @@
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
: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
Expand All @@ -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:
Expand All @@ -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")
Expand Down

0 comments on commit 67c488a

Please sign in to comment.