Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ Cellular samples
* The :ref:`nrf_cloud_coap_fota_sample` sample to demonstrate how to use the `nRF Cloud CoAP API`_ for FOTA updates.
* The :ref:`nrf_cloud_coap_device_message` sample to demonstrate how to use the `nRF Cloud CoAP API`_ for device messages.
* The :ref:`nrf_cloud_mqtt_device_message` sample to demonstrate how to use the `nRF Cloud MQTT API`_ for device messages.
* The :ref:`nrf_cloud_mqtt_fota` sample to demonstrate how to use the `nRF Cloud MQTT API`_ for FOTA updates.

* Removed the SLM Shell sample.
Use the `Serial Modem Host Shell`_ sample instead.
Expand Down
20 changes: 20 additions & 0 deletions samples/cellular/nrf_cloud_mqtt_fota/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# Copyright (c) 2025 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(nrf_cloud_mqtt_fota_sample)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
project(nrf_cloud_mqtt_fota_sample)
project(nrf_cloud_mqtt_fota)


# NORDIC SDK APP START
target_sources(app PRIVATE src/main.c)

if(CONFIG_NRF_CLOUD_FOTA_SMP AND CONFIG_BOARD_NRF9160DK_NRF9160_NS)
target_sources(app PRIVATE src/smp_reset.c)
endif()
# NORDIC SDK APP END

zephyr_include_directories(src)
Comment on lines +19 to +20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
zephyr_include_directories(src)

src files can just do include "local_file.h"; it doesn't make sense to add a global zephyr include for the application directory

31 changes: 31 additions & 0 deletions samples/cellular/nrf_cloud_mqtt_fota/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#
# Copyright (c) 2025 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

menu "nRF Cloud MQTT FOTA Sample"

config CLOUD_CONNECTION_RETRY_TIMEOUT_SECONDS
int "Cloud connection retry timeout (seconds)"
default 30
help
If connecting to nRF Cloud takes longer than this timeout, it will be
reattempted.

config CLOUD_READY_TIMEOUT_SECONDS
int "Cloud readiness timeout (seconds)"
default 600
help
If the connection to nRF Cloud does not become ready within this
timeout, the sample will reset its connection and try again.

module = NRF_CLOUD_MQTT_FOTA_SAMPLE
module-str = nRF Cloud MQTT FOTA Sample
source "${ZEPHYR_BASE}/subsys/logging/Kconfig.template.log_config"

endmenu

menu "Zephyr Kernel"
source "Kconfig.zephyr"
endmenu
178 changes: 178 additions & 0 deletions samples/cellular/nrf_cloud_mqtt_fota/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
.. _nrf_cloud_mqtt_fota:

Cellular: nRF Cloud MQTT FOTA
#############################

.. contents::
:local:
:depth: 2

The nRF Cloud MQTT FOTA sample demonstrates how to use the `nRF Cloud MQTT API`_ to perform Firmware Over-The-Air (FOTA) updates over MQTT on your device.
This covers modem, application, and full modem FOTA updates (FMFU).
Also, with the nRF9160 DK, it supports SMP FOTA updates to the firmware on the nRF52840 SoC present on the DK board (not a separate device).

When using MQTT, the `FOTA update <nRF Cloud Getting Started FOTA Documentation_>`_ support is almost entirely implemented by enabling the :kconfig:option:`CONFIG_NRF_CLOUD_FOTA` option, which is implicitly enabled by :kconfig:option:`CONFIG_NRF_CLOUD_MQTT`.

However, even with the :kconfig:option:`CONFIG_NRF_CLOUD_FOTA` Kconfig option enabled, applications must still reboot themselves manually after FOTA download completion, and must still update their `Device Shadow <nRF Cloud Device Shadows_>`_ to reflect FOTA support.

Requirements
************

The sample supports the following development kits:

.. table-from-sample-yaml::

.. include:: /includes/tfm.txt

The sample requires an `nRF Cloud`_ account.

Your device must be onboarded to nRF Cloud.
If it is not, follow the instructions in `Device onboarding <nrf_cloud_mqtt_fota_sample_onboarding_>`_.

.. note::
This sample requires modem firmware v1.3.x or later for an nRF9160 SiP and v2.0.0 or later for nRF9161 and nRF9151 SiPs.

.. include:: /includes/external_flash_nrf91.txt

.. note::
Full modem FOTA requires development kit version 0.14.0 or higher if you are using an nRF9160 DK.

Overview
********

You can update your device firmware on the `nRF Cloud`_ portal or directly through the `nRF Cloud MQTT API`_.
See the `nRF Cloud Getting Started FOTA documentation`_ for details.


User interface
**************

Button 1:
Check for a FOTA update right away without waiting for the timeout.

.. _nrf_cloud_mqtt_fota_sample_onboarding:

Setup
=====

You must onboard your device to nRF Cloud for this sample to function.
You only need to do this once for each device.

To onboard your device, install `nRF Cloud Utils`_ and follow the instructions in the README.

Configuration
*************

|config|

Configuration options
=====================

