CircuitPython version and board name
Description
I’m building a custom nRF52840 board (BOARD=sensera2) and want to disable SPIM3 and reclaim the 8 KB reserved “SPIM3_RAM” back into APP_RAM. I created a board-local linker script without SPIM3_RAM and pointed my board to it, but the final build still shows SPIM3_RAM: 8 KB and APP_RAM stays at 192 KB.
It looks like the build system may still be using the template/generated linker instead of my board-local .ld, or it’s otherwise re-introducing the SPIM3 region.
Environment
- Repo: https://github.com/adafruit/circuitpython (fresh clone; current main as of Oct 6, 2025)
- Port:
ports/nordic
- Board: custom
sensera2
- Host OS: Linux (Ubuntu-like)
- Build toolchain: arm-none-eabi-gcc (version not captured)
### Code/REPL
```python
import gc
gc.collect()
print("heap_total:", gc.mem_free() + gc.mem_alloc())
Behavior
What I did (board-only changes)
ports/nordic/boards/sensera2/mpconfigboard.mk
USB_VID = 0x239A
USB_PID = 0x80DA
USB_PRODUCT = "PCA10056"
USB_MANUFACTURER = "Nordic Semiconductor"
MCU_CHIP = nrf52840
UF2_NAME = "SENSERA_Device"
CIRCUITPY_BUILD_EXTENSIONS = bin,uf2
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICES = "GD25Q16C, W25Q16JVxQ"
# Core BLE module + workflows
CIRCUITPY_BLEIO = 1
CIRCUITPY_BLE_WORKFLOW = 1
CIRCUITPY_BLE_FILE_SERVICE = 1
# Use a board-local linker without SPIM3 reservation
override LD_FILE = boards/sensera2/nrf52840_no_spim3.ld
# Disable SPIM3 for this board
CFLAGS += -DNRFX_SPIM3_ENABLED=0
# BLE: single peripheral link
CIRCUITPY_BLE = 1
CIRCUITPY_BLE_MAX_CONNECTIONS = 1
CFLAGS += -DNRF_SDH_BLE_PERIPHERAL_LINK_COUNT=1
CFLAGS += -DNRF_SDH_BLE_CENTRAL_LINK_COUNT=0
ports/nordic/boards/sensera2/board.cmake
set(MCU_VARIANT nrf52840)
set(OUTPUT_NAME "Sensera_Firmware")
# Use the board-local linker (no SPIM3 reservation)
set(LD_FILE ${CMAKE_CURRENT_LIST_DIR}/nrf52840_no_spim3.ld CACHE STRING "" FORCE)
(Happy to also set LD_TEMPLATE_FILE if that’s the correct knob for the template path.)
ports/nordic/boards/sensera2/nrf52840_no_spim3.ld (board-local; no SPIM3 region)
MEMORY
{
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 /* 256 KB */
SD_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0E000 /* 56 KB */
APP_RAM (rwx) : ORIGIN = 0x2000E000, LENGTH = 0x32000 /* 200 KB */
}
Commands & log
source venv/bin/activate
cd circuitpython/ports/nordic
make clean BOARD=sensera2
make BOARD=sensera2 V=1 2>&1 | tee build-sensera2.log
Size summary (end of build):
Memory region Used Size Region Size %age Used
FLASH: 0 GB 1 MB 0.00%
FLASH_MBR: 0 GB 4 KB 0.00%
FLASH_SD: 0 GB 148 KB 0.00%
FLASH_ISR: 248 B 4 KB 6.05%
FLASH_FIRMWARE: 610340 B 780 KB 76.41%
FLASH_BLE_CONFIG: 0 GB 32 KB 0.00%
FLASH_NVM: 0 GB 8 KB 0.00%
FLASH_FATFS: 0 GB 0 GB
FLASH_BOOTLOADER: 0 GB 40 KB 0.00%
FLASH_BOOTLOADER_SETTINGS: 0 GB 4 KB 0.00%
RAM: 0 GB 256 KB 0.00%
SD_RAM: 0 GB 56 KB 0.00%
SPIM3_RAM: 0 GB 8 KB 0.00%
APP_RAM: 51884 B 192 KB 26.39%
I expected no SPIM3_RAM line and APP_RAM = 200 KB.
Local checks of the board linker file:
ls -l ports/nordic/boards/sensera2/nrf52840_no_spim3.ld
# -rwxrwx--- (readable; no exec required)
grep -n '^[[:space:]]*SPIM3_RAM' ports/nordic/boards/sensera2/nrf52840_no_spim3.ld
# OK: no SPIM3_RAM region
awk '/^MEMORY/{p=1} p; /^\}/{p=0}' ports/nordic/boards/sensera2/nrf52840_no_spim3.ld
# shows RAM 256 KB, SD_RAM 56 KB, APP_RAM 200 KB
(I also set override LD_FILE = boards/sensera2/nrf52840_no_spim3.ld in mpconfigboard.mk, and forced the same via board.cmake with set(LD_FILE ... FORCE).)
What I expected
- The link step to use my board-local
.ld, or to generate a firmware.ld without SPIM3_RAM.
- Size summary to show no SPIM3_RAM and APP_RAM = 200 KB, so I get ~8 KB more heap at runtime.
What happened instead
Questions
-
For ports/nordic, what’s the canonical way (per board) to remove the SPIM3_RAM reservation?
- Override
LD_FILE?
- Override
LD_TEMPLATE_FILE in board.cmake?
- Another variable?
-
Is there any caching / CMake behavior that could ignore a board-level LD_FILE override?
-
Is the size summary derived strictly from the linked regions, or from separate build variables (which might still include SPIM3)?
-
If the template path is preferred, can you point me to the correct set of CMake variables to set per board so the generated firmware.ld excludes SPIM3_RAM?
Happy to provide the -T ...ld line from the verbose link step if needed; right now the size report implies the default template/regions are still in effect.
Thanks!
Description
No response
Additional information
No response
CircuitPython version and board name
Description
I’m building a custom nRF52840 board (
BOARD=sensera2) and want to disable SPIM3 and reclaim the 8 KB reserved “SPIM3_RAM” back into APP_RAM. I created a board-local linker script withoutSPIM3_RAMand pointed my board to it, but the final build still showsSPIM3_RAM: 8 KBand APP_RAM stays at 192 KB.It looks like the build system may still be using the template/generated linker instead of my board-local
.ld, or it’s otherwise re-introducing the SPIM3 region.Environment
ports/nordicsensera2Behavior
What I did (board-only changes)
ports/nordic/boards/sensera2/mpconfigboard.mkports/nordic/boards/sensera2/board.cmake(Happy to also set
LD_TEMPLATE_FILEif that’s the correct knob for the template path.)ports/nordic/boards/sensera2/nrf52840_no_spim3.ld(board-local; no SPIM3 region)Commands & log
Size summary (end of build):
I expected no
SPIM3_RAMline and APP_RAM = 200 KB.Local checks of the board linker file:
(I also set
override LD_FILE = boards/sensera2/nrf52840_no_spim3.ldinmpconfigboard.mk, and forced the same viaboard.cmakewithset(LD_FILE ... FORCE).)What I expected
.ld, or to generate afirmware.ldwithoutSPIM3_RAM.What happened instead
The size summary still shows
SPIM3_RAM: 8 KBandAPP_RAM: 192 KB, suggesting the build is either:SPIM3_RAM, orQuestions
For ports/nordic, what’s the canonical way (per board) to remove the
SPIM3_RAMreservation?LD_FILE?LD_TEMPLATE_FILEinboard.cmake?Is there any caching / CMake behavior that could ignore a board-level
LD_FILEoverride?Is the size summary derived strictly from the linked regions, or from separate build variables (which might still include SPIM3)?
If the template path is preferred, can you point me to the correct set of CMake variables to set per board so the generated
firmware.ldexcludesSPIM3_RAM?Happy to provide the
-T ...ldline from the verbose link step if needed; right now the size report implies the default template/regions are still in effect.Thanks!
Description
No response
Additional information
No response