Embedded Software

When Security Locks You In: A Hard Lesson in Flash Partition Planning on the nRF52840

Home

>

Blog

>

Embedded Software

>

When Security Locks You In: A Hard Lesson in Flash Partition Planning on the nRF52840

Published: 2026/07/29

6 min read

“Secure-by-design” is a gold standard in modern hardware development, but what happens when early security choices permanently lock out future updates? We faced this very dilemma during a routine firmware migration. Or at least that’s what we thought it would be – move FW 1.0 to a newer version, adjust a few things and ship it. If only it had been that simple. It wasn’t.

What began as a routine migration turned into a full rewrite. The rewrite itself was not caused by memory lock – instead, it exposed a deeper issue in the system’s storage design that had been hidden until that point.

In this article, we take a close look at how a sophisticated commercial workplace presence sensor became a victim of its own rigid architecture.

The real-world case study: a presence and environmental sensor

The device in question belongs to the custom electronics sector – namely, a modern workplace presence and environmental sensor. Designed to enable smart office automation and gather spatial analytics, this compact device is deployed across office meeting spaces, conference rooms and focus booths.

At the heart of this hardware architecture is the Nordic Semiconductor nRF52840 System on Chip (SoC). Featuring a 32-bit ARM Cortex-M4 CPU running at 64 MHz, a built-in cryptographic unit and extensive multiprotocol capabilities (supporting Bluetooth LE, Thread and Zigbee concurrently), the nRF52840 is a highly advanced platform.

On paper, the chip’s 1 MB of Flash and 256 KB of RAM offer a generous amount of memory for demanding enterprise applications. However, this project proved that when sophisticated feature sets are bound by a rigid structural architecture, even 1 MB of space can vanish remarkably fast.

The moment of realization: the NVS bottleneck

At first, everything looked fine. The firmware compiled, the features worked and the device booted as expected. But once we began working through the new version, that’s when the actual roadblock reared its ugly head.

The immediate bottleneck was persistent data storage, specifically handled by the Non-Volatile Storage (NVS) file system. However, the root cause wasn’t just a simple file system error. It was a poorly optimized memory layout left behind by the previous vendor.

This layout defect created a severe space crunch. We had to cram critical assets – such as runtime settings, security keys and unique calibration data – into a heavily restricted boundary. This triggered a common pitfall with NVS: assuming it only requires the exact byte size of the data it holds. In reality, to maintain data integrity over a long lifecycle, adequate physical sector headroom is needed to perform background management tasks like:

  • Garbage collection,
  • Wear leveling,
  • Defragmentation.

Because the wasted space elsewhere prevented us from allocating a larger partition, the existing NVS partition simply didn’t have enough empty “scratchpad” space left to handle these chores. The garbage collection process stalled completely, leaving us with a file system that could no longer write new data.

Why a routine port forced a total rethink

Resizing partitions would normally be the obvious fix. But on this device, that option was off the table due to early architectural choices made under the guise of security: the system had an immutable bootloader, a hardcoded memory layout, flash regions protected by ACLs and debug access locked with APPROTECT.

These protective measures were highly effective at securing the device on day one, but they rendered the internal memory layout completely rigid from an evolutionary perspective.

The hidden constraint

Another important detail was that these sensors store highly specific, unique calibration constants and hardware identities written directly during factory provisioning that was difficult, if not impossible, to regenerate.

The relationship was set in stone: the bootloader defined the memory layout, the layout defined the NVS size and the NVS size capped the operational scope of the firmware. Security had locked out evolution.

Why two-stage bootloaders weren’t a silver bullet

A common alternative is to use a two-stage bootloader architecture. In this setup, Stage 1 acts as an immutable Root of Trust (RoT), while Stage 2 handles updatable logic.

While that works incredibly well for larger systems, it introduces some heavy trade-offs on resource-constrained chips like the nRF52840.

For starters, the flash overhead is high, as running two separate bootloader images chews through valuable code space. It also adds a lot of complexity; validating, securing and swapping secondary bootloader stages introduces new attack vectors and potential failure points during over-the-air (OTA) updates.

In this specific case, the system had already been designed too tightly to squeeze in a secondary rescue mechanism.

The real lesson: engineering for evolution

Ultimately, we managed to salvage the deployment by offloading non-sensitive configuration data and encrypted backups into the board’s secondary external memory – EEPROM. While this workaround kept the devices functioning in the field, it proved a costly point: if the foundation is flawed, you are locked into it for the entire lifecycle of the product.

The real takeaway drawn from this project was not about bootloaders alone. It boiled down to planning for change. A good, embedded design is one that avoids hardcoded constraints that paralyze future updates. Instead, we should design systems where layout configurations can evolve securely over time, storage has plenty of overhead to run background tasks and firmware, device identity and data storage are clearly isolated.

At the end of the day, memory allocation is never just a low-level detail in the embedded world. It dictates what your product can become.

Storage planning is architecture, not housekeeping

This project reinforced a vital reality for the embedded space. Long before you deploy advanced analytics, AI capabilities or dense connectivity features, you must solve a critical problem: Will this device still be adaptable in two years without compromising its identity? If the layout is hardcoded, the answer is likely no.

Navigating these exact bottlenecks is what has shaped our approach. Experiencing architecture constraints like these firsthand is what has honed our engineering perspective. These hard-won insights are baked right into our embedded software services, where we focus on production-ready frameworks that balance strict chip-level security with long-term adaptability. We help engineering teams design resilient memory structures on platforms like the Nordic nRF52 series, ensuring hardware remains secure on day one and maintainable for years to come.

Struggling with rigid firmware constraints or tight flash boundaries? Get in touch with us to design a flexible roadmap for your next hardware platform.

FAQ

Can you update an immutable flash partition layout via Over-the-Air (OTA) firmware updates?

No. If the bootloader and memory offsets are hardcoded and immutable, changing the physical layout remotely is practically impossible. Attempting to force an update will cause the bootloader to look for code in the wrong addresses, resulting in a bricked device.

How do you balance embedded hardware security with long-term firmware flexibility?

By separating your security mechanisms from your storage layout. Keep your cryptographic bootloader permanent, but store the actual partition coordinates in a separate, digitally signed metadata table that can be securely modified during a firmware update.

How can factory-provisioned data like unique calibration constants be protected during layout changes?

Hardware identities and calibration values should always be strictly isolated from both the application runtime space and the primary file system. This immutable data should be placed into its own dedicated, read-only flash sector – protected by Access Control Lists (ACLs) or hardware-enforced page protection – so that even a massive firmware overhaul cannot overwrite it.

About the authorArkadiusz Bochyński

Embedded Software Engineer

Arkadiusz is an accomplished Embedded Engineer with over eight years' experience in developing and testing embedded devices, from HiFi audio technology and marine applications to solution designs and IoT systems. His past work includes firmware for stationary engine controllers, built with FreeRTOS, C++20 and the Model-View-Presenter architecture. He's currently working on two projects in parallel: an IoT device based on Zephyr with BLE and LoRaWAN connectivity, and a high-end gaming headset built on ThreadX and USBX. Arkadiusz has also co-authored articles on synchronous signal acquisition involving energy-efficient wireless links and real-time wireless synchronous data transmission, which were published in renowned electronics and telecommunications forums. His work highlights innovation, reliability and efficient embedded system design.

Subscribe to our newsletter

Sign up for our newsletter

Most popular posts

Newsletter

Privacy policyTerms and Conditions

Copyright © 2026 by Software Mind. All rights reserved.