One of the key features of Azure Sphere and one of the 7-properties of a highly secure device is Renewable Security.  Think about a deployed IoT device, or thousands of devices, that don't have the ability to be updated remotely.  These devices may be considered secure when they ship, but as time goes by, clever hackers may find vulnerabilities or the engineering community may find issues with common operating systems that need to be patched.  Without the ability to remotely update these devices they can become unsecure.  Additionally, OEM applications may need to be updated to add new features, or to fix a software bug that was discovered. 


The Azure Sphere ecosystem provides Over-the-Air (OTA) updates for the Operating System but also provides methods and global infrastructure for OEMs/developers to manage/deploy application images OTA.  This is a free feature that is included for all Azure Sphere devices. 



OTA Update Specifics

Microsoft has detailed documentation on setting up OTA updates here, and deferring OTA updates here.  I recommended that you review that documentation.  One Azure Sphere OTA behavior that is sometimes seen as a negative, is that OTA updates can trigger at any time.  And when they do, the device will download the update and proceed to apply the update to the device.  This includes restarting the device so that the updates are used right away.  Microsoft recognized that this behavior is less than ideal for many devices, so they include the ability for high level applications to defer updates.


When do OTA updates trigger?

Over the Air updates are managed by the Azure Sphere Security Service (AS3) in the cloud.  Azure Sphere devices connect to AS3 for Device Authentication and Attestation (DAA) activities.  DAA is the process where the AS3 validates that the device is a genuine Azure Sphere device and that the device is running the correct OS and Application versions.  If the DAA step identifies that the device is running old or unauthorized software, then the OTA process kicks off.  The DAA process starts when the device first powers on, and then approximately every 24-hours.  So any given Azure Sphere device could receive an update at any time of the day, it depends on the time of day when the device last powered up.  There is currently not a mechanism to schedule when updates are pushed to devices, or a way for the Azure Sphere application to ask AS3 if there is an update pending.


OTA Events

At a high level the Azure Sphere High Level application registers for OTA events and provides a handler that will be called when OTA events trigger.  The events are shown below, note that there is a 10 second window where the application has the opportunity to defer the update.

Note that there is a limit to how long the application is allowed to defer the updates.  For OS updates the limit is 24 hours, and for application updates the limit is 167 hours (~7 days) .  These time periods start when the application gets the first notification that an update is pending.  If the application asks for a deferment period greater than the remaining allowed period, the requested period is adjusted to reflect the max time remaining.


OTA Deferment Example Applications

Microsoft has published a simple straight forward example demonstrating how to use this feature.  You can review the example here.


Avnet Example

I've recently developed and published an Azure Sphere implementation that allows applications to manage OTA updates.  The Avnet implementation implements the following features . . .

  • Poll for the current OTA status
    • This functionality could be useful if your application frequently powers down to conserve power.  Before powering down, make sure an update is not in progress or pending.  If so, don't power down, allow the update!
            // Functions to poll current OTA status

            bool OtaUpdateIsInProgress(void);

            bool OtaUpdateIsPending(void);

  • Defer and resume OTA updates if they come in
    • This functionality could be useful if your application enters a critical section (brewing coffee for example) and should not be interrupted
            // Functions to manage OTA udates at runtime

            void delayOtaUpdates(uint16_t pausePeriod);

            void allowOtaUpdates(void);

  • Device twin handler that allows the user to configure a specific target time of day for any future OTA updates from the cloud
    • This functionality will defer any future updates until a specific target time of day
    • This could be useful if your device is installed in a business that is closed overnight
    • The target time of day data is written to mutable storage so that if the device resets or power cycles, the target time is read and known on future power-on/reset events
      • Since the device performs the DAA step on power-up, it's critical that the target time of day is known on power-up


Avnet Source

You can review/reuse the Avnet implantation by pulling our Azure Sphere GitHub repo

  • Repo link
  • Note you need to pull the entire repo to use the examples since the Hardware definitions are in the root directory structure


Example projects

There are two examples in the repo that use this implementation.  Both examples have been written to help Azure Sphere Developers quickly implement full featured Azure Sphere applications (expect more blogs on these examples soon).  Please see the files for each example.

  • Avnet Starter Kit Example: Link

  • Avnet Guardian 100 Example: Link


How to use the example

If you leverage the Avnet examples, you just need to enable the feature by enabling the compile flag in common/build_options.h

Device Twin Details

To set a target time of day for OTA installs from the cloud, you just need to update the device twin desired properties

{"otaTargetUtcTime": "04:21:00"}

This entry will tell the application to only apply OTA updates at 4:21 AM UTC, 12:21 AM here in North Carolina (UTC -4).


Use the example in your Azure Sphere application

