Your product is in a customer's kitchen, garage, or pocket. You found a bug. The fix is four lines of firmware. Now what? For a huge class of connected products, the answer is the phone the customer already owns: the app downloads a new firmware image from your server and pushes it into the device over Bluetooth or a cable. That process is usually called DFU — device firmware update — and it is one of those features that looks like a checkbox on a spec sheet and turns into a month of engineering when someone finally builds it. Here is what actually goes into it.
Why the phone is the update path
Plenty of products update themselves directly over Wi-Fi or cellular, and if yours has a permanent internet connection that is usually the cleaner architecture — see our overview of remote firmware updates on a connected product. But an enormous number of devices are Bluetooth-only: wearables, sensors, tools, medical accessories, anything running for months on a coin cell. They have no route to your server except through the user's phone. The app becomes the delivery truck.
The upside: the phone has bandwidth, storage, and a screen you control. The downside: updates only happen when the user opens the app and stays nearby, so your fleet updates on a timeline you do not control.
The bootloader decides everything
An update is only as safe as the code that receives it. That code is the bootloader, a small program that runs before your application and decides what to launch. If you take one thing from this article: the bootloader architecture is chosen at the beginning of a project and is painful to change later, so choose it deliberately. Our primer on bootloaders in embedded products covers the fundamentals; the update-specific decision is single-bank versus dual-bank flash.
| Single-bank | Dual-bank | |
|---|---|---|
| How it works | New image overwrites the running application in place | New image is written to a second slot, then swapped on reboot |
| Flash needed | Roughly one image plus bootloader | Roughly two images plus bootloader |
| Interrupted transfer | Device is bricked until re-flashed; only the bootloader survives | Old image still runs; retry later |
| Usable during update | No | Yes, until the reboot |
| Typical use | Very cost-sensitive parts with tight flash | Anything a customer paid real money for |
Dual-bank costs you flash, and flash costs cents. Bricking a customer's device costs you a replacement unit, shipping both ways, and a review. Size the part with the second bank in mind from the start — this is one of the classic reasons a project runs out of memory late, which is covered in how much flash and RAM your microcontroller really needs.
Signing, verification, and rollback protection
An update channel is also an attack channel. If the device accepts any image handed to it over Bluetooth, anyone within radio range can install their own firmware — extract your IP, turn the product into something it was never meant to be, or simply destroy it. Three protections belong in every design:
- Signed images. You sign the firmware with a private key held in your build system; the bootloader verifies the signature with a public key baked into the device. The phone never holds a key and never needs to be trusted.
- Integrity check before swap. Verify a hash over the complete received image before you commit to it. A transfer that ended cleanly is not the same as a transfer that arrived intact.
- Rollback protection. A monotonic version counter that refuses images older than the running one. Otherwise an attacker simply installs your last release — the one with the vulnerability you just fixed.
If your firmware itself is valuable, encryption of the image at rest and in transit is the next layer; secure boot and firmware encryption goes into how the chain of trust is built.
How long it actually takes over BLE
This is where expectations break. Bluetooth Low Energy was designed to move small amounts of data infrequently, not to stream a firmware image. Real-world throughput on a well-tuned connection with a large MTU and a short connection interval typically lands somewhere in the range of 20 to 100 kilobytes per second, and it degrades fast with distance, interference, and phones that refuse your preferred connection parameters. A 256 KB image is therefore a few seconds in the best case and several minutes in a realistic one. A 1 MB Linux-class image over BLE is not a good idea at all.
Practical levers, roughly in order of payoff: negotiate the largest MTU both sides support, request the shortest connection interval the platform will grant, compress the image, and ship delta updates that send only what changed — a delta can cut a routine bug fix to a fraction of a full image. If the device also has Wi-Fi, use it for the transfer and keep BLE for control; the same reasoning appears in choosing between Bluetooth and Wi-Fi for a smart product.
The user walks away
Assume it. Assume the phone locks, the app gets backgrounded, the user drives off, the elevator arrives. Both mobile platforms will suspend your app's Bluetooth activity in the background, and there is no way to hold a long transfer open indefinitely. Design for the interruption instead of trying to prevent it:
- Resumable transfers. The device tracks how many bytes of the new slot it has validly received; on reconnect the app asks and continues from there. This alone converts most failures into a shrug.
- Keep the device alive. With dual-bank flash, the product keeps working normally on the old firmware for as long as the update takes. Only the final reboot is disruptive, and it should take seconds.
- Do not reboot at a bad moment. Let the firmware refuse the swap while it is mid-task, charging, or in an active session, and apply it at the next idle window.
- Honest UI. Real progress, a plain warning to stay in range, and a recovery screen that explains what to do rather than an endless spinner.
Staged rollouts and version chaos
Never ship a firmware release to the whole fleet at once. Push to internal devices, then to a small percentage of real users, watch your crash and connectivity telemetry for a few days, then widen. Your update server should decide which image a given serial number and hardware revision is allowed to receive — because within a year you will have several hardware revisions in the field with different sensors and different flash layouts, and handing the wrong image to the wrong board is exactly how a recall starts. Firmware version management in production and the field covers the tracking discipline this requires.
The app has the mirror-image problem: a user running a two-year-old app version may be talking to brand-new firmware, or the reverse. Both sides need a compatibility matrix and a graceful "please update the app first" path, which is the core subject of supporting several product generations from one app.
What to budget
DFU is not a small feature. Expect bootloader work, firmware transfer and validation logic, a mobile implementation on each platform, server-side hosting and version rules, and a test matrix that includes deliberately yanking power and walking out of range — typically two to six engineer-weeks across firmware and app. Building it before the first production run is far cheaper than retrofitting devices already on shelves.
Projects House builds firmware, hardware, and companion apps as one system, including the update path that keeps a product fixable after it ships. If you are deciding how your product will receive its next firmware release, describe it to us through the contact form.