Skip to content

Commit

Permalink
nrf_modem: version 1.0.0
Browse files Browse the repository at this point in the history
- Add support for full modem firmware updates
- Add support for configuring the size and location of the shared
  memory area, to let application tailor resource usage
- Switched to an external memory allocator, implemented in the glue
- Add a macro to retrieve the library version
- Add a function to retrieve the library build version
- Return POSIX error codes in `nrf_getaddrinfo()`
- Fixed a bug where `nrf_poll()` would incorrectly report `NRF_POLLERR`
- Fixed a bug where `nrf_getsockopt()` called with `NRF_SO_PDN_STATE`
  would incorrectly set errno
- Fixed a bug where disabling trace output could crash the modem

Signed-off-by: Emanuele Di Santo <[email protected]>
Signed-off-by: Uma Praseeda <[email protected]>
  • Loading branch information
lemrey authored and rlubos committed Feb 11, 2021
1 parent ac06d53 commit a21b5e2
Show file tree
Hide file tree
Showing 19 changed files with 4,478 additions and 745 deletions.
2 changes: 1 addition & 1 deletion nrf_modem/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
#

if(CONFIG_NRF_MODEM_LINK_WITH_BINARY)
if(CONFIG_NRF_MODEM_LINK_BINARY)

nrfxlib_calculate_lib_path(lib_path)

Expand Down
8 changes: 7 additions & 1 deletion nrf_modem/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ choice NRF_MODEM_BUILD_STRATEGY
depends on NRF_MODEM
prompt "Modem library build strategy"

config NRF_MODEM_LINK_WITH_BINARY
config NRF_MODEM_LINK_BINARY
bool "Link binary"

endchoice

# This configuration is auto-generated.
# Do not edit.
config NRF_MODEM_SHMEM_CTRL_SIZE
hex
default 0x4e8 # import
1 change: 1 addition & 0 deletions nrf_modem/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ For more information, see :ref:`nrf_modem_ug_porting`.
doc/tls_dtls_configuration
doc/extensions
doc/ug_nrf_modem_porting_os
doc/full-dfu
doc/CHANGELOG
doc/api
15 changes: 14 additions & 1 deletion nrf_modem/doc/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ Changelog

All notable changes to this project are documented in this file.

nrf_modem 1.0.0
***************

* Added support for full modem firmware updates.
* Added support for configuring the size and location of the shared memory area.
* Switched to an external memory allocator that is provided by the glue.
* Added a macro to retrieve the library version.
* Added a function to retrieve the library build version.
* Updated to return POSIX error codes in :c:func:`nrf_getaddrinfo`.
* Fixed an issue where :c:func:`nrf_poll` would incorrectly report ``NRF_POLLERR``.
* Fixed an issue where :c:func:`nrf_getsockopt` called with ``NRF_SO_PDN_STATE`` would incorrectly set errno.
* Fixed an issue where disabling the trace output causes the modem to crash in some situations.

nrf_modem 0.8.99
****************

Expand Down Expand Up @@ -141,7 +154,7 @@ bsdlib 0.6.0
bsdlib 0.5.1
************

* Fixed internal memory issue in GNSS which lead to crash when running for hours.
* Fixed internal memory issue in GNSS, which lead to crash when running for hours.

bsdlib 0.5.0
************
Expand Down
4 changes: 0 additions & 4 deletions nrf_modem/doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ Resources for the Modem library
:project: nrfxlib
:members:

.. doxygengroup:: nrf_modem_reserved_memory
:project: nrfxlib
:members:

.. doxygengroup:: nrf_modem_reserved_interrupts
:project: nrfxlib
:members:
Expand Down
83 changes: 74 additions & 9 deletions nrf_modem/doc/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,84 @@
Library architecture
####################

The purpose of the Modem library is to communicate with the nRF9160 modem firmware.
This is done by sending events and getting responses over the Inter Processor Communication (IPC) peripheral.
To facilitate data transfer between the application and the modem, payload data is set in the shared RAM.
The Modem library is the application interface to the nRF9160 modem firmware, which contains a full IP and DTLS/TLS stack as well as GNSS.
It provides the standard Socket APIs, to facilitate application development and additional APIs to manage the modem and perform full-modem firmware updates.

