Sample: External MCU update - reference solution
Your product may incorporate other MCUs with your Azure Sphere device, and those other MCUs may require updates. Assuming the other MCUs permit updates to be loaded over the connection you establish with the Azure Sphere device, for example over UART, you can use the Azure Sphere device to securely deliver those updates.
This reference solution demonstrates how you might deploy an update to an external MCU device using Azure Sphere. This solution contains an Azure Sphere app that deploys firmware to the Nordic nRF52 Development Kit over UART. This app can itself be updated remotely via over-the-air updates, ensuring that the software versions of this app and the MCU firmware are always in sync.
This reference solution uses beta APIs and requires the following:
- Azure Sphere SDK version 19.02 or above. In an Azure Sphere Developer Command Prompt, run azsphere show-version to check. Download and install the latest SDK as needed.
- Azure Sphere MT3620 board
- Nordic nRF52 BLE development board
- Jumper wires to connect the boards
- Two free USB ports on your computer
Connect Azure Sphere MT3620 to the Nordic nRF52
Make the following connections between the nRF52 and MT3620 dev boards using the jumper wires:
- nRF52 RX: P0.11 to MT3620 UART0 TX: Header 2 (lower left) Pin 3
- nRF52 TX: P0.12 to MT3620 UART0 RX: Header 2 (lower left) Pin 1
- nRF52 CTS: P0.23 to MT3620 UART0 RTS: Header 2 (lower left) Pin 7
- nRF52 RTS: P0.22 to MT3620 UART0 CTS: Header 2 (lower left) Pin 5
- nRF52 Reset: P0.21 to MT3620 GPIO5: Header 2 (lower left) Pin 4
- nRF52 DFU: P0.16 to MT3620 GPIO44: Header 2 (lower left) Pin 14
- nRF52 Ground: GND to MT3620 GND: Header 2 (lower left) Pin 2
Refer to the following graphic for details.
Install bootloader on the nRF52
- If you haven't already done so, clone this repo.
git clone https://github.com/Azure/azure-sphere-samples.git
- Connect the nRF52 developer board to your computer using USB. Once connected, the nRF52 displays a JLINK removable drive in Windows.
- Find softdevice_Bootloader.hex in the ExternalMcuUpdateNrf52\Binaries folder, and copy it to the JLINK drive. The nRF52 restarts automatically and runs the bootloader.
- Observe that LED1 and LED3 are lit on the nRF52 development board, which indicates that the bootloader has started successfully.
Run the Azure Sphere app that updates the firmware on the nRF52
- Open ExternalMcuUpdateNrf52\AzureSphereApp\ExternalMcuUpdateNrf52.sln in Visual Studio.
- Build and debug (F5) the app.
- As the app runs, observe the Output window for activity messages. You should see the sample firmware install on the nRF52.
- Observe that LED2 and LED4 are blinking on the nRF52 development board, which indicates the new firmware is running.
- Press button A to restart the update process. In the Output window, observe that the app determines the nRF52 firmware is already up to date, and does not reinstall it.
If you see numerous errors in the Visual Studio Error List relating to missing headers and undefined identifiers, or if when building the app, you see the following error in the Visual Studio Build Output:
error MSB6004: The specified task executable location "C:\Program Files (x86)\Microsoft Azure Sphere SDK\\SysRoot\tools\gcc\arm-poky-linux-musleabi-gcc.exe" is invalid.
Then it is likely you have an older version of the Azure Sphere SDK installed; ensure you have version 19.02 or newer.
Edit the Azure Sphere app to deploy different firmware to the nRF52
The nRF52 firmware files are included as resources within the Azure Sphere app. The app can easily be rebuilt to include different firmware.
- Remove the existing BlinkyV1.dat and BlinkyV1.bin nRF52 firmware files from the solution. In Solution Explorer, find them under Resource Files. Right-click on them, and select Remove.
- Add BlinkyV2.bin and BlinkyV2.dat files as resources to the solution. Right-click on Resource Files, select Add -> Existing Item, and find these files in the ExternalMcuUpdateNrf52\AzureSphereApp\External Nrf52 Firmware subfolder.
- After you add the files, right-click each file and set the Content property to Yes, to ensure that they are included as resources when the image package is created.
- Update the filename constants in main.c to point at BlinkyV2 instead of BlinkyV1.
- Update the accompanying version constant to '2' instead of '1'.
- Ensure the "SoftDevice" BLE stack firmware files (s132_nrf52_6.1.0_softdevice.bin and s132_nrf52_6.1.0_softdevice.dat) are still included as resources. Do not edit the constants that relate to these files.
- Build and debug (F5) the Azure Sphere app.
- Use the Output window to observe as the BlinkyV2 firmware is installed and run on the nRF52.
- Observe that LED3 and LED4 are now blinking on the nRF52 development board, which indicates that the BlinkyV2 firmware is running.
- Notice that the SoftDevice BLE stack was not updated because it is already at the correct version.
Build and deploy your own app firmware for the nRF52
You can adapt this solution to include your own nRF52 app.
Create a new 'BlinkyV3' nRF52 app
- Download and install SEGGER Embedded Studio. Download the 32-bit version, not the 64-bit version. Ensure that you are licensed to use it for your purposes. In Oct 2018, we were able to obtain the license for free because we were developing for NRF52.
- Download and unzip the Nordic NRF5 SDK V15.2.
- Edit Nordic's Blinky sample app so you can build it against your SDK:
- Use a text editor to open <NORDIC_SDK_PATH>\examples\peripheral\blinky\pca10040\s132\ses\blinky_pca10040_s132.emProject.
- Set the SDK_ROOT variable in this file to point to the root directory your Nordic SDK install. Specifically, replace the words "CHANGE_THIS_TO_YOUR_NORDIC_SDK_PATH" with the correct path, changing any backslashes ("\") to forward slashes ("/") in the path. For example: macros="SDK_ROOT=C:/Users/ExampleUser/source/nRF5_SDK_15.2.0_9412b96;…"
- Open this .emProject file in the Segger IDE.
- Build it (Build->Build Solution) to generate a .hex file. It is placed in this location: <NORDIC_SDK_PATH>\examples\peripheral\blinky\pca10040\s132\ses\Output\Release\Exe\blinky_pca10040_s132.hex
Obtain the BlinkyV3.bin and BlinkyV3.dat app firmware files
- Install Python 2.7.6 (32-bit) or later. Note: Python 3 won't work but it's fine to have this installed side-by-side.
- Install the Nordic nrfutil CLI.
- Use the nrfutil utility to transform the downloaded app .hex file into a firmware update package .zip file. Specify the app version in the command.
- Open a command prompt and go to the directory that contains the .hex file generated above.
- Run this command:
nrfutil pkg generate --application blinky_pca10040_s132.hex --sd-req "0xA8","0xAF" --application-version 3 --hw-version 52 blinkyV3.zip
- The version specified to pack the application ('3' in this case) must also be specified in the Azure Sphere app when you deploy the new firmware.
- Note the warning about 'not providing a signature key'. This doesn't stop you from proceeding, but you should consider whether this is acceptable for your production scenario or whether, for example, your product is designed so that only the Azure Sphere chip has the ability to update the nRF52 firmware.
- See the nrfutil documentation for more details about its command options.
- Open the resulting .zip file and extract the .bin and metadata .dat back out from this .zip package.
- Rename these files as desired—for example, BlinkyV3.bin/.dat.
Deploy the new firmware
Add BlinkyV3.bin and BlinkyV3.dat as resources in the AzureSphere app by following the steps specified in Edit the Azure Sphere app to deploy different firmware to the nRF52. Remember to update the filenames and the version to '3' in main.c.
Combine this solution with the solution for BLE-based wifi setup
You can combine this solution for external MCU update with the solution for [BLE-based wifi setup] (https://github.com/Azure/azure-sphere-samples/tree/master/Samples/WifiSetupAndDeviceControlViaBle). Doing so allows you to remotely update that solution's nRF52 application.
Create a single Azure Sphere application
- Remove the code that uses button A to trigger a firmware update and instead trigger it only when the combined app starts. In particular, remove the DfuTimerEventHandler, dfuButtonTimerEvent, gpioButtonFd, buttonPressCheckPeriod and dfuButtonTimerFd.
- Combine the initialization and close functions. In particular, the UART, Epoll, and Reset file descriptors are opened and closed by both applications. Make sure you maintain only a single copy of each.
- After the MCU update is complete, make sure to remove any of its UART event handlers from the epoll event loop. This will allow the wifi setup code to register its own UART event handlers when needed. Failure to do so will result in such registrations returning -1 with errno set to EEXISTS.
- Combine the app manifest. In particular, add the required GPIOs for both applications and set the WifiConfig capability to true.
Obtain the nRF52 firmware files
- Re-build the nRF52 firmware for the [BLE-based wifi app] (https://github.com/Azure/azure-sphere-samples/tree/master/Samples/WifiSetupAndDeviceControlViaBle#build-your-own-solution) (Build->Build Solution) or press F7 to generate a .hex file. The hex file is placed in this location: <PATH_TO_YOUR_CLONED_REPO>\WifiSetupAndDeviceControlViaBle\Nrf52App\pca10040\s132\ses\Output\Release\Exe\ble_app_uart_pca10040_s132.hex
- Follow the steps specified in [Obtain the BlinkyV3.bin and BlinkyV3.dat app firmware files] (https://github.com/Azure/azure-sphere-samples/tree/master/Samples/ExternalMcuUpdateNrf52#obtain-the-blinkyv3bin-and-blinkyv3dat-app-firmware-files) to transform this .hex file into .dat and .bin files.
- Rename these fields as desired—for example, WifiSetupAndDeviceControlViaBle.bin/.dat
Edit the Azure Sphere application to deploy the new nRF52 firmware
Add WifiSetupAndDeviceControlViaBle.bin and WifiSetupAndDeviceControlViaBle.dat as resources in the ExternalMcuUpdateNrf52 app by following the steps specified in Edit the Azure Sphere app to deploy different firmware to the nRF52. Remember to update the filenames and the version in main.c. For example, if you've previously deployed version '3' of the firmware (even if it was just test firmware such as 'Blinky') then the version should now be '4'.
Build your own bootloader
This sample includes a modified version of the example bootloader (secure_bootloader\pca10040_uart_debug) in the nRF5 SDK. It has been modified to:
- Use a custom board configuration where the UART pins are remapped and have pull-up resistors enabled on the input pins.
- Accept signed or unsigned applications—consider whether this is acceptable for your production scenario.
- Accept signed or unsigned bootloaders—consider whether this is acceptable for your production scenario.
- Accept firmware upgrades or downgrades.
- Enable Device Firmware Update (DFU) mode via pin input, as well as by pressing the Reset button on the nRF52 board.
To further edit and deploy this bootloader:
- Edit the bootloader sample so you can build it against your SDK:
- Use a text editor to open ExternalMcuUpdateNrf52\Nrf52Bootloader\pca10040\s132\ses\bootloader_uart_mbr_pca10040_debug.emProject.
- Set the SDK_ROOT variable in this file to point to the root directory your Nordic SDK install. Specifically, replace the words "CHANGE_THIS_TO_YOUR_NORDIC_SDK_PATH" with the correct path, changing the backslashes ("\") to forward slashes ("/") in the path. For example: macros="SDK_ROOT=C:/Users/ExampleUser/source/nRF5_SDK_15.2.0_9412b96;…"
- Open this .emProject file in the Segger IDE.
- Build it (Build->Build Solution) to generate a .hex file. It is placed in this location: ExternalMcuUpdateNrf52\Nrf52Bootloader\pca10040\s132\ses\Output\Release\Exe\bootloader_uart_mbr_pca10040_debug.hex
- Copy this file to the JLINK drive presented by the nRF52. The nRF52 restart automatically and runs the bootloader.
For license details, see LICENSE.txt in each directory.
Code of Conduct
This project has adopted the Microsoft Open Source Code of Conduct.