From 7e1b56371b1c8992e4481a8baff940796fc82dbb Mon Sep 17 00:00:00 2001 From: Kevin Le Date: Sat, 6 Jun 2026 12:50:06 +0700 Subject: [PATCH] Added time keeping for NRF52 across resets --- boards/nrf52840_s140_v6.ld | 15 ++++++- boards/nrf52840_s140_v6_extrafs.ld | 15 ++++++- boards/nrf52840_s140_v7.ld | 15 ++++++- boards/nrf52840_s140_v7_extrafs.ld | 12 +++++- src/helpers/ArduinoHelpers.cpp | 6 +++ src/helpers/ArduinoHelpers.h | 42 ++++++++++++++++++- variants/gat562_30s_mesh_kit/platformio.ini | 1 + .../gat562_mesh_tracker_pro/platformio.ini | 1 + variants/promicro/platformio.ini | 1 + variants/rak3401/platformio.ini | 1 + variants/rak4631/platformio.ini | 1 + variants/rak_wismesh_tag/platformio.ini | 1 + 12 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 src/helpers/ArduinoHelpers.cpp diff --git a/boards/nrf52840_s140_v6.ld b/boards/nrf52840_s140_v6.ld index 6dad975b0d..d0c7d1dc8b 100644 --- a/boards/nrf52840_s140_v6.ld +++ b/boards/nrf52840_s140_v6.ld @@ -7,6 +7,9 @@ MEMORY { FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xED000 - 0x26000 + /* To keep data in RAM across resets */ + PERSISTENT_RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 8 + /* SRAM required by Softdevice depend on * - Attribute Table Size (Number of Services and Characteristics) * - Vendor UUID count @@ -14,11 +17,19 @@ MEMORY * - Concurrent connection peripheral + central + secure links * - Event Len, HVN queue, Write CMD queue */ - RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000 + RAM (rwx) : ORIGIN = 0x20006000 + 8, LENGTH = 0x20040000 - 0x20006000 - 8 } SECTIONS { + . = ALIGN(4); + .persistent (NOLOAD) : + { + KEEP(*(.persistent_magic)) + KEEP(*(.persistent_data)) + . = ALIGN(4); + } > PERSISTENT_RAM + . = ALIGN(4); .svc_data : { @@ -33,6 +44,6 @@ SECTIONS KEEP(*(.fs_data)) PROVIDE(__stop_fs_data = .); } > RAM -} INSERT AFTER .data; +} INCLUDE "nrf52_common.ld" diff --git a/boards/nrf52840_s140_v6_extrafs.ld b/boards/nrf52840_s140_v6_extrafs.ld index 352610679e..bd4547473a 100644 --- a/boards/nrf52840_s140_v6_extrafs.ld +++ b/boards/nrf52840_s140_v6_extrafs.ld @@ -7,6 +7,9 @@ MEMORY { FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xD4000 - 0x26000 + /* To keep data in RAM across resets */ + PERSISTENT_RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 8 + /* SRAM required by Softdevice depend on * - Attribute Table Size (Number of Services and Characteristics) * - Vendor UUID count @@ -14,11 +17,19 @@ MEMORY * - Concurrent connection peripheral + central + secure links * - Event Len, HVN queue, Write CMD queue */ - RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000 + RAM (rwx) : ORIGIN = 0x20006000 + 8, LENGTH = 0x20040000 - 0x20006000 - 8 } SECTIONS { + . = ALIGN(4); + .persistent (NOLOAD) : + { + KEEP(*(.persistent_magic)) + KEEP(*(.persistent_data)) + . = ALIGN(4); + } > PERSISTENT_RAM + . = ALIGN(4); .svc_data : { @@ -33,6 +44,6 @@ SECTIONS KEEP(*(.fs_data)) PROVIDE(__stop_fs_data = .); } > RAM -} INSERT AFTER .data; +} INCLUDE "nrf52_common.ld" diff --git a/boards/nrf52840_s140_v7.ld b/boards/nrf52840_s140_v7.ld index 6aaeb4034f..2333238f28 100644 --- a/boards/nrf52840_s140_v7.ld +++ b/boards/nrf52840_s140_v7.ld @@ -7,6 +7,9 @@ MEMORY { FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0xED000 - 0x27000 + /* To keep data in RAM across resets */ + PERSISTENT_RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 8 + /* SRAM required by Softdevice depend on * - Attribute Table Size (Number of Services and Characteristics) * - Vendor UUID count @@ -14,11 +17,19 @@ MEMORY * - Concurrent connection peripheral + central + secure links * - Event Len, HVN queue, Write CMD queue */ - RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000 + RAM (rwx) : ORIGIN = 0x20006000 + 8, LENGTH = 0x20040000 - 0x20006000 - 8 } SECTIONS { + . = ALIGN(4); + .persistent (NOLOAD) : + { + KEEP(*(.persistent_magic)) + KEEP(*(.persistent_data)) + . = ALIGN(4); + } > PERSISTENT_RAM + . = ALIGN(4); .svc_data : { @@ -33,6 +44,6 @@ SECTIONS KEEP(*(.fs_data)) PROVIDE(__stop_fs_data = .); } > RAM -} INSERT AFTER .data; +} INCLUDE "nrf52_common.ld" diff --git a/boards/nrf52840_s140_v7_extrafs.ld b/boards/nrf52840_s140_v7_extrafs.ld index 5956183aa3..48348188af 100644 --- a/boards/nrf52840_s140_v7_extrafs.ld +++ b/boards/nrf52840_s140_v7_extrafs.ld @@ -14,11 +14,19 @@ MEMORY * - Concurrent connection peripheral + central + secure links * - Event Len, HVN queue, Write CMD queue */ - RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000 + RAM (rwx) : ORIGIN = 0x20006000 + 8, LENGTH = 0x20040000 - 0x20006000 - 8 } SECTIONS { + . = ALIGN(4); + .persistent (NOLOAD) : + { + KEEP(*(.persistent_magic)) + KEEP(*(.persistent_data)) + . = ALIGN(4); + } > PERSISTENT_RAM + . = ALIGN(4); .svc_data : { @@ -33,6 +41,6 @@ SECTIONS KEEP(*(.fs_data)) PROVIDE(__stop_fs_data = .); } > RAM -} INSERT AFTER .data; +} INCLUDE "nrf52_common.ld" diff --git a/src/helpers/ArduinoHelpers.cpp b/src/helpers/ArduinoHelpers.cpp new file mode 100644 index 0000000000..feb77a79c6 --- /dev/null +++ b/src/helpers/ArduinoHelpers.cpp @@ -0,0 +1,6 @@ +#include + +extern "C" { + __attribute__((section(".persistent_magic"))) uint32_t persistent_magic; + __attribute__((section(".persistent_data"))) uint32_t persistent_time; +} \ No newline at end of file diff --git a/src/helpers/ArduinoHelpers.h b/src/helpers/ArduinoHelpers.h index 97596daa31..9b50b98caf 100644 --- a/src/helpers/ArduinoHelpers.h +++ b/src/helpers/ArduinoHelpers.h @@ -3,19 +3,57 @@ #include #include +#ifdef NRF52_PLATFORM +#define CLOCK_MAGIC_NUM 0xAA55CC33 +#define RTC_TIME_MIN 1772323200 // 1 Mar 2026 + +extern uint32_t persistent_magic; +extern uint32_t persistent_time; +#endif + class VolatileRTCClock : public mesh::RTCClock { uint32_t base_time; uint64_t accumulator; unsigned long prev_millis; + public: - VolatileRTCClock() { base_time = 1715770351; accumulator = 0; prev_millis = millis(); } // 15 May 2024, 8:50pm + VolatileRTCClock() { +#ifdef NRF52_PLATFORM + if (persistent_magic == CLOCK_MAGIC_NUM && persistent_time >= RTC_TIME_MIN) { + base_time = persistent_time; + } else { + base_time = RTC_TIME_MIN; + } +#else + base_time = 1715770351; +#endif + + accumulator = 0; + prev_millis = millis(); + } + uint32_t getCurrentTime() override { return base_time + accumulator/1000; } - void setCurrentTime(uint32_t time) override { base_time = time; accumulator = 0; prev_millis = millis(); } + + void setCurrentTime(uint32_t time) override { + base_time = time; + accumulator = 0; + prev_millis = millis(); + +#ifdef NRF52_PLATFORM + persistent_magic = CLOCK_MAGIC_NUM; + persistent_time = time; +#endif + } void tick() override { unsigned long now = millis(); accumulator += (now - prev_millis); prev_millis = now; + +#ifdef NRF52_PLATFORM + persistent_magic = CLOCK_MAGIC_NUM; + persistent_time = getCurrentTime(); +#endif } }; diff --git a/variants/gat562_30s_mesh_kit/platformio.ini b/variants/gat562_30s_mesh_kit/platformio.ini index 2baac2561b..e9f2e19076 100644 --- a/variants/gat562_30s_mesh_kit/platformio.ini +++ b/variants/gat562_30s_mesh_kit/platformio.ini @@ -2,6 +2,7 @@ extends = nrf52_base board = rak4631 board_check = true +board_build.ldscript = boards/nrf52840_s140_v6.ld build_flags = ${nrf52_base.build_flags} ${sensor_base.build_flags} -I variants/gat562_30s_mesh_kit diff --git a/variants/gat562_mesh_tracker_pro/platformio.ini b/variants/gat562_mesh_tracker_pro/platformio.ini index af153b8fc2..8a4df6dcb3 100644 --- a/variants/gat562_mesh_tracker_pro/platformio.ini +++ b/variants/gat562_mesh_tracker_pro/platformio.ini @@ -2,6 +2,7 @@ extends = nrf52_base board = rak4631 board_check = true +board_build.ldscript = boards/nrf52840_s140_v6.ld build_flags = ${nrf52_base.build_flags} ${sensor_base.build_flags} -I variants/gat562_mesh_tracker_pro diff --git a/variants/promicro/platformio.ini b/variants/promicro/platformio.ini index 5415e15861..1e1a32740f 100644 --- a/variants/promicro/platformio.ini +++ b/variants/promicro/platformio.ini @@ -1,6 +1,7 @@ [Promicro] extends = nrf52_base board = promicro_nrf52840 +board_build.ldscript = boards/nrf52840_s140_v6.ld build_flags = ${nrf52_base.build_flags} -I variants/promicro -D PROMICRO diff --git a/variants/rak3401/platformio.ini b/variants/rak3401/platformio.ini index 20a8a548b9..7dd8d2fb9c 100644 --- a/variants/rak3401/platformio.ini +++ b/variants/rak3401/platformio.ini @@ -2,6 +2,7 @@ extends = nrf52_base board = rak3401 board_check = true +board_build.ldscript = boards/nrf52840_s140_v6.ld build_flags = ${nrf52_base.build_flags} ${sensor_base.build_flags} -I variants/rak3401 diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index 2bbba31463..216910489d 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -2,6 +2,7 @@ extends = nrf52_base board = rak4631 board_check = true +board_build.ldscript = boards/nrf52840_s140_v6.ld extra_scripts = ${nrf52_base.extra_scripts} post:variants/rak4631/fix_bsec_lib.py build_flags = ${nrf52_base.build_flags} diff --git a/variants/rak_wismesh_tag/platformio.ini b/variants/rak_wismesh_tag/platformio.ini index e9cddb74dd..b596c9a659 100644 --- a/variants/rak_wismesh_tag/platformio.ini +++ b/variants/rak_wismesh_tag/platformio.ini @@ -2,6 +2,7 @@ extends = nrf52_base board = rak4631 board_check = true +board_build.ldscript = boards/nrf52840_s140_v6.ld build_flags = ${nrf52_base.build_flags} ${sensor_base.build_flags} -I variants/rak_wismesh_tag