The modem contains a full IP and DTLS/TLS stack as well as GNSS.
The library internally communicates over a Remote Procedure Call (RPC) protocol using the IPC and the shared RAM to utilize the protocol stacks inside the modem.
You can dispatch data to and from the different modules in the modem firmware by providing the right combinations of address families, types, and protocols to the Modem library.
The library implements a communication interface between the Application and Modem cores on the nRF9160 via the RPC protocol, using the Inter Processor Communication (IPC) peripheral and a shared region of RAM.

The Modem library aims to provide a standard programming interface on top of the RPC protocol, to facilitate application development.

The following figure shows a simplified Modem library architecture.
The following figure shows a simplified Modem library architecture:

.. figure:: images/nrf_modem_architecture.svg
:alt: Modem library architecture diagram

Modem library architecture diagram

Shared memory configuration
***************************

The Modem library implements a communication interface between the application core and the modem core by using a shared memory area to exchange data.
The shared memory area can be located anywhere within the first 128 kilobytes of RAM (lowest addresses) and it is logically divided into the following four regions:

* Control
* TX
* RX
* Trace

The application can configure the size and location of these regions.
The application is responsible for reserving the memory area by setting the values of these parameters before passing them onto the library.
The library accepts these values as parameters to the :c:func:`nrf_modem_init` function via :c:enum:`nrf_modem_shmem_cfg`.

.. note::
The size of the Control area is fixed.

The application can adjust the size of these regions based on the needs to minimize the RAM requirements of the library.


For |NCS| users, the Partition Manager will automatically reserve some RAM for each region during linking, according to the size of each region as specified in the glue.

Control area
============

The control area contains the data structures that are used to setup the communication between the modem core and the application core.
Among the sizes of the memory regions, only the size of the control area is fixed, and it is exported in the :file:`nrf_modem_platform.h` file.

For |NCS| users, the build system and the glue implementation will automatically take care of passing the correct size to the :c:func:`nrf_modem_init` call.

TX area
=======

The TX area contains the data payload of messages that are sent to the modem.
The size of this area affects the largest buffer that :c:func:`nrf_send` can send in a single call, and the size of the longest AT command that can be sent to the modem.
When provisioning the TLS certificates, the size of the TX area must be large enough to accommodate the TLS certificate and the AT command that is used for provisioning.
The library OS abstraction layer defines the following functions to allocate and free data in this memory region:

* :c:func:`nrf_modem_os_shm_tx_alloc`
* :c:func:`nrf_modem_os_shm_tx_free`

RX area
=======

The RX area is entirely managed by the modem and this area contains all the incoming data from the modem.
The incoming data includes GNSS data, AT command responses, and IP traffic.
The size of this area determines the maximum amount of incoming data from the modem that the application core can buffer.
If the area is full and the application has not read the data yet, new data cannot be buffered in this area.

An example of an operation that requires a large RX area is the reading of a TLS certificate associated with a security tag.
The size of the RX area must be as large as the size of the TLS certificate that is being read, and the AT command that is used to read the certificate.

Trace area
==========

The trace area contains the trace output from the modem core.
This area of memory is optional, and the area size can be configured to be zero, to disable the trace output.

Library heap
************

The Modem library needs to dynamically allocate memory (a heap) for proper functioning.
This memory is used to store the internal data structures that are used to manage the communication between the application core and the modem core.
This memory is never shared with the modem core and hence, it can be located anywhere in the application core's RAM instead of the shared memory regions.
The library OS abstraction layer defines the following functions to allocate and free up dynamic memory for the library:

* :c:func:`nrf_modem_os_alloc`
* :c:func:`nrf_modem_os_free`
140 changes: 140 additions & 0 deletions nrf_modem/doc/full-dfu.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
.. _full_dfu:

Full-modem firmware update
##########################

The modem library supports the full update of the modem firmware when the library is initialized in full DFU mode via the :file:`nrf_modem_full_dfu.h` interface.
Full-modem firmware update is the only operation that can be performed in full DFU mode.
The sockets are not available to the application.

