Skip to content

Commit 45230d7

Browse files
maxd-nordicnordicjm
authored andcommitted
samples: cellular: add nrf_cloud_coap_fota sample
This sample demonstrates how to use the nRF Cloud CoAP API to do over-the-air firmware (FOTA) updates. Signed-off-by: Maximilian Deubel <[email protected]>
1 parent 4c4ea89 commit 45230d7

21 files changed

+1276
-1
lines changed

doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,10 @@ Bluetooth Fast Pair samples
264264
Cellular samples
265265
----------------
266266

267-
* Added the :ref:`nrf_cloud_coap_cell_location` sample to demonstrate how to use the `nRF Cloud CoAP API`_ for nRF Cloud's cellular location service.
267+
* Added:
268+
269+
* The :ref:`nrf_cloud_coap_cell_location` sample to demonstrate how to use the `nRF Cloud CoAP API`_ for nRF Cloud's cellular location service.
270+
* The :ref:`nrf_cloud_coap_fota_sample` sample to demonstrate how to use the `nRF Cloud CoAP API`_ for FOTA updates.
268271

269272
* :ref:`nrf_cloud_rest_cell_location` sample:
270273

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
cmake_minimum_required(VERSION 3.20.0)
8+
9+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
10+
project(nrf_cloud_fota_sample)
11+
12+
# NORDIC SDK APP START
13+
target_sources(app PRIVATE src/main.c)
14+
15+
if(CONFIG_NRF_CLOUD_FOTA_SMP AND CONFIG_BOARD_NRF9160DK_NRF9160_NS)
16+
target_sources(app PRIVATE src/smp_reset.c)
17+
endif()
18+
# NORDIC SDK APP END
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
menu "nRF Cloud CoAP FOTA Sample"
8+
9+
config COAP_FOTA_JOB_CHECK_RATE_MIN
10+
int "Rate (minutes) at which this sample will check for FOTA updates"
11+
range 1 10080
12+
default 15
13+
14+
config COAP_FOTA_LTE_LED_NUM
15+
int "LED number to use for LTE connection status"
16+
default 0
17+
18+
config COAP_FOTA_BUTTON_EVT_NUM
19+
int "Button number to use for device interactions"
20+
default 1
21+
22+
module = NRF_CLOUD_COAP_FOTA_SAMPLE
23+
module-str = nRF Cloud CoAP FOTA Sample
24+
source "${ZEPHYR_BASE}/subsys/logging/Kconfig.template.log_config"
25+
26+
endmenu
27+
menu "Zephyr Kernel"
28+
source "Kconfig.zephyr"
29+
endmenu
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
.. _nrf_cloud_coap_fota_sample:
2+
3+
Cellular: nRF Cloud CoAP FOTA
4+
#############################
5+
6+
.. contents::
7+
:local:
8+
:depth: 2
9+
10+
The nRF Cloud CoAP FOTA sample demonstrates how to use the `nRF Cloud CoAP API`_ to perform Firmware Over-the-Air (FOTA) updates over CoAP on your device.
11+
This covers modem, application, and full modem FOTA updates (FMFU).
12+
Also, with the nRF9160 DK, it supports SMP FOTA updates to the firmware on the nRF52840 SoC.
13+
14+
Requirements
15+
************
16+
17+
The sample supports the following development kits:
18+
19+
.. table-from-sample-yaml::
20+
21+
.. include:: /includes/tfm.txt
22+
23+
The sample requires an `nRF Cloud`_ account.
24+
25+
Your device must be onboarded to nRF Cloud.
26+
If it is not, follow the instructions in `Device on-boarding <nrf_cloud_coap_fota_sample_onboarding_>`_.
27+
28+
.. note::
29+
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.
30+
31+
.. include:: /includes/external_flash_nrf91.txt
32+
33+
.. note::
34+
Full modem FOTA requires development kit version 0.14.0 or higher if you are using an nRF9160 DK.
35+
36+
Overview
37+
********
38+
39+
You can update your device firmware on the `nRF Cloud`_ portal or directly through the `nRF Cloud CoAP API`_.
40+
See the `nRF Cloud Getting Started FOTA documentation`_ for details.
41+
42+
Limitations
43+
***********
44+
45+
This sample requires the network carrier to provide date and time to the modem.
46+
Without a valid date and time, the modem cannot generate JSON Web Tokens (JWT) with an expiration time.
47+
48+
User interface
49+
**************
50+
51+
Button 1:
52+
Check for a FOTA update right away without waiting for the timeout.
53+
54+
.. _nrf_cloud_coap_fota_sample_onboarding:
55+
56+
Setup
57+
=====
58+
59+
You must onboard your device to nRF Cloud for this sample to function.
60+
You only need to do this once for each device.
61+
62+
To onboard your device, install `nRF Cloud Utils`_ and follow the instructions in the README.
63+
64+
Configuration
65+
*************
66+
|config|
67+
68+
Configuration options
69+
=====================
70+
71+
Check and configure the following configuration options for the sample:
72+
73+
.. _CONFIG_COAP_FOTA_JOB_CHECK_RATE_MIN:
74+
75+
CONFIG_COAP_FOTA_JOB_CHECK_RATE_MIN - Update check rate
76+
Defines how often the sample checks for FOTA updates.
77+
You can modify this value at runtime by adding or updating the ``"fotaInterval"`` item in the desired config section of the device's shadow.
78+
Use the `nRF Cloud`_ portal or the REST API to perform the config update.
79+
80+
.. _CONFIG_COAP_FOTA_LTE_LED_NUM:
81+
82+
CONFIG_COAP_FOTA_LTE_LED_NUM - LTE LED number
83+
Defines the LED used to indicate the connection to the LTE network.
84+
85+
.. _CONFIG_COAP_FOTA_BUTTON_EVT_NUM:
86+
87+
CONFIG_COAP_FOTA_BUTTON_EVT_NUM - Button number
88+
Defines the button to use for a manual FOTA update check.
89+
90+
.. include:: /libraries/modem/nrf_modem_lib/nrf_modem_lib_trace.rst
91+
:start-after: modem_lib_sending_traces_UART_start
92+
:end-before: modem_lib_sending_traces_UART_end
93+
94+
Building and running
95+
********************
96+
97+
.. |sample path| replace:: :file:`samples/cellular/nrf_cloud_coap_fota`
98+
99+
.. include:: /includes/build_and_run_ns.txt
100+
101+
The configuration files for this sample are located in the :file:`samples/cellular/nrf_cloud_coap_fota` folder.
102+
See :ref:`configure_application` on how to configure the parameters.
103+
104+
To create a FOTA test version of this sample, add the following parameter to your build command:
105+
106+
``-DEXTRA_CONF_FILE=overlay_fota_test.conf``
107+
108+
To enable full modem FOTA, add the following parameter to your build command:
109+
110+
``-DEXTRA_CONF_FILE=overlay_full_modem_fota.conf``
111+
112+
Also, if you are using an nRF9160 DK, specify your development kit version by appending it to the board name.
113+
For example, if you are using version 1.0.1, use the board name ``[email protected]/nrf9160/ns`` in your build command.
114+
115+
To enable SMP FOTA (nRF9160 DK only), add the following parameters to your build command:
116+
117+
* ``-DEXTRA_CONF_FILE=overlay_smp_fota.conf``
118+
* ``-DEXTRA_DTC_OVERLAY_FILE=nrf9160dk_mcumgr_client_uart2.overlay``
119+
120+
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.
121+
The nRF52840 device on your DK must be running firmware compatible with SMP, such as the :ref:`smp_svr` sample.
122+
Otherwise, the CoAP FOTA sample cannot connect to the nRF52840 and will keep trying to connect.
123+
Build the :ref:`smp_svr` sample for the ``nrf9160dk/nrf52840`` board with the following parameters:
124+
125+
* ``-DEXTRA_CONF_FILE=overlay-serial.conf``
126+
* ``-DEXTRA_DTC_OVERLAY_FILE=nrf9160dk_nrf52840_mcumgr_svr.overlay``
127+
128+
To change :ref:`smp_svr` sample's application version, set the :kconfig:option:`CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION` Kconfig option.
129+
130+
Testing
131+
=======
132+
133+
|test_sample|
134+
135+
#. |connect_kit|
136+
#. |connect_terminal|
137+
#. Reset the development kit.
138+
#. Observe in the terminal window that the application starts.
139+
This is indicated by output similar to the following (there is also a lot of additional information about the LTE connection):
140+
141+
.. code-block:: console
142+
143+
*** Booting nRF Connect SDK v3.1.99-7ff1f906b7b0 ***
144+
*** Using Zephyr OS v4.1.99-2cc69ef97a5c ***
145+
Attempting to boot slot 0.
146+
Attempting to boot from address 0x8200.
147+
I: Trying to get Firmware version
148+
I: Verifying signature against key 0.
149+
I: Hash: 0x3e...f9
150+
I: Firmware signature verified.
151+
Firmware version 2
152+
I: Setting monotonic counter (version: 2, slot: 0)
153+
�[00:00:00.254,821] <inf> spi_nor: GD25LE255E@0: 32 MiBy flash
154+
*** Booting My Application v1.0.0-7ff1f906b7b0 ***
155+
*** Using nRF Connect SDK v3.1.99-7ff1f906b7b0 ***
156+
*** Using Zephyr OS v4.1.99-2cc69ef97a5c ***
157+
[00:00:00.311,981] <inf> nrf_cloud_fota_sample: nRF Cloud FOTA Sample, version: 1.0.0
158+
[00:00:00.689,270] <inf> nrf_cloud_fota_common: Saved job: , type: 7, validate: 0, bl: 0x0
159+
[00:0:00.699,066] <inf> nrf_cloud_fota_sample: Application Name: N/A
160+
[00:00:00.705,902] <inf> nrf_cloud_fota_sample: nRF Connect SDK version: 3.1.99-7ff1f906b7b0
161+
[00:00:00.912,902] <inf> nrf_cloud_credentials: Sec Tag: 16842753; CA: Yes, Client Cert: Yes, Private Key: Yes
162+
[00:00:00.923,309] <inf> nrf_cloud_credentials: CA Size: 1824, AWS: Likely, CoAP: Likely
163+
[00:00:00.931,854] <inf> nrf_cloud_fota_sample: nRF Cloud credentials detected!
164+
[00:00:00.939,605] <inf> nrf_cloud_fota_sample: Enabling connectivity...
165+
+CGEV: EXCE STATUS 0
166+
+CEREG: 2,"0901","020A7716",7
167+
%MDMEV: PRACH CE-LEVEL 0
168+
+CSCON: 1
169+
+CGEV: ME PDN ACT 0,0
170+
+CNEC_ESM: 50,0
171+
%MDMEV: SEARCH STATUS 2
172+
+CEREG: 5,"0901","020A7716",7,,,"11100000","11100000"
173+
[00:00:05.376,922] <inf> nrf_cloud_fota_sample: Connected to LTE
174+
[00:00:05.415,954] <inf> nrf_cloud_fota_sample: Waiting for modem to acquire network time...
175+
[00:00:08.425,659] <inf> nrf_cloud_fota_sample: Network time obtained
176+
[00:00:08.432,525] <inf> nrf_cloud_info: Device ID: 7e699894-79b6-11f0-a2b4-db93a314a2aa
177+
[00:00:08.447,601] <inf> nrf_cloud_info: IMEI: 359400123456789
178+
[00:00:08.545,837] <inf> nrf_cloud_info: UUID: 7e699894-79b6-11f0-a2b4-db93a314a2aa
179+
[00:00:08.560,821] <inf> nrf_cloud_info: Modem FW: mfw_nrf91x1_2.0.2
180+
[00:00:08.567,657] <inf> nrf_cloud_info: Protocol: CoAP
181+
[00:00:08.574,096] <inf> nrf_cloud_info: Download protocol: CoAP
182+
[00:00:08.580,535] <inf> nrf_cloud_info: Sec tag: 16842753
183+
[00:00:08.587,341] <inf> nrf_cloud_info: CoAP JWT Sec tag: 16842753
184+
[00:00:08.594,146] <inf> nrf_cloud_info: Host name: coap.nrfcloud.com
185+
[00:00:10.981,414] <inf> nrf_cloud_coap_transport: Request authorization with JWT
186+
[00:00:11.336,212] <inf> nrf_cloud_coap_transport: Authorization result_code: 2.01
187+
[00:00:11.344,299] <inf> nrf_cloud_coap_transport: Authorized
188+
[00:00:11.350,616] <inf> nrf_cloud_coap_transport: DTLS CID is active
189+
[00:00:12.139,984] <inf> nrf_cloud_fota_sample: Sending device status...
190+
[00:00:12.565,460] <inf> nrf_cloud_fota_sample: FOTA enabled in device shadow
191+
[00:00:12.572,998] <inf> nrf_cloud_fota_poll: Checking for FOTA job...
192+
[00:00:13.205,413] <inf> nrf_cloud_fota_poll: No pending FOTA job
193+
[00:00:13.211,975] <inf> nrf_cloud_fota_sample: Checking for shadow delta...
194+
[00:00:13.554,901] <inf> nrf_cloud_log: Changing cloud log level from:1 to:3
195+
[00:00:13.562,347] <inf> nrf_cloud_log: Changing cloud logging enabled to:1
196+
[00:00:14.165,435] <inf> nrf_cloud_fota_sample: Desired interval: 5.000000
197+
[00:00:14.541,442] <inf> nrf_cloud_fota_sample: Updated shadow delta sent
198+
[00:00:14.548,645] <inf> nrf_cloud_fota_sample: Checking for FOTA job in 5 minute(s) or when button 1 is pressed
199+
200+
Dependencies
201+
************
202+
203+
This sample uses the following |NCS| libraries:
204+
205+
* :ref:`lib_nrf_cloud`
206+
* :ref:`lib_nrf_cloud_coap`
207+
* :ref:`lib_modem_jwt`
208+
* :ref:`lte_lc_readme`
209+
* :ref:`dk_buttons_and_leds_readme`
210+
* :ref:`modem_info_readme`
211+
* :ref:`lib_at_host`
212+
213+
In addition, it uses the following secure firmware component:
214+
215+
* :ref:`Trusted Firmware-M <ug_tfm>`
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
VERSION_MAJOR = 1
2+
VERSION_MINOR = 0
3+
PATCHLEVEL = 0
4+
VERSION_TWEAK = 0
5+
EXTRAVERSION =
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
/ {
8+
chosen {
9+
nordic,pm-ext-flash = &gd25wb256;
10+
};
11+
};
12+
13+
/* External flash device is disabled by default */
14+
&gd25wb256 {
15+
status = "okay";
16+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
/ {
8+
chosen {
9+
nordic,pm-ext-flash = &mx25r64;
10+
};
11+
};
12+
13+
/* External flash device is disabled by default */
14+
&mx25r64 {
15+
status = "okay";
16+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
/ {
8+
chosen {
9+
nordic,pm-ext-flash = &gd25wb256;
10+
};
11+
};
12+
13+
/* External flash device is disabled by default */
14+
&gd25wb256 {
15+
status = "okay";
16+
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
/delete-node/ &gd25wb256;
8+
9+
/ {
10+
chosen {
11+
nordic,pm-ext-flash = &gd25lb256;
12+
};
13+
};
14+
15+
&gd25lb256 {
16+
status = "okay";
17+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
# Configuration file for Thingy:91 X.
8+
# This file is merged with prj.conf in the application folder, and options
9+
# set here will take precedence if they are present in both files.
10+
11+
# Enable external flash
12+
CONFIG_SPI_NOR_SFDP_DEVICETREE=y
13+
CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y
14+
CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y

0 commit comments

Comments
 (0)