To port the example into your project . . .

  1. Include the avnet/deferred_update.c and avnet/deferred_update.h files in your project
  2. Add the deferred update specific ExitCodes into your ExitCode enumeration definition
  3. Call deferredOtaUpdate_Init() from your startup routine
  4. Call deferredOtaUpdate_cleanup() from your exit/cleanup routine
  5. Port the avnet/deferred_update.c::setOtaTargetUtcTime() device twin handler into your device twin implementation
  6. Search the example project for the compile flag DEFER_OTA_UPDATES to see all the required code


Execution Capture

Testing my implementation was tricky.  I could not test the example from Visual Studio Code, since the only way I could get an OTA update to kick off was to update my OTA device group, then reset my device.  I ended up using an Avnet Guardian 100 device that has an external USB port connected to the MT3620 ISU1 UART.  I added code to write OTA debug to ISU1 and monitored a teraTerm terminal window.  I also added Azure IoTHub telemetry messages to capture the events.  I thought this would be a nice feature to use in the field as OTA events could be captured as telemetry and reviewed to see when a device received an OTA event and how it responded to the event.


Marked up debug with my comments in Bold


// Application running . . .

// Send device twin to defer updates until 05:10:00 PM UTC

TX Reported State: {"otaTargetUtcTime":"17:10:00"}


// Upload new image to my Device Group

// Power cycle device so it gets the update

Avnet Guardian 100 Default Application starting.


// Device receives OTA event "Pending"

// Attempts to send telemetry with event details, but not connected to IoTHub so telemetry gets queued (see ENABLE_TELEMETRY_RESEND_LOGIC feature

// Delay OTA update for 5 minutes

TX Telemetry: {"otaUpdateType":"Application","otaUpdateStatus":"Pending","otaMaxDeferalTime":10020}

deferredOtaCallback(): Pending

INFO: Deferring update for 5 minutes.

TX Telemetry: {"otaUpdateDelayPeriod":5}

TX Telemetry: {"otaUpdateType":"Application","otaUpdateStatus":"Deferred","otaMaxDeferalTime":10020}


// Device receives OTA event "Deferred"

deferredOtaCallback(): Deferred

INFO: Update deferred.


// Application connects to IoTHub

// Sends queued up telemetry messages

Azure IoT connection status: IOTHUB_CLIENT_CONNECTION_OK

TX Reported State: {"versionString":"AvnetG100Template-V2","manufacturer":"Avnet","model":"Azure Sphere Guardian 100"}


TX Telemetry: {"otaUpdateType":"Application","otaUpdateStatus":"Pending","otaMaxDeferalTime":10020}

TX Telemetry: {"otaUpdateDelayPeriod":5}

TX Telemetry: {"otaUpdateType":"Application","otaUpdateStatus":"Deferred","otaMaxDeferalTime":10020}


// Receives device twins desired properties messages

TX Reported State: {"sensorPollPeriod":15}

TX Reported State: {"telemetryPeriod":30}

TX Reported State: {"enableUartDebug":true}

TX Reported State: {"ssid":"IoTDemo","freq":2437,"bssid":"e4:95:6e:4c:7b:b6"}

TX Reported State: {"otaTargetUtcTime":"17:10:00"}


// Device receives OTA event "Pending" when time defer time expires

deferredOtaCallback(): Pending


// Logic allows update

// Device receives OTA event "Final" because OTA update has completed

INFO: Allowing update.

TX Telemetry: {"otaUpdateType":"Application","otaUpdateStatus":"Final","otaMaxDeferalTime":0}

deferredOtaCallback(): Final

INFO: Final update. App will update in 10 seconds.


// Device restarts

Avnet Guardian 100 Default Application starting.


// Device receives OTA event "Completed"

TX Telemetry: {"otaUpdateType":"Application","otaUpdateStatus":"Completed","otaMaxDeferalTime":0}

deferredOtaCallback(): Completed

INFO: OTA Update completed!


Avnet Over the Air Lab Documents

Avnet has created OTA update lab documents that contain all the details on how to create and manage Azure Sphere OTA  deployments.  You can download these documents by clicking on the graphics below.

Download OTA LabDownload OTA Cheat Sheet


Avnet Over the Air Lab Video Walk Through

We have created a video walking through the OTA Lab.  If you want to see the lab in action, just click on the graphic below, the video is 32 minutes long.

View Avnet OTA Video



I hope you learned something about Azure Sphere OTA updates and how to defer them from your application.  I hope you'll be able to reuse the code I developed to configure OTA update target time of day from the cloud.  I had fun developing it.  If you have any comments, questions, or find issues with my code.  Please don't hesitate to leave a comment.


Future improvements . . .

  • Add the ability to set a local target OTA update time of day (not UTC)