It is possible to switch between the full-DFU and normal operation modes by reinitializing the library.

Memory requirements
*******************

The total size of all the shared memory regions must be at least 8220 bytes.
This is because programming requires 8 kB data buffer and some storage for structures used in RPC communication.

.. note::

When using |NCS|, the library is initialized via the glue, which will configure the size and position of the shared memory regions in RAM.
Use the Kconfig options belonging to the glue to ensure that the total size of the shared memory region is sufficiently large.

Modem library initialization
============================

To perform a full-modem firmware update, the library must be initialized in ``FULL_DFU`` mode as shown in the following code:

.. code-block:: c
/* Shutdown modem to prepare for DFU */
nrf_modem_init(init_params, FULL_DFU_MODE);
If the library has already been initialized in ``NORMAL_MODE`` mode, it must be shut down via the :c:func:`nrf_modem_shutdown` function and reinitialized as shown in the following code:

.. code-block:: c
nrf_modem_init(init_params, NORMAL_MODE);
/* Shutdown modem to prepare for DFU */
nrf_modem_shutdown();
nrf_modem_init(init_params, FULL_DFU_MODE);
Considerations for corrupted modem firmware
===========================================

When designing your application, you might have to consider an interrupted DFU process, which can lead to corrupted modem firmware.
There can be various reasons (for example, power outage) that can cause an interruption in a firmware update.
The modem does not have a back-up ROM and hence, an interruption in DFU can prevent the modem from further boot up.

As a workaround to the above scenario, either the application must tolerate the situation or another means of recovery must be provided (for example, reprogramming the modem with PC tools).

You must then initialize the modem library manually by using the following code:

.. code-block:: c
int main(void)
{
int rc = nrf_modem_init(init_params, NORMAL_MODE);
if (rc < 0) {
/* Recover the modem firmware from external flash */
nrf_modem_init(init_params, FULL_DFU_MODE);
/* Perform FULL modem firmware update. */
nrf_modem_shutdown();
nrf_modem_init(init_params, NORMAL_MODE);
}
/* Modem firmware updated, continue as normal */
}
Full DFU API
************

A full-modem firmware upgrade consists of the following steps:

1. Initialization
#. Programming the bootloader
#. Programming the modem firmware
#. Verification

Bootloader forms the first segment of the firmware package and it must be programmed initially.
If any failures happen, the sequence of steps must be restarted from the initialization phase.

Initialization
==============

To initialize the full modem firmware update process, call the following function:

.. code-block:: c
int nrf_modem_full_dfu_init(struct nrf_modem_full_dfu_digest *digest_buffer);
Programming the bootloader
==========================

To program a bootloader, call the following function:

.. code-block:: c
int nrf_modem_full_dfu_bl_write(uint32_t len, void *src)
The bootloader may be written in smaller chunks, which are internally appended together by the library.
When all pieces are written, call the following function:

.. code-block:: c
int nrf_modem_full_dfu_apply(void)
After a successful call, the modem changes to the DFU mode.
At this stage, you may write firmware segments or issue any other DFU commands like ``verify``.

Programming the modem firmware
==============================

Firmware segments are written by using the following function call:

.. code-block:: c
int nrf_modem_full_dfu_fw_write(uint32_t addr, uint32_t len, void *src)
The modem library buffers the data with the same destination address, until one of the following conditions occur:
* The buffered data reaches 8kb.
* The destination address changes.
At this point, the buffer is written to the flash.
When all the segments are written, you must call the following function:

.. code-block:: c
int nrf_modem_full_dfu_apply(void)
Verification
============

To verify the content of the modem flash, use the following function:

.. code-block:: c
nrf_modem_full_dfu_digest(uint32_t addr, uint32_t size, struct nrf_modem_full_dfu_digest *digest_buffer);
This function calculates SHA-256 hash over the given flash area.
Compare the hash to the precalculated value that comes with the modem firmware package, to ensure that the image is programmed successfully.
Loading

0 comments on commit a21b5e2

Please sign in to comment.