2025-08-07 11:53 AM
Hello everyone,
I am working with an SPC58NH92C5RMI0X microcontroller using SPC5Studio v6.0 and the corresponding GCC toolchain.
Objective: I am trying to implement a persistent variable that survives warm resets (debugger or pin resets) but is initialized in a controlled manner on a cold boot (power-on). To achieve this, I have created a custom .noinit section in memory.
Symptoms: The system's behavior is inconsistent and depends on the boot type:
Under the Debugger (Warm Resets): The system works perfectly. I can write a value to my persistent variable, perform a reset via the debugger, and the correct value is read in the next session.
On Power-On (Cold Boot): The system behaves erratically. Sometimes it boots correctly, but most of the time it halts/crashes.
Point of Failure: When the system halts, the crash occurs precisely at the instruction that attempts to read the persisted variable for the first time in my main() function.
Implementation:
To isolate the variable from the standard RAM clearing routines (_sysraminit in boot.s and the BSS clear in crt0.s), I have modified my linker script to create a dedicated memory region at the end of dram2.
1. C Code Variable:
__attribute__((section(".noinit"), used))
volatile uint32_t persisted;
int main(void) {
// ... initializations ...
pal_lld_setpad(PORT_LED2_KIT, LED2_KIT); // Turn on LED to indicate main has started
// >>> THE CODE CRASHES HERE ON COLD BOOT <<<
if (persisted == 0xdeadbeef) {
pal_lld_setpad(PORT_LED1_KIT, LED1_KIT); // Indicates the value was read successfully
} else {
pal_lld_setpad(PORT_LED3_KIT, LED3_KIT); // Indicates the value was different
}
// ...
}
2. Linker Script (user.ld):
MEMORY
{
dataflash : org = 0x00800000, len = 256k
flash : org = 0x00FC0000, len = 10M
ram : org = 0x40028000, len = 1376k - 288k
iram0 : org = 0x50000000, len = 32k
iram1 : org = 0x51000000, len = 32k
iram2 : org = 0x52000000, len = 32k
dram0 : org = 0x50800000, len = 64k
dram1 : org = 0x51800000, len = 64k
dram2 : org = 0x52800000, len = 64k - 4k
noinit_ram : org = 0x52800000 + (64k - 4k), len = 4k
}
SECTIONS
{
/* ... other sections ... */
.noinit (NOLOAD):
{
. = ALIGN(4);
__noinit_start__ = .;
*(.noinit)
*(.noinit.*)
. = ALIGN(4);
__noinit_end__ = .;
} > noinit_ram
__heap_base__ = __bss_end__;
__heap_end__ = __ram_end__;
}
Any help or insight would be greatly appreciated. Thank you.