Check and configure the following configuration options for the sample:

.. _CONFIG_CLOUD_CONNECTION_RETRY_TIMEOUT_S:

CONFIG_CLOUD_CONNECTION_RETRY_TIMEOUT_S - Cloud connection retry timeout (seconds)
Sets the cloud connection retry timeout in seconds.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These configuration options are already defined in the "nRF Cloud multi-service" sample - https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples/cellular/nrf_cloud_multi_service/README.html#configuration_options. Hence, these Kconfig options could be removed.

We could just list these two Kconfig options like below:

Check and configure the following configuration options for the sample:

  • :ref:CONFIG_CLOUD_CONNECTION_RETRY_TIMEOUT_SECONDS <CONFIG_CLOUD_CONNECTION_RETRY_TIMEOUT_SECONDS>
  • :ref: CONFIG_CLOUD_READY_TIMEOUT_SECOND <CONFIG_CLOUD_READY_TIMEOUT_SECOND>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part of the reason why we are creating this sample is to break in smaller samples the Multi Service sample and eventually delete it.

Copy link
Contributor

@divipillai divipillai Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we could remove only these two configuration options from the Multi Service sample docs (This is to avoid the doc build error), and here in this sample, could give the below configuration syntax:

.. options-from-kconfig::
:show-type:

Going forward we would be using the above syntax for the sample-specific Kconfig options. Could refer the sample template: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/templates/sample_README.html#configuration_options


.. _CONFIG_CLOUD_READY_TIMEOUT_S:

CONFIG_CLOUD_READY_TIMEOUT_S - Cloud readiness timeout (seconds)
Sets the cloud readiness timeout in seconds.
If the connection to nRF Cloud does not become ready within this timeout, the sample will reset its connection and try again.

.. include:: /libraries/modem/nrf_modem_lib/nrf_modem_lib_trace.rst
:start-after: modem_lib_sending_traces_UART_start
:end-before: modem_lib_sending_traces_UART_end

Building and running
********************

.. |sample path| replace:: :file:`samples/cellular/nrf_cloud_mqtt_fota`

.. include:: /includes/build_and_run_ns.txt

The configuration files for this sample are located in the :file:`samples/cellular/nrf_cloud_mqtt_fota` folder.
See :ref:`configure_application` on how to configure the parameters.

To create a FOTA test version of this sample, change the ``PATCHLEVEL`` in the :file:`VERSION` file.

To enable full modem FOTA, add the following parameter to your build command:

``-DEXTRA_CONF_FILE=full_modem_fota.conf``

Also, if you are using an nRF9160 DK, specify your development kit version by appending it to the board name.
For example, if you are using version 1.0.1, use the board name ``nrf9160dk@1.0.1/nrf9160/ns`` in your build command.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

version 1.0.1? There is no such board target https://github.com/zephyrproject-rtos/zephyr/blob/main/boards/nordic/nrf9160dk/board.yml also this is a board target not a board/board name


To enable SMP FOTA (nRF9160 DK only), add the following parameters to your build command:

* ``-DEXTRA_CONF_FILE=smp_fota.conf``
* ``-DEXTRA_DTC_OVERLAY_FILE=nrf9160dk_mcumgr_client_uart2.overlay``
Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent parameter name: should be -DDTC_OVERLAY_FILE (as used in sample.yaml line 53) not -DEXTRA_DTC_OVERLAY_FILE.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the bot is right

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think is correct to select DEXTRA_DTC_OVERLAY_FILE and I would need to change the reference in sample.yaml

Copy link
Contributor

@nordicjm nordicjm Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this bot is trash, the readme is fine, though there should be quotes around the files e.g. -DEXTRA_CONF_FILE="smp_fota.conf" this is a string


Once you have flashed your nRF9160 DK, change the switch **SW10** to the **nRF52** position to be able to flash the nRF52840 firmware on the DK.
The nRF52840 device on your DK must be running firmware compatible with SMP, such as the :ref:`smp_svr` sample.
Otherwise, the MQTT FOTA sample cannot connect to the nRF52840 and will keep trying to connect.
Build the :ref:`smp_svr` sample for the ``nrf9160dk/nrf52840`` board with the following parameters:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*board target


* ``-DEXTRA_CONF_FILE=overlay-serial.conf``
* ``-DEXTRA_DTC_OVERLAY_FILE=nrf9160dk_nrf52840_mcumgr_svr.overlay``
Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent parameter name: should be -DDTC_OVERLAY_FILE not -DEXTRA_DTC_OVERLAY_FILE.

Copilot uses AI. Check for mistakes.

To change :ref:`smp_svr` sample's application version, set the :kconfig:option:`CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION` Kconfig option.

Testing
=======

|test_sample|

#. |connect_kit|
#. |connect_terminal|
#. Reset the development kit.
#. Observe in the terminal window that the application starts.
This is indicated by output similar to the following (there is also a lot of additional information about the LTE connection):

.. code-block:: console

