What this ticket reports
We ship a battery-powered nRF5340 product using the nRF Connect SDK's documented production security configuration: immutable bootloader (NSIB/b0) + upgradable MCUboot in s0/s1, signed and encrypted application images, and firmware-over-BLE (SMP/mcumgr) as the only update path for fielded units.
In this configuration, on NCS v3.3.x, no encrypted application OTA can ever complete: on the first boot after an update is staged and marked pending, MCUboot mis-classifies the encrypted image in the secondary slot, never schedules the swap, and then deliberately erases the staged image. The device boots the old firmware, and nothing is logged above DEBUG level.
We root-caused this to four distinct, individually measurable defects in the NCS MCUboot integration (three in Nordic-only [nrf noup] code, one shared with upstream mcu-tools/mcuboot). This ticket documents each defect with measurements, explains how they interlock, reports which of them NCS 3.4.0 does and does not fix, and attaches a minimal bench-proven patch set. The specific requests are listed at the end; the headline one is that the 3.4.0 fix for defect 1 is compile-time unavailable to Partition-Manager-based projects, which leaves fielded products with no supported configuration in which encrypted OTA works.
Environment
- nRF5340 (QKAA), custom board derived from nrf5340dk_nrf5340_cpuapp
- NCS v3.3.1. We verified v3.3.2, v3.3.3 and v3.3.4 all pin the identical sdk-mcuboot revision (
3de5b4df, "v2.3.0-dev"), so everything below applies to the whole 3.3.x line. - Sysbuild + static Partition Manager layout (
pm_static.yml, attached); app-core secondary slot in external QSPI NOR (MX25R6435F), size 0xd3000 (864,256 bytes) SB_CONFIG_SECURE_BOOT_APPCORE=y(b0 + s0/s1),SB_CONFIG_BOOT_ENCRYPTION=y(ECIES-P256 key exchange, AES-128-CTR payload),SB_CONFIG_MCUBOOT_MODE_SWAP_USING_MOVE=ySB_CONFIG_MCUBOOT_NRF53_MULTI_IMAGE_UPDATE=y— network-core update via PCD, sharing the same external secondary slotCONFIG_UPDATEABLE_IMAGE_NUMBER=3as sysbuild derives it: image 0 = app core, image 1 = net core, image 2 = s0/s1 (MCUboot self-update). This value cannot be lowered from the project — see "Defect 2" below, which also explains why.- The application arms a task watchdog with a 10.5 s hardware fallback window (
CONFIG_TASK_WDT+CONFIG_TASK_WDT_HW_FALLBACK). This is relevant because the nRF5340 WDT deliberately survives warm resets and cannot be stopped, and a field OTA reboot (sys_rebootafter the mcumgr upload + test mark) is a warm reset — so MCUboot runs the entire swap with the application's watchdog counting down underneath it.
Summary of the failure chain
Staging an encrypted app image triggers the following chain. (Defects are numbered by how we isolated them, not by the order they fire; on a stock build the watchdog cuts the boot at the first operation that exceeds its window, so the individual timings below were measured on boots where the watchdog was not armed — see "How we measured".)
- Defect 1 — the NSIB slot-disambiguation code reads the staged image's reset vector from the secondary slot without decrypting it, concludes the (perfectly valid) image belongs to no slot, and returns before the slot is marked as assigned.
- Defect 3 — the "unusable slot" cleanup then erases the staged image: 15.8 s of blocking erase over external QSPI in one unfed call, followed by a second 17.9 s erase of the same physical area on behalf of image 2.
- Defect 2 — independently, image 2's swap-state scan never returns when anything is staged in the shared secondary, because it reads a flash area backed by the powered-off network core (≥10.86 s observed before our watchdog cut the boot).
- Defect 4 — MCUboot never feeds the watchdog on any of these paths, nor on the ~60 s swap path itself. So with any application watchdog under ~60 s the device additionally takes a mid-operation DOG0 reset; without one, the staged image is simply erased and the boot proceeds normally.
Either way the update never happens and the old image keeps running. With all four fixes applied (attached patch), the full encrypted OTA chain works on our bench: swap in ~60.6 s, application self-confirm, persistence across resets, and watchdog-driven revert of a deliberately broken image.
How we measured
Everything below comes from the target hardware, not from reading code alone. Method: RTT attach over SWD immediately after releasing reset, so MCUboot's log is captured from its first instruction; warm resets issued over BLE/mcumgr exactly as a fielded unit experiences them; RESETREAS read and cleared around every experiment so each reset is attributed to its cause (DOG0 vs SREQ vs pin); and, where the stock DEBUG log was insufficient, temporary instrumentation compiled into MCUboot (entry/exit timestamps, and the actual header fields and addresses each decision reads). Timings longer than the 10.5 s watchdog window were captured on boots where the application watchdog had not yet been armed (power-on and debugger flash cycles rather than warm OTA resets), so each operation could run to completion; the DOG0 observations come from the warm-reset runs with the watchdog live. All timings are RTT timestamps, reproducible across runs. The attached logs are raw captures; PROOF.txt is the acceptance evidence for the full fix set.
Defect 1 (keystone): NSIB slot disambiguation reads the reset vector of an encrypted image as plaintext
boot/bootutil/src/loader.c, boot_validated_swap_type() — the downstream block introduced by [nrf noup] 977324e9 ("Rework CPUNET application update logic"). Because the s0/s1 self-update image shares the app's external secondary slot, this block reads the staged image's reset vector (offset ih_hdr_size + 4 in the secondary) to decide which image the staged binary belongs to. The read is raw flash — never decrypted. For an AES-CTR-encrypted image that word is ciphertext, so the range checks conclude "not intended for any image" and the function returns BOOT_SWAP_TYPE_NONE before sec_slot_mark_assigned() runs. The slot is left in the SEC_SLOT_TOUCHED state, which sec_slot_cleanup_if_unusable() then erases (defect 3).
Instrumented capture — the same boot, both images' classification of the shared secondary side by side:
img=0 magic=0x96f3b83d ih_flags=0x4 (IMAGE_F_ENCRYPTED_AES128) reset_addr=0x3ee3fbc2 -> "not in primary [0x28000,0xfc000]" -> BOOT_SWAP_TYPE_NONE (never assigned) img=1 magic=0x96f3b83d ih_flags=0x100 (no ENCRYPTIONFLAGS bit -- unencrypted net-core image) reset_addr=0x1023291 -> assigned (this is why only the encrypted app image ever fails)
(The primary span above is 0x1000 larger than the secondary because swap-using-move keeps the primary one sector larger.) Note the code has the encryption flag in hand at the moment of the bad read — hdr->ih_flags comes from the plaintext header it already parsed.
Suggested fix: skip the plaintext-only disambiguation when ih_flags & ENCRYPTIONFLAGS is set — the two-line guard in boot_validated_swap_type() in the attached patch. With it, the entire OTA chain works; bench-proven, logs attached.
Prior art: mcu-tools/mcuboot PR #2473 (closed unmerged), whose discussion notes that the reset-vector disambiguation "explicitly does not support encrypted images".
Defect 2: image-2 swap-state scan never returns when the network core is off (≥10.86 s observed)
boot_prepare_image_for_update() → swap_status_source() → boot_read_swap_state() for image index 2. Image 2's primary flash area resolves to mcuboot_primary_1 — the nordic_ram_flash_controller (PCD) staging area backed by the network core, which is held in FORCEOFF while MCUboot runs. The read blocks and was still blocked when our watchdog fired 10.86 s in (bisected with entry/exit timestamps; images 0 and 1 traverse the identical code in under 1 ms).
Trigger condition: image 2's secondary is the shared mcuboot_secondary, so staging any app image gives image 2's secondary "good magic" and sends its swap-state scan into the unbacked primary. Idle boots short-circuit before the read and look healthy — which is why this survives testing that never stages an image.
We also verified image 2 cannot be disabled from a project: CONFIG_UPDATEABLE_IMAGE_NUMBER is force-set by nrf/sysbuild/CMakeLists.txt (set_config_int), SB_CONFIG_MCUBOOT_ADDITIONAL_UPDATEABLE_IMAGES is Kconfig-pinned to range [1,1] when SECURE_BOOT_APPCORE is on, and forcing the count to 2 anyway produces an application-core LOCKUP (the image-ID plumbing assumes all three images exist).
Suggested fix: guard the swap-state read for net-core-backed areas (or for the NSIB-owned image) the way downgrade-prevention paths already are. Our patch skips image 2's update processing entirely in boot_prepare_image_for_update() — correct for products whose s0/s1 updates are delivered as signed app-style images, but a general fix belongs in the SDK.
Defect 3: sec_slot_cleanup_if_unusable() erases the whole external secondary in one unfed call — twice
Introduced by [nrf noup] 0751a63a. A single flash_area_erase(fa, 0, fa->fa_size) over our 844 KiB QSPI secondary measured 15.80 s for image 0 — then ran again for image 2 over the same shared physical area, 17.88 s. Each alone exceeds a 10.5 s watchdog window, so on watchdog-equipped products the erase itself is interrupted mid-flight, leaving a torn slot.
Independent of the watchdog interaction, note what this call destroys in the defect-1 scenario: a signature-valid, correctly staged application image, erased as a side effect of a mis-classification, partly on behalf of an image-2 slot that cannot function on this platform at all (defect 2).
Suggested fix: chunk the erase with MCUBOOT_WATCHDOG_FEED() between chunks (our patch uses 32 KB chunks in sec_slot_cleanup_if_unusable()), skip the redundant second erase of a shared area, and log a warning whenever a staged image is about to be destroyed — today the path is silent above DEBUG.
Defect 4: MCUBOOT_WATCHDOG_FEED() has no call sites on the swap path
The macro exists and is default y on Nordic SoCs (CONFIG_BOOT_WATCHDOG_FEED), but at 3de5b4df it is called from only four places: twice in boot/bootutil/src/bootutil_area.c, once at startup in boot/zephyr/main.c, and one copy loop in loader.c. There are zero feeds in swap_move.c — neither in the move-up loop, nor the sector-swap loop, nor swap_read_status_bytes(), which at BOOT_MAX_IMG_SECTORS=256 issues ~1000 single-byte reads over external QSPI — and zero in the image hash/decrypt chunk loop (bootutil_img_hash.c). Our encrypted swap takes ~60 s end to end; none of it feeds the watchdog.
This matters beyond our product: on nRF SoCs the watchdog survives warm resets and cannot be stopped, and a field OTA reboot is a warm reset, so any application watchdog shorter than the swap time will reset the device mid-swap. Swap-using-move tolerates the interruption and resumes — but with defects 1–3 in play, the interrupted operation was the erase of the staged image.
Suggested fix: feed coverage across the swap/validate path. Our patch adds four feed sites: swap_read_status_bytes(), both loops in swap_run(), and the hash chunk loop.
What NCS 3.4.0 changes — and what it does not
Before filing this we checked each defect against NCS v3.4.0 and current sdk-mcuboot main:
| Defect | NCS 3.3.x | NCS 3.4.0 | Remaining gap |
|---|---|---|---|
| 1 — encrypted secondary read as plaintext | Broken | Fixed only outside Partition Manager. The reset-vector read is replaced by a plaintext-header check, CONFIG_MCUBOOT_CHECK_HEADER_LOAD_ADDRESS (uses ih_load_addr, works "even when the image is encrypted"). |
The new option is declared depends on !PARTITION_MANAGER_ENABLED — a project on a PM static layout (i.e. an existing fielded nRF5340 product with a frozen flash map) compiles the old path in 3.4.0 too. |
| 2 — non-returning read of the net-core-backed area | Broken | Unchanged. 3.4.0 adds IS_NSIB_OWNED() guards elsewhere, but not around this read. |
Present in 3.4.0 and sdk-mcuboot main; we found no public report of it. |
| 3 — monolithic unfed 15.8 s + 17.9 s erases | Broken | Unchanged. Same single-call flash_area_erase, still run per-image over the shared area. |
Present in 3.4.0 and sdk-mcuboot main; no public report found. |
| 4 — no watchdog feeds on the swap path | Broken | Unchanged. swap_move.c in 3.4.0 and upstream main contains zero MCUBOOT_WATCHDOG_FEED occurrences. |
Upstream-shared code (mcu-tools/mcuboot). |
So for a product already in the field on a Partition Manager layout — which cannot migrate its flash map because OTA is its only firmware path — upgrading to NCS 3.4.0 fixes none of the four defects.
Reproduction
Deterministic, every staged boot, no special timing needed:
- Build any application with the Environment configuration above (secure boot + encryption + swap-using-move + shared external secondary; a watchdog under ~60 s makes the failure louder but is not required).
- Upload any correctly signed+encrypted app image over SMP, mark it pending (test mode), and warm-reset.
- Observe via RTT on MCUboot: the image trailer is read as pending (the mcumgr "test" mark), but
boot_validated_swap_type()returnsBOOT_SWAP_TYPE_NONEbecause the staged image is classified as belonging to no slot; the secondary is erased and the old version boots. With a watchdog armed,RESETREASadditionally showsDOG0partway through the erase; without one, the erase completes and the boot log looks normal at default log levels.
We have not attempted this on a stock nrf5340dk (its default layout has no external shared secondary). Defect 1 is layout-independent — a plaintext read of an encrypted secondary — and should reproduce on any secure-boot + encryption + multi-image build; defects 2 and 3 need the shared external secondary. We can put together a DK-based reduced case on request.
Attachments
ncs-3.3.1-mcuboot-secured-swap.patch— minimal 4-fix set, applies cleanly to sdk-mcuboot3de5b4df(the whole 3.3.x line). With it applied, our full acceptance run passes: encrypted swap in, self-confirm, persistence across reset, and automatic revert of a deliberately broken image — timings and logs inPROOF.txt.PROOF.txt— acceptance table, timings, RESETREAS trails, and the exact configuration used.partitions.yml.txt— the static Partition Manager layout (renamed from .yml for upload).rtt-keystone-encrypted-reset-vector.log— defect 1: ciphertext reset-vector classification, both images side by side.rtt-img2-hang-bisect.log— defect 2: the ≥10.86 s block bisected to the image-2 swap-state read.rtt-secondary-erase-timing.log— defect 3: the 15.80 s / 17.88 s erase pair.rtt-row2-swap-pass.log,rtt-row3-revert.log— passing encrypted swap and passing revert with the patch set applied ("row 2" / "row 3" refer to the acceptance table inPROOF.txt).
What we are asking for
- Internal bug IDs for defects 1–4 (defects 2 and 3 appear publicly unreported as far as we can tell).
- A position on the Partition Manager gap for defect 1: is a PM-compatible fix planned, and is a backport of any fix to the 3.3.x line possible?
- Review of the attached minimal patch set — we would like to converge on something Nordic-blessed rather than maintain out-of-tree SDK patches.
- Whether you prefer the defect-4 watchdog feeds (upstream-shared files) as a direct mcu-tools/mcuboot PR.
app:
address: 0x28200
end_address: 0xfc000
region: flash_primary
size: 0xd3e00
app_image:
address: 0x28200
end_address: 0xfc000
orig_span: &id001
- app
region: flash_primary
size: 0xd3e00
span: *id001
b0:
address: 0x0
end_address: 0x8000
placement:
after:
- start
region: flash_primary
size: 0x8000
b0_container:
address: 0x0
end_address: 0x8000
orig_span: &id002
- b0
region: flash_primary
size: 0x8000
span: *id002
ble_key_storage:
address: 0xfe000
end_address: 0x100000
placement:
after:
- settings_storage
region: flash_primary
size: 0x2000
crash_record_sram:
address: 0x2006fc00
end_address: 0x20070000
placement:
before:
- rpmsg_nrf53_sram
region: sram_primary
size: 0x400
external_flash:
address: 0x113000
end_address: 0x800000
region: external_flash
size: 0x6ed000
mcuboot:
address: 0x8200
end_address: 0x18000
region: flash_primary
size: 0xfe00
mcuboot_pad:
address: 0x28000
end_address: 0x28200
placement:
align:
start: 0x4000
before:
- mcuboot_primary_app
region: flash_primary
size: 0x200
mcuboot_primary:
address: 0x28000
end_address: 0xfc000
orig_span: &id003
- mcuboot_pad
- app
region: flash_primary
size: 0xd4000
span: *id003
mcuboot_primary_1:
address: 0x0
device: nordic_ram_flash_controller
end_address: 0x40000
region: ram_flash
size: 0x40000
mcuboot_primary_app:
address: 0x28200
end_address: 0xfc000
orig_span: &id004
- app
region: flash_primary
size: 0xd3e00
span: *id004
mcuboot_secondary:
address: 0x0
device: DT_CHOSEN(nordic_pm_ext_flash)
end_address: 0xd3000
placement:
align:
start: 0x4
region: external_flash
size: 0xd3000
mcuboot_secondary_1:
address: 0xd3000
device: DT_CHOSEN(nordic_pm_ext_flash)
end_address: 0x113000
region: external_flash
size: 0x40000
otp:
address: 0xff8380
end_address: 0xff83fc
region: otp
size: 0x7c
pcd_sram:
address: 0x20000000
end_address: 0x20002000
placement:
after:
- start
region: sram_primary
size: 0x2000
provision:
address: 0xff8100
end_address: 0xff8380
region: otp
size: 0x280
ram_flash:
address: 0x40000
end_address: 0x40000
region: ram_flash
size: 0x0
rpmsg_nrf53_sram:
address: 0x20070000
end_address: 0x20080000
placement:
before:
- end
region: sram_primary
size: 0x10000
s0:
address: 0x8000
end_address: 0x18000
orig_span: &id005
- s0_pad
- s0_image
region: flash_primary
size: 0x10000
span: *id005
s0_image:
address: 0x8200
end_address: 0x18000
orig_span: &id006
- mcuboot
region: flash_primary
size: 0xfe00
span: *id006
s0_pad:
address: 0x8000
end_address: 0x8200
placement:
after:
- b0_container
align:
start: 0x4000
region: flash_primary
size: 0x200
s1:
address: 0x18000
end_address: 0x28000
orig_span: &id007
- s1_pad
- s1_image
region: flash_primary
size: 0x10000
span: *id007
s1_image:
address: 0x18200
end_address: 0x28000
region: flash_primary
share_size:
- s0_image
size: 0xfe00
s1_pad:
address: 0x18000
end_address: 0x18200
placement:
after:
- s0
align:
start: 0x4000
region: flash_primary
size: 0x200
settings_storage:
address: 0xfc000
end_address: 0xfe000
placement:
align:
start: 0x4000
before:
- end
region: flash_primary
size: 0x2000
sram_primary:
address: 0x20002000
end_address: 0x2006fc00
region: sram_primary
size: 0x6dc00
WARN probe_rs::rtt: Buffer for up channel 1 not initialized WARN probe_rs::rtt: Buffer for up channel 2 not initialized WARN probe_rs::rtt: Buffer for down channel 1 not initialized WARN probe_rs::rtt: Buffer for down channel 2 not initialized Failed to create readline O��)��pF G���� ( ] �E �� ] �1 dQ ���?? pQ pQ pQ pQ p �% �% �% �% 22:02:33.177: k=0x3 22:02:33.177: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 22:02:33.177: I: Boot source: none 22:02:33.177: I: DIAG ncs img=1 magic=0x96f3b83d flags=0x100 reset_addr=0x1023291 22:02:33.177: I: DIAG ncs ASSIGNED img=1 22:02:33.177: I: Image index: 1, Swap type: none 22:02:33.177: I: DIAG skip prepare img=2 22:02:33.177: I: Bootloader chainload address offset: 0x28000 22:02:33.177: I: Image version: v0.1.2 22:02:33.177: I: Jumping to the first image slot 22:02:33.177: *** Booting MCUboot v2.3.0-dev-3de5b4df5f9f *** 22:02:33.177: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 22:02:33.177: *** Using Zephyr OS v4.3.99-37e6c28576ee *** 22:02:33.177: I: Starting bootloader 22:02:33.177: I: Primary image: magic=unset, swap_type=0x1, cop[00:01:11.428,070] <inf> app: BleCore.cpp: onDisconnected() [2203]:: [XX:XX:XX:XX:XX:02 (public)] BLE device disconnected with reason 19 22:02:33.918: [00:01:11.428,100] <inf> app: DeviceStateManager.cpp: bleOnDisconnect() [ 280]:: Disconnected 22:02:33.918: [00:01:11.428,161] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: ACTIVE: CONNECTED => ACTIVE: WAIT CONN 22:02:33.918: [00:01:11.428,497] <inf> app: Application.cpp: handleNewState() [2295]:: Handling new device state... 22:02:33.918: [00:01:11.428,619] <inf> app: BleServerController.cpp: processIntCmd() [ 337]:: Starting advertising without whitelist 22:02:33.918: [00:01:11.428,649] <inf> app: BleCore.cpp: advertisingStart() [1101]:: Adv data size: 3; ScanRespPacketsData size: 1 22:02:33.918: [00:01:11.431,091] <inf> app: BleServerController.cpp: processIntCmd() [ 341]:: Advertising started 22:02:36.934: [00:01:15.348,785] <inf> app: BleCore.cpp: onConnected() [2178]:: New BLE connection established: [XX:XX:XX:XX:XX:02 (public)], MTU: 23 bytes 22:02:36.934: [00:01:15.349,304] <inf> app: ---- Basic nonce (len: 13): ---- 22:02:36.934: [00:01:15.349,334] <inf> app: Content: 22:02:36.934: 5b 1a a8 7d b0 00 29 1b 56 41 b7 e2 e4 |[..}..). VA... 22:02:36.934: [00:01:15.349,365] <inf> app: ---- Basic nonce end ---- 22:02:36.934: [00:01:15.372,924] <inf> app: DeviceStateManager.cpp: bleOnConnect() [ 272]:: Connected 22:02:36.934: [00:01:15.372,985] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: ACTIVE: WAIT CONN => ACTIVE: CONNECTED 22:02:36.934: [00:01:15.373,443] <inf> app: BleCore.cpp: onDataLengthUpdated() [2269]:: LE data len updated: TX (len: 251 bytes time: 2120 us) RX (len: 251 bytes time: 2120 us) 22:02:36.934: [00:01:15.373,565] <inf> app: Application.cpp: handleNewState() [2295]:: Handling new device state... 22:02:36.934: [00:01:15.423,583] <inf> app: BleCore.cpp: mtuExchangeFuncful 22:02:36.939: 22:02:37.781: *** Booting MCUboot v2.3.0-dev-3de5b4df5f9f *** 22:02:37.781: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 22:02:37.781: *** Using Zephyr OS v4.3.99-37e6c28576ee *** 22:02:37.781: I: Starting bootloader 22:02:37.781: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 22:02:37.781: I: Secondary image: magic=good, swap_type=0x2, copy_done=0x3, image_ok=0x3 22:02:37.781: I: Boot source: none 22:02:37.781: I: DIAG ncs img=0 magic=0x96f3b83d flags=0x4 reset_addr=0x3ee3fbc2 22:02:37.781: I: DIAG ncs RETURN-NONE img=0 reset_addr=0x3ee3fbc2 NOT in primary [0x28000,0xfc000] 22:02:37.781: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 22:02:37.781: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 22:02:37.781: I: Boot source: none 22:02:37.781: I: DIAG ncs img=1 magic=0x96f3b83d flags=0x100 reset_addr=0x1023291 22:02:37.781: I: DIAG ncs ASSIGNED img=1 22:02:37.781: I: Image index: 1, Swap type: none 22:02:37.781: I: DIAG skip prepare img=2 22:02:37.781: I: DIAG enter sec_erase img=0 22:02:53.474: I: DIAG exit sec_erase img=0 rc=0 22:02:53.474: E: Erase secondary: img 0: 0 22:02:53.474: I: DIAG enter sec_erase img=2 22:03:11.339: I: DIAG exit sec_erase img=2 rc=0 22:03:11.339: E: Erase secondary: img 2: 0 22:03:12.582: I: Bootloader chainload address offset: 0x28000 22:03:12.582: I: Image version: v0.1.2 22:03:12.582: I: Jumping to the first image slot 22:03:13.838: *** Booting My Application v0.1.2-0d268237374f *** 22:03:13.838: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 22:03:13.838: *** Using Zephyr OS v4.3.99-37e6c28576ee *** 22:03:13.838: [00:00:00.051,330] <wrn> app: main.cpp: main() [ 47]:: nRF5340 app, last-good-ncs-2.6-95-g0d26823-d 22:03:13.838: [00:00:00.056,152] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: <UNDEFINED> => STANDBY 22:03:13.838: [00:00:00.056,213] <inf> app: Npm1300.cpp: init() [ 244]:: nRF Fuel Gauge version: 1.1.1 22:03:13.838: [00:00:00.056,793] <inf> app: Npm1300.cpp: initChargerState() [ 806]:: Charger init (regs: SET: 0x1; CLR: 0x1) 22:03:13.838: [00:00:00.057,617] <inf> app: Npm1300.cpp: controlCharger() [ 855]:: Charger disabled (regs: SET: 0x0; CLR: 0x0) 22:03:13.838: [00:00:00.559,600] <wrn> app: Npm1300.cpp: init() [ 283]:: (init) NPM1300 data: 4.174000V, -0.000000A, 25.617737°C 22:03:14.773: [00:00:01.061,523] <wrn> app: Npm1300.cpp: init() [ 283]:: (init) NPM1300 data: 4.174000V, -0.000000A, 25.617737°C 22:03:14.773: [00:00:01.063,690] <inf> app: Npm1300.cpp: controlCharger() [ 855]:: Charger enabled (regs: SET: 0x1; CLR: 0x1) 22:03:16.739: [00:00:02.978,881] <inf> app: AFE4403.cpp: findCapacitanceConfig() [2000]:: Finding feedback capacitor: Target: 5, Best: 5, Config: 0x00000000 22:03:16.861: [00:00:04.108,459] <inf> app: Application.cpp: initCrypto() [ 893]:: BLE session key: built-in default (no valid override) 22:03:16.861: [00:00:04.113,708] <inf> fs_nvs: 2 Sectors of 4096 bytes 22:03:16.861: [00:00:04.113,708] <inf> fs_nvs: alloc wra: 0, fe8 22:03:16.861: [00:00:04.113,708] <inf> fs_nvs: data wra: 0, 0 22:03:16.861: [00:00:04.113,800] <wrn> app: Application.cpp: initCrypto() [ 918]:: BLE app-layer encryption: ENCRYPTED 22:03:16.861: [00:00:04.113,861] <wrn> app: Application.cpp: init() [ 532]:: Charger interlock: ON 22:03:16.861: [00:00:04.113,922] <wrn> app: Application.cpp: init() [ 543]:: OTA version gate: OFF (factory default) 22:03:16.861: [00:00:04.113,983] <inf> app: LedFillCapSetting.cpp: init() [ 59]:: LED fill cap: 30 % 22:03:16.861: [00:00:04.114,044] <inf> app: AutoAnimBrightSetting.cpp: init() [ 61]:: Auto-animation brightness cap: 20 % 22:03:16.861: [00:00:04.115,417] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 22:03:16.861: [00:00:04.115,692] <inf> app: BleCore.cpp: addService() [ 22:03:16.861: 22:03:16.873: --- 1 messages dropped --- 22:03:16.873: [00:00:04.116,363] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 22:03:16.873: [00:00:04.116,424] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 22:03:16.873: [00:00:04.116,516] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 22:03:16.873: [00:00:04.116,668] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 22:03:16.873: [00:00:04.116,729] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 22:03:16.873: [00:00:04.116,821] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 22:03:16.873: [00:00:04.116,973] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 22:03:16.884: [00:00:04.139,373] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002) 22:03:16.884: [00:00:04.139,404] <inf> bt_hci_core: HW Variant: nRF53x (0x0003) 22:03:16.884: [00:00:04.139,434] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 252.31313 Build 1865177321 22:03:16.884: [00:00:04.141,754] <inf> bt_hci_core: HCI transport: IPC 22:03:16.904: [00:00:04.141,876] <inf> bt_hci_core: Identity: XX:XX:XX:XX:XX:01 (random) 22:03:16.904: [00:00:04.141,906] <inf> bt_hci_core: HCI: version 6.3 (0x11) revision 0x201f, manufacturer 0x0059 22:03:16.904: [00:00:04.141,937] <inf> bt_hci_core: LMP: version 6.3 (0x11) subver 0x201f 22:03:16.904: [00:00:04.142,456] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: STANDBY => ACTIVE: WAIT CONN 22:03:16.904: [00:00:04.144,958] <wrn> app: BatteryStateMonitorTask.hpp: start() [ 284]:: Charger is connected 22:03:16.904: [00:00:04.144,989] <inf> app: BatteryStateMonitorTask.hpp: notifyObservers() [1139]:: charger: connected 22:03:16.904: [00:00:04.145,019] <inf> app: Application.cpp: handleChargerState() [1890]:: Handling new charger state... 22:03:16.904: [00:00:04.145,263] <inf> app: BatteryStateMonitorTask.hpp: notifyObservers() [1165]:: bat state: full 22:03:16.904: [00:00:04.145,294] <inf> app: Application.cpp: handleBatteryState() [2216]:: Handling new battery state... 22:03:16.904: [00:00:04.148,071] <err> app: Application.cpp: powerDownUnusedPeripherals() [1864]:: Failed to suspend LSM6DSM (err: -120) 22:03:17.018: [00:00:04.148,559] <wrn> app: Application.cpp: armTaskWatchdogs() [1656]:: Task watchdog armed 22:03:17.018: [00:00:04.148,590] <inf> app: Application.cpp: handleNewState() [2295]:: Handling new device state... 22:03:17.018: [00:00:04.148,712] <wrn> app: DisplayTask.hpp: evtHandler() [ 101]:: Activating LED boost conv 22:03:18.994: [00:00:05.236,785] <inf> app: BleServerController.cpp: processIntCmd() [ 337]:: Starting advertising without whitelist 22:03:18.994: [00:00:05.236,938] <inf> app: BleCore.cpp: advertisingStart() [1101]:: Adv data size: 3; ScanRespPacketsData size: 1 22:03:18.994: [00:00:05.238,586] <inf> mcuboot_util: Image index: 0, Swap type: none 22:03:18.994: [00:00:05.238,647] <inf> app: Application.cpp: confirmRunningImage() [2484]:: Running image already confirmed, nothing to do 22:03:18.994: [00:00:05.239,501] <inf> app: BleServerController.cpp: processIntCmd() [ 341]:: Advertising started Received SIGTERM, exiting Exited by user request
WARN probe_rs::rtt: Buffer for up channel 1 not initialized WARN probe_rs::rtt: Buffer for up channel 2 not initialized WARN probe_rs::rtt: Buffer for down channel 1 not initialized WARN probe_rs::rtt: Buffer for down channel 2 not initialized Failed to create readline O��)��pF G���� ( ] �E �� ] �1 dQ ���?? pQ pQ pQ pQ p �% �% �% �% 20:56:53.169: exit swap_status_source (none) 20:56:53.169: I: Boot source: none 20:56:53.169: I: DIAG enter boot_swap_type_multi img=0 20:56:53.169: I: DIAG bstm: primary done, reading secondary 20:56:53.169: I: DIAG bstm: secondary state read done 20:56:53.169: I: Image index: 0, Swap type: none 20:56:53.169: I: DIAG enter swap_status_source img=1 20:56:53.169: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 20:56:53.169: I: DIAG after read_swap_state PRIMARY 20:56:53.169: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 20:56:53.169: I: DIAG after read_swap_state SECONDARY 20:56:53.169: I: DIAG exit swap_status_source (none) 20:56:53.169: I: Boot source: none 20:56:53.169: I: DIAG enter boot_swap_type_multi img=1 20:56:53.912: [00:01:16.632,904] <inf> app: BleCore.cpp: onDisconnected() [2203]:: [XX:XX:XX:XX:XX:02 (public)] BLE device disconnected with reason 19 20:56:53.912: [00:01:16.632,965] <inf> app: DeviceStateManager.cpp: bleOnDisconnect() [ 280]:: Disconnected 20:56:53.912: [00:01:16.633,026] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: ACTIVE: CONNECTED => ACTIVE: WAIT CONN 20:56:53.912: [00:01:16.633,422] <inf> app: Application.cpp: handleNewState() [2295]:: Handling new device state... 20:56:53.912: [00:01:16.633,575] <inf> app: BleServerController.cpp: processIntCmd() [ 337]:: Starting advertising without whitelist 20:56:53.912: [00:01:16.633,636] <inf> app: BleCore.cpp: advertisingStart() [1101]:: Adv data size: 3; ScanRespPacketsData size: 1 20:56:53.912: [00:01:16.636,077] <inf> app: BleServerController.cpp: processIntCmd() [ 341]:: Advertising started 20:56:58.274: [00:01:21.899,780] <inf> app: BleCore.cpp: onConnected() [2178]:: New BLE connection established: [XX:XX:XX:XX:XX:02 (public)], MTU: 23 bytes 20:56:58.274: [00:01:21.900,421] <inf> app: ---- Basic nonce (len: 13): ---- 20:56:58.274: [00:01:21.900,451] <inf> app: Content: 20:56:58.274: 89 87 fc 7c 6a 31 98 e6 dd 8b 1e cd 34 |...|j1.. ....4 20:56:58.274: [00:01:21.900,482] <inf> app: ---- Basic nonce end ---- 20:56:58.274: [00:01:21.925,354] <inf> app: DeviceStateManager.cpp: bleOnConnect() [ 272]:: Connected 20:56:58.274: [00:01:21.925,415] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: ACTIVE: WAIT CONN => ACTIVE: CONNECTED 20:56:58.274: [00:01:21.925,872] <inf> app: BleCore.cpp: onDataLengthUpdated() [2269]:: LE data len updated: TX (len: 251 bytes time: 2120 us) RX (len: 251 bytes time: 2120 us) 20:56:58.274: [00:01:21.925,964] <inf> app: Application.cpp: handleNewState() [2295]:: Handling new device state... 20:56:58.274: [00:01:21.973,205] <inf> app: BleCore.cpp: mtuExchangeFuncful 20:56:58.278: 20:56:59.124: *** Booting MCUboot v2.3.0-dev-3de5b4df5f9f *** 20:56:59.124: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 20:56:59.124: *** Using Zephyr OS v4.3.99-37e6c28576ee *** 20:56:59.124: I: Starting bootloader 20:56:59.124: I: DIAG enter swap_status_source img=0 20:56:59.124: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 20:56:59.124: I: DIAG after read_swap_state PRIMARY 20:56:59.124: I: Secondary image: magic=good, swap_type=0x2, copy_done=0x3, image_ok=0x3 20:56:59.124: I: DIAG after read_swap_state SECONDARY 20:56:59.124: I: DIAG exit swap_status_source (none) 20:56:59.124: I: Boot source: none 20:56:59.124: I: DIAG enter swap_status_source img=1 20:56:59.124: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 20:56:59.124: I: DIAG after read_swap_state PRIMARY 20:56:59.124: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 20:56:59.124: I: DIAG after read_swap_state SECONDARY 20:56:59.124: I: DIAG exit swap_status_source (none) 20:56:59.124: I: Boot source: none 20:56:59.124: I: DIAG enter boot_swap_type_multi img=1 20:56:59.124: I: DIAG bstm: primary done, reading secondary 20:56:59.124: I: DIAG bstm: secondary state read done 20:56:59.124: I: Image index: 1, Swap type: none 20:56:59.124: I: DIAG enter swap_status_source img=2 20:56:59.124: I: *** Booting MCUboot v2.3.0-dev-3de5b4df5f9f *** 20:57:09.986: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 20:57:09.986: *** Using Zephyr OS v4.3.99-37e6c28576ee *** 20:57:09.986: I: Starting bootloader 20:57:09.986: I: DIAG enter swap_status_source img=0 20:57:09.986: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 20:57:09.986: I: DIAG after read_swap_state PRIMARY 20:57:09.986: I: Secondary image: magic=good, swap_type=0x2, copy_done=0x3, image_ok=0x3 20:57:09.986: I: DIAG after read_swap_state SECONDARY 20:57:09.986: I: DIAG exit swap_status_source (none) 20:57:09.986: I: Boot source: none 20:57:09.986: I: DIAG enter boot_swap_type_multi img=0 20:57:09.986: I: DIAG bstm: primary done, reading secondary 20:57:09.986: I: DIAG bstm: secondary state read done 20:57:09.986: I: Image index: 0, Swap type: test 20:57:10.106: I: DIAG enter boot_swap_type_multi img=0 20:57:10.106: I: DIAG bstm: primary done, reading secondary 20:57:10.106: I: DIAG bstm: secondary state read done 20:57:10.106: I: Image index: 0, Swap type: none 20:57:10.106: I: DIAG enter swap_status_source img=1 20:57:10.106: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 20:57:10.106: I: DIAG after read_swap_state PRIMARY 20:57:10.106: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 20:57:10.106: I: DIAG after read_swap_state SECONDARY 20:57:10.106: I: DIAG exit swap_status_source (none) 20:57:10.106: I: Boot source: none 20:57:10.106: I: DIAG enter boot_swap_type_multi img=1 20:57:10.106: I: DIAG bstm: primary done, reading secondary 20:57:10.106: I: DIAG bstm: secondary state read done 20:57:10.106: I: Image index: 1, Swap type: none 20:57:10.106: I: DIAG enter swap_status_source img=2 20:57:10.106: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 20:57:10.106: I: DIAG after read_swap_state PRIMARY 20:57:10.106: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 20:57:10.106: I: DIAG after read_swap_state SECONDARY 20:57:10.106: I: DIAG exit swap_status_source (none) 20:57:10.106: I: Boot source: none 20:57:10.106: I: DIAG enter boot_swap_type_multi img=2 20:57:10.106: I: DI: Bootloader chainload address offset: 0x28000 20:57:11.346: I: Image version: v0.1.2 20:57:11.346: I: Jumping to the first image slot 20:57:12.603: *** Booting My Application v0.1.2-0d268237374f *** 20:57:12.603: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 20:57:12.603: *** Using Zephyr OS v4.3.99-37e6c28576ee *** 20:57:12.603: [00:00:00.051,330] <wrn> app: main.cpp: main() [ 47]:: nRF5340 app, last-good-ncs-2.6-95-g0d26823-d 20:57:12.603: [00:00:00.056,121] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: <UNDEFINED> => STANDBY 20:57:12.603: [00:00:00.056,182] <inf> app: Npm1300.cpp: init() [ 244]:: nRF Fuel Gauge version: 1.1.1 20:57:12.603: [00:00:00.056,762] <inf> app: Npm1300.cpp: initChargerState() [ 806]:: Charger init (regs: SET: 0x1; CLR: 0x1) 20:57:12.603: [00:00:00.057,556] <inf> app: Npm1300.cpp: controlCharger() [ 855]:: Charger disabled (regs: SET: 0x0; CLR: 0x0) 20:57:12.603: [00:00:00.559,539] <wrn> app: Npm1300.cpp: init() [ 283]:: (init) NPM1300 data: 4.174000V, -0.000000A, 25.927582°C 20:57:13.538: [00:00:01.061,462] <wrn> app: Npm1300.cpp: init() [ 283]:: (init) NPM1300 data: 4.174000V, -0.000000A, 25.927582°C 20:57:13.538: [00:00:01.063,629] <inf> app: Npm1300.cpp: controlCharger() [ 855]:: Charger enabled (regs: SET: 0x1; CLR: 0x1) 20:57:15.510: [00:00:02.978,546] <inf> app: AFE4403.cpp: findCapacitanceConfig() [2000]:: Finding feedback capacitor: Target: 5, Best: 5, Config: 0x00000000 20:57:15.631: [00:00:04.108,032] <inf> app: Application.cpp: initCrypto() [ 893]:: BLE session key: built-in default (no valid override) 20:57:15.631: [00:00:04.113,342] <inf> fs_nvs: 2 Sectors of 4096 bytes 20:57:15.631: [00:00:04.113,372] <inf> fs_nvs: alloc wra: 0, fe8 20:57:15.631: [00:00:04.113,372] <inf> fs_nvs: data wra: 0, 0 20:57:15.631: [00:00:04.113,464] <wrn> app: Application.cpp: initCrypto() [ 918]:: BLE app-layer encryption: ENCRYPTED 20:57:15.631: [00:00:04.113,525] <wrn> app: Application.cpp: init() [ 532]:: Charger interlock: ON 20:57:15.631: [00:00:04.113,586] <wrn> app: Application.cpp: init() [ 543]:: OTA version gate: OFF (factory default) 20:57:15.631: [00:00:04.113,647] <inf> app: LedFillCapSetting.cpp: init() [ 59]:: LED fill cap: 30 % 20:57:15.631: [00:00:04.113,708] <inf> app: AutoAnimBrightSetting.cpp: init() [ 61]:: Auto-animation brightness cap: 20 % 20:57:15.631: [00:00:04.115,081] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 20:57:15.631: [00:00:04.115,356] <inf> app: BleCore.cpp: addService() [ 20:57:15.635: 20:57:15.646: --- 1 messages dropped --- 20:57:15.646: [00:00:04.116,027] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 20:57:15.646: [00:00:04.116,088] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 20:57:15.646: [00:00:04.116,149] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 20:57:15.646: [00:00:04.116,333] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 20:57:15.658: [00:00:04.116,394] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 20:57:15.658: [00:00:04.116,455] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 20:57:15.658: [00:00:04.116,638] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 20:57:15.658: [00:00:04.138,916] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002) 20:57:15.658: [00:00:04.138,946] <inf> bt_hci_core: HW Variant: nRF53x (0x0003) 20:57:15.658: [00:00:04.138,977] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 252.31313 Build 1865177321 20:57:15.658: [00:00:04.141,326] <inf> bt_hci_core: HCI transport: IPC 20:57:15.668: [00:00:04.141,448] <inf> bt_hci_core: Identity: XX:XX:XX:XX:XX:01 (random) 20:57:15.668: [00:00:04.141,479] <inf> bt_hci_core: HCI: version 6.3 (0x11) revision 0x201f, manufacturer 0x0059 20:57:15.668: [00:00:04.141,510] <inf> bt_hci_core: LMP: version 6.3 (0x11) subver 0x201f 20:57:15.668: [00:00:04.142,028] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: STANDBY => ACTIVE: WAIT CONN 20:57:15.681: [00:00:04.144,500] <wrn> app: BatteryStateMonitorTask.hpp: start() [ 284]:: Charger is connected 20:57:15.681: [00:00:04.144,531] <inf> app: BatteryStateMonitorTask.hpp: notifyObservers() [1139]:: charger: connected 20:57:15.681: [00:00:04.144,561] <inf> app: Application.cpp: handleChargerState() [1890]:: Handling new charger state... 20:57:15.681: [00:00:04.144,805] <inf> app: BatteryStateMonitorTask.hpp: notifyObservers() [1165]:: bat state: full 20:57:15.681: [00:00:04.144,836] <inf> app: Application.cpp: handleBatteryState() [2216]:: Handling new battery state... 20:57:15.681: [00:00:04.147,613] <err> app: Application.cpp: powerDownUnusedPeripherals() [1864]:: Failed to suspend LSM6DSM (err: -120) 20:57:15.690: [00:00:04.148,101] <wrn> app: Application.cpp: armTaskWatchdogs() [1656]:: Task watchdog armed 20:57:15.690: [00:00:04.148,132] <inf> app: Application.cpp: handleNewState() [2295]:: Handling new device state... 20:57:15.690: [00:00:04.148,254] <wrn> app: DisplayTask.hpp: evtHandler() [ 101]:: Activating LED boost conv 20:57:17.781: [00:00:05.236,236] <inf> app: BleServerController.cpp: processIntCmd() [ 337]:: Starting advertising without whitelist 20:57:17.781: [00:00:05.236,389] <inf> app: BleCore.cpp: advertisingStart() [1101]:: Adv data size: 3; ScanRespPacketsData size: 1 20:57:17.781: [00:00:05.236,633] <inf> mcuboot_util: DIAG enter boot_swap_type_multi img=0 20:57:17.781: [00:00:05.236,694] <inf> mcuboot_util: DIAG bstm: primary done, reading secondary 20:57:17.781: [00:00:05.238,006] <inf> mcuboot_util: DIAG bstm: secondary state read done 20:57:17.781: [00:00:05.238,006] <inf> mcuboot_util: Image index: 0, Swap type: none 20:57:17.781: [00:00:05.238,037] <inf> app: Application.cpp: confirmRunningImage() [2484]:: Running image already confirmed, nothing to do 20:57:17.781: [00:00:05.239,044] <inf> app: BleServerController.cpp: processIntCmd() [ 341]:: Advertising started Received SIGTERM, exiting Exited by user request
WARN probe_rs::rtt: Buffer for up channel 1 not initialized
WARN probe_rs::rtt: Buffer for up channel 2 not initialized
WARN probe_rs::rtt: Buffer for down channel 1 not initialized
WARN probe_rs::rtt: Buffer for down channel 2 not initialized
Failed to create readline
O��)��pF G���� ( ] �E �� ] �1 dQ ���?? pQ pQ pQ pQ p �% �% �% �%
22:22:07.347: index: 0, Swap type: none
22:22:07.347: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
22:22:07.347: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
22:22:07.347: I: Boot source: none
22:22:07.347: I: DIAG ncs img=1 magic=0x96f3b83d flags=0x100 reset_addr=0x1023291
22:22:07.347: I: DIAG ncs ASSIGNED img=1
22:22:07.347: I: Image index: 1, Swap type: none
22:22:07.347: I: DIAG skip prepare img=2
22:22:07.347: I: Bootloader chainload address offset: 0x28000
22:22:07.347: I: Image version: v0.1.2
22:22:07.347: I: Jumping to the first image slot
22:22:07.347: *** Booting MCUboot v2.3.0-dev-3de5b4df5f9f ***
22:22:07.347: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 ***
22:22:07.347: *** Using Zephyr OS v4.[00:01:10.080,718] <inf> app: BleCore.cpp: onConnected() [2178]:: New BLE connection established: [XX:XX:XX:XX:XX:02 (public)], MTU: 23 bytes
22:22:12.125: [00:01:10.081,359] <inf> app: ---- Basic nonce (len: 13): ----
22:22:12.125: [00:01:10.081,359] <inf> app: Content:
22:22:12.125: f6 de 97 c1 7b 74 67 fa d6 b2 02 2f 83 |....{tg. .../.
22:22:12.125: [00:01:10.081,420] <inf> app: ---- Basic nonce end ----
22:22:12.125: [00:01:10.106,506] <inf> app: DeviceStateManager.cpp: bleOnConnect() [ 272]:: Connected
22:22:12.125: [00:01:10.106,567] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: ACTIVE: WAIT CONN => ACTIVE: CONNECTED
22:22:12.125: [00:01:10.107,025] <inf> app: BleCore.cpp: onDataLengthUpdated() [2269]:: LE data len updated: TX (len: 251 bytes time: 2120 us) RX (len: 251 bytes time: 2120 us)
22:22:12.125: [00:01:10.107,147] <inf> app: Application.cpp: handleNewState() [2295]:: Handling new device state...
22:22:12.125: [00:01:10.153,503] <inf> app: BleCore.cpp: mtuExchangeFuncful
22:22:12.125:
22:22:12.858: *** Booting MCUboot v2.3.0-dev-3de5b4df5f9f ***
22:22:12.858: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 ***
22:22:12.858: *** Using Zephyr OS v4.3.99-37e6c28576ee ***
22:22:12.858: I: Starting bootloader
22:22:12.858: I: Primary image: magic=good, swap_type=0x4, copy_done=0x1, image_ok=0x1
22:22:12.858: I: Secondary image: magic=good, swap_type=0x2, copy_done=0x3, image_ok=0x3
22:22:12.858: I: Boot source: none
22:22:12.858: I: DIAG ncs img=0 magic=0x96f3b83d flags=0x4 reset_addr=0x3ee3fbc2
22:22:12.858: I: DIAG ncs ASSIGNED img=0
22:22:12.858: I: Image index: 0, Swap type: test
22:22:22.175: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
22:22:22.175: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
22:22:22.175: I: Boot source: none
22:22:22.175: I: DIAG ncs img=1 magic=0x96f3b83d flags=0x100 reset_addr=0x1023291
22:22:22.175: I: DIAG ncs ASSIGNED img=1
22:22:22.175: I: Image index: 1, Swap type: none
22:22:22.175: I: DIAG skip prepare img=2
22:22:22.799: I: Starting swap using move algorithm.
22:23:23.393: I: Bootloader chainload address offset: 0x28000
22:23:23.393: I: Image version: v0.1.3
22:23:23.393: I: Jumping to the first image slot
22:23:24.630: *** Booting My Application v0.1.3-0d268237374f ***
22:23:24.630: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 ***
22:23:24.630: *** Using Zephyr OS v4.3.99-37e6c28576ee ***
22:23:24.630: [00:00:00.051,452] <wrn> app: main.cpp: main() [ 47]:: nRF5340 app, last-good-ncs-2.6-95-g0d26823-d
22:23:24.630: [00:00:00.056,274] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: <UNDEFINED> => STANDBY
22:23:24.630: [00:00:00.056,335] <inf> app: Npm1300.cpp: init() [ 244]:: nRF Fuel Gauge version: 1.1.1
22:23:24.630: [00:00:00.056,915] <inf> app: Npm1300.cpp: initChargerState() [ 806]:: Charger init (regs: SET: 0x1; CLR: 0x1)
22:23:24.630: [00:00:00.057,739] <inf> app: Npm1300.cpp: controlCharger() [ 855]:: Charger disabled (regs: SET: 0x0; CLR: 0x0)
22:23:24.630: [00:00:00.559,692] <wrn> app: Npm1300.cpp: init() [ 283]:: (init) NPM1300 data: 4.174000V, -0.000000A, 25.205627°C
22:23:25.583: [00:00:01.061,645] <wrn> app: Npm1300.cpp: init() [ 283]:: (init) NPM1300 data: 4.174000V, -0.000000A, 25.205627°C
22:23:25.583: [00:00:01.063,812] <inf> app: Npm1300.cpp: controlCharger() [ 855]:: Charger enabled (regs: SET: 0x1; CLR: 0x1)
22:23:27.488: [00:00:02.979,125] <inf> app: AFE4403.cpp: findCapacitanceConfig() [2000]:: Finding feedback capacitor: Target: 5, Best: 5, Config: 0x00000000
22:23:27.653: [00:00:04.108,734] <inf> app: Application.cpp: initCrypto() [ 893]:: BLE session key: built-in default (no valid override)
22:23:27.653: [00:00:04.113,952] <inf> fs_nvs: 2 Sectors of 4096 bytes
22:23:27.653: [00:00:04.113,983] <inf> fs_nvs: alloc wra: 0, fe8
22:23:27.653: [00:00:04.113,983] <inf> fs_nvs: data wra: 0, 0
22:23:27.653: [00:00:04.114,074] <wrn> app: Application.cpp: initCrypto() [ 918]:: BLE app-layer encryption: ENCRYPTED
22:23:27.653: [00:00:04.114,135] <wrn> app: Application.cpp: init() [ 532]:: Charger interlock: ON
22:23:27.653: [00:00:04.114,196] <wrn> app: Application.cpp: init() [ 543]:: OTA version gate: OFF (factory default)
22:23:27.653: [00:00:04.114,257] <inf> app: LedFillCapSetting.cpp: init() [ 59]:: LED fill cap: 30 %
22:23:27.653: [00:00:04.114,288] <inf> app: AutoAnimBrightSetting.cpp: init() [ 61]:: Auto-animation brightness cap: 20 %
22:23:27.653: [00:00:04.115,692] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars...
22:23:27.653: [00:00:04.115,936] <inf> app: BleCore.cpp: addService() [
22:23:27.717:
22:23:27.717: [00:00:04.142,761] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: STANDBY => ACTIVE: WAIT CONN
22:23:27.717: [00:00:04.145,263] <wrn> app: BatteryStateMonitorTask.hpp: start() [ 284]:: Charger is connected
22:23:27.717: [00:00:04.145,294] <inf> app: BatteryStateMonitorTask.hpp: notifyObservers() [1139]:: charger: connected
22:23:27.717: [00:00:04.145,324] <inf> app: Application.cpp: handleChargerState() [1890]:: Handling new charger state...
22:23:27.717: [00:00:04.145,568] <inf> app: BatteryStateMonitorTask.hpp: notifyObservers() [1165]:: bat state: full
22:23:27.717: [00:00:04.145,599] <inf> app: Application.cpp: handleBatteryState() [2216]:: Handling new battery state...
22:23:27.717: [00:00:04.148,406] <err> app: Application.cpp: powerDownUnusedPeripherals() [1864]:: Failed to suspend LSM6DSM (err: -120)
22:23:27.717: [00:00:04.148,895] <wrn> app: Application.cpp: armTaskWatchdogs() [1656]:: Task watchdog armed
Received SIGTERM, exiting
22:23:27.717: [00:00:04.148,925] <inf> app: Application.cpp: handleNewState() [2295]:: Handling new deviceExited by user request
### ROW 3 part 1: broken v0.1.3 swap-in (warm BLE reset) WARN probe_rs::rtt: Buffer for up channel 1 not initialized WARN probe_rs::rtt: Buffer for up channel 2 not initialized WARN probe_rs::rtt: Buffer for down channel 1 not initialized WARN probe_rs::rtt: Buffer for down channel 2 not initialized Failed to create readline O��)��pF G���� ( ] �E �� ] �1 dQ ���?? pQ pQ pQ pQ p �% �% �% �% 22:26:31.574: index: 0, Swap type: none 22:26:31.574: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 22:26:31.574: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 22:26:31.574: I: Boot source: none 22:26:31.574: I: DIAG ncs img=1 magic=0x96f3b83d flags=0x100 reset_addr=0x1023291 22:26:31.574: I: DIAG ncs ASSIGNED img=1 22:26:31.574: I: Image index: 1, Swap type: none 22:26:31.574: I: DIAG skip prepare img=2 22:26:31.574: I: Bootloader chainload address offset: 0x28000 22:26:31.574: I: Image version: v0.1.2 22:26:31.574: I: Jumping to the first image slot 22:26:31.574: *** Booting MCUboot v2.3.0-dev-3de5b4df5f9f *** 22:26:31.574: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 22:26:31.574: *** Using Zephyr OS v4.[00:01:13.534,484] <inf> app: BleCore.cpp: onConnected() [2178]:: New BLE connection established: [XX:XX:XX:XX:XX:02 (public)], MTU: 23 bytes 22:26:35.527: [00:01:13.535,003] <inf> app: ---- Basic nonce (len: 13): ---- 22:26:35.527: [00:01:13.535,034] <inf> app: Content: 22:26:35.527: dd 83 c4 46 1b cc 5a 84 14 93 04 67 a1 |...F..Z. ...g. 22:26:35.527: [00:01:13.535,064] <inf> app: ---- Basic nonce end ---- 22:26:35.527: [00:01:13.558,624] <inf> app: DeviceStateManager.cpp: bleOnConnect() [ 272]:: Connected 22:26:35.527: [00:01:13.558,685] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: ACTIVE: WAIT CONN => ACTIVE: CONNECTED 22:26:35.527: [00:01:13.559,143] <inf> app: BleCore.cpp: onDataLengthUpdated() [2269]:: LE data len updated: TX (len: 251 bytes time: 2120 us) RX (len: 251 bytes time: 2120 us) 22:26:35.527: [00:01:13.559,234] <inf> app: Application.cpp: handleNewState() [2295]:: Handling new device state... 22:26:35.527: [00:01:13.607,666] <inf> app: BleCore.cpp: mtuExchangeFuncful 22:26:35.527: 22:26:36.265: *** Booting MCUboot v2.3.0-dev-3de5b4df5f9f *** 22:26:36.265: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 22:26:36.265: *** Using Zephyr OS v4.3.99-37e6c28576ee *** 22:26:36.265: I: Starting bootloader 22:26:36.265: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 22:26:36.265: I: Secondary image: magic=good, swap_type=0x2, copy_done=0x3, image_ok=0x3 22:26:36.265: I: Boot source: none 22:26:36.265: I: DIAG ncs img=0 magic=0x96f3b83d flags=0x4 reset_addr=0x9769f57c 22:26:36.265: I: DIAG ncs ASSIGNED img=0 22:26:36.265: I: Image index: 0, Swap type: test 22:26:45.654: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 22:26:45.654: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 22:26:45.654: I: Boot source: none 22:26:45.654: I: DIAG ncs img=1 magic=0x96f3b83d flags=0x100 reset_addr=0x1023291 22:26:45.654: I: DIAG ncs ASSIGNED img=1 22:26:45.654: I: Image index: 1, Swap type: none 22:26:45.654: I: DIAG skip prepare img=2 22:26:46.280: I: Starting swap using move algorithm. 22:27:46.775: I: Bootloader chainload address offset: 0x28000 22:27:46.775: I: Image version: v0.1.3 22:27:46.775: I: Jumping to the first image slot 22:27:48.048: *** Booting My Application v0.1.3-0d268237374f *** 22:27:48.048: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 22:27:48.048: *** Using Zephyr OS v4.3.99-37e6c28576ee *** 22:27:48.048: [00:00:00.051,239] <wrn> app: main.cpp: main() [ 47]:: nRF5340 app, last-good-ncs-2.6-95-g0d26823-d 22:27:48.048: [00:00:00.056,091] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: <UNDEFINED> => STANDBY 22:27:48.048: [00:00:00.056,152] <inf> app: Npm1300.cpp: init() [ 244]:: nRF Fuel Gauge version: 1.1.1 22:27:48.048: [00:00:00.056,732] <inf> app: Npm1300.cpp: initChargerState() [ 806]:: Charger init (regs: SET: 0x1; CLR: 0x1) 22:27:48.048: [00:00:00.057,525] <inf> app: Npm1300.cpp: controlCharger() [ 855]:: Charger disabled (regs: SET: 0x0; CLR: 0x0) 22:27:48.048: [00:00:00.559,448] <wrn> app: Npm1300.cpp: init() [ 283]:: (init) NPM1300 data: 4.174000V, -0.000000A, 25.000000°C 22:27:49.040: [00:00:01.061,431] <wrn> app: Npm1300.cpp: init() [ 283]:: (init) NPM1300 data: 4.174000V, -0.000000A, 25.000000°C 22:27:49.040: [00:00:01.063,568] <inf> app: Npm1300.cpp: controlCharger() [ 855]:: Charger enabled (regs: SET: 0x1; CLR: 0x1) 22:27:50.907: [00:00:02.978,759] <inf> app: AFE4403.cpp: findCapacitanceConfig() [2000]:: Finding feedback capacitor: Target: 5, Best: 5, Config: 0x00000000 22:27:51.034: [00:00:04.108,306] <inf> app: Application.cpp: initCrypto() [ 893]:: BLE session key: built-in default (no valid override) 22:27:51.034: [00:00:04.113,525] <inf> fs_nvs: 2 Sectors of 4096 bytes 22:27:51.034: [00:00:04.113,525] <inf> fs_nvs: alloc wra: 0, fe8 22:27:51.034: [00:00:04.113,525] <inf> fs_nvs: data wra: 0, 0 22:27:51.034: [00:00:04.113,616] <wrn> app: Application.cpp: initCrypto() [ 918]:: BLE app-layer encryption: ENCRYPTED 22:27:51.034: [00:00:04.113,677] <wrn> app: Application.cpp: init() [ 532]:: Charger interlock: ON 22:27:51.034: [00:00:04.113,769] <wrn> app: Application.cpp: init() [ 543]:: OTA version gate: OFF (factory default) 22:27:51.034: [00:00:04.113,800] <inf> app: LedFillCapSetting.cpp: init() [ 59]:: LED fill cap: 30 % 22:27:51.034: [00:00:04.113,861] <inf> app: AutoAnimBrightSetting.cpp: init() [ 61]:: Auto-animation brightness cap: 20 % 22:27:51.034: [00:00:04.115,234] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 22:27:51.034: [00:00:04.115,509] <inf> app: BleCore.cpp: addService() [ addService() [ 333]:: Adding chars... 22:27:51.043: [00:00:04.115,783] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 22:27:51.043: [00:00:04.115,875] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 22:27:51.064: [00:00:04.115,997] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 22:27:51.064: [00:00:04.116,210] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 22:27:51.064: [00:00:04.116,241] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 22:27:51.064: [00:00:04.116,333] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 22:27:51.064: [00:00:04.116,516] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 22:27:51.064: [00:00:04.116,577] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 22:27:51.064: [00:00:04.116,638] <inf> app: BleCore.cpp: addService() [ 406]:: Adding descriptors... 22:27:51.064: [00:00:04.116,821] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 22:27:51.064: [00:00:04.139,343] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002) 22:27:51.064: [00:00:04.139,373] <inf> bt_hci_core: HW Variant: nRF53x (0x0003) 22:27:51.064: [00:00:04.139,404] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 252.31313 Build 1865177321 22:27:51.070: [00:00:04.141,998] <inf> bt_hci_core: HCI transport: IPC 22:27:51.093: [00:00:04.142,089] <inf> bt_hci_core: Identity: XX:XX:XX:XX:XX:01 (random) 22:27:51.093: [00:00:04.142,150] <inf> bt_hci_core: HCI: version 6.3 (0x11) revision 0x201f, manufacturer 0x0059 22:27:51.093: [00:00:04.142,181] <inf> bt_hci_core: LMP: version 6.3 (0x11) subver 0x201f 22:27:51.093: [00:00:04.142,669] <inf> app: DeviceStateManager.cpp: benchForceAdvertise() [ 150]:: BENCH BROKEN IMAGE v0.1.3 -- advertising deliberately disabled 22:27:51.093: [00:00:04.145,202] <wrn> app: BatteryStateMonitorTask.hpp: start() [ 284]:: Charger is connected 22:27:51.093: [00:00:04.145,233] <inf> app: BatteryStateMonitorTask.hpp: notifyObservers() [1139]:: charger: connected 22:27:51.093: [00:00:04.145,263] <inf> app: Application.cpp: handleChargerState() [1890]:: Handling new charger state... 22:27:51.093: [00:00:04.145,507] <inf> app: BatteryStateMonitorTask.hpp: notifyObservers() [1165]:: bat state: full 22:27:51.093: [00:00:04.145,538] <inf> app: Application.cpp: handleBatteryState() [2216]:: Handling new battery state... 22:27:51.102: [00:00:04.148,345] <err> app: Application.cpp: powerDownUnusedPeripherals() [1864]:: Failed to suspend LSM6DSM (err: -120) 22:27:51.102: [00:00:04.148,803] <wrn> app: Application.cpp: armTaskWatchdogs() [1656]:: Task watchdog armed 22:27:51.102: [00:00:04.148,925] <wrn> app: DisplayTask.hpp: evtHandler() [ 101]:: Activating LED boost conv Received SIGTERM, exiting Exited by user request ### ROW 3 part 2: manual probe-rs reset -> MCUboot REVERT to v0.1.2 WARN probe_rs::rtt: Buffer for up channel 1 not initialized WARN probe_rs::rtt: Buffer for up channel 2 not initialized WARN probe_rs::rtt: Buffer for down channel 1 not initialized WARN probe_rs::rtt: Buffer for down channel 2 not initialized Failed to create readline *** Booting MCUboot v2.3.0-dev-3de5b4df5f9f *** 22:29:37.736: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 22:29:37.736: *** Using Zephyr OS v4.3.99-37e6c28576ee *** 22:29:37.736: I: Starting bootloader 22:29:37.736: I: Primary image: magic=good, swap_type=0x2, copy_done=0x1, image_ok=0x3 22:29:37.736: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 22:29:37.736: I: Boot source: none 22:29:37.736: I: DIAG ncs img=0 magic=0x96f3b83d flags=0x4 reset_addr=0xa78fbdc3 22:29:37.736: I: DIAG ncs ASSIGNED img=0 22:29:37.736: I: Image index: 0, Swap type: revert 22:29:47.076: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 22:29:47.076: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 22:29:47.076: I: Boot source: none 22:29:47.076: I: DIAG ncs img=1 magic=0x96f3b83d flags=0x100 reset_addr=0x1023291 22:29:47.076: I: DIAG ncs ASSIGNED img=1 22:29:47.076: I: Image index: 1, Swap type: none 22:29:47.076: I: DIAG skip prepare img=2 22:29:47.749: I: Starting swap using move algorithm. 22:29:47.749: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 22:30:48.389: I: Bootloader chainload address offset: 0x28000 22:30:48.389: I: Image version: v0.1.2 22:30:48.389: I: Jumping to the first image slot 22:30:49.539: *** Booting My Application v0.1.2-0d268237374f *** 22:30:49.555: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 22:30:49.555: *** Using Zephyr OS v4.3.99-37e6c28576ee *** 22:30:49.555: [00:00:00.051,361] <wrn> app: main.cpp: main() [ 47]:: nRF5340 app, last-good-ncs-2.6-95-g0d26823-d 22:30:49.555: [00:00:00.056,182] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: <UNDEFINED> => STANDBY 22:30:49.555: [00:00:00.056,213] <inf> app: Npm1300.cpp: init() [ 244]:: nRF Fuel Gauge version: 1.1.1 22:30:49.555: [00:00:00.056,823] <inf> app: Npm1300.cpp: initChargerState() [ 806]:: Charger init (regs: SET: 0x1; CLR: 0x1) 22:30:49.555: [00:00:00.057,617] <inf> app: Npm1300.cpp: controlCharger() [ 855]:: Charger disabled (regs: SET: 0x0; CLR: 0x0) 22:30:49.555: [00:00:00.559,600] <wrn> app: Npm1300.cpp: init() [ 283]:: (init) NPM1300 data: 4.174000V, -0.000000A, 25.308533°C 22:30:50.625: [00:00:01.061,523] <wrn> app: Npm1300.cpp: init() [ 283]:: (init) NPM1300 data: 4.174000V, -0.000000A, 25.308533°C 22:30:50.625: [00:00:01.063,690] <inf> app: Npm1300.cpp: controlCharger() [ 855]:: Charger enabled (regs: SET: 0x1; CLR: 0x1) 22:30:52.489: [00:00:02.978,881] <inf> app: AFE4403.cpp: findCapacitanceConfig() [2000]:: Finding feedback capacitor: Target: 5, Best: 5, Config: 0x00000000 22:30:52.714: [00:00:04.108,459] <inf> app: Application.cpp: initCrypto() [ 893]:: BLE session key: built-in default (no valid override) 22:30:52.714: [00:00:04.113,708] <inf> fs_nvs: 2 Sectors of 4096 bytes 22:30:52.714: [00:00:04.113,708] <inf> fs_nvs: alloc wra: 0, fe8 22:30:52.714: [00:00:04.113,708] <inf> fs_nvs: data wra: 0, 0 22:30:52.714: [00:00:04.113,800] <wrn> app: Application.cpp: initCrypto() [ 918]:: BLE app-layer encryption: ENCRYPTED 22:30:52.714: [00:00:04.113,861] <wrn> app: Application.cpp: init() [ 532]:: Charger interlock: ON 22:30:52.714: [00:00:04.113,952] <wrn> app: Application.cpp: init() [ 543]:: OTA version gate: OFF (factory default) 22:30:52.714: [00:00:04.113,983] <inf> app: LedFillCapSetting.cpp: init() [ 59]:: LED fill cap: 30 % 22:30:52.714: [00:00:04.114,044] <inf> app: AutoAnimBrightSetting.cpp: init() [ 61]:: Auto-animation brightness cap: 20 % 22:30:52.714: [00:00:04.115,417] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 22:30:52.714: [00:00:04.115,692] <inf> app: BleCore.cpp: addService() [ 22:30:52.714: 22:30:54.795: [00:00:05.236,602] <inf> app: BleServerController.cpp: processIntCmd() [ 337]:: Starting advertising without whitelist 22:30:54.795: [00:00:05.236,724] <inf> app: BleCore.cpp: advertisingStart() [1101]:: Adv data size: 3; ScanRespPacketsData size: 1 22:30:54.795: [00:00:05.238,403] <inf> mcuboot_util: Image index: 0, Swap type: none 22:30:54.795: [00:00:05.238,433] <inf> app: Application.cpp: confirmRunningImage() [2484]:: Running image already confirmed, nothing to do 22:30:54.795: [00:00:05.239,379] <inf> app: BleServerController.cpp: processIntCmd() [ 341]:: Advertising started Received SIGTERM, exiting Exited by user request
WARN probe_rs::rtt: Buffer for up channel 1 not initialized WARN probe_rs::rtt: Buffer for up channel 2 not initialized WARN probe_rs::rtt: Buffer for down channel 1 not initialized WARN probe_rs::rtt: Buffer for down channel 2 not initialized Failed to create readline O��)��pF G���� ( ] �E �� ] �1 dQ ���?? pQ pQ pQ pQ p �% �% �% �% 21:54:46.179: k=0x3 21:54:46.179: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 21:54:46.179: I: Boot source: none 21:54:46.179: I: Image index: 1, Swap type: none 21:54:46.179: I: DIAG skip prepare img=2 21:54:46.179: I: Bootloader chainload address offset: 0x28000 21:54:46.179: I: Image version: v0.1.2 21:54:46.179: I: Jumping to the first image slot 21:54:46.179: *** Booting MCUboot v2.3.0-dev-3de5b4df5f9f *** 21:54:46.179: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 21:54:46.179: *** Using Zephyr OS v4.3.99-37e6c28576ee *** 21:54:46.179: I: Starting bootloader 21:54:46.179: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 21:54:46.179: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_o[00:01:01.486,450] <inf> app: BleCore.cpp: onDisconnected() [2203]:: [XX:XX:XX:XX:XX:02 (public)] BLE device disconnected with reason 19 21:54:46.919: [00:01:01.486,480] <inf> app: DeviceStateManager.cpp: bleOnDisconnect() [ 280]:: Disconnected 21:54:46.919: [00:01:01.486,541] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: ACTIVE: CONNECTED => ACTIVE: WAIT CONN 21:54:46.919: [00:01:01.486,877] <inf> app: Application.cpp: handleNewState() [2295]:: Handling new device state... 21:54:46.919: [00:01:01.486,999] <inf> app: BleServerController.cpp: processIntCmd() [ 337]:: Starting advertising without whitelist 21:54:46.919: [00:01:01.487,030] <inf> app: BleCore.cpp: advertisingStart() [1101]:: Adv data size: 3; ScanRespPacketsData size: 1 21:54:46.919: [00:01:01.489,440] <inf> app: BleServerController.cpp: processIntCmd() [ 341]:: Advertising started 21:54:49.728: [00:01:05.181,030] <inf> app: BleCore.cpp: onConnected() [2178]:: New BLE connection established: [XX:XX:XX:XX:XX:02 (public)], MTU: 23 bytes 21:54:49.728: [00:01:05.181,549] <inf> app: ---- Basic nonce (len: 13): ---- 21:54:49.728: [00:01:05.181,579] <inf> app: Content: 21:54:49.728: 04 e4 55 b5 e9 2e 75 25 a9 1f 2d 83 27 |..U...u% ..-.' 21:54:49.728: [00:01:05.181,610] <inf> app: ---- Basic nonce end ---- 21:54:49.728: [00:01:05.205,139] <inf> app: DeviceStateManager.cpp: bleOnConnect() [ 272]:: Connected 21:54:49.728: [00:01:05.205,200] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: ACTIVE: WAIT CONN => ACTIVE: CONNECTED 21:54:49.728: [00:01:05.205,627] <inf> app: Application.cpp: handleNewState() [2295]:: Handling new device state... 21:54:49.728: [00:01:05.206,207] <inf> app: BleCore.cpp: onDataLengthUpdated() [2269]:: LE data len updated: TX (len: 251 bytes time: 2120 us) RX (len: 251 bytes time: 2120 us) 21:54:49.728: [00:01:05.258,209] <inf> app: BleCore.cpp: mtuExchangeFuncful 21:54:49.728: 21:54:50.567: *** Booting MCUboot v2.3.0-dev-3de5b4df5f9f *** 21:54:50.567: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 21:54:50.567: *** Using Zephyr OS v4.3.99-37e6c28576ee *** 21:54:50.567: I: Starting bootloader 21:54:50.567: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 21:54:50.567: I: Secondary image: magic=good, swap_type=0x2, copy_done=0x3, image_ok=0x3 21:54:50.567: I: Boot source: none 21:54:50.567: I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 21:54:50.567: I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3 21:54:50.567: I: Boot source: none 21:54:50.567: I: Image index: 1, Swap type: none 21:54:50.567: I: DIAG skip prepare img=2 21:54:50.567: I: DIAG enter sec_erase img=0 size=0xd3000 21:55:06.371: I: DIAG exit sec_erase img=0 rc=0 21:55:06.371: E: Erase secondary: img 0: 0 21:55:06.371: I: DIAG enter sec_erase img=2 size=0xd3000 21:55:24.246: I: DIAG exit sec_erase img=2 rc=0 21:55:24.246: E: Erase secondary: img 2: 0 21:55:25.388: I: Bootloader chainload address offset: 0x28000 21:55:25.388: I: Image version: v0.1.2 21:55:25.388: I: Jumping to the first image slot 21:55:26.643: *** Booting My Application v0.1.2-0d268237374f *** 21:55:26.643: *** Using nRF Connect SDK v3.3.1-1d7a0b0e49b8 *** 21:55:26.643: *** Using Zephyr OS v4.3.99-37e6c28576ee *** 21:55:26.643: [00:00:00.051,361] <wrn> app: main.cpp: main() [ 47]:: nRF5340 app, last-good-ncs-2.6-95-g0d26823-d 21:55:26.643: [00:00:00.056,182] <wrn> app: GeneralFsm.hpp: setState() [ 78]:: State: <UNDEFINED> => STANDBY 21:55:26.643: [00:00:00.056,243] <inf> app: Npm1300.cpp: init() [ 244]:: nRF Fuel Gauge version: 1.1.1 21:55:26.643: [00:00:00.056,823] <inf> app: Npm1300.cpp: initChargerState() [ 806]:: Charger init (regs: SET: 0x1; CLR: 0x1) 21:55:26.643: [00:00:00.057,647] <inf> app: Npm1300.cpp: controlCharger() [ 855]:: Charger disabled (regs: SET: 0x0; CLR: 0x0) 21:55:26.643: [00:00:00.559,631] <wrn> app: Npm1300.cpp: init() [ 283]:: (init) NPM1300 data: 4.174000V, -0.000000A, 25.617737°C 21:55:27.682: [00:00:01.061,553] <wrn> app: Npm1300.cpp: init() [ 283]:: (init) NPM1300 data: 4.174000V, -0.000000A, 25.617737°C 21:55:27.682: [00:00:01.063,720] <inf> app: Npm1300.cpp: controlCharger() [ 855]:: Charger enabled (regs: SET: 0x1; CLR: 0x1) 21:55:29.547: [00:00:02.978,912] <inf> app: AFE4403.cpp: findCapacitanceConfig() [2000]:: Finding feedback capacitor: Target: 5, Best: 5, Config: 0x00000000 21:55:29.773: [00:00:04.108,489] <inf> app: Application.cpp: initCrypto() [ 893]:: BLE session key: built-in default (no valid override) 21:55:29.773: [00:00:04.113,739] <inf> fs_nvs: 2 Sectors of 4096 bytes 21:55:29.773: [00:00:04.113,739] <inf> fs_nvs: alloc wra: 0, fe8 21:55:29.773: [00:00:04.113,739] <inf> fs_nvs: data wra: 0, 0 21:55:29.773: [00:00:04.113,830] <wrn> app: Application.cpp: initCrypto() [ 918]:: BLE app-layer encryption: ENCRYPTED 21:55:29.773: [00:00:04.113,891] <wrn> app: Application.cpp: init() [ 532]:: Charger interlock: ON 21:55:29.773: [00:00:04.113,983] <wrn> app: Application.cpp: init() [ 543]:: OTA version gate: OFF (factory default) 21:55:29.773: [00:00:04.114,013] <inf> app: LedFillCapSetting.cpp: init() [ 59]:: LED fill cap: 30 % 21:55:29.773: [00:00:04.114,074] <inf> app: AutoAnimBrightSetting.cpp: init() [ 61]:: Auto-animation brightness cap: 20 % 21:55:29.773: [00:00:04.115,447] <inf> app: BleCore.cpp: addService() [ 333]:: Adding chars... 21:55:29.773: [00:00:04.115,722] <inf> app: BleCore.cpp: addService() [ 21:55:29.773: 21:55:31.850: [00:00:05.236,846] <inf> app: BleServerController.cpp: processIntCmd() [ 337]:: Starting advertising without whitelist 21:55:31.850: [00:00:05.236,999] <inf> app: BleCore.cpp: advertisingStart() [1101]:: Adv data size: 3; ScanRespPacketsData size: 1 21:55:31.850: [00:00:05.238,677] <inf> mcuboot_util: Image index: 0, Swap type: none 21:55:31.850: [00:00:05.238,708] <inf> app: Application.cpp: confirmRunningImage() [2484]:: Running image already confirmed, nothing to do 21:55:31.850: [00:00:05.239,654] <inf> app: BleServerController.cpp: processIntCmd() [ 341]:: Advertising started Received SIGTERM, exiting Exited by user request
# Secured-line swap-with-revert — hardware acceptance proof Bench-proven on a single nRF5340 custom board, 2026-08-23. All three acceptance rows PASS on the SECURED line (b0 + s0/s1, AES-128 encrypted images, MCUboot swap-using-move) over the real field path — a warm mcumgr/BLE reset, not a pin reset. Every row below required the four SDK patches in `ncs-3.3.1-mcuboot-secured-swap.patch`. Without them the encrypted secured line can never complete an OTA: the staged image is silently erased on every boot. ## 1. Acceptance table | Row | Image | Boots | Advertises | Swap executes | Self-confirms | Persists / reverts | RESETREAS | |---|---|---|---|---|---|---|---| | 1 | baseline v0.1.2 (SWD-flashed) | yes | yes | n/a | n/a (wired flash, already confirmed) | `v0.1.2 [active,confirmed,bootable]` | `0x08` (SREQ only) | | 2 | good v0.1.3 (BLE OTA, warm reset) | yes | yes | **yes**, `Swap type: test` | **yes** | **PASS** — 2nd reset still `v0.1.3 [active,confirmed,bootable]`, no revert | `0x08` | | 3 | broken v0.1.3 (BLE OTA, warm reset) | yes | **no** (by design) | **yes**, `Swap type: test` | **no** (never reaches the confirm point) | **REVERTS** — `Swap type: revert` → `v0.1.2 [active,confirmed,bootable]`, advertising | `0x00` while broken image ran (no self-reset), `0x08` after manual reset | No `DOG0` (watchdog) and no `LOCKUP` bit in RESETREAS in any row. ### Row 2 — good image swaps in, self-confirms, persists MCUboot log (`run14b-artifacts/rtt-row2-swap-pass.log`): ``` 22:22:12.858 I: Starting bootloader 22:22:12.858 I: DIAG ncs img=0 magic=0x96f3b83d flags=0x4 reset_addr=0x3ee3fbc2 22:22:12.858 I: DIAG ncs ASSIGNED img=0 22:22:12.858 I: Image index: 0, Swap type: test 22:22:22.799 I: Starting swap using move algorithm. 22:23:23.393 I: Image version: v0.1.3 22:23:23.393 I: Jumping to the first image slot ``` `flags=0x4` is `IMAGE_F_ENCRYPTED_AES128` and `reset_addr=0x3ee3fbc2` is ciphertext, outside the valid primary range `[0x28000,0xfc000]`. Before the keystone patch this exact input produced `RETURN-NONE` and the slot was erased; with the patch it is `ASSIGNED` and the swap proceeds. State after, read over BLE (mcumgr `image list`): ``` image 0 slot 0 v0.1.3 [active,confirmed,bootable] image 0 slot 1 v0.1.2 [bootable] ``` `confirmed` is the application self-confirming via its `confirmRunningImage()` path once advertising and the SMP transport were up. The old image moved down to slot 1, which is swap-using-move behaviour. A further reset left the state unchanged (persistence proven). ### Row 3 — broken image swaps in, never confirms, reverts Swap-in and broken-image banner (`run14b-artifacts/rtt-row3-revert.log`): ``` 22:26:36.265 I: Starting bootloader 22:26:36.265 I: DIAG ncs img=0 magic=0x96f3b83d flags=0x4 reset_addr=0x9769f57c 22:26:36.265 I: Image index: 0, Swap type: test 22:26:46.280 I: Starting swap using move algorithm. 22:27:46.775 I: Image version: v0.1.3 22:27:46.775 I: Jumping to the first image slot 22:27:51.093 <inf> app: benchForceAdvertise(): BENCH BROKEN IMAGE v0.1.3 -- advertising deliberately disabled ``` The broken image then ran for 62 s: header stayed `v0.1.3`, no BLE advertising, and `RESETREAS` stayed `0x00000000` — it did **not** self-reset. That is a known application-side gap (see section 4). Recovery therefore needed an external reset. On that reset: ``` 22:29:37.736 I: Starting bootloader 22:29:37.736 I: DIAG ncs img=0 magic=0x96f3b83d flags=0x4 reset_addr=0xa78fbdc3 22:29:37.736 I: Image index: 0, Swap type: revert 22:29:47.749 I: Starting swap using move algorithm. 22:30:48.389 I: Image version: v0.1.2 22:30:48.389 I: Jumping to the first image slot ``` End state, over BLE: `image 0 slot 0 v0.1.2 [active,confirmed,bootable]`, the unit advertising and serviceable. ## 2. Timings (measured) | Quantity | Value | |---|---| | App image OTA upload (462,492 B over BLE) | 38.3 s | | Broken app image upload (462,667 B) | 38.6 s | | Net-core image upload (145,499 B) | 12.2–12.5 s | | Swap execution, good (`Starting swap using move` → `Jumping`) | 60.59 s | | Swap execution, broken | 60.50 s | | Revert swap execution | 60.64 s | | Boot → new image running, good (bootloader start → jump) | 70.5 s | | Boot → revert complete | 70.7 s | | Baseline boot → BLE advertising | ~8–12 s | | Secondary slot erase, 0xd3000 = 864,256 B (single unfed call) | 15.80 s (img 0), 17.88 s (img 2) | | Image hash + decrypt, 462,224 B | 0.83 s | | ECDSA signature verify | 0.315 s | | Image-2 swap-state read hang (unpatched) | 10.86 s | | Inherited application task watchdog window | 10.5 s (`CRV` 0x54000 @ 32768 Hz) | The swap window is ~60 s, consistent with the ~58 s encrypted-swap figure recorded in earlier encrypted-image testing on the same board. ## 3. Defect chain (four SDK defects, all in NCS v3.3.1 MCUboot) 1. **Encrypted reset-vector misread — the keystone.** `boot_validated_swap_type()` reads the secondary slot's reset vector as plaintext. For an AES-encrypted image it is ciphertext (`0x3ee3fbc2` / `0x9769f57c` / `0xa78fbdc3` observed) and never falls inside the primary range `[0x28000,0xfc000]`, so MCUboot concludes "not intended for any image" and returns `BOOT_SWAP_TYPE_NONE` before `sec_slot_mark_assigned()`. The plaintext net-core image (`flags=0x100`, `reset_addr=0x1023291`) passes, which is why only the encrypted app image ever failed. NCS v3.3.1 has no encryption guard anywhere in that block, although `ih_flags & ENCRYPTIONFLAGS` is available. Implication: `SB_CONFIG_SECURE_BOOT_APPCORE` + `SB_CONFIG_BOOT_ENCRYPTION` are effectively incompatible on nRF5340 in NCS v3.3.1 without this fix. 2. **Image-2 swap-state read blocks the boot.** Image 2 is the NSIB s0/s1 self-update slot. Its primary is `mcuboot_primary_1`, a `nordic_ram_flash_controller` (PCD/RAM-flash) area backed by the network core, which is held off during boot, so the read blocks — 10.86 s measured, versus <1 ms for images 0 and 1 through the same code. Its secondary is the *shared* `mcuboot_secondary`, so any staged app image gives image 2 "good magic" and triggers this on every staged boot. 3. **Whole-secondary erase in one unfed call.** `sec_slot_cleanup_if_unusable()` erases the entire external-QSPI secondary in a single `flash_area_erase` — 15.80 s and 17.88 s measured, each far beyond the 10.5 s watchdog window. It erases the shared area twice, once on behalf of unwired image 2, destroying a good staged app image. This is what made every failed attempt leave a torn slot. 4. **Missing watchdog feeds on the swap/validate path.** `CONFIG_BOOT_WATCHDOG_FEED` exists but upstream calls it from only three places, none on the swap or validate path, which runs for tens of seconds over external QSPI. The nRF watchdog survives `sys_reboot`, so MCUboot inherits the running 10.5 s application `task_wdt` across a warm reset — the real field OTA path. Defects 2, 3 and 4 combine to reset the device mid-operation and erase the staged image; defect 1 guarantees the image would have been rejected anyway. ## 4. Fix inventory ### Already in the application build (not SDK changes) - `sysbuild/mcuboot.overlay` — external-flash (`mx25r64`) properties mirrored from the application overlay so MCUboot drives the external flash identically. Hardening only; bench-proven **not** to be the no-swap cause. - `sysbuild/mcuboot.conf` — documentation block recording that `CONFIG_UPDATEABLE_IMAGE_NUMBER` cannot be lowered from the application repository (sysbuild's `set_config_int` overrides the fragment; the `SB_CONFIG` knob is Kconfig-pinned to `range [1,1]` under `SECURE_BOOT_APPCORE` and hard-fails configuration). The setting is left commented out deliberately. ### SDK patch, required (`ncs-3.3.1-mcuboot-secured-swap.patch`) All four hunks are necessary; none is sufficient alone. | Hunk | File | Fixes | |---|---|---| | 1 | `loader.c` `boot_validated_swap_type()` | defect 1 (keystone) | | 2 | `loader.c` `boot_prepare_image_for_update()` | defect 2 | | 3 | `loader.c` `sec_slot_cleanup_if_unusable()` | defect 3 | | 4 | `swap_move.c` ×3, `bootutil_img_hash.c` ×1 | defect 4 | Rejected during investigation: forcing MCUboot's image count to 2. It produced the intended count but broke the application (no advertising, `RESETREAS` showed `LOCKUP`). ### Additional observations for Nordic - Defects 1–4 above, with the measured numbers. - Shared-secondary coupling: marking image 0 pending also flips image 1's reported state in `image list`. - `boot_read_image_headers()` swallows a failed read (`i > 0 && !require_all` → `rc 0`) and keeps a stale header — observed as a valid cached header alongside a fresh read of `ff ff ff ff`. - `swap_read_status_bytes()` issues roughly 1000 single-byte `flash_area_read` calls over external QSPI (`BOOT_MAX_IMG_SECTORS=256`); should be batched. ### Application-side, not an SDK issue A booted-but-never-advertising image does not self-reset, because the task watchdog is fed unconditionally. Row 3 evidences this: `RESETREAS` stayed `0x00000000` for 62 s while the broken image ran. MCUboot's revert is correct and fires on the next reset, but on a fielded unit nothing generates that reset. Tracked separately on our side. ## 5. Evidence index | File | Contents | |---|---| | `ncs-3.3.1-mcuboot-secured-swap.patch` | the four-hunk SDK patch, applies cleanly to mcuboot @ `3de5b4df5f9f` | | `run14b-artifacts/rtt-row2-swap-pass.log` | row 2: `ASSIGNED` → `Swap type: test` → swap → `v0.1.3` | | `run14b-artifacts/rtt-row3-revert.log` | row 3: broken swap-in + banner, then `Swap type: revert` → `v0.1.2` | | `run14b-artifacts/rtt-keystone-encrypted-reset-vector.log` | pre-fix capture: `RETURN-NONE`, ciphertext `reset_addr` vs primary range | | `run14b-artifacts/rtt-secondary-erase-timing.log` | 15.80 s / 17.88 s erase measurement | | `run14b-artifacts/rtt-img2-hang-bisect.log` | 10.86 s image-2 hang bisect | | `run14b-artifacts/partitions.yml` | partition geometry | Build outputs (merged hex images, DFU bundles, `mcuboot-zephyr.config`, `app-zephyr.config`, `mcuboot-zephyr.dts`) were retained locally and are not included here; the logs above are the primary evidence and can be supplied on request. ## 6. Bench provenance - One nRF5340 custom board (the bench unit), BLE OTA over a Linux host. - Debug probe: CMSIS-DAP probe, `probe-rs` v0.32.0 at 500 kHz. - Toolchain: NCS `v3.3.1-1d7a0b0e49b8`, toolchain bundle `911f4c5c26`; MCUboot `v2.3.0-dev-3de5b4df5f9f`. - Line: secured — `SB_CONFIG_SECURE_BOOT_APPCORE`, `SB_CONFIG_BOOT_ENCRYPTION` (AES-128), `SB_CONFIG_MCUBOOT_MODE_SWAP_USING_MOVE`, development keys from a local key directory. - Geometry: `b0` 0x0–0x8000, `s0` 0x8000–0x18000, `s1` 0x18000–0x28000, `mcuboot_primary` 0x28000–0xfc000, `mcuboot_secondary` 0x0–0xd3000 in external QSPI (primary minus one sector, the swap-using-move requirement). - b0 provision written to OTP at `0xff8128` via an NVMC workaround (`probe-rs` 0.32 cannot program the OTP page; error 104). - Bench overlays on all images: auto-advertise and charger-interlock-bypass fragments, plus an RTT console overlay (`CONFIG_SERIAL=n`, so RTT is the only console). ### Builds used | Build | Version | MCUboot binary md5 (first 12) | Role | |---|---|---|---| | baseline build | 0.1.2+0 | `4723182e9a08` | baseline, carries all four SDK patches | | good build | 0.1.3+0 | `a601e851b3f7` | good image: boots, advertises, self-confirms | | broken build | 0.1.3+0 | `0efa90344afe` | broken image: boots, never advertises | Only the app image is staged over BLE for these rows; the good and broken images are app-image-only OTAs, which is the self-healing case under test. Version note: MCUboot compares only major.minor.patch — `CONFIG_BOOT_VERSION_CMP_USE_BUILD_NUMBER` is not set — so a `VERSION_TWEAK` bump is not an upgrade under `MCUBOOT_DOWNGRADE_PREVENTION`. The test images use a PATCH bump (0.1.2 → 0.1.3).