*** Booting My Application v1.0.0-f135319f826e ***
*** Using nRF Connect SDK v3.1.99-f135319f826e ***
*** Using Zephyr OS v4.2.99-be1a9fd0eeca ***
[00:00:00.255,889] <inf> nrf_cloud_mqtt_fota: nRF Cloud MQTT FOTA Sample, version: 1.0.0
[00:00:00.255,920] <inf> nrf_cloud_mqtt_fota: Reset reason: 0x1
[00:00:00.828,735] <inf> nrf_cloud_credentials: Sec Tag: 16842753; CA: Yes, Client Cert: Yes, Private Key: Yes
[00:00:00.828,765] <inf> nrf_cloud_credentials: CA Size: 1824, AWS: Likely, CoAP: Likely
[00:00:00.828,796] <inf> nrf_cloud_mqtt_fota: nRF Cloud credentials detected!
[00:00:00.829,589] <inf> nrf_cloud_mqtt_fota: Enabling connectivity...
+CGEV: EXCE STATUS 0
+CEREG: 2,"81A6","03229B10",7
%MDMEV: PRACH CE-LEVEL 0
+CSCON: 1
+CGEV: ME PDN ACT 0
%MDMEV: SEARCH STATUS 2
+CEREG: 1,"81A6","03229B10",7,,,"11100000","11100000"
[00:00:02.471,496] <inf> nrf_cloud_mqtt_fota: Connected to LTE
+CGEV: IPV6 0
[00:00:05.473,724] <inf> nrf_cloud_info: Device ID: 12345678-1234-5678-9abc-def012345678
[00:00:05.474,395] <inf> nrf_cloud_info: IMEI: 359404230026479
[00:00:05.474,575] <inf> nrf_cloud_info: UUID: 12345678-1234-5678-9abc-def012345678
[00:00:05.474,822] <inf> nrf_cloud_info: Modem FW: mfw_nrf91x1_2.0.3
[00:00:05.474,853] <inf> nrf_cloud_info: Protocol: MQTT
[00:00:05.474,884] <inf> nrf_cloud_info: Download protocol: HTTPS
[00:00:05.474,884] <inf> nrf_cloud_info: Sec tag: 16842753
[00:00:05.474,914] <inf> nrf_cloud_info: Host name: mqtt.nrfcloud.com
[00:00:05.474,945] <inf> nrf_cloud_mqtt_fota: Connecting to nRF Cloud...
[00:00:08.681,701] <inf> nrf_cloud_mqtt_fota: Connection to nRF Cloud ready
[00:00:08.681,793] <inf> nrf_cloud_info: Team ID: 12345678-1234-5678-9abc-def012345670

Dependencies
************

This sample uses the following |NCS| libraries:

* :ref:`lib_nrf_cloud`
* :ref:`lte_lc_readme`
* :ref:`dk_buttons_and_leds_readme`
* :ref:`modem_info_readme`
* :ref:`lib_at_host`

In addition, it uses the following secure firmware component:

* :ref:`Trusted Firmware-M <ug_tfm>`
5 changes: 5 additions & 0 deletions samples/cellular/nrf_cloud_mqtt_fota/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
VERSION_MAJOR = 1
VERSION_MINOR = 0
PATCHLEVEL = 0
VERSION_TWEAK = 0
EXTRAVERSION =
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

/ {
chosen {
nordic,pm-ext-flash = &gd25wb256;
};
};

/* External flash device is disabled by default */
&gd25wb256 {
status = "okay";
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

/ {
chosen {
nordic,pm-ext-flash = &mx25r64;
};
};

/* External flash device is disabled by default */
&mx25r64 {
status = "okay";
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

/ {
chosen {
nordic,pm-ext-flash = &gd25wb256;
};
};

/* External flash device is disabled by default */
&gd25wb256 {
status = "okay";
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

/delete-node/ &gd25wb256;

/ {
chosen {
nordic,pm-ext-flash = &gd25lb256;
};
};

&gd25lb256 {
status = "okay";
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#
# Copyright (c) 2025 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# Configuration file for Thingy:91 X.
# This file is merged with prj.conf in the application folder, and options
# set here will take precedence if they are present in both files.

# Enable external flash
CONFIG_SPI_NOR_SFDP_DEVICETREE=y
CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y
CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

/ {
aliases {
ext-flash = &flash_ext;
};
};
20 changes: 20 additions & 0 deletions samples/cellular/nrf_cloud_mqtt_fota/full_modem_fota.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# Copyright (c) 2025 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# Full Modem FOTA
CONFIG_NRF_CLOUD_FOTA_FULL_MODEM_UPDATE=y
CONFIG_SPI=y
CONFIG_SPI_NOR=y
CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y

# FMFU requires additional heap space.
# If the heap is too small, a boot loop can occur when the full modem image is installed.
CONFIG_HEAP_MEM_POOL_SIZE=47250

CONFIG_IMG_ERASE_PROGRESSIVELY=n
CONFIG_SPI_NOR_SFDP_MINIMAL=n
CONFIG_SPI_NOR_SFDP_DEVICETREE=y
Loading
Loading