From 8b7c3158d570bdb92b47e0ceeb5e6fee4aa5ae8e Mon Sep 17 00:00:00 2001 From: Rubin Gerritsen Date: Thu, 22 Aug 2024 16:10:01 +0200 Subject: [PATCH 01/72] doc: Move Bluetooth Controller docs to Stack architecture docs The Controller is just a part of the entire Bluetooth stack, so it makes more sense to make it part of the Bluetooth stack architecture page. This page already included some parts about Bluetooth Controller. These two documentation sections are now merged. Signed-off-by: Rubin Gerritsen --- doc/nrf/protocols/bt/ble/index.rst | 67 -------------------------- doc/nrf/protocols/bt/bt_stack_arch.rst | 57 ++++++++++++++++++++-- doc/nrf/protocols/bt/index.rst | 7 +-- 3 files changed, 58 insertions(+), 73 deletions(-) delete mode 100644 doc/nrf/protocols/bt/ble/index.rst diff --git a/doc/nrf/protocols/bt/ble/index.rst b/doc/nrf/protocols/bt/ble/index.rst deleted file mode 100644 index a3936eb9135c..000000000000 --- a/doc/nrf/protocols/bt/ble/index.rst +++ /dev/null @@ -1,67 +0,0 @@ -.. _ug_ble_controller: - -Bluetooth LE Controller -####################### - -.. contents:: - :local: - :depth: 2 - -When you develop a Bluetooth® Low Energy (LE) application, you must include a Bluetooth® LE Controller. -A Bluetooth LE Controller is the layer of the Bluetooth stack that handles the physical layer packets and all associated timing. -It implements the Link Layer, which is the low-level, real-time protocol that controls the Bluetooth LE communication. - -The |NCS| contains two implementations of a Bluetooth LE Controller: - -* `SoftDevice Controller`_ -* `Zephyr Bluetooth LE Controller`_ - -The SoftDevice Controller is implemented by Nordic Semiconductor. -The Zephyr Bluetooth LE Controller is an open source Link Layer developed in `Zephyr`_, to which Nordic Semiconductor is a contributor. - -Both Link Layers integrate with the Zephyr Bluetooth Host, which completes the full Bluetooth LE protocol stack solution in the |NCS|. -It is possible to select either Bluetooth LE Controller for application development. -See `Usage in samples`_ for more information. - -If you want to go through an online training course to familiarize yourself with Bluetooth Low Energy and the development of Bluetooth LE applications, enroll in the `Bluetooth LE Fundamentals course`_ in the `Nordic Developer Academy`_. - -.. _ug_ble_controller_softdevice: - -SoftDevice Controller -********************* - -The :ref:`SoftDevice Controller ` provides the same implementation of the Link Layer that is available as part of Nordic Semiconductor's SoftDevices. -The SoftDevice Controller is developed, tested, and supported by Nordic Semiconductor. - -The SoftDevice Controller is distributed as a set of precompiled, linkable libraries that can be found in the `sdk-nrfxlib`_ repository. -There are different variants of the libraries that support different feature sets. -Which variant you should choose depends on the chip that you are using, the features that you need, and the amount of available memory. - -Nordic's SoftDevice Controller supports an extensive standard feature set from the Bluetooth® specification and a number of extensions for high-performance applications like Low Latency Packet mode (LLPM). -See the :ref:`SoftDevice Controller documentation ` for a detailed list of supported features. - - -Zephyr Bluetooth LE Controller -****************************** - -`Zephyr`_ has a full, open source, :ref:`Bluetooth Low Energy stack `, which includes the Zephyr Bluetooth LE Controller. -This Bluetooth LE Controller is designed with an upper and lower implementation to make it possible to support multiple hardware platforms. -It is developed by the Zephyr community and provided as open source. - -To use Zephyr's Bluetooth LE Controller in your application, include a :ref:`Controller-only build ` of the Bluetooth LE stack. - -Zephyr's Bluetooth LE Controller supports most of the standard Bluetooth LE features. -See the :ref:`Zephyr documentation ` for a detailed list of supported features. - - -Usage in samples -**************** - -Most :ref:`Bluetooth LE samples ` in the |NCS|, including the :ref:`bt_mesh_samples`, can use either Bluetooth LE Controller. -Exceptions are the :ref:`ble_llpm` sample, which requires the SoftDevice Controller that supports LLPM, and the :ref:`nrf53_audio_app`, which require the SoftDevice Controller that supports :ref:`LE Isochronous Channels `. - -By default, all samples are currently configured to use SoftDevice Controller. -To use the Zephyr Bluetooth LE Controller instead, set :kconfig:option:`CONFIG_BT_LL_SW_SPLIT` to ``y`` in the :file:`prj.conf` file (see :ref:`configure_application`) and make sure to build from a clean build directory. - -.. note:: - If your Bluetooth application requires the LE Secure Connections pairing and you want to use the Zephyr Bluetooth LE Controller, make sure to enable the :kconfig:option:`CONFIG_BT_TINYCRYPT_ECC` option as the ECDH cryptography is not supported by this Bluetooth LE Controller. diff --git a/doc/nrf/protocols/bt/bt_stack_arch.rst b/doc/nrf/protocols/bt/bt_stack_arch.rst index 0891e5a0aecf..a733284c4187 100644 --- a/doc/nrf/protocols/bt/bt_stack_arch.rst +++ b/doc/nrf/protocols/bt/bt_stack_arch.rst @@ -1,6 +1,10 @@ Blutooth stack architecture ########################### +.. contents:: + :local: + :depth: 2 + The Bluetooth protocol has a layered architecture, and the |NCS| Bluetooth implementation combines components from the Zephyr Project and components developed by Nordic Semiconductor. This section briefly describes the main components and provides links to pages with additional information. @@ -26,13 +30,21 @@ Key features required for Bluetooth Direction Finding support are also part of t Feature support for PHY features depend on specific SoCs. Please refer to the Bluetooth feature support table on the :ref:`software_maturity` page. +.. _ug_ble_controller: + Controller ********** -The :ref:`nrfxlib:softdevice_controller` is the supported Bluetooth controller in the |NCS|. -Application examples in the SDK use the SoftDevice Controller as the default controller, and it is the controller used for release testing of the SDK. +A Bluetooth LE Controller is the layer of the Bluetooth stack that handles the physical layer packets and all associated timing. +It implements the Link Layer, which is the low-level, real-time protocol that controls the Bluetooth LE communication. + +The |NCS| contains two implementations of a Bluetooth LE Controller: -The Bluetooth support includes: +* `SoftDevice Controller`_ +* `Zephyr Bluetooth LE Controller`_ + +The :ref:`nrfxlib:softdevice_controller` is the default and supported Bluetooth controller in the |NCS|. +For this controller the support includes: * Implementation of new Bluetooth LE controller features. * Valid qualification (QDID) for each SDK release. @@ -41,6 +53,45 @@ The Zephyr Project has a community support :ref:`ug_ble_controller`. This Bluetooth controller will be the default when using Zephyr RTOS stand-alone. It is possible to configure projects in the |NCS| to use the Zephyr Controller, but Nordic Semiconductor does not support this configuration for production. +.. _ug_ble_controller_softdevice: + +SoftDevice Controller +===================== + +The :ref:`SoftDevice Controller ` is developed from the same code base as Nordic Semiconductor's SoftDevices. +The SoftDevice Controller is developed, tested, and supported by Nordic Semiconductor. + +The SoftDevice Controller is distributed as a set of precompiled, linkable libraries that can be found in the `sdk-nrfxlib`_ repository. +There are different variants of the libraries that support different feature sets. +Which variant you should choose depends on the chip that you are using, the features that you need, and the amount of available memory. + +Nordic's SoftDevice Controller supports an extensive standard feature set from the Bluetooth® specification and a number of extensions for high-performance applications like Low Latency Packet mode (LLPM). +See the :ref:`SoftDevice Controller documentation ` for a detailed list of supported features. + +Zephyr Bluetooth LE Controller +============================== + +`Zephyr`_ has a full, open source, :ref:`Bluetooth Low Energy stack `, which includes the Zephyr Bluetooth LE Controller. +This Bluetooth LE Controller is designed with an upper and lower implementation to make it possible to support multiple hardware platforms. +It is developed by the Zephyr community and provided as open source. + +To use Zephyr's Bluetooth LE Controller in your application, include a :ref:`Controller-only build ` of the Bluetooth LE stack. + +Zephyr's Bluetooth LE Controller supports most of the standard Bluetooth LE features. +See the :ref:`Zephyr documentation ` for a detailed list of supported features. + +Usage in samples +================ + +Most :ref:`Bluetooth LE samples ` in the |NCS|, including the :ref:`bt_mesh_samples`, can use either Bluetooth LE Controller. +Exceptions are the :ref:`ble_llpm` sample, which requires the SoftDevice Controller that supports LLPM, and the :ref:`nrf53_audio_app`, which require the SoftDevice Controller that supports :ref:`LE Isochronous Channels `. + +By default, all samples are currently configured to use SoftDevice Controller. +To use the Zephyr Bluetooth LE Controller instead, set :kconfig:option:`CONFIG_BT_LL_SW_SPLIT` to ``y`` in the :file:`prj.conf` file (see :ref:`configure_application`) and make sure to build from a clean build directory. + +.. note:: + If your Bluetooth application requires the LE Secure Connections pairing and you want to use the Zephyr Bluetooth LE Controller, make sure to enable the :kconfig:option:`CONFIG_BT_TINYCRYPT_ECC` Kconfig option as the ECDH cryptography is not supported by this Bluetooth LE Controller. + Zephyr Host *********** diff --git a/doc/nrf/protocols/bt/index.rst b/doc/nrf/protocols/bt/index.rst index 98030b6dbc70..c114c0c897b8 100644 --- a/doc/nrf/protocols/bt/index.rst +++ b/doc/nrf/protocols/bt/index.rst @@ -10,8 +10,10 @@ used world wide and supports a wide range of use cases. Nordic Semiconductor products support the power efficient Bluetooth LE protocol. The nRF Connect SDK provides qualified Bluetooth core stack, profiles and application examples for typical use cases. -The following section describes Bluetooth solution areas and architecture. -It also contains descriptions of Bluetooth LE Controller and Bluetooth Mesh, including the guidelines on how to qualify a product that uses these subsystems. +If you want to go through an online training course to familiarize yourself with Bluetooth Low Energy and the development of Bluetooth LE applications, enroll in the `Bluetooth LE Fundamentals course`_ in the `Nordic Developer Academy`_. + +The following section describes Bluetooth solution areas and architecture, as well as the Bluetooth Mesh protocol. +It also includes guidelines on how to qualify a product that uses Bluetooth technology. To enable Bluetooth LE in your application, you can use the standard HCI-based architecture, where the Bluetooth Host libraries (:ref:`zephyr:bluetooth`) are included in your application or run Bluetooth API functions as remote procedure calls using :ref:`ble_rpc`. @@ -21,6 +23,5 @@ To enable Bluetooth LE in your application, you can use the standard HCI-based a bt_solutions.rst bt_stack_arch.rst - ble/index.rst bt_mesh/index.rst bt_qualification/index.rst From e3b6540f4566c9f3caddd875b702dd50758b9aa2 Mon Sep 17 00:00:00 2001 From: Nordic Builder Date: Thu, 22 Aug 2024 10:51:08 +0000 Subject: [PATCH 02/72] manifest: Update sdk-zephyr revision (auto-manifest PR) Automatically created by Github Action Signed-off-by: Nordic Builder --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 652b277e4060..b9143b611fb4 100644 --- a/west.yml +++ b/west.yml @@ -72,7 +72,7 @@ manifest: # https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/modules.html - name: zephyr repo-path: sdk-zephyr - revision: 8bd088c7c2936dbc94eddd5ede980d45a341e73d + revision: 468d06db5542594fe9e6420fd2e1fe30d9209699 import: # In addition to the zephyr repository itself, NCS also # imports the contents of zephyr/west.yml at the above From 4023bfae77890c43f7b6961b1078cf9efaa28318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Mi=C5=9B?= Date: Wed, 21 Aug 2024 11:51:41 +0200 Subject: [PATCH 03/72] manifest: update doc-internal revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reserve resources for direct IPC between NS and Secure Domain Define common memory management for multi-master scenarios Signed-off-by: Hubert Miś --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index b9143b611fb4..6584936774c5 100644 --- a/west.yml +++ b/west.yml @@ -262,7 +262,7 @@ manifest: - name: doc-internal repo-path: doc-internal path: modules/doc-internal - revision: f598c1901b67990c4519d5b2a542cf5b81e1298d + revision: a0aeb01ca944734486138d93575baa8afd24cb63 groups: - doc-internal From a013ce7bd7811cbc9989e505b4da2e6aa7e61dbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vidar=20Lilleb=C3=B8?= Date: Wed, 21 Aug 2024 12:23:44 +0200 Subject: [PATCH 04/72] cracen: IKG support adaptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exposes IKG keys on lilium with official key ids. Signed-off-by: Vidar Lillebø --- .../src/drivers/cracen/cracenpsa/src/common.c | 21 +++++++--- .../src/drivers/cracen/cracenpsa/src/common.h | 5 +++ .../cracen/cracenpsa/src/key_management.c | 22 +++++++---- .../src/platform_keys/platform_keys.c | 39 +++++++++++++++++-- .../src/drivers/cracen/cracenpsa/src/sign.c | 6 ++- .../baremetal_ba414e_with_ik/pk_baremetal.c | 6 --- .../cracen/silexpk/target/hw/ik/ikhardware.c | 16 ++++---- 7 files changed, 85 insertions(+), 30 deletions(-) diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/common.c b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/common.c index d1035a888309..3cb237241f45 100644 --- a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/common.c +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/common.c @@ -39,6 +39,7 @@ #define DOMAIN_SYSCTRL 0x08 #define DEVICE_SECRET_LENGTH 4 +#define DEVICE_SECRET_ADDRESS ((uint32_t *)0x0E001620) #endif static const uint8_t RSA_ALGORITHM_IDENTIFIER[] = {0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, @@ -678,10 +679,7 @@ int cracen_prepare_ik_key(const uint8_t *user_data) struct sx_pk_config_ik cfg = {}; #ifdef NRF54H_SERIES - /* NCSDK-27273: Fetch device secret from persistent storage. */ - uint32_t device_secret[DEVICE_SECRET_LENGTH] = {}; - - cfg.device_secret = device_secret; + cfg.device_secret = DEVICE_SECRET_ADDRESS; cfg.device_secret_sz = DEVICE_SECRET_LENGTH; switch (((uint32_t *)user_data)[0]) { @@ -788,7 +786,20 @@ psa_status_t cracen_load_keyref(const psa_key_attributes_t *attributes, const ui k->clean_key = NULL; break; default: - return PSA_ERROR_INVALID_HANDLE; + if (key_buffer_size == 0) { + return PSA_ERROR_CORRUPTION_DETECTED; + } + + if (key_buffer_size == sizeof(ikg_opaque_key)) { + k->cfg = ((ikg_opaque_key *)key_buffer)->slot_number; + k->owner_id = ((ikg_opaque_key *)key_buffer)->owner_id; + } else { + /* Normal transparent key. */ + k->prepare_key = NULL; + k->clean_key = NULL; + k->key = key_buffer; + k->sz = key_buffer_size; + } } } else { k->key = key_buffer; diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/common.h b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/common.h index 5b557c361d13..8971f7d23dc1 100644 --- a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/common.h +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/common.h @@ -33,6 +33,11 @@ #define CRACEN_X25519_KEY_SIZE_BYTES (32) #define CRACEN_X448_KEY_SIZE_BYTES (56) +typedef struct { + uint8_t slot_number; + uint8_t owner_id; +} ikg_opaque_key; + __attribute__((warn_unused_result)) psa_status_t silex_statuscodes_to_psa(int ret); __attribute__((warn_unused_result)) psa_status_t diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/key_management.c b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/key_management.c index 3c797831be6e..9681fce61a44 100644 --- a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/key_management.c +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/key_management.c @@ -636,7 +636,11 @@ static psa_status_t export_ecc_public_key_from_keypair(const psa_key_attributes_ if (PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes)) == PSA_KEY_LOCATION_CRACEN) { - priv_key = si_sig_fetch_ikprivkey(sx_curve, *key_buffer); + if (key_buffer_size != sizeof(ikg_opaque_key)) { + return PSA_ERROR_INVALID_ARGUMENT; + } + priv_key = + si_sig_fetch_ikprivkey(sx_curve, ((ikg_opaque_key *)key_buffer)->owner_id); data[0] = SI_ECC_PUBKEY_UNCOMPRESSED; pub_key.key.eckey.qx = &data[1]; pub_key.key.eckey.qy = &data[1 + sx_pk_curve_opsize(sx_curve)]; @@ -1172,13 +1176,13 @@ size_t cracen_get_opaque_size(const psa_key_attributes_t *attributes) case CRACEN_BUILTIN_IDENTITY_KEY_ID: if (psa_get_key_type(attributes) == PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)) { - return 2; + return sizeof(ikg_opaque_key); } break; case CRACEN_BUILTIN_MEXT_ID: case CRACEN_BUILTIN_MKEK_ID: if (psa_get_key_type(attributes) == PSA_KEY_TYPE_AES) { - return 2; + return sizeof(ikg_opaque_key); } break; #ifdef CONFIG_PSA_NEED_CRACEN_PLATFORM_KEYS @@ -1231,8 +1235,10 @@ psa_status_t cracen_get_builtin_key(psa_drv_slot_number_t slot_number, */ if (key_buffer_size >= cracen_get_opaque_size(attributes)) { *key_buffer_length = cracen_get_opaque_size(attributes); - key_buffer[0] = slot_number; - key_buffer[1] = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(psa_get_key_id(attributes)); + *((ikg_opaque_key *)key_buffer) = + (ikg_opaque_key){.slot_number = slot_number, + .owner_id = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( + psa_get_key_id(attributes))}; return PSA_SUCCESS; } else { return PSA_ERROR_BUFFER_TOO_SMALL; @@ -1255,8 +1261,10 @@ psa_status_t cracen_get_builtin_key(psa_drv_slot_number_t slot_number, */ if (key_buffer_size >= cracen_get_opaque_size(attributes)) { *key_buffer_length = cracen_get_opaque_size(attributes); - key_buffer[0] = slot_number; - key_buffer[1] = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(psa_get_key_id(attributes)); + *((ikg_opaque_key *)key_buffer) = + (ikg_opaque_key){.slot_number = slot_number, + .owner_id = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( + psa_get_key_id(attributes))}; return PSA_SUCCESS; } else { return PSA_ERROR_BUFFER_TOO_SMALL; diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/platform_keys/platform_keys.c b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/platform_keys/platform_keys.c index 6ed6bdb513d6..58db18ecee53 100644 --- a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/platform_keys/platform_keys.c +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/platform_keys/platform_keys.c @@ -33,6 +33,9 @@ #define PLATFORM_KEY_GET_DOMAIN(x) (((x) >> 16) & 0xff) #define PLATFORM_KEY_GET_ACCESS(x) (((x) >> 24) & 0xf) +#define USAGE_IAK 0x1 +#define USAGE_MKEK 0x2 +#define USAGE_MEXT 0x3 #define USAGE_FWENC 0x20 #define USAGE_PUBKEY 0x21 #define USAGE_AUTHDEBUG 0x23 @@ -145,13 +148,15 @@ typedef union { sicr_key sicr; embedded_key embedded; derived_key derived; + ikg_key ikg; } platform_key; typedef enum { INVALID, EMBEDDED, DERIVED, - SICR + SICR, + IKG, } key_type; #define APPEND_STR(str, end, part) \ @@ -258,6 +263,22 @@ static key_type find_key(uint32_t id, platform_key *key) return DERIVED; } + if (usage == USAGE_IAK || usage == USAGE_MKEK || usage == USAGE_MEXT) { + key->ikg.domain = domain; + switch (usage) { + case USAGE_IAK: + key->ikg.slot_number = CRACEN_IDENTITY_KEY_SLOT_NUMBER; + break; + case USAGE_MKEK: + key->ikg.slot_number = CRACEN_MKEK_SLOT_NUMBER; + break; + case USAGE_MEXT: + key->ikg.slot_number = CRACEN_MEXT_SLOT_NUMBER; + break; + } + return IKG; + } + for (size_t i = 0; i < ARRAY_SIZE(embedded_keys); i++) { if (id == embedded_keys[i].id) { key->embedded = embedded_keys[i]; @@ -331,7 +352,7 @@ psa_status_t cracen_platform_get_builtin_key(psa_drv_slot_number_t slot_number, /* Note: PSA Driver wrapper API require that attributes are filled before returning * error. */ - if (key_bytes < key_buffer_size) { + if (key_bytes > key_buffer_size) { return PSA_ERROR_BUFFER_TOO_SMALL; } else if (key_buffer == NULL || key_buffer_length == NULL) { return PSA_ERROR_INVALID_ARGUMENT; @@ -436,7 +457,7 @@ psa_status_t cracen_platform_get_builtin_key(psa_drv_slot_number_t slot_number, /* Note: PSA Driver wrapper API require that attributes are filled before returning * error. */ - if (32 < key_buffer_size) { + if (32 > key_buffer_size) { return PSA_ERROR_BUFFER_TOO_SMALL; } else if (key_buffer == NULL || key_buffer_length == NULL) { return PSA_ERROR_INVALID_ARGUMENT; @@ -491,6 +512,10 @@ size_t cracen_platform_keys_get_size(psa_key_attributes_t const *attributes) return 0; } + if (type == IKG) { + return sizeof(ikg_opaque_key); + } + if (key_type == PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS) || key_type == PSA_KEY_TYPE_AES) { return PSA_BITS_TO_BYTES(psa_get_key_bits(attributes)); @@ -524,6 +549,14 @@ psa_status_t cracen_platform_get_key_slot(mbedtls_svc_key_id_t key_id, psa_key_l return PSA_SUCCESS; } + if (type == IKG) { + *slot_number = key.ikg.slot_number; + *lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( + PSA_KEY_PERSISTENCE_READ_ONLY, PSA_KEY_LOCATION_CRACEN); + + return PSA_SUCCESS; + } + return PSA_ERROR_DOES_NOT_EXIST; } diff --git a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/sign.c b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/sign.c index 0e516e4c9cea..0186741ac6e8 100644 --- a/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/sign.c +++ b/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/sign.c @@ -102,7 +102,11 @@ static int cracen_signature_prepare_ec_prvkey(struct si_sig_privkey *privkey, ch if (PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes)) == PSA_KEY_LOCATION_CRACEN) { - *privkey = si_sig_fetch_ikprivkey(*sicurve, *key_buffer); + if (key_buffer_size != sizeof(ikg_opaque_key)) { + return SX_ERR_INVALID_ARG; + } + *privkey = + si_sig_fetch_ikprivkey(*sicurve, ((ikg_opaque_key *)key_buffer)->owner_id); return status; } diff --git a/subsys/nrf_security/src/drivers/cracen/silexpk/target/baremetal_ba414e_with_ik/pk_baremetal.c b/subsys/nrf_security/src/drivers/cracen/silexpk/target/baremetal_ba414e_with_ik/pk_baremetal.c index f1db703d39c8..f3c398d34fef 100644 --- a/subsys/nrf_security/src/drivers/cracen/silexpk/target/baremetal_ba414e_with_ik/pk_baremetal.c +++ b/subsys/nrf_security/src/drivers/cracen/silexpk/target/baremetal_ba414e_with_ik/pk_baremetal.c @@ -52,8 +52,6 @@ struct sx_pk_cnx { struct sx_pk_cnx silex_pk_engine; -int cracen_prepare_ik_key(const uint8_t *user_data); - NRF_SECURITY_MUTEX_DEFINE(cracen_mutex_asymmetric); bool ba414ep_is_busy(sx_pk_req *req) @@ -198,10 +196,6 @@ struct sx_pk_acq_req sx_pk_acquire_req(const struct sx_pk_cmd_def *cmd) cracen_wait_for_pke_interrupt(); } - if (sx_pk_is_ik_cmd(req.req)) { - req.status = cracen_prepare_ik_key(NULL); - } - return req; } diff --git a/subsys/nrf_security/src/drivers/cracen/silexpk/target/hw/ik/ikhardware.c b/subsys/nrf_security/src/drivers/cracen/silexpk/target/hw/ik/ikhardware.c index 406c0e30fba7..9467d502e1c0 100644 --- a/subsys/nrf_security/src/drivers/cracen/silexpk/target/hw/ik/ikhardware.c +++ b/subsys/nrf_security/src/drivers/cracen/silexpk/target/hw/ik/ikhardware.c @@ -19,6 +19,8 @@ #include #include +int cracen_prepare_ik_key(const uint8_t *user_data); + int sx_pk_is_ik_cmd(sx_pk_req *req) { return req->cmd->cmdcode & SX_PK_OP_IK; @@ -88,17 +90,15 @@ int sx_pk_list_ik_inslots(sx_pk_req *req, unsigned int key, struct sx_pk_slot *i req->ik_mode = 0; } else { if (!req->ik_mode) { + int status = cracen_prepare_ik_key((uint8_t *)&key); + + if (status != SX_OK) { + sx_pk_release_req(req); + return SX_ERR_INVALID_PARAM; + } sx_pk_wrreg(&req->regs, PK_REG_CONTROL, PK_RB_CONTROL_CLEAR_IRQ); req->ik_mode = 1; } - uint32_t config = sx_pk_rdreg(&req->regs, IK_REG_HW_CONFIG); - uint32_t max_hw_keys = ((config & IK_NB_PRIV_KEYS_MASK) >> 4); - - if (key >= max_hw_keys) { - sx_pk_release_req(req); - return SX_ERR_INVALID_PARAM; - } - rval |= (key << 4); } /* Write IK cmd register */ From cd65ee94bcb1a587f5ba9cced073cd42b525b2ec Mon Sep 17 00:00:00 2001 From: Tomasz Chyrowicz Date: Wed, 14 Aug 2024 15:48:37 +0200 Subject: [PATCH 05/72] suit: Configure versioning through VERSION file Use the VERSION file to specify manifest sequence number as well as manifest current (semantic) version. Ref: NCSDK-28657 Signed-off-by: Tomasz Chyrowicz --- applications/nrf_desktop/VERSION | 9 +++ applications/nrf_desktop/bootloader_dfu.rst | 5 +- cmake/sysbuild/suit.cmake | 33 ++++++++- .../default/v1/app_envelope.yaml.jinja2 | 12 +++- .../default/v1/rad_envelope.yaml.jinja2 | 12 +++- .../root_with_binary_nordic_top.yaml.jinja2 | 11 ++- .../matter/v1/app_envelope.yaml.jinja2 | 12 +++- .../matter/v1/rad_envelope.yaml.jinja2 | 14 +++- .../root_with_binary_nordic_top.yaml.jinja2 | 11 ++- .../nrf54h/ug_nrf54h20_suit_customize_dfu.rst | 19 ++++- .../ug_nrf54h20_suit_external_memory.rst | 2 +- .../migration/migration_guide_2.8.rst | 29 ++++++++ .../app_recovery_envelope.yaml.jinja2 | 11 ++- .../rad_recovery_envelope.yaml.jinja2 | 12 +++- samples/suit/smp_transfer/Kconfig | 4 +- samples/suit/smp_transfer/README.rst | 42 ++++++----- samples/suit/smp_transfer/VERSION | 17 +++++ samples/suit/smp_transfer/sample.yaml | 72 ++----------------- samples/suit/smp_transfer/src/main.c | 28 +------- .../app_envelope_extflash.yaml.jinja2 | 12 +++- .../rad_envelope_extflash.yaml.jinja2 | 12 +++- ...ith_binary_nordic_top_extflash.yaml.jinja2 | 11 ++- samples/suit/smp_transfer/sysbuild.cmake | 9 --- sysbuild/Kconfig.suit | 5 -- west.yml | 2 +- 25 files changed, 252 insertions(+), 154 deletions(-) create mode 100644 samples/suit/smp_transfer/VERSION delete mode 100644 samples/suit/smp_transfer/sysbuild.cmake diff --git a/applications/nrf_desktop/VERSION b/applications/nrf_desktop/VERSION index b5c2c35ecc1a..19a2caf000e5 100644 --- a/applications/nrf_desktop/VERSION +++ b/applications/nrf_desktop/VERSION @@ -3,3 +3,12 @@ VERSION_MINOR = 7 PATCHLEVEL = 99 VERSION_TWEAK = 0 EXTRAVERSION = + +APP_ROOT_SEQ_NUM = 1 +APP_ROOT_VERSION = 2.7.99 + +APP_LOCAL_1_SEQ_NUM = 1 +APP_LOCAL_1_VERSION = 2.7.99 + +RAD_LOCAL_1_SEQ_NUM = 1 +RAD_LOCAL_1_VERSION = 2.7.99 diff --git a/applications/nrf_desktop/bootloader_dfu.rst b/applications/nrf_desktop/bootloader_dfu.rst index e0ff259f6638..99c588b278d4 100644 --- a/applications/nrf_desktop/bootloader_dfu.rst +++ b/applications/nrf_desktop/bootloader_dfu.rst @@ -216,11 +216,14 @@ SUIT also has the following options in the sysbuild configuration: * ``SB_CONFIG_SUIT_ENVELOPE`` - Required to create the SUIT envelope. Turned on by default on the ``nrf54h20dk`` board. The envelope is used directly as a DFU update file by the DFU tools. - * ``SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM`` - The nRF Desktop application uses the sequence number to define an application version. .. note:: The ``SB_CONFIG_SUIT_ENVELOPE_SIGN`` is disabled, so the generated SUIT envelope is not signed. +SUIT reads the following options from the :file:`VERSION` file, used for :ref:`zephyr:app-version-details` in Zephyr and the |NCS|.: + + * ``APP_ROOT_SEQ_NUM`` - The nRF Desktop application uses the sequence number of root manifest to define an application version. + On the ``nrf54h20dk`` board, the dedicated DFU partition called ``dfu_partition`` is defined by default in the DTS. The partition is used to store the incoming SUIT envelope with an update candidate. The application relies on the default memory layout defined by the board. diff --git a/cmake/sysbuild/suit.cmake b/cmake/sysbuild/suit.cmake index b53b8fafe4d2..124d5123a90f 100644 --- a/cmake/sysbuild/suit.cmake +++ b/cmake/sysbuild/suit.cmake @@ -149,6 +149,27 @@ function(suit_get_manifest template_name output_variable) endif() endfunction() +# Find a VERSION file path. +# +# Usage: +# suit_get_version_file() +# +# Parameters: +# 'output_variable' - variable to store path +function(suit_get_version_file output_variable) + sysbuild_get(PROJECT_DIR IMAGE ${DEFAULT_IMAGE} VAR APPLICATION_SOURCE_DIR CACHE) + + if(DEFINED VERSION_FILE) + set(${output_variable} "${VERSION_FILE}" PARENT_SCOPE) + message(STATUS "Using version: ${VERSION_FILE}") + elseif((DEFINED PROJECT_DIR) AND (EXISTS ${PROJECT_DIR}/VERSION)) + set(${output_variable} "${PROJECT_DIR}/VERSION" PARENT_SCOPE) + message(STATUS "Using version: ${PROJECT_DIR}/VERSION") + else() + message(STATUS "Unable to find a VERSION file. Using default values (seq: 1, no semver)") + endif() +endfunction() + # Create DFU package/main envelope. # # Usage: @@ -196,6 +217,14 @@ function(suit_create_package) suit_copy_artifact_to_output_directory(${image} ${BINARY_DIR}/zephyr/${BINARY_FILE}) endforeach() + set(TEMPLATE_ARGS ${CORE_ARGS}) + suit_get_version_file(VERSION_PATH) + if (DEFINED VERSION_PATH) + list(APPEND TEMPLATE_ARGS + --version_file ${VERSION_PATH} + ) + endif() + foreach(image ${IMAGES}) unset(GENERATE_LOCAL_ENVELOPE) sysbuild_get(GENERATE_LOCAL_ENVELOPE IMAGE ${image} VAR CONFIG_SUIT_LOCAL_ENVELOPE_GENERATE KCONFIG) @@ -225,7 +254,7 @@ function(suit_create_package) set(ENVELOPE_YAML_FILE ${SUIT_ROOT_DIRECTORY}${target}.yaml) set(ENVELOPE_SUIT_FILE ${SUIT_ROOT_DIRECTORY}${target}.suit) - suit_render_template(${INPUT_ENVELOPE_JINJA_FILE} ${ENVELOPE_YAML_FILE} "${CORE_ARGS}") + suit_render_template(${INPUT_ENVELOPE_JINJA_FILE} ${ENVELOPE_YAML_FILE} "${TEMPLATE_ARGS}") suit_create_envelope(${ENVELOPE_YAML_FILE} ${ENVELOPE_SUIT_FILE} ${SB_CONFIG_SUIT_ENVELOPE_SIGN}) list(APPEND STORAGE_BOOT_ARGS --input-envelope ${ENVELOPE_SUIT_FILE} @@ -242,7 +271,7 @@ function(suit_create_package) suit_set_absolute_or_relative_path(${INPUT_ROOT_ENVELOPE_JINJA_FILE} ${app_config_dir} INPUT_ROOT_ENVELOPE_JINJA_FILE) set(ROOT_ENVELOPE_YAML_FILE ${SUIT_ROOT_DIRECTORY}${ROOT_NAME}.yaml) set(ROOT_ENVELOPE_SUIT_FILE ${SUIT_ROOT_DIRECTORY}${ROOT_NAME}.suit) - suit_render_template(${INPUT_ROOT_ENVELOPE_JINJA_FILE} ${ROOT_ENVELOPE_YAML_FILE} "${CORE_ARGS}") + suit_render_template(${INPUT_ROOT_ENVELOPE_JINJA_FILE} ${ROOT_ENVELOPE_YAML_FILE} "${TEMPLATE_ARGS}") suit_create_envelope(${ROOT_ENVELOPE_YAML_FILE} ${ROOT_ENVELOPE_SUIT_FILE} ${SB_CONFIG_SUIT_ENVELOPE_SIGN}) list(APPEND STORAGE_BOOT_ARGS --input-envelope ${ROOT_ENVELOPE_SUIT_FILE} diff --git a/config/suit/templates/nrf54h20/default/v1/app_envelope.yaml.jinja2 b/config/suit/templates/nrf54h20/default/v1/app_envelope.yaml.jinja2 index b35092e71552..4afa82e0da09 100644 --- a/config/suit/templates/nrf54h20/default/v1/app_envelope.yaml.jinja2 +++ b/config/suit/templates/nrf54h20/default/v1/app_envelope.yaml.jinja2 @@ -1,13 +1,16 @@ {%- set mpi_application_vendor_name = application['config']['CONFIG_SUIT_MPI_APP_LOCAL_1_VENDOR_NAME']|default('nordicsemi.com') %} {%- set mpi_application_class_name = application['config']['CONFIG_SUIT_MPI_APP_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_app') %} -{%- set sequence_number = sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] %} SUIT_Envelope_Tagged: suit-authentication-wrapper: SuitDigest: suit-digest-algorithm-id: cose-alg-sha-256 suit-manifest: suit-manifest-version: 1 - suit-manifest-sequence-number: {{ sequence_number }} +{%- if APP_LOCAL_1_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ APP_LOCAL_1_SEQ_NUM }} +{%- else %} + suit-manifest-sequence-number: 1 +{%- endif %} suit-common: suit-components: - - MEM @@ -62,6 +65,11 @@ SUIT_Envelope_Tagged: - suit-directive-set-component-index: 0 - suit-directive-invoke: - suit-send-record-failure + +{%- if APP_LOCAL_1_VERSION is defined %} + suit-current-version: {{ APP_LOCAL_1_VERSION }} +{%- endif %} + suit-install: - suit-directive-set-component-index: 1 - suit-directive-override-parameters: diff --git a/config/suit/templates/nrf54h20/default/v1/rad_envelope.yaml.jinja2 b/config/suit/templates/nrf54h20/default/v1/rad_envelope.yaml.jinja2 index adc8623c6a38..c2a483dbaec4 100644 --- a/config/suit/templates/nrf54h20/default/v1/rad_envelope.yaml.jinja2 +++ b/config/suit/templates/nrf54h20/default/v1/rad_envelope.yaml.jinja2 @@ -5,14 +5,17 @@ {%- endif %} {%- set mpi_radio_vendor_name = main_config['config']['CONFIG_SUIT_MPI_RAD_LOCAL_1_VENDOR_NAME']|default('nordicsemi.com') %} {%- set mpi_radio_class_name = main_config['config']['CONFIG_SUIT_MPI_RAD_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_rad') %} -{%- set sequence_number = sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] %} SUIT_Envelope_Tagged: suit-authentication-wrapper: SuitDigest: suit-digest-algorithm-id: cose-alg-sha-256 suit-manifest: suit-manifest-version: 1 - suit-manifest-sequence-number: {{ sequence_number }} +{%- if RAD_LOCAL_1_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ RAD_LOCAL_1_SEQ_NUM }} +{%- else %} + suit-manifest-sequence-number: 1 +{%- endif %} suit-common: suit-components: - - MEM @@ -67,6 +70,11 @@ SUIT_Envelope_Tagged: - suit-directive-set-component-index: 0 - suit-directive-invoke: - suit-send-record-failure + +{%- if RAD_LOCAL_1_VERSION is defined %} + suit-current-version: {{ RAD_LOCAL_1_VERSION }} +{%- endif %} + suit-install: - suit-directive-set-component-index: 1 - suit-directive-override-parameters: diff --git a/config/suit/templates/nrf54h20/default/v1/root_with_binary_nordic_top.yaml.jinja2 b/config/suit/templates/nrf54h20/default/v1/root_with_binary_nordic_top.yaml.jinja2 index 22606db876d0..0ddd6a4f3a06 100644 --- a/config/suit/templates/nrf54h20/default/v1/root_with_binary_nordic_top.yaml.jinja2 +++ b/config/suit/templates/nrf54h20/default/v1/root_with_binary_nordic_top.yaml.jinja2 @@ -11,7 +11,6 @@ {%- set mpi_application_class_name = main_config['config']['CONFIG_SUIT_MPI_APP_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_app') %} {%- set mpi_radio_vendor_name = main_config['config']['CONFIG_SUIT_MPI_RAD_LOCAL_1_VENDOR_NAME']|default('nordicsemi.com') %} {%- set mpi_radio_class_name = main_config['config']['CONFIG_SUIT_MPI_RAD_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_rad') %} -{%- set sequence_number = sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] %} {%- if 'SB_CONFIG_SUIT_ENVELOPE_NORDIC_TOP_DIRECTORY' in sysbuild['config'] and sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_NORDIC_TOP_DIRECTORY'] != '' %} {%- set nordic_top = True %} {%- else %} @@ -23,7 +22,11 @@ SUIT_Envelope_Tagged: suit-digest-algorithm-id: cose-alg-sha-256 suit-manifest: suit-manifest-version: 1 - suit-manifest-sequence-number: {{ sequence_number }} +{%- if APP_ROOT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ APP_ROOT_SEQ_NUM }} +{%- else %} + suit-manifest-sequence-number: 1 +{%- endif %} suit-common: suit-components: - - CAND_MFST @@ -109,6 +112,10 @@ SUIT_Envelope_Tagged: - suit-send-sysinfo-success - suit-send-sysinfo-failure +{%- if APP_ROOT_VERSION is defined %} + suit-current-version: {{ APP_ROOT_VERSION }} +{%- endif %} + suit-install: - suit-directive-set-component-index: 0 {%- if radio is defined %} diff --git a/config/suit/templates/nrf54h20/matter/v1/app_envelope.yaml.jinja2 b/config/suit/templates/nrf54h20/matter/v1/app_envelope.yaml.jinja2 index 321c6d2a31ee..fce0ca5de7ed 100644 --- a/config/suit/templates/nrf54h20/matter/v1/app_envelope.yaml.jinja2 +++ b/config/suit/templates/nrf54h20/matter/v1/app_envelope.yaml.jinja2 @@ -1,13 +1,16 @@ {%- set mpi_application_vendor_name = application['config']['CONFIG_SUIT_MPI_APP_LOCAL_1_VENDOR_NAME']|default('nordicsemi.com') %} {%- set mpi_application_class_name = application['config']['CONFIG_SUIT_MPI_APP_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_app') %} -{%- set sequence_number = sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] %} SUIT_Envelope_Tagged: suit-authentication-wrapper: SuitDigest: suit-digest-algorithm-id: cose-alg-sha-256 suit-manifest: suit-manifest-version: 1 - suit-manifest-sequence-number: {{ sequence_number }} +{%- if APP_LOCAL_1_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ APP_LOCAL_1_SEQ_NUM }} +{%- else %} + suit-manifest-sequence-number: 1 +{%- endif %} suit-common: suit-components: - - MEM @@ -72,6 +75,11 @@ SUIT_Envelope_Tagged: - suit-directive-set-component-index: 0 - suit-directive-invoke: - suit-send-record-failure + +{%- if APP_LOCAL_1_VERSION is defined %} + suit-current-version: {{ APP_LOCAL_1_VERSION }} +{%- endif %} + suit-install: {%- if flash_companion is defined %} - suit-directive-set-component-index: 1 diff --git a/config/suit/templates/nrf54h20/matter/v1/rad_envelope.yaml.jinja2 b/config/suit/templates/nrf54h20/matter/v1/rad_envelope.yaml.jinja2 index 24be0ef3f21a..61eeb7bdb0d6 100644 --- a/config/suit/templates/nrf54h20/matter/v1/rad_envelope.yaml.jinja2 +++ b/config/suit/templates/nrf54h20/matter/v1/rad_envelope.yaml.jinja2 @@ -5,14 +5,17 @@ {%- endif %} {%- set mpi_radio_vendor_name = main_config['config']['CONFIG_SUIT_MPI_RAD_LOCAL_1_VENDOR_NAME']|default('nordicsemi.com') %} {%- set mpi_radio_class_name = main_config['config']['CONFIG_SUIT_MPI_RAD_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_rad') %} -{%- set sequence_number = sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] %} SUIT_Envelope_Tagged: suit-authentication-wrapper: SuitDigest: suit-digest-algorithm-id: cose-alg-sha-256 suit-manifest: suit-manifest-version: 1 - suit-manifest-sequence-number: {{ sequence_number }} +{%- if RAD_LOCAL_1_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ RAD_LOCAL_1_SEQ_NUM }} +{%- else %} + suit-manifest-sequence-number: 1 +{%- endif %} suit-common: suit-components: - - MEM @@ -63,6 +66,11 @@ SUIT_Envelope_Tagged: - suit-directive-set-component-index: 0 - suit-directive-invoke: - suit-send-record-failure + +{%- if RAD_LOCAL_1_VERSION is defined %} + suit-current-version: {{ RAD_LOCAL_1_VERSION }} +{%- endif %} + suit-install: - suit-directive-set-component-index: 1 - suit-directive-override-parameters: @@ -101,4 +109,4 @@ SUIT_Envelope_Tagged: suit-text-component-description: Sample radio core FW suit-text-component-version: v1.0.0 suit-integrated-payloads: - '#{{ radio['name'] }}': {{ radio['binary'] }} \ No newline at end of file + '#{{ radio['name'] }}': {{ radio['binary'] }} diff --git a/config/suit/templates/nrf54h20/matter/v1/root_with_binary_nordic_top.yaml.jinja2 b/config/suit/templates/nrf54h20/matter/v1/root_with_binary_nordic_top.yaml.jinja2 index fc3ce02e3858..5acaafde9785 100644 --- a/config/suit/templates/nrf54h20/matter/v1/root_with_binary_nordic_top.yaml.jinja2 +++ b/config/suit/templates/nrf54h20/matter/v1/root_with_binary_nordic_top.yaml.jinja2 @@ -11,7 +11,6 @@ {%- set mpi_application_class_name = main_config['config']['CONFIG_SUIT_MPI_APP_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_app') %} {%- set mpi_radio_vendor_name = main_config['config']['CONFIG_SUIT_MPI_RAD_LOCAL_1_VENDOR_NAME']|default('nordicsemi.com') %} {%- set mpi_radio_class_name = main_config['config']['CONFIG_SUIT_MPI_RAD_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_rad') %} -{%- set sequence_number = sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] %} {%- if 'SB_CONFIG_SUIT_ENVELOPE_NORDIC_TOP_DIRECTORY' in sysbuild['config'] and sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_NORDIC_TOP_DIRECTORY'] != '' %} {%- set nordic_top = True %} {%- else %} @@ -23,7 +22,11 @@ SUIT_Envelope_Tagged: suit-digest-algorithm-id: cose-alg-sha-256 suit-manifest: suit-manifest-version: 1 - suit-manifest-sequence-number: {{ sequence_number }} +{%- if APP_ROOT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ APP_ROOT_SEQ_NUM }} +{%- else %} + suit-manifest-sequence-number: 1 +{%- endif %} suit-common: suit-components: - - CAND_MFST @@ -109,6 +112,10 @@ SUIT_Envelope_Tagged: - suit-send-sysinfo-success - suit-send-sysinfo-failure +{%- if APP_ROOT_VERSION is defined %} + suit-current-version: {{ APP_ROOT_VERSION }} +{%- endif %} + suit-install: - suit-directive-set-component-index: 0 {%- if radio is defined %} diff --git a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_suit_customize_dfu.rst b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_suit_customize_dfu.rst index fecf88b0c0cb..0ae51c223b6e 100644 --- a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_suit_customize_dfu.rst +++ b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_suit_customize_dfu.rst @@ -238,14 +238,27 @@ Each variable is a Python dictionary type (``dict``) containing the following ke * ``dt`` - Devicetree representation (`edtlib`_ object) * ``binary`` - Path to the binary, which holds the firmware for the target -Additionally, the Python dictionary holds a variable called ``version`` that holds the application version. +Additionally, the Python dictionary holds all the variables defined inside the :file:`VERSION` file, used for :ref:`zephyr:app-version-details` in Zephyr and the |NCS|. +The default templates searches for the following options inside the :file:`VERSION` file: + +* ``APP_ROOT_SEQ_NUM`` - Sets the application root manifest sequence number. +* ``APP_ROOT_VERSION`` - Sets the application root manifest current (semantic) version. +* ``APP_LOCAL_1_SEQ_NUM`` - Sets the application local manifest sequence number. +* ``APP_LOCAL_1_VERSION`` - Sets the application local manifest current (semantic) version. +* ``RAD_LOCAL_1_SEQ_NUM`` - Sets the radio local manifest sequence number. +* ``RAD_LOCAL_1_VERSION`` - Sets the radio local manifest current (semantic) version. +* ``APP_RECOVERY_SEQ_NUM`` - Sets the application recovery manifest sequence number. +* ``APP_RECOVERY_VERSION`` - Sets the application recovery manifest current (semantic) version. +* ``RAD_RECOVERY_SEQ_NUM`` - Sets the radio recovery manifest sequence number. +* ``RAD_RECOVERY_VERSION`` - Sets the radio recovery manifest current (semantic) version. + With the Python dictionary you are able to, for example: * Extract the CPU ID by using ``application['dt'].label2node['cpu'].unit_addr`` * Obtain the partition address with ``application['dt'].chosen_nodes['zephyr,code-partition']`` * Obtain the size of partition with ``application['dt'].chosen_nodes['zephyr,code-partition'].regs[0].size`` * Get the pair of URI name and the binary path by using ``'#{{ application['name'] }}': {{ application['binary'] }}`` -* Get the application version with ``suit-manifest-sequence-number: {{ sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] }}`` +* Get the root manifest sequence number with ``suit-manifest-sequence-number: {{ APP_ROOT_SEQ_NUM }}`` Additionally, the **get_absolute_address** method is available to recalculate the absolute address of the partition. With these variables and methods, you can define templates which will next be filled out by the build system and use them to prepare the output binary SUIT envelope. @@ -307,7 +320,7 @@ For more information, see the file available in the sample and `Jinja documentat suit-digest-algorithm-id: cose-alg-sha-256 suit-manifest: suit-manifest-version: 1 - suit-manifest-sequence-number: {{ sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] }} # Assign value defined in the `CONFIG_APP_VERSION` Kconfig option. + suit-manifest-sequence-number: {{ APP_ROOT_SEQ_NUM }} # Assign value defined in the `VERSION` file. suit-common: suit-components: - - CAND_MFST diff --git a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_suit_external_memory.rst b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_suit_external_memory.rst index 8868d7df67a8..1420c6b26142 100644 --- a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_suit_external_memory.rst +++ b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_suit_external_memory.rst @@ -132,7 +132,7 @@ To enable the external memory, you must add the ``-DFILE_SUFFIX="extflash"`` arg The build system will automatically use :ref:`configuration_system_overview_sysbuild` and generate a :file:`build/zephyr/dfu_suit.zip` archive, which contains the SUIT envelope and candidate images. -#. Build a new version of the application with the incremented ``SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM`` value. +#. Build a new version of the application with the incremented ``CONFIG_N_BLINKS`` value. #. Download the new :file:`dfu_suit.zip` archive to your mobile device. diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_2.8.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_2.8.rst index a43fb6f1aac6..5db420d6db7a 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_2.8.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_2.8.rst @@ -53,6 +53,35 @@ Serial LTE Modem (SLM) * ``AT#XSOCKETOPT=1,53,`` with ``AT#XSOCKETOPT=1,61,4`` to indicate ``RAI_ONGOING``. * ``AT#XSOCKETOPT=1,54,`` with ``AT#XSOCKETOPT=1,61,5`` to indicate ``RAI_WAIT_MORE``. +SUIT DFU for nRF54H20 +--------------------- + +.. toggle:: + + * The manifest sequence number is no longer configured through a :ref:`sysbuild ` Kconfig option. + The values are now read from the :file:`VERSION` file, used for :ref:`zephyr:app-version-details` in Zephyr and the |NCS|. + This change to the :ref:`sysbuild ` Kconfig option requires the following updates in the SUIT templates for your project: + + * Remove from all templates: + + .. code-block:: YAML + + suit-manifest-sequence-number: {{ sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] }} + + * Add the line that corresponds to the manifest name, that is ``APP_ROOT_SEQ_NUM`` for the application root manifest: + + .. code-block:: YAML + + suit-manifest-sequence-number: {{ APP_ROOT_SEQ_NUM }} + + If the value of the sequence number was changed in your application, append the following line to the :file:`VERSION` file: + + .. code-block:: sh + + APP_ROOT_SEQ_NUM = + + For the list of all variables, set through the :file:`VERSION`, refer to the :ref:`ug_nrf54h20_suit_customize_dfu`. + Libraries ========= diff --git a/samples/suit/recovery/suit/nrf54h20/app_recovery_envelope.yaml.jinja2 b/samples/suit/recovery/suit/nrf54h20/app_recovery_envelope.yaml.jinja2 index fe05ba9e13c2..4d4cad647b54 100644 --- a/samples/suit/recovery/suit/nrf54h20/app_recovery_envelope.yaml.jinja2 +++ b/samples/suit/recovery/suit/nrf54h20/app_recovery_envelope.yaml.jinja2 @@ -5,14 +5,17 @@ {%- set mpi_app_recovery_class_name = application['config']['CONFIG_SUIT_MPI_APP_RECOVERY_CLASS_NAME']|default('nRF54H20_app_recovery') %} {%- set mpi_rad_recovery_vendor_name = application['config']['CONFIG_SUIT_MPI_RAD_RECOVERY_VENDOR_NAME']|default('nordicsemi.com') %} {%- set mpi_rad_recovery_class_name = application['config']['CONFIG_SUIT_MPI_RAD_RECOVERY_CLASS_NAME']|default('nRF54H20_rad_recovery') %} -{%- set sequence_number = sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] %} SUIT_Envelope_Tagged: suit-authentication-wrapper: SuitDigest: suit-digest-algorithm-id: cose-alg-sha-256 suit-manifest: suit-manifest-version: 1 - suit-manifest-sequence-number: {{ sequence_number }} +{%- if APP_RECOVERY_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ APP_RECOVERY_SEQ_NUM }} +{%- else %} + suit-manifest-sequence-number: 1 +{%- endif %} suit-common: suit-components: - - CAND_IMG @@ -128,6 +131,10 @@ SUIT_Envelope_Tagged: - suit-send-record-failure {%- endif %} +{%- if APP_RECOVERY_VERSION is defined %} + suit-current-version: {{ APP_RECOVERY_VERSION }} +{%- endif %} + suit-install: {%- if radio is defined %} - suit-directive-set-component-index: 1 diff --git a/samples/suit/recovery/suit/nrf54h20/rad_recovery_envelope.yaml.jinja2 b/samples/suit/recovery/suit/nrf54h20/rad_recovery_envelope.yaml.jinja2 index 7dffe19be6c6..1d9cebcd2363 100644 --- a/samples/suit/recovery/suit/nrf54h20/rad_recovery_envelope.yaml.jinja2 +++ b/samples/suit/recovery/suit/nrf54h20/rad_recovery_envelope.yaml.jinja2 @@ -1,13 +1,16 @@ {%- set mpi_rad_recovery_vendor_name = application['config']['CONFIG_SUIT_MPI_RAD_RECOVERY_VENDOR_NAME']|default('nordicsemi.com') %} {%- set mpi_rad_recovery_class_name = application['config']['CONFIG_SUIT_MPI_RAD_RECOVERY_CLASS_NAME']|default('nRF54H20_sample_rad_recovery') %} -{%- set sequence_number = sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] %} SUIT_Envelope_Tagged: suit-authentication-wrapper: SuitDigest: suit-digest-algorithm-id: cose-alg-sha-256 suit-manifest: suit-manifest-version: 1 - suit-manifest-sequence-number: {{ sequence_number }} +{%- if RAD_RECOVERY_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ RAD_RECOVERY_SEQ_NUM }} +{%- else %} + suit-manifest-sequence-number: 1 +{%- endif %} suit-common: suit-components: - - MEM @@ -62,6 +65,11 @@ SUIT_Envelope_Tagged: - suit-directive-set-component-index: 1 - suit-directive-override-parameters: suit-parameter-uri: '#{{ radio['name'] }}' + +{%- if RAD_RECOVERY_VERSION is defined %} + suit-current-version: {{ RAD_RECOVERY_VERSION }} +{%- endif %} + - suit-directive-fetch: - suit-send-record-failure - suit-condition-image-match: diff --git a/samples/suit/smp_transfer/Kconfig b/samples/suit/smp_transfer/Kconfig index 3982c990dd59..6170d5c3f8eb 100644 --- a/samples/suit/smp_transfer/Kconfig +++ b/samples/suit/smp_transfer/Kconfig @@ -4,8 +4,8 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # -config SUIT_ENVELOPE_SEQUENCE_NUM - int "Sequence number of the SUIT envelopes" +config N_BLINKS + int "Number of fast blinks" default 1 source "Kconfig.zephyr" diff --git a/samples/suit/smp_transfer/README.rst b/samples/suit/smp_transfer/README.rst index 9e60f924854d..3bfc92252498 100644 --- a/samples/suit/smp_transfer/README.rst +++ b/samples/suit/smp_transfer/README.rst @@ -55,27 +55,23 @@ Configuration |config| The default configuration uses UART with sequence number 1 (shown as Version 1 in the nRF Device Manager app). -To change the sequence number of the application, configure the ``SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM`` sysbuild Kconfig option. -This also changes the number of blinks on **LED 0** and sets the :ref:`sequence number ` of the :ref:`SUIT envelope `’s manifest. -To use this configuration, build the sample with :ref:`configuration_system_overview_sysbuild` and set the ``SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM`` sysbuild Kconfig option to ``x``, where ``x`` is the version number. -For example: +To change the sequence number of the application, configure the ``APP_ROOT_SEQ_NUM`` inside the :file:`VERSION` file, used for :ref:`zephyr:app-version-details` in Zephyr and the |NCS|. +It sets the :ref:`sequence number ` of the :ref:`SUIT envelope `’s manifest. +If you do not provide the :file:`VERSION` file, the sample is built with sequence number set to 1 (shown as Version 1 in the nRF Device Manager app). -.. code-block:: console - - west build -b nrf54h20dk/nrf54h20/cpuapp -- -DSB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=2 - -If you do not specify this configuration, the sample is built with sequence number 1 (shown as Version 1 in the nRF Device Manager app). +To change the number of blinks on **LED 0**, configure the ``CONFIG_N_BLINKS`` Kconfig option. +If you do not specify this configuration, the sample is built with the number of blinks set to 1. Configuration options ===================== Check and configure the following configuration option for the sample: -.. _SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM: +.. _CONFIG_N_BLINKS: -SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM - Configuration for the sequence number. - The sample configuration updates the sequence number of the SUIT envelope, which is reflected as the version of the application in the nRF Device Manager app. +CONFIG_N_BLINKS - Configuration for the number of blinks. + The sample configuration change the number of blinks on **LED 0**. The default value is ``1``. Modify partition sizes @@ -153,7 +149,7 @@ To build and program the sample to the nRF54H20 DK, complete the following steps .. code-block:: console - west build -p -b nrf54h20dk/nrf54h20/cpuapp -- -DFILE_SUFFIX=bt -DSB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=1 + west build -p -b nrf54h20dk/nrf54h20/cpuapp -- -DFILE_SUFFIX=bt -DCONFIG_N_BLINKS=1 The output build files can be found in the :file:`build/DFU` directory, including the :ref:`app_build_output_files_suit_dfu`. @@ -163,11 +159,17 @@ To build and program the sample to the nRF54H20 DK, complete the following steps #. Connect the DK to your computer using a USB cable. #. Power on the DK. #. Program the sample to the kit (see :ref:`programming_cmd` for instructions). - #. Update the SUIT envelope sequence number, by rebuilding the sample with an updated sequence number: + #. Update the SUIT envelope sequence number, by appending the following line to the :file:`VERSION` file: .. code-block:: console - west build -b nrf54h20dk/nrf54h20/cpuapp -- -DFILE_SUFFIX=bt -DSB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=2 + APP_ROOT_SEQ_NUM = 2 + + #. Update the number of LED blinks, by rebuilding the sample with the following Kconfig options set: + + .. code-block:: console + + west build -b nrf54h20dk/nrf54h20/cpuapp -- -DFILE_SUFFIX=bt -DCONFIG_N_BLINKS=2 Another :file:`root.suit` file is created after running this command, that contains the updated firmware. You must manually transfer this file onto the same mobile device you will use with the nRF Device Manager app. @@ -192,11 +194,17 @@ To build and program the sample to the nRF54H20 DK, complete the following steps #. Connect the DK to your computer using a USB cable. #. Power on the DK. #. Program the sample to the kit (see :ref:`programming_cmd` for instructions). - #. Update the SUIT envelope sequence number, by rebuilding the sample with an updated sequence number: + #. Update the SUIT envelope sequence number, by appending the following line to the :file:`VERSION` file: + + .. code-block:: console + + APP_ROOT_SEQ_NUM = 2 + + #. Update the number of LED blinks, by rebuilding the sample with the following Kconfig options set: .. code-block:: console - west build -b nrf54h20dk/nrf54h20/cpuapp -- -DSB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=2 + west build -b nrf54h20dk/nrf54h20/cpuapp -- -DCONFIG_N_BLINKS=2 Another :file:`root.suit` file is created after running this command, that contains the updated firmware. diff --git a/samples/suit/smp_transfer/VERSION b/samples/suit/smp_transfer/VERSION new file mode 100644 index 000000000000..ad39cbd97b9b --- /dev/null +++ b/samples/suit/smp_transfer/VERSION @@ -0,0 +1,17 @@ +VERSION_MAJOR = 0 +VERSION_MINOR = 1 +PATCHLEVEL = 0 +VERSION_TWEAK = 0 + + +APP_ROOT_SEQ_NUM = 1 +APP_ROOT_VERSION = 0.1.0 + +APP_LOCAL_1_SEQ_NUM = 1 +APP_LOCAL_1_VERSION = 0.1.0 + +APP_RECOVERY_SEQ_NUM = 1 +APP_RECOVERY_VERSION = 0.1.0 + +RAD_LOCAL_1_SEQ_NUM = 1 +RAD_LOCAL_1_VERSION = 0.1.0 diff --git a/samples/suit/smp_transfer/sample.yaml b/samples/suit/smp_transfer/sample.yaml index c93bd3858bae..34fc5c59bbd2 100644 --- a/samples/suit/smp_transfer/sample.yaml +++ b/samples/suit/smp_transfer/sample.yaml @@ -13,100 +13,42 @@ common: build_only: true sysbuild: true tests: - subsys.suit.smp_transfer.v1: - extra_args: - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=1 - tags: suit ci_samples_suit - - subsys.suit.smp_transfer.bt.v1: - extra_args: - - FILE_SUFFIX=bt - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=1 - tags: suit bluetooth ci_samples_suit - - subsys.suit.smp_transfer.v2: - extra_args: - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=2 + sample.suit.smp_transfer: tags: suit ci_samples_suit - subsys.suit.smp_transfer.bt.v2: + sample.suit.smp_transfer.bt: extra_args: - FILE_SUFFIX=bt - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=2 tags: suit bluetooth ci_samples_suit - subsys.suit.smp_transfer.full.v1: - extra_args: - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=1 + sample.suit.smp_transfer.full: extra_configs: - CONFIG_SUIT_DFU_CANDIDATE_PROCESSING_FULL=y tags: suit ci_samples_suit - subsys.suit.smp_transfer.full.v2: - extra_args: - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=2 - extra_configs: - - CONFIG_SUIT_DFU_CANDIDATE_PROCESSING_FULL=y - tags: suit ci_samples_suit - - subsys.suit.smp_transfer.full.bt.v1: + sample.suit.smp_transfer.full.bt: extra_args: - FILE_SUFFIX=bt - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=1 extra_configs: - CONFIG_SUIT_DFU_CANDIDATE_PROCESSING_FULL=y tags: suit bluetooth ci_samples_suit - subsys.suit.smp_transfer.full.bt.v2: - extra_args: - - FILE_SUFFIX=bt - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=2 - extra_configs: - - CONFIG_SUIT_DFU_CANDIDATE_PROCESSING_FULL=y - tags: suit bluetooth ci_samples_suit - - subsys.suit.smp_transfer.full.extflash.v1: - extra_args: - - FILE_SUFFIX=extflash - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=1 - tags: suit ci_samples_suit - - subsys.suit.smp_transfer.full.extflash.v2: + sample.suit.smp_transfer.full.extflash: extra_args: - FILE_SUFFIX=extflash - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=2 tags: suit ci_samples_suit - subsys.suit.smp_transfer.recovery.v1: - extra_args: - - FILE_SUFFIX=bt - - SB_CONFIG_SUIT_BUILD_RECOVERY=y - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=1 - extra_configs: - - CONFIG_SUIT_DFU_CANDIDATE_PROCESSING_FULL=y - tags: suit bluetooth ci_samples_suit - - subsys.suit.smp_transfer.recovery.v2: + sample.suit.smp_transfer.recovery: extra_args: - FILE_SUFFIX=bt - SB_CONFIG_SUIT_BUILD_RECOVERY=y - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=2 extra_configs: - CONFIG_SUIT_DFU_CANDIDATE_PROCESSING_FULL=y tags: suit bluetooth ci_samples_suit - subsys.suit.smp_transfer.full.extflash.bt.v1: - extra_args: - - FILE_SUFFIX=extflash - - OVERLAY_CONFIG="sysbuild/smp_transfer_bt.conf" - - SB_OVERLAY_CONFIG="sysbuild_bt.conf" - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=1 - tags: suit bluetooth ci_samples_suit - - subsys.suit.smp_transfer.full.extflash.bt.v2: + sample.suit.smp_transfer.full.extflash.bt: extra_args: - FILE_SUFFIX=extflash - OVERLAY_CONFIG="sysbuild/smp_transfer_bt.conf" - SB_OVERLAY_CONFIG="sysbuild_bt.conf" - - SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=2 tags: suit bluetooth ci_samples_suit diff --git a/samples/suit/smp_transfer/src/main.c b/samples/suit/smp_transfer/src/main.c index f65d75f0786a..ba48308f7ce4 100644 --- a/samples/suit/smp_transfer/src/main.c +++ b/samples/suit/smp_transfer/src/main.c @@ -28,37 +28,15 @@ int main(void) printk("Cannot init LEDs (err: %d)\r\n", ret); } - printk("Hello world from %s version: %d, BUILD: %s %s\r\n", CONFIG_BOARD, - CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM, __DATE__, __TIME__); - -#if (CONFIG_SSF_SUIT_SERVICE_ENABLED) && (CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM == 1) && \ - (!CONFIG_MGMT_SUITFU) - suit_plat_mreg_t update_candidate[] = { - { - .mem = DFU_PARTITION_ADDRESS, - .size = DFU_PARTITION_SIZE, - }, - }; - - printk("Validate candidate: %p (0x%x)\r\n", update_candidate[0].mem, - update_candidate[0].size); - bool dfu_partition_valid = - suit_validate_candidate(update_candidate[0].mem, update_candidate[0].size); - - printk("DFU update candidate found in DFU partition: %d\r\n", dfu_partition_valid); - if (dfu_partition_valid) { - int ret = suit_trigger_update(update_candidate, ARRAY_SIZE(update_candidate)); - - printk("DFU triggered with status: %d\r\n", ret); - } -#endif + printk("Hello world from %s blinks: %d, BUILD: %s %s\r\n", CONFIG_BOARD, CONFIG_N_BLINKS, + __DATE__, __TIME__); if (IS_ENABLED(CONFIG_MCUMGR_TRANSPORT_BT)) { start_smp_bluetooth_adverts(); } while (1) { - for (int i = 0; i < CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM; i++) { + for (int i = 0; i < CONFIG_N_BLINKS; i++) { dk_set_led_on(DK_LED1); k_msleep(250); dk_set_led_off(DK_LED1); diff --git a/samples/suit/smp_transfer/suit/nrf54h20/app_envelope_extflash.yaml.jinja2 b/samples/suit/smp_transfer/suit/nrf54h20/app_envelope_extflash.yaml.jinja2 index 0118adaae7b7..0a58d07c1c78 100644 --- a/samples/suit/smp_transfer/suit/nrf54h20/app_envelope_extflash.yaml.jinja2 +++ b/samples/suit/smp_transfer/suit/nrf54h20/app_envelope_extflash.yaml.jinja2 @@ -1,13 +1,16 @@ {%- set mpi_application_vendor_name = application['config']['CONFIG_SUIT_MPI_APP_LOCAL_1_VENDOR_NAME']|default('nordicsemi.com') %} {%- set mpi_application_class_name = application['config']['CONFIG_SUIT_MPI_APP_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_app') %} -{%- set sequence_number = sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] %} SUIT_Envelope_Tagged: suit-authentication-wrapper: SuitDigest: suit-digest-algorithm-id: cose-alg-sha-256 suit-manifest: suit-manifest-version: 1 - suit-manifest-sequence-number: {{ sequence_number }} +{%- if APP_LOCAL_1_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ APP_LOCAL_1_SEQ_NUM }} +{%- else %} + suit-manifest-sequence-number: 1 +{%- endif %} suit-common: suit-components: - - MEM @@ -74,6 +77,11 @@ SUIT_Envelope_Tagged: - suit-directive-set-component-index: 0 - suit-directive-invoke: - suit-send-record-failure + +{%- if APP_LOCAL_1_VERSION is defined %} + suit-current-version: {{ APP_LOCAL_1_VERSION }} +{%- endif %} + suit-payload-fetch: - suit-directive-set-component-index: 2 - suit-directive-override-parameters: diff --git a/samples/suit/smp_transfer/suit/nrf54h20/rad_envelope_extflash.yaml.jinja2 b/samples/suit/smp_transfer/suit/nrf54h20/rad_envelope_extflash.yaml.jinja2 index 3dff4584da5d..fb44f67b27b6 100644 --- a/samples/suit/smp_transfer/suit/nrf54h20/rad_envelope_extflash.yaml.jinja2 +++ b/samples/suit/smp_transfer/suit/nrf54h20/rad_envelope_extflash.yaml.jinja2 @@ -5,14 +5,17 @@ {%- endif %} {%- set mpi_radio_vendor_name = main_config['config']['CONFIG_SUIT_MPI_RAD_LOCAL_1_VENDOR_NAME']|default('nordicsemi.com') %} {%- set mpi_radio_class_name = main_config['config']['CONFIG_SUIT_MPI_RAD_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_rad') %} -{%- set sequence_number = sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] %} SUIT_Envelope_Tagged: suit-authentication-wrapper: SuitDigest: suit-digest-algorithm-id: cose-alg-sha-256 suit-manifest: suit-manifest-version: 1 - suit-manifest-sequence-number: {{ sequence_number }} +{%- if RAD_LOCAL_1_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ RAD_LOCAL_1_SEQ_NUM }} +{%- else %} + suit-manifest-sequence-number: 1 +{%- endif %} suit-common: suit-components: - - MEM @@ -65,6 +68,11 @@ SUIT_Envelope_Tagged: - suit-directive-set-component-index: 0 - suit-directive-invoke: - suit-send-record-failure + +{%- if RAD_LOCAL_1_VERSION is defined %} + suit-current-version: {{ RAD_LOCAL_1_VERSION }} +{%- endif %} + suit-payload-fetch: - suit-directive-set-component-index: 2 - suit-directive-override-parameters: diff --git a/samples/suit/smp_transfer/suit/nrf54h20/root_with_binary_nordic_top_extflash.yaml.jinja2 b/samples/suit/smp_transfer/suit/nrf54h20/root_with_binary_nordic_top_extflash.yaml.jinja2 index b0afd55b987d..d7db0e1da298 100644 --- a/samples/suit/smp_transfer/suit/nrf54h20/root_with_binary_nordic_top_extflash.yaml.jinja2 +++ b/samples/suit/smp_transfer/suit/nrf54h20/root_with_binary_nordic_top_extflash.yaml.jinja2 @@ -11,7 +11,6 @@ {%- set mpi_application_class_name = main_config['config']['CONFIG_SUIT_MPI_APP_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_app') %} {%- set mpi_radio_vendor_name = main_config['config']['CONFIG_SUIT_MPI_RAD_LOCAL_1_VENDOR_NAME']|default('nordicsemi.com') %} {%- set mpi_radio_class_name = main_config['config']['CONFIG_SUIT_MPI_RAD_LOCAL_1_CLASS_NAME']|default('nRF54H20_sample_rad') %} -{%- set sequence_number = sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM'] %} {%- if 'SB_CONFIG_SUIT_ENVELOPE_NORDIC_TOP_DIRECTORY' in sysbuild['config'] and sysbuild['config']['SB_CONFIG_SUIT_ENVELOPE_NORDIC_TOP_DIRECTORY'] != '' %} {%- set nordic_top = True %} {%- else %} @@ -23,7 +22,11 @@ SUIT_Envelope_Tagged: suit-digest-algorithm-id: cose-alg-sha-256 suit-manifest: suit-manifest-version: 1 - suit-manifest-sequence-number: {{ sequence_number }} +{%- if APP_ROOT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ APP_ROOT_SEQ_NUM }} +{%- else %} + suit-manifest-sequence-number: 1 +{%- endif %} suit-common: suit-components: - - CAND_MFST @@ -109,6 +112,10 @@ SUIT_Envelope_Tagged: - suit-send-sysinfo-success - suit-send-sysinfo-failure +{%- if APP_ROOT_VERSION is defined %} + suit-current-version: {{ APP_ROOT_VERSION }} +{%- endif %} + suit-payload-fetch: {%- if application is defined %} - suit-directive-set-component-index: 0 diff --git a/samples/suit/smp_transfer/sysbuild.cmake b/samples/suit/smp_transfer/sysbuild.cmake deleted file mode 100644 index 3f5dca3413d8..000000000000 --- a/samples/suit/smp_transfer/sysbuild.cmake +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) 2024 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# - -# Set the CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM defined in smp_transfer/Kconfig -# to be equal to SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM -set_property(TARGET smp_transfer APPEND_STRING PROPERTY CONFIG "CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM=${SB_CONFIG_SUIT_ENVELOPE_SEQUENCE_NUM}\n") diff --git a/sysbuild/Kconfig.suit b/sysbuild/Kconfig.suit index baf889fbb9ec..51fdf52bb530 100644 --- a/sysbuild/Kconfig.suit +++ b/sysbuild/Kconfig.suit @@ -19,11 +19,6 @@ config SUIT_ENVELOPE_SIGN help Sign created SUIT envelope by external script -config SUIT_ENVELOPE_SEQUENCE_NUM - int "Sequence number of the generated SUIT manifest" - range 0 2147483647 - default 1 - config SUIT_ENVELOPE_ROOT_TEMPLATE_FILENAME string "Path to the default root envelope template" default "root_with_binary_nordic_top.yaml.jinja2" diff --git a/west.yml b/west.yml index 6584936774c5..0126de27e78f 100644 --- a/west.yml +++ b/west.yml @@ -254,7 +254,7 @@ manifest: upstream-sha: c6eaeda5a1c1c5dbb24dce7e027340cb8893a77b compare-by-default: false - name: suit-generator - revision: dcd58e681a98d5b8b49ec56a065315f53e21a2b7 + revision: 97ef5bdd41716aa7fa21a0f0c149a66d1f91ab8d path: modules/lib/suit-generator - name: suit-processor revision: ee58d543994256d545c692e14badf3efa9830237 From dc4f591b1f72807659f32a1bab75bb9a8b239d03 Mon Sep 17 00:00:00 2001 From: Tomasz Chyrowicz Date: Tue, 20 Aug 2024 16:48:37 +0200 Subject: [PATCH 06/72] suit: Add a support for default versions Add a possibility to use Zephyr-defined version to calculate manifest sequence number as well as manifest current (semantic) version. Ref: NCSDK-28657 Signed-off-by: Tomasz Chyrowicz --- applications/nrf_desktop/VERSION | 9 --------- applications/nrf_desktop/bootloader_dfu.rst | 5 +++-- .../nrf54h20/default/v1/app_envelope.yaml.jinja2 | 4 ++++ .../nrf54h20/default/v1/rad_envelope.yaml.jinja2 | 4 ++++ .../default/v1/root_with_binary_nordic_top.yaml.jinja2 | 4 ++++ .../nrf54h20/matter/v1/app_envelope.yaml.jinja2 | 4 ++++ .../nrf54h20/matter/v1/rad_envelope.yaml.jinja2 | 4 ++++ .../matter/v1/root_with_binary_nordic_top.yaml.jinja2 | 4 ++++ .../nrf54h/ug_nrf54h20_suit_customize_dfu.rst | 5 +++++ .../suit/nrf54h20/app_recovery_envelope.yaml.jinja2 | 4 ++++ .../suit/nrf54h20/rad_recovery_envelope.yaml.jinja2 | 4 ++++ .../suit/nrf54h20/app_envelope_extflash.yaml.jinja2 | 4 ++++ .../suit/nrf54h20/rad_envelope_extflash.yaml.jinja2 | 4 ++++ .../root_with_binary_nordic_top_extflash.yaml.jinja2 | 4 ++++ 14 files changed, 52 insertions(+), 11 deletions(-) diff --git a/applications/nrf_desktop/VERSION b/applications/nrf_desktop/VERSION index 19a2caf000e5..b5c2c35ecc1a 100644 --- a/applications/nrf_desktop/VERSION +++ b/applications/nrf_desktop/VERSION @@ -3,12 +3,3 @@ VERSION_MINOR = 7 PATCHLEVEL = 99 VERSION_TWEAK = 0 EXTRAVERSION = - -APP_ROOT_SEQ_NUM = 1 -APP_ROOT_VERSION = 2.7.99 - -APP_LOCAL_1_SEQ_NUM = 1 -APP_LOCAL_1_VERSION = 2.7.99 - -RAD_LOCAL_1_SEQ_NUM = 1 -RAD_LOCAL_1_VERSION = 2.7.99 diff --git a/applications/nrf_desktop/bootloader_dfu.rst b/applications/nrf_desktop/bootloader_dfu.rst index 99c588b278d4..fb4daf33e2c6 100644 --- a/applications/nrf_desktop/bootloader_dfu.rst +++ b/applications/nrf_desktop/bootloader_dfu.rst @@ -220,9 +220,10 @@ SUIT also has the following options in the sysbuild configuration: .. note:: The ``SB_CONFIG_SUIT_ENVELOPE_SIGN`` is disabled, so the generated SUIT envelope is not signed. -SUIT reads the following options from the :file:`VERSION` file, used for :ref:`zephyr:app-version-details` in Zephyr and the |NCS|.: +By default, the SUIT generator sets the values inside the manifest based on the content of the :file:`VERSION` file, used for :ref:`zephyr:app-version-details` in Zephyr and the |NCS|.: - * ``APP_ROOT_SEQ_NUM`` - The nRF Desktop application uses the sequence number of root manifest to define an application version. + * The manifest sequence number is set in the same manner as the ``APPVERSION`` CMake variable. + * The manifest current (semantic) version is set in the same manner as the ``APP_VERSION_EXTENDED_STRING`` CMake variable. On the ``nrf54h20dk`` board, the dedicated DFU partition called ``dfu_partition`` is defined by default in the DTS. The partition is used to store the incoming SUIT envelope with an update candidate. diff --git a/config/suit/templates/nrf54h20/default/v1/app_envelope.yaml.jinja2 b/config/suit/templates/nrf54h20/default/v1/app_envelope.yaml.jinja2 index 4afa82e0da09..700aa1740bc6 100644 --- a/config/suit/templates/nrf54h20/default/v1/app_envelope.yaml.jinja2 +++ b/config/suit/templates/nrf54h20/default/v1/app_envelope.yaml.jinja2 @@ -8,6 +8,8 @@ SUIT_Envelope_Tagged: suit-manifest-version: 1 {%- if APP_LOCAL_1_SEQ_NUM is defined %} suit-manifest-sequence-number: {{ APP_LOCAL_1_SEQ_NUM }} +{%- elif DEFAULT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ DEFAULT_SEQ_NUM }} {%- else %} suit-manifest-sequence-number: 1 {%- endif %} @@ -68,6 +70,8 @@ SUIT_Envelope_Tagged: {%- if APP_LOCAL_1_VERSION is defined %} suit-current-version: {{ APP_LOCAL_1_VERSION }} +{%- elif DEFAULT_VERSION is defined %} + suit-current-version: {{ DEFAULT_VERSION }} {%- endif %} suit-install: diff --git a/config/suit/templates/nrf54h20/default/v1/rad_envelope.yaml.jinja2 b/config/suit/templates/nrf54h20/default/v1/rad_envelope.yaml.jinja2 index c2a483dbaec4..026cd632f3fc 100644 --- a/config/suit/templates/nrf54h20/default/v1/rad_envelope.yaml.jinja2 +++ b/config/suit/templates/nrf54h20/default/v1/rad_envelope.yaml.jinja2 @@ -13,6 +13,8 @@ SUIT_Envelope_Tagged: suit-manifest-version: 1 {%- if RAD_LOCAL_1_SEQ_NUM is defined %} suit-manifest-sequence-number: {{ RAD_LOCAL_1_SEQ_NUM }} +{%- elif DEFAULT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ DEFAULT_SEQ_NUM }} {%- else %} suit-manifest-sequence-number: 1 {%- endif %} @@ -73,6 +75,8 @@ SUIT_Envelope_Tagged: {%- if RAD_LOCAL_1_VERSION is defined %} suit-current-version: {{ RAD_LOCAL_1_VERSION }} +{%- elif DEFAULT_VERSION is defined %} + suit-current-version: {{ DEFAULT_VERSION }} {%- endif %} suit-install: diff --git a/config/suit/templates/nrf54h20/default/v1/root_with_binary_nordic_top.yaml.jinja2 b/config/suit/templates/nrf54h20/default/v1/root_with_binary_nordic_top.yaml.jinja2 index 0ddd6a4f3a06..7677b82e229e 100644 --- a/config/suit/templates/nrf54h20/default/v1/root_with_binary_nordic_top.yaml.jinja2 +++ b/config/suit/templates/nrf54h20/default/v1/root_with_binary_nordic_top.yaml.jinja2 @@ -24,6 +24,8 @@ SUIT_Envelope_Tagged: suit-manifest-version: 1 {%- if APP_ROOT_SEQ_NUM is defined %} suit-manifest-sequence-number: {{ APP_ROOT_SEQ_NUM }} +{%- elif DEFAULT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ DEFAULT_SEQ_NUM }} {%- else %} suit-manifest-sequence-number: 1 {%- endif %} @@ -114,6 +116,8 @@ SUIT_Envelope_Tagged: {%- if APP_ROOT_VERSION is defined %} suit-current-version: {{ APP_ROOT_VERSION }} +{%- elif DEFAULT_VERSION is defined %} + suit-current-version: {{ DEFAULT_VERSION }} {%- endif %} suit-install: diff --git a/config/suit/templates/nrf54h20/matter/v1/app_envelope.yaml.jinja2 b/config/suit/templates/nrf54h20/matter/v1/app_envelope.yaml.jinja2 index fce0ca5de7ed..941da9fd28f1 100644 --- a/config/suit/templates/nrf54h20/matter/v1/app_envelope.yaml.jinja2 +++ b/config/suit/templates/nrf54h20/matter/v1/app_envelope.yaml.jinja2 @@ -8,6 +8,8 @@ SUIT_Envelope_Tagged: suit-manifest-version: 1 {%- if APP_LOCAL_1_SEQ_NUM is defined %} suit-manifest-sequence-number: {{ APP_LOCAL_1_SEQ_NUM }} +{%- elif DEFAULT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ DEFAULT_SEQ_NUM }} {%- else %} suit-manifest-sequence-number: 1 {%- endif %} @@ -78,6 +80,8 @@ SUIT_Envelope_Tagged: {%- if APP_LOCAL_1_VERSION is defined %} suit-current-version: {{ APP_LOCAL_1_VERSION }} +{%- elif DEFAULT_VERSION is defined %} + suit-current-version: {{ DEFAULT_VERSION }} {%- endif %} suit-install: diff --git a/config/suit/templates/nrf54h20/matter/v1/rad_envelope.yaml.jinja2 b/config/suit/templates/nrf54h20/matter/v1/rad_envelope.yaml.jinja2 index 61eeb7bdb0d6..58a7777d4df4 100644 --- a/config/suit/templates/nrf54h20/matter/v1/rad_envelope.yaml.jinja2 +++ b/config/suit/templates/nrf54h20/matter/v1/rad_envelope.yaml.jinja2 @@ -13,6 +13,8 @@ SUIT_Envelope_Tagged: suit-manifest-version: 1 {%- if RAD_LOCAL_1_SEQ_NUM is defined %} suit-manifest-sequence-number: {{ RAD_LOCAL_1_SEQ_NUM }} +{%- elif DEFAULT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ DEFAULT_SEQ_NUM }} {%- else %} suit-manifest-sequence-number: 1 {%- endif %} @@ -69,6 +71,8 @@ SUIT_Envelope_Tagged: {%- if RAD_LOCAL_1_VERSION is defined %} suit-current-version: {{ RAD_LOCAL_1_VERSION }} +{%- elif DEFAULT_VERSION is defined %} + suit-current-version: {{ DEFAULT_VERSION }} {%- endif %} suit-install: diff --git a/config/suit/templates/nrf54h20/matter/v1/root_with_binary_nordic_top.yaml.jinja2 b/config/suit/templates/nrf54h20/matter/v1/root_with_binary_nordic_top.yaml.jinja2 index 5acaafde9785..04308783fb13 100644 --- a/config/suit/templates/nrf54h20/matter/v1/root_with_binary_nordic_top.yaml.jinja2 +++ b/config/suit/templates/nrf54h20/matter/v1/root_with_binary_nordic_top.yaml.jinja2 @@ -24,6 +24,8 @@ SUIT_Envelope_Tagged: suit-manifest-version: 1 {%- if APP_ROOT_SEQ_NUM is defined %} suit-manifest-sequence-number: {{ APP_ROOT_SEQ_NUM }} +{%- elif DEFAULT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ DEFAULT_SEQ_NUM }} {%- else %} suit-manifest-sequence-number: 1 {%- endif %} @@ -114,6 +116,8 @@ SUIT_Envelope_Tagged: {%- if APP_ROOT_VERSION is defined %} suit-current-version: {{ APP_ROOT_VERSION }} +{%- elif DEFAULT_VERSION is defined %} + suit-current-version: {{ DEFAULT_VERSION }} {%- endif %} suit-install: diff --git a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_suit_customize_dfu.rst b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_suit_customize_dfu.rst index 0ae51c223b6e..6dad99270453 100644 --- a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_suit_customize_dfu.rst +++ b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_suit_customize_dfu.rst @@ -252,6 +252,11 @@ The default templates searches for the following options inside the :file:`VERSI * ``RAD_RECOVERY_SEQ_NUM`` - Sets the radio recovery manifest sequence number. * ``RAD_RECOVERY_VERSION`` - Sets the radio recovery manifest current (semantic) version. +If the manifest sequence number or current (semantic) version is not defined for a manifest, the default template tries to generate those values, based on the application version values: + + * The default manifest sequence number is set in the same manner as the ``APPVERSION`` CMake variable. + * The default manifest current (semantic) version is set in the same manner as the ``APP_VERSION_EXTENDED_STRING`` CMake variable. + With the Python dictionary you are able to, for example: * Extract the CPU ID by using ``application['dt'].label2node['cpu'].unit_addr`` diff --git a/samples/suit/recovery/suit/nrf54h20/app_recovery_envelope.yaml.jinja2 b/samples/suit/recovery/suit/nrf54h20/app_recovery_envelope.yaml.jinja2 index 4d4cad647b54..9de9e4226e15 100644 --- a/samples/suit/recovery/suit/nrf54h20/app_recovery_envelope.yaml.jinja2 +++ b/samples/suit/recovery/suit/nrf54h20/app_recovery_envelope.yaml.jinja2 @@ -13,6 +13,8 @@ SUIT_Envelope_Tagged: suit-manifest-version: 1 {%- if APP_RECOVERY_SEQ_NUM is defined %} suit-manifest-sequence-number: {{ APP_RECOVERY_SEQ_NUM }} +{%- elif DEFAULT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ DEFAULT_SEQ_NUM }} {%- else %} suit-manifest-sequence-number: 1 {%- endif %} @@ -133,6 +135,8 @@ SUIT_Envelope_Tagged: {%- if APP_RECOVERY_VERSION is defined %} suit-current-version: {{ APP_RECOVERY_VERSION }} +{%- elif DEFAULT_VERSION is defined %} + suit-current-version: {{ DEFAULT_VERSION }} {%- endif %} suit-install: diff --git a/samples/suit/recovery/suit/nrf54h20/rad_recovery_envelope.yaml.jinja2 b/samples/suit/recovery/suit/nrf54h20/rad_recovery_envelope.yaml.jinja2 index 1d9cebcd2363..e45bbb8db9e6 100644 --- a/samples/suit/recovery/suit/nrf54h20/rad_recovery_envelope.yaml.jinja2 +++ b/samples/suit/recovery/suit/nrf54h20/rad_recovery_envelope.yaml.jinja2 @@ -8,6 +8,8 @@ SUIT_Envelope_Tagged: suit-manifest-version: 1 {%- if RAD_RECOVERY_SEQ_NUM is defined %} suit-manifest-sequence-number: {{ RAD_RECOVERY_SEQ_NUM }} +{%- elif DEFAULT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ DEFAULT_SEQ_NUM }} {%- else %} suit-manifest-sequence-number: 1 {%- endif %} @@ -68,6 +70,8 @@ SUIT_Envelope_Tagged: {%- if RAD_RECOVERY_VERSION is defined %} suit-current-version: {{ RAD_RECOVERY_VERSION }} +{%- elif DEFAULT_VERSION is defined %} + suit-current-version: {{ DEFAULT_VERSION }} {%- endif %} - suit-directive-fetch: diff --git a/samples/suit/smp_transfer/suit/nrf54h20/app_envelope_extflash.yaml.jinja2 b/samples/suit/smp_transfer/suit/nrf54h20/app_envelope_extflash.yaml.jinja2 index 0a58d07c1c78..895c5bfdf67b 100644 --- a/samples/suit/smp_transfer/suit/nrf54h20/app_envelope_extflash.yaml.jinja2 +++ b/samples/suit/smp_transfer/suit/nrf54h20/app_envelope_extflash.yaml.jinja2 @@ -8,6 +8,8 @@ SUIT_Envelope_Tagged: suit-manifest-version: 1 {%- if APP_LOCAL_1_SEQ_NUM is defined %} suit-manifest-sequence-number: {{ APP_LOCAL_1_SEQ_NUM }} +{%- elif DEFAULT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ DEFAULT_SEQ_NUM }} {%- else %} suit-manifest-sequence-number: 1 {%- endif %} @@ -80,6 +82,8 @@ SUIT_Envelope_Tagged: {%- if APP_LOCAL_1_VERSION is defined %} suit-current-version: {{ APP_LOCAL_1_VERSION }} +{%- elif DEFAULT_VERSION is defined %} + suit-current-version: {{ DEFAULT_VERSION }} {%- endif %} suit-payload-fetch: diff --git a/samples/suit/smp_transfer/suit/nrf54h20/rad_envelope_extflash.yaml.jinja2 b/samples/suit/smp_transfer/suit/nrf54h20/rad_envelope_extflash.yaml.jinja2 index fb44f67b27b6..29b34a4e87b6 100644 --- a/samples/suit/smp_transfer/suit/nrf54h20/rad_envelope_extflash.yaml.jinja2 +++ b/samples/suit/smp_transfer/suit/nrf54h20/rad_envelope_extflash.yaml.jinja2 @@ -13,6 +13,8 @@ SUIT_Envelope_Tagged: suit-manifest-version: 1 {%- if RAD_LOCAL_1_SEQ_NUM is defined %} suit-manifest-sequence-number: {{ RAD_LOCAL_1_SEQ_NUM }} +{%- elif DEFAULT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ DEFAULT_SEQ_NUM }} {%- else %} suit-manifest-sequence-number: 1 {%- endif %} @@ -71,6 +73,8 @@ SUIT_Envelope_Tagged: {%- if RAD_LOCAL_1_VERSION is defined %} suit-current-version: {{ RAD_LOCAL_1_VERSION }} +{%- elif DEFAULT_VERSION is defined %} + suit-current-version: {{ DEFAULT_VERSION }} {%- endif %} suit-payload-fetch: diff --git a/samples/suit/smp_transfer/suit/nrf54h20/root_with_binary_nordic_top_extflash.yaml.jinja2 b/samples/suit/smp_transfer/suit/nrf54h20/root_with_binary_nordic_top_extflash.yaml.jinja2 index d7db0e1da298..acd9bdd49bb0 100644 --- a/samples/suit/smp_transfer/suit/nrf54h20/root_with_binary_nordic_top_extflash.yaml.jinja2 +++ b/samples/suit/smp_transfer/suit/nrf54h20/root_with_binary_nordic_top_extflash.yaml.jinja2 @@ -24,6 +24,8 @@ SUIT_Envelope_Tagged: suit-manifest-version: 1 {%- if APP_ROOT_SEQ_NUM is defined %} suit-manifest-sequence-number: {{ APP_ROOT_SEQ_NUM }} +{%- elif DEFAULT_SEQ_NUM is defined %} + suit-manifest-sequence-number: {{ DEFAULT_SEQ_NUM }} {%- else %} suit-manifest-sequence-number: 1 {%- endif %} @@ -114,6 +116,8 @@ SUIT_Envelope_Tagged: {%- if APP_ROOT_VERSION is defined %} suit-current-version: {{ APP_ROOT_VERSION }} +{%- elif DEFAULT_VERSION is defined %} + suit-current-version: {{ DEFAULT_VERSION }} {%- endif %} suit-payload-fetch: From 66f7d9dfe6fdfff6a1607ca76d942c8201351052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vidar=20Lilleb=C3=B8?= Date: Thu, 22 Aug 2024 14:54:44 +0200 Subject: [PATCH 07/72] nrf_security: Add haltium key id definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copy of key id header file from internal docs. Signed-off-by: Vidar Lillebø --- .../include/psa/nrf_platform_key_ids.h | 365 ++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100644 subsys/nrf_security/include/psa/nrf_platform_key_ids.h diff --git a/subsys/nrf_security/include/psa/nrf_platform_key_ids.h b/subsys/nrf_security/include/psa/nrf_platform_key_ids.h new file mode 100644 index 000000000000..e7ca99adfa1f --- /dev/null +++ b/subsys/nrf_security/include/psa/nrf_platform_key_ids.h @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/** + * @file + * Nordic platform specific key identifiers. + */ + +#ifndef NRF_PLATFORM_KEY_IDS_H +#define NRF_PLATFORM_KEY_IDS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define HALTIUM_PLATFORM_PSA_KEY_ID(access, domain, usage, generation) \ + ((0x4 << 28) | ((access & 0xF) << 24) | ((domain & 0xFF) << 16) | ((usage & 0xFF) << 8) | \ + (generation & 0xF)) + +/* Key access rights */ +#define ACCESS_INTERNAL 0x0 +#define ACCESS_LOCAL 0x1 + +/* Domains */ +#define DOMAIN_NONE 0x00 +#define DOMAIN_SECURE 0x01 +#define DOMAIN_APPLICATION 0x02 +#define DOMAIN_RADIO 0x03 +#define DOMAIN_CELL 0x04 +#define DOMAIN_ISIM 0x05 +#define DOMAIN_WIFI 0x06 +#define DOMAIN_SYSCTRL 0x08 + +/* Key usage */ +#define USAGE_IAK 0x01 +#define USAGE_MKEK 0x02 +#define USAGE_MEXT 0x03 +#define USAGE_UROTENC 0x10 +#define USAGE_UROTPUBKEY 0x11 +#define USAGE_UROTRECOVERY 0x12 +#define USAGE_AUTHDEBUG 0x13 +#define USAGE_AUTHOP 0x14 +#define USAGE_FWENC 0x20 +#define USAGE_PUBKEY 0x21 +#define USAGE_AUTHDEBUG 0x23 +#define USAGE_STMTRACE 0x25 +#define USAGE_COREDUMP 0x26 +#define USAGE_RMNORDIC 0xAA +#define USAGE_RMOEM 0xBB + +/* KeyIDs used by SDFW for Identity Attestation Keys (IAKs) */ + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: SECURE (0x01), Usage: IAK (0x01), + * Generation: 1 (0x0) + */ +#define IAK_SECDOM_GEN1 0x40010100 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: APPLICATION (0x02), Usage: IAK (0x01), + * Generation: 1 (0x0) + */ +#define IAK_APPLICATION_GEN1 0x41020100 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: RADIO (0x03), Usage: IAK (0x01), + * Generation: 1 (0x0) + */ +#define IAK_RADIO_GEN1 0x41030100 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: CELL (0x04), Usage: IAK (0x01), + * Generation: 1 (0x0) + */ +#define IAK_CELL_GEN1 0x41040100 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: WIFI (0x06), Usage: IAK (0x01), + * Generation: 1 (0x0) + */ +#define IAK_WIFI_GEN1 0x41060100 + +/* KeyIDs used by SDFW for Master Key Encryption Keys (MKEKs) */ + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: SECURE (0x01), Usage: MKEK (0x02), + * Generation: 1 (0x0) + */ +#define MKEK_SECDOM_GEN1 0x40010200 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: APPLICATION (0x02), Usage: MKEK (0x02), + * Generation: 1 (0x0) + */ +#define MKEK_APPLICATION_GEN1 0x40020200 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: RADIO (0x03), Usage: MKEK (0x02), + * Generation: 1 (0x0) + */ +#define MKEK_RADIO_GEN1 0x40030200 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: CELL (0x04), Usage: MKEK (0x02), + * Generation: 1 (0x0) + */ +#define MKEK_CELL_GEN1 0x40040200 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: WIFI (0x06), Usage: MKEK (0x02), + * Generation: 1 (0x0) + */ +#define MKEK_WIFI_GEN1 0x40060200 + +/* KeyIDs used by SDFW for Master External Storage Keys (MEXTs) */ + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: SECURE (0x01), Usage: MEXT (0x03), + * Generation: 1 (0x0) + */ +#define MEXT_SECDOM_GEN1 0x40010300 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: APPLICATION (0x02), Usage: MEXT (0x03), + * Generation: 1 (0x0) + */ +#define MEXT_APPLICATION_GEN1 0x40020300 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: RADIO (0x03), Usage: MEXT (0x03), + * Generation: 1 (0x0) + */ +#define MEXT_RADIO_GEN1 0x40030300 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: CELL (0x04), Usage: MEXT (0x03), + * Generation: 1 (0x0) + */ +#define MEXT_CELL_GEN1 0x40040300 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: WIFI (0x06), Usage: MEXT (0x03), + * Generation: 1 (0x0) + */ +#define MEXT_WIFI_GEN1 0x40060300 + +/* KeyIDs used by SDFW for IETF SUIT manifest verification */ + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: NONE (0x00), Usage: + * MANIFEST_OEM_ROOT (0xAA), Generation: 1-4 (0x0-0x3) + */ +#define MANIFEST_PUBKEY_OEM_ROOT_GEN1 0x4000AA00 +#define MANIFEST_PUBKEY_OEM_ROOT_GEN2 0x4000AA01 +#define MANIFEST_PUBKEY_OEM_ROOT_GEN3 0x4000AA02 +#define MANIFEST_PUBKEY_OEM_ROOT_GEN4 0x4000AA03 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: NONE (0x00), Usage: + * MANIFEST_NORDIC_TOP (0xBB), Generation: 1-4 (0x0-0x3) + */ +#define MANIFEST_PUBKEY_NRF_TOP_GEN1 0x4000BB00 +#define MANIFEST_PUBKEY_NRF_TOP_GEN2 0x4000BB01 +#define MANIFEST_PUBKEY_NRF_TOP_GEN3 0x4000BB02 +#define MANIFEST_PUBKEY_NRF_TOP_GEN4 0x4000BB03 + +/* KeyIDs used by SDFW for IETF SUIT secure boot of local domain FW */ + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: SECURE (0x01), Usage: UROTPUBKEY + * (0x11), Generation: 1-4 (0x0-0x3) + */ +#define MANIFEST_PUBKEY_SECURE_GEN1 0x40011100 +#define MANIFEST_PUBKEY_SECURE_GEN2 0x40011101 +#define MANIFEST_PUBKEY_SECURE_GEN3 0x40011102 +#define MANIFEST_PUBKEY_SECURE_GEN4 0x40011103 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: APPLICATION (0x02), Usage: PUBKEY (0x21), + * Generation: 1-4 (0x0-0x3) + */ +#define MANIFEST_PUBKEY_APPLICATION_GEN1 0x40022100 +#define MANIFEST_PUBKEY_APPLICATION_GEN2 0x40022101 +#define MANIFEST_PUBKEY_APPLICATION_GEN3 0x40022102 +#define MANIFEST_PUBKEY_APPLICATION_GEN4 0x40022103 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: RADIOCORE (0x03), Usage: PUBKEY (0x21), + * Generation: 1-4 (0x0-0x3) + */ +#define MANIFEST_PUBKEY_RADIO_GEN1 0x40032100 +#define MANIFEST_PUBKEY_RADIO_GEN2 0x40032101 +#define MANIFEST_PUBKEY_RADIO_GEN3 0x40032102 +#define MANIFEST_PUBKEY_RADIO_GEN4 0x40032103 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: CELL (0x04), Usage: PUBKEY (0x21), + * Generation: 1-4 (0x0-0x3) + */ +#define MANIFEST_PUBKEY_CELL_GEN1 0x40042100 +#define MANIFEST_PUBKEY_CELL_GEN2 0x40042101 +#define MANIFEST_PUBKEY_CELL_GEN3 0x40042102 +#define MANIFEST_PUBKEY_CELL_GEN4 0x40042103 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: WIFI (0x06), Usage: PUBKEY (0x21), + * Generation: 1-4 (0x0-0x3) + */ +#define MANIFEST_PUBKEY_WIFI_GEN1 0x40062100 +#define MANIFEST_PUBKEY_WIFI_GEN2 0x40062101 +#define MANIFEST_PUBKEY_WIFI_GEN3 0x40062102 +#define MANIFEST_PUBKEY_WIFI_GEN4 0x40062103 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: SYSCTRL (0x08), Usage: PUBKEY (0x21), + * Generation: 1-4 (0x0-0x3) + */ +#define MANIFEST_PUBKEY_SYSCTRL_GEN1 0x40082100 +#define MANIFEST_PUBKEY_SYSCTRL_GEN2 0x40082101 +#define MANIFEST_PUBKEY_SYSCTRL_GEN3 0x40082102 +#define MANIFEST_PUBKEY_SYSCTRL_GEN4 0x40082103 + +/* KeyIDs used by SDFW for SUIT manifest decryption of local domain FW */ + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: SECURE (0x01), Usage: UROTENC (0x10), + * Generation: 1-2 (0x0-0x1) + */ +#define UROTENC_SECURE_GEN1 0x40011000 +#define UROTENC_SECURE_GEN2 0x40011001 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: APPLICATION (0x02), Usage: FWENC (0x20), + * Generation: 1-2 (0x0-0x1) + */ +#define FWENC_APPLICATION_GEN1 0x40022000 +#define FWENC_APPLICATION_GEN2 0x40022001 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: RADIO (0x03), Usage: FWENC (0x20), + * Generation: 1-2 (0x0-0x1) + */ +#define FWENC_RADIO_GEN1 0x40032000 +#define FWENC_RADIO_GEN2 0x40032001 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: CELL (0x04), Usage: FWENC (0x20), + * Generation: 1-2 (0x0-0x1) + */ +#define FWENC_CELL_GEN1 0x40042000 +#define FWENC_CELL_GEN2 0x40042001 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: WIFI (0x06), Usage: FWENC (0x20), + * Generation: 1-2 (0x0-0x1) + */ +#define FWENC_WIFI_GEN1 0x40062000 +#define FWENC_WIFI_GEN2 0x40062001 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: SYSCTRL (0x08), Usage: FWENC (0x20), + * Generation: 1-2 (0x0-0x1) + */ +#define FWENC_SYSCTRL_GEN1 0x40082000 +#define FWENC_SYSCTRL_GEN2 0x40082001 + +/* KeyIDs used by SDFW for temporarily re-enabling local domain debug access port using the Arm ADAC + * protocol + */ + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: SECURE (0x01), Usage: AUTHDEBUG + * (0x23), Generation: 1-4 (0x0-0x3) + */ +#define AUTHDEBUG_SECURE_GEN1 0x40012300 +#define AUTHDEBUG_SECURE_GEN2 0x40012301 +#define AUTHDEBUG_SECURE_GEN3 0x40012302 +#define AUTHDEBUG_SECURE_GEN4 0x40012303 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: APPLICATION (0x02), Usage: AUTHDEBUG + * (0x23), Generation: 1-4 (0x0-0x3) + */ +#define AUTHDEBUG_APPLICATION_GEN1 0x40022300 +#define AUTHDEBUG_APPLICATION_GEN2 0x40022301 +#define AUTHDEBUG_APPLICATION_GEN3 0x40022302 +#define AUTHDEBUG_APPLICATION_GEN4 0x40022303 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: RADIO (0x03), Usage: AUTHDEBUG + * (0x23), Generation: 1-4 (0x0-0x3) + */ +#define AUTHDEBUG_RADIO_GEN1 0x40032300 +#define AUTHDEBUG_RADIO_GEN2 0x40032301 +#define AUTHDEBUG_RADIO_GEN3 0x40032302 +#define AUTHDEBUG_RADIO_GEN4 0x40032303 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: CELL (0x04), Usage: AUTHDEBUG + * (0x23), Generation: 1-4 (0x0-0x3) + */ +#define AUTHDEBUG_CELL_GEN1 0x40042300 +#define AUTHDEBUG_CELL_GEN2 0x40042301 +#define AUTHDEBUG_CELL_GEN3 0x40042302 +#define AUTHDEBUG_CELL_GEN4 0x40042303 + +/* Class: Platform (0x4), Access: Internal (0x0), Domain: WIFI (0x06), Usage: AUTHDEBUG + * (0x23), Generation: 1-4 (0x0-0x3) + */ +#define AUTHDEBUG_WIFI_GEN1 0x40062300 +#define AUTHDEBUG_WIFI_GEN2 0x40062301 +#define AUTHDEBUG_WIFI_GEN3 0x40062302 +#define AUTHDEBUG_WIFI_GEN4 0x40062303 + +/* KeyIDs used by local domains to encrypt their STM trace data. */ + +/* Class: Platform (0x4), Access: Local (0x1), Domain: SECURE (0x01), Usage: STMTRACE (0x25), + * Generation: 1-2 (0x0-0x1) + */ +#define STMTRACE_SECURE_GEN1 0x41012500 +#define STMTRACE_SECURE_GEN2 0x41012501 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: APPLICATION (0x02), Usage: STMTRACE (0x25), + * Generation: 1-2 (0x0-0x1) + */ +#define STMTRACE_APPLICATION_GEN1 0x41022500 +#define STMTRACE_APPLICATION_GEN2 0x41022501 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: RADIO (0x03), Usage: STMTRACE (0x25), + * Generation: 1-2 (0x0-0x1) + */ +#define STMTRACE_RADIO_GEN1 0x41032500 +#define STMTRACE_RADIO_GEN2 0x41032501 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: CELL (0x04), Usage: STMTRACE (0x25), + * Generation: 1-2 (0x0-0x1) + */ +#define STMTRACE_CELL_GEN1 0x41042500 +#define STMTRACE_CELL_GEN2 0x41042501 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: WIFI (0x06), Usage: STMTRACE (0x25), + * Generation: 1-2 (0x0-0x1) + */ +#define STMTRACE_WIFI_GEN1 0x41062500 +#define STMTRACE_WIFI_GEN2 0x41062501 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: SYSCTRL (0x08), Usage: STMTRACE (0x25), + * Generation: 1-2 (0x0-0x1) + */ +#define STMTRACE_SYSCTRL_GEN1 0x41082500 +#define STMTRACE_SYSCTRL_GEN2 0x41082501 + +/* KeyIDs used by local domains to encrypt their coredump data from inside their fault handler. */ + +/* Class: Platform (0x4), Access: Local (0x1), Domain: SECURE (0x01), Usage: COREDUMP (0x26), + * Generation: 1-2 (0x0-0x1) + */ +#define COREDUMP_SECURE_GEN1 0x41012600 +#define COREDUMP_SECURE_GEN2 0x41012601 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: APPLICATION (0x02), Usage: COREDUMP (0x26), + * Generation: 1-2 (0x0-0x1) + */ +#define COREDUMP_APPLICATION_GEN1 0x41022600 +#define COREDUMP_APPLICATION_GEN2 0x41022601 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: RADIO (0x03), Usage: COREDUMP (0x26), + * Generation: 1-2 (0x0-0x1) + */ +#define COREDUMP_RADIO_GEN1 0x41032600 +#define COREDUMP_RADIO_GEN2 0x41032601 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: CELL (0x04), Usage: COREDUMP (0x26), + * Generation: 1-2 (0x0-0x1) + */ +#define COREDUMP_CELL_GEN1 0x41042600 +#define COREDUMP_CELL_GEN2 0x41042601 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: WIFI (0x06), Usage: COREDUMP (0x26), + * Generation: 1-2 (0x0-0x1) + */ +#define COREDUMP_WIFI_GEN1 0x41062600 +#define COREDUMP_WIFI_GEN2 0x41062601 + +/* Class: Platform (0x4), Access: Local (0x1), Domain: SYSCTRL (0x08), Usage: COREDUMP (0x26), + * Generation: 1-2 (0x0-0x1) + */ +#define COREDUMP_SYSCTRL_GEN1 0x41082600 +#define COREDUMP_SYSCTRL_GEN2 0x41082601 + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_PLATFORM_KEY_IDS_H */ From 277e156fac5cfea8712f23ad7fbbc94e8ac842b7 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 17 Jul 2024 12:07:19 +0100 Subject: [PATCH 08/72] sysbuild: Add MCUboot image numbers to Kconfig Adds Kconfig entries for the various MCUboot image numbers so that these can be referenced, and are automatically calculated based on what parts are enabled Signed-off-by: Jamie McCrae --- sysbuild/Kconfig.mcuboot | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/sysbuild/Kconfig.mcuboot b/sysbuild/Kconfig.mcuboot index 9429438d8946..aa3ec2df80da 100644 --- a/sysbuild/Kconfig.mcuboot +++ b/sysbuild/Kconfig.mcuboot @@ -119,14 +119,40 @@ endif # MCUBOOT_HARDWARE_DOWNGRADE_PREVENTION config MCUBOOT_MAX_UPDATEABLE_IMAGES int - default 3 + default 4 + +config MCUBOOT_APPLICATION_IMAGE_NUMBER + int + default 0 + +config MCUBOOT_NETWORK_CORE_IMAGE_NUMBER + int + default 1 if NETCORE_APP_UPDATE + default -1 + +config MCUBOOT_WIFI_PATCHES_IMAGE_NUMBER + int + default 2 if (WIFI_PATCHES_EXT_FLASH_XIP || WIFI_PATCHES_EXT_FLASH_STORE) && MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 + default 1 if (WIFI_PATCHES_EXT_FLASH_XIP || WIFI_PATCHES_EXT_FLASH_STORE) + default -1 + +config MCUBOOT_QSPI_XIP_IMAGE_NUMBER + int + default 3 if QSPI_XIP_SUPPORT && MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 && MCUBOOT_WIFI_PATCHES_IMAGE_NUMBER != -1 + default 2 if QSPI_XIP_SUPPORT && MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 + default 1 if QSPI_XIP_SUPPORT + default -1 + +config MCUBOOT_MIN_UPDATEABLE_IMAGES + int + default 4 if MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 && MCUBOOT_WIFI_PATCHES_IMAGE_NUMBER != -1 && MCUBOOT_QSPI_XIP_IMAGE_NUMBER != -1 + default 3 if (MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 && MCUBOOT_WIFI_PATCHES_IMAGE_NUMBER != -1) || (MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 && MCUBOOT_QSPI_XIP_IMAGE_NUMBER != -1) || (MCUBOOT_WIFI_PATCHES_IMAGE_NUMBER != -1 && MCUBOOT_QSPI_XIP_IMAGE_NUMBER != -1) + default 2 if MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 || MCUBOOT_WIFI_PATCHES_IMAGE_NUMBER != -1 || MCUBOOT_QSPI_XIP_IMAGE_NUMBER != -1 + default 1 config MCUBOOT_UPDATEABLE_IMAGES int "Updateable images" - range 3 MCUBOOT_MAX_UPDATEABLE_IMAGES if QSPI_XIP_SUPPORT - range 3 MCUBOOT_MAX_UPDATEABLE_IMAGES if NETCORE_APP_UPDATE && (WIFI_PATCHES_EXT_FLASH_XIP || WIFI_PATCHES_EXT_FLASH_STORE) - range 2 MCUBOOT_MAX_UPDATEABLE_IMAGES if NETCORE_APP_UPDATE || WIFI_PATCHES_EXT_FLASH_XIP || WIFI_PATCHES_EXT_FLASH_STORE - range 1 MCUBOOT_MAX_UPDATEABLE_IMAGES + range MCUBOOT_MIN_UPDATEABLE_IMAGES MCUBOOT_MAX_UPDATEABLE_IMAGES default 2 if SOC_SERIES_NRF91X && SECURE_BOOT_APPCORE && (MCUBOOT_MODE_SWAP_WITHOUT_SCRATCH || MCUBOOT_MODE_SWAP_SCRATCH || MCUBOOT_MODE_OVERWRITE_ONLY) help The number of images that MCUboot will be built with. From 5837db5004af557cb6e98b4d8fc032064e23bf53 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 17 Jul 2024 10:41:55 +0100 Subject: [PATCH 09/72] sysbuild: Add support for QSPI XIP split functionality Adds support for splitting up an application image into internal flash and external QSPI flash, allowing it to work from MCUboot Signed-off-by: Jamie McCrae --- cmake/sysbuild/image_signing_split.cmake | 255 +++++++++++++++++++++++ cmake/sysbuild/zip.cmake | 204 ++++++++++++------ sysbuild/CMakeLists.txt | 75 ++++++- sysbuild/Kconfig.dfu | 1 + sysbuild/Kconfig.mcuboot | 6 +- sysbuild/Kconfig.xip | 21 +- 6 files changed, 481 insertions(+), 81 deletions(-) create mode 100644 cmake/sysbuild/image_signing_split.cmake diff --git a/cmake/sysbuild/image_signing_split.cmake b/cmake/sysbuild/image_signing_split.cmake new file mode 100644 index 000000000000..daa690d1994b --- /dev/null +++ b/cmake/sysbuild/image_signing_split.cmake @@ -0,0 +1,255 @@ +# Copyright (c) 2020-2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + +# This file includes extra build system logic that is enabled when +# CONFIG_BOOTLOADER_MCUBOOT=y. +# +# It builds signed binaries using imgtool as a post-processing step +# after zephyr/zephyr.elf is created in the build directory. +# +# Since this file is brought in via include(), we do the work in a +# function to avoid polluting the top-level scope. + +function(zephyr_runner_file type path) + # Property magic which makes west flash choose the signed build + # output of a given type. + set_target_properties(runners_yaml_props_target PROPERTIES "${type}_file" "${path}") +endfunction() + +function(split) + # Splits an elf image into 2 sets of hex and bin files + # + # Required arguments are: + # ELF_FILE_IN + # ELF_SECTION_NAMES + # HEX_INCLUDE_FILE_OUT + # HEX_EXCLUDE_FILE_OUT + set(oneValueArgs ELF_FILE_IN HEX_INCLUDE_FILE_OUT HEX_EXCLUDE_FILE_OUT) + set(multiValueArgs ELF_SECTION_NAMES) + cmake_parse_arguments(SPLIT_ARG "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + check_arguments_required_all(split SPLIT_ARG ${oneValueArgs} ELF_SECTION_NAMES) + + set(include_param) + set(exclude_param) + + foreach(section_name ${SPLIT_ARG_ELF_SECTION_NAMES}) + set(include_param ${include_param} -R ${section_name}) + set(exclude_param ${exclude_param} -j ${section_name}) + endforeach() + + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${CMAKE_OBJCOPY} --output-target=ihex ${include_param} ${SPLIT_ARG_ELF_FILE_IN} ${SPLIT_ARG_HEX_INCLUDE_FILE_OUT}) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${CMAKE_OBJCOPY} --output-target=ihex ${exclude_param} ${SPLIT_ARG_ELF_FILE_IN} ${SPLIT_ARG_HEX_EXCLUDE_FILE_OUT}) +endfunction() + +function(zephyr_mcuboot_tasks) + set(keyfile "${CONFIG_MCUBOOT_SIGNATURE_KEY_FILE}") + set(keyfile_enc "${CONFIG_MCUBOOT_ENCRYPTION_KEY_FILE}") + + if(NOT "${CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE}") + # Check for misconfiguration. + if("${keyfile}" STREQUAL "") + # No signature key file, no signed binaries. No error, though: + # this is the documented behavior. + message(WARNING "Neither CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE or " + "CONFIG_MCUBOOT_SIGNATURE_KEY_FILE are set, the generated build will not be " + "bootable by MCUboot unless it is signed manually/externally.") + return() + endif() + endif() + + foreach(file keyfile keyfile_enc) + if(NOT "${${file}}" STREQUAL "") + if(NOT IS_ABSOLUTE "${${file}}") + # Relative paths are relative to 'west topdir'. + set(${file} "${WEST_TOPDIR}/${${file}}") + endif() + + if(NOT EXISTS "${${file}}" AND NOT "${CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE}") + message(FATAL_ERROR "west sign can't find file ${${file}} (Note: Relative paths are relative to the west workspace topdir \"${WEST_TOPDIR}\")") + elseif(NOT (CONFIG_BUILD_OUTPUT_BIN OR CONFIG_BUILD_OUTPUT_HEX)) + message(FATAL_ERROR "Can't sign images for MCUboot: Neither CONFIG_BUILD_OUTPUT_BIN nor CONFIG_BUILD_OUTPUT_HEX is enabled, so there's nothing to sign.") + endif() + endif() + endforeach() + + # Find imgtool. Even though west is installed, imgtool might not be. + # The user may also have a custom manifest which doesn't include + # MCUboot. + # + # Therefore, go with an explicitly installed imgtool first, falling + # back on mcuboot/scripts/imgtool.py. + if(IMGTOOL) + set(imgtool_path "${IMGTOOL}") + elseif(DEFINED ZEPHYR_MCUBOOT_MODULE_DIR) + set(IMGTOOL_PY "${ZEPHYR_MCUBOOT_MODULE_DIR}/scripts/imgtool.py") + if(EXISTS "${IMGTOOL_PY}") + set(imgtool_path "${IMGTOOL_PY}") + endif() + endif() + + # No imgtool, no signed binaries. + if(NOT DEFINED imgtool_path) + message(FATAL_ERROR "Can't sign images for MCUboot: can't find imgtool. To fix, install imgtool with pip3, or add the mcuboot repository to the west manifest and ensure it has a scripts/imgtool.py file.") + return() + endif() + + # Fetch QSPI XIP MCUboot image number from sysbuild + zephyr_get(qspi_xip_image_number VAR QSPI_XIP_IMAGE_NUMBER SYSBUILD) + + if(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT OR CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) + # XIP image, need to use the fixed address for these slots + if(CONFIG_NCS_IS_VARIANT_IMAGE) + set(imgtool_internal_rom_command --rom-fixed @PM_MCUBOOT_SECONDARY_ADDRESS@) + set(imgtool_external_rom_command --rom-fixed @PM_MCUBOOT_SECONDARY_${qspi_xip_image_number}_ADDRESS@) + else() + set(imgtool_internal_rom_command --rom-fixed @PM_MCUBOOT_PRIMARY_ADDRESS@) + set(imgtool_external_rom_command --rom-fixed @PM_MCUBOOT_PRIMARY_${qspi_xip_image_number}_ADDRESS@) + endif() + endif() + + # Split fields, imgtool_[internal/external]_sign_sysbuild are stored in cache which will have + # fields updated by sysbuild, imgtool_[internal/external]_sign must not be stored in cache + # because it would then prevent those fields from being updated without a pristine build + # TODO: NCSDK-28461 sysbuild PM fields cannot be updated without a pristine build, will become + # invalid if a static PM file is updated without pristine build + set(imgtool_internal_sign_sysbuild --slot-size @PM_MCUBOOT_PRIMARY_SIZE@ --pad-header --header-size @PM_MCUBOOT_PAD_SIZE@ ${imgtool_internal_rom_command} CACHE STRING "imgtool sign (internal flash) sysbuild replacement") + set(imgtool_external_sign_sysbuild --slot-size @PM_MCUBOOT_PRIMARY_${qspi_xip_image_number}_SIZE@ --pad-header --header-size @PM_MCUBOOT_PAD_SIZE@ ${imgtool_external_rom_command} CACHE STRING "imgtool sign (external flash) sysbuild replacement") + set(imgtool_internal_sign ${PYTHON_EXECUTABLE} ${imgtool_path} sign --version ${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION} --align 4 ${imgtool_internal_sign_sysbuild} ${imgtool_internal_rom_command} CACHE STRING "imgtool sign command (internal flash)") + set(imgtool_external_sign ${PYTHON_EXECUTABLE} ${imgtool_path} sign --version ${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION} --align 4 ${imgtool_external_sign_sysbuild} ${imgtool_external_rom_command} CACHE STRING "imgtool sign command (external flash)") + + # Arguments to imgtool. + if(NOT CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS STREQUAL "") + # Separate extra arguments into the proper format for adding to + # extra_post_build_commands. + # + # Use UNIX_COMMAND syntax for uniform results across host + # platforms. + separate_arguments(imgtool_extra UNIX_COMMAND ${CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS}) + else() + set(imgtool_extra) + endif() + + if(CONFIG_MCUBOOT_HARDWARE_DOWNGRADE_PREVENTION) + set(imgtool_extra --security-counter ${CONFIG_MCUBOOT_HW_DOWNGRADE_PREVENTION_COUNTER_VALUE} ${imgtool_extra}) + endif() + + if(NOT "${keyfile}" STREQUAL "") + set(imgtool_extra -k "${keyfile}" ${imgtool_extra}) + endif() + + set(imgtool_args ${imgtool_extra}) + + # Extensionless prefix of any output file. + set(output_internal ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.internal.signed) + set(output_external ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.external.signed) + set(output_merged ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.signed) + + if(CONFIG_BUILD_WITH_TFM) +# set(input ${APPLICATION_BINARY_DIR}/zephyr/tfm_merged) + message(FATAL_ERROR "TFM is not currently supported with QSPI XIP") + else() + set(input_internal ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.internal) + set(input_external ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.external) + endif() + + # List of additional build byproducts. + set(byproducts) + + # 'west sign' arguments for confirmed, unconfirmed and encrypted images. + set(unconfirmed_args) + set(confirmed_args) + set(encrypted_args) + + # Split files apart + split( + ELF_FILE_IN ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} + ELF_SECTION_NAMES ".extflash_text_reloc;.extflash_rodata_reloc" + HEX_INCLUDE_FILE_OUT ${input_internal}.hex + HEX_EXCLUDE_FILE_OUT ${input_external}.hex + ) + + # Set up .hex outputs. + if(CONFIG_BUILD_OUTPUT_HEX) + set(unconfirmed_internal_args ${input_internal}.hex ${output_internal}.hex) + set(unconfirmed_external_args ${input_external}.hex ${output_external}.hex) + list(APPEND byproducts ${output_internal}.hex ${output_external}.hex) + + # Do not run zephyr_runner_file here as PM will provide the merged hex file from + # sysbuild's scope unless this is a variant image + if(CONFIG_NCS_IS_VARIANT_IMAGE) + zephyr_runner_file(hex ${output_merged}.hex) + endif() + + set(BYPRODUCT_KERNEL_SIGNED_HEX_NAME "${output_merged}.hex" + CACHE FILEPATH "Signed kernel hex file" FORCE + ) + + # Add the west sign calls and their byproducts to the post-processing + # steps for zephyr.elf. + # + # CMake guarantees that multiple COMMANDs given to + # add_custom_command() are run in order, so adding the 'west sign' + # calls to the "extra_post_build_commands" property ensures they run + # after the commands which generate the unsigned versions. + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${imgtool_internal_sign} ${imgtool_args} ${unconfirmed_internal_args}) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${imgtool_external_sign} ${imgtool_args} ${unconfirmed_external_args}) + + # Combine the signed hex files into a single output hex file + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py -o ${output_merged}.hex ${output_internal}.hex ${output_external}.hex) + + if(NOT "${keyfile_enc}" STREQUAL "") + set(unconfirmed_internal_args ${input_internal}.hex ${output_internal}.encrypted.hex) + set(unconfirmed_external_args ${input_external}.hex ${output_external}.encrypted.hex) + list(APPEND byproducts ${output_internal}.encrypted.hex ${output_external}.encrypted.hex) + set(BYPRODUCT_KERNEL_SIGNED_ENCRYPTED_HEX_NAME "${output_merged}.encrypted.hex" + CACHE FILEPATH "Signed and encrypted kernel hex file" FORCE + ) + + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${imgtool_internal_sign} ${imgtool_args} --encrypt "${keyfile_enc}" ${unconfirmed_internal_args}) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${imgtool_external_sign} ${imgtool_args} --encrypt "${keyfile_enc}" ${unconfirmed_external_args}) + + # Combine the signed hex files into a single output hex file + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py -o ${output_merged}.encrypted.hex ${output_internal}.hex ${output_external}.hex) + endif() + endif() + + # Set up .bin outputs. + if(CONFIG_BUILD_OUTPUT_BIN) + # Instead of re-signing, convert the hex files to binary using objcopy + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${CMAKE_OBJCOPY} --input-target=ihex --output-target=binary ${output_internal}.hex ${output_internal}.bin) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${CMAKE_OBJCOPY} --input-target=ihex --output-target=binary ${output_external}.hex ${output_external}.bin) + + list(APPEND byproducts "${output_internal}.bin;${output_external}.bin") + + set(BYPRODUCT_KERNEL_SIGNED_BIN_NAME "${output_internal}.bin;${output_external}.bin" + CACHE FILEPATH "Signed kernel bin files" FORCE + ) + + if(NOT "${keyfile_enc}" STREQUAL "") + # Instead of re-signing, convert the encrypted hex files to binary using objcopy + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${CMAKE_OBJCOPY} --input-target=ihex --output-target=binary ${output_internal}.encrypted.hex ${output_internal}.encrypted.bin) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${CMAKE_OBJCOPY} --input-target=ihex --output-target=binary ${output_external}.encrypted.hex ${output_external}.encrypted.bin) + + list(APPEND byproducts "${output_internal}.encrypted.bin;${output_external}.encrypted.bin") + set(BYPRODUCT_KERNEL_SIGNED_ENCRYPTED_BIN_NAME "${output_internal}.encrypted.bin;${output_external}.encrypted.bin" + CACHE FILEPATH "Signed and encrypted kernel bin files" FORCE + ) + endif() + endif() + + set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts ${byproducts}) +endfunction() + +zephyr_mcuboot_tasks() diff --git a/cmake/sysbuild/zip.cmake b/cmake/sysbuild/zip.cmake index 935909e0718e..7c7ca4841470 100644 --- a/cmake/sysbuild/zip.cmake +++ b/cmake/sysbuild/zip.cmake @@ -1,6 +1,18 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +function(mcuboot_image_number_to_slot result image secondary) + if(secondary) + set(secondary_offset "+ 1") + else() + set(secondary_offset "") + endif() + + math(EXPR slot "${image} * 2 ${secondary_offset}") + + set(${result} ${slot} PARENT_SCOPE) +endfunction() + function(dfu_app_zip_package) set(bin_files) set(zip_names) @@ -13,50 +25,125 @@ function(dfu_app_zip_package) sysbuild_get(CONFIG_KERNEL_BIN_NAME IMAGE ${DEFAULT_IMAGE} VAR CONFIG_KERNEL_BIN_NAME KCONFIG) if(SB_CONFIG_DFU_ZIP_APP) - set(app_update_name "${DEFAULT_IMAGE}.bin") - set(secondary_app_update_name mcuboot_secondary_app.bin) - - if(NOT SB_CONFIG_MCUBOOT_BUILD_DIRECT_XIP_VARIANT) - # Application - set(generate_script_app_params - "${app_update_name}load_address=$" - "${app_update_name}image_index=0" - "${app_update_name}slot_index_primary=1" - "${app_update_name}slot_index_secondary=2" - "${app_update_name}version_MCUBOOT=${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION}" - ) - list(APPEND bin_files "${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.signed.bin") - list(APPEND zip_names ${app_update_name}) - list(APPEND signed_targets ${DEFAULT_IMAGE}_extra_byproducts) - set(exclude_files EXCLUDE ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.signed.bin) - set(include_files INCLUDE ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin) + if(SB_CONFIG_QSPI_XIP_SPLIT_IMAGE) + set(app_internal_update_name "${DEFAULT_IMAGE}.internal.bin") + set(app_external_update_name "${DEFAULT_IMAGE}.external.bin") + set(secondary_app_internal_update_name mcuboot_secondary_app.internal.bin) + set(secondary_app_external_update_name mcuboot_secondary_app.external.bin) + mcuboot_image_number_to_slot(internal_slot_primary ${SB_CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER} n) + mcuboot_image_number_to_slot(internal_slot_secondary ${SB_CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER} y) + mcuboot_image_number_to_slot(external_slot_primary ${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER} n) + mcuboot_image_number_to_slot(external_slot_secondary ${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER} y) + + if(NOT SB_CONFIG_MCUBOOT_BUILD_DIRECT_XIP_VARIANT) + # Application + set(generate_script_app_params + "${app_internal_update_name}load_address=$" + "${app_internal_update_name}image_index=${SB_CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER}" + "${app_internal_update_name}slot_index_primary=${internal_slot_primary}" + "${app_internal_update_name}slot_index_secondary=${internal_slot_secondary}" + "${app_internal_update_name}version_MCUBOOT=${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION}" + "${app_external_update_name}load_address=$" + "${app_external_update_name}image_index=${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER}" + "${app_external_update_name}slot_index_primary=${external_slot_primary}" + "${app_external_update_name}slot_index_secondary=${external_slot_secondary}" + "${app_external_update_name}version_MCUBOOT=${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION}" + ) + list(APPEND bin_files "${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.internal.signed.bin") + list(APPEND bin_files "${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.external.signed.bin") + list(APPEND zip_names "${app_internal_update_name};${app_external_update_name}") + list(APPEND signed_targets ${DEFAULT_IMAGE}_extra_byproducts) + set(exclude_files EXCLUDE ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.internal.signed.bin) + set(exclude_files EXCLUDE ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.external.signed.bin) + set(include_files INCLUDE ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin) + else() + # Application in DirectXIP mode + set(generate_script_app_params + "${app_internal_update_name}load_address=$" + "${app_internal_update_name}version_MCUBOOT+XIP=${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION}" + "${app_internal_update_name}image_index=${SB_CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER}" + "${app_internal_update_name}slot=${internal_slot_primary}" + "${app_external_update_name}load_address=$" + "${app_external_update_name}version_MCUBOOT+XIP=${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION}" + "${app_external_update_name}image_index=${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER}" + "${app_external_update_name}slot=${external_slot_primary}" + "${secondary_app_internal_update_name}load_address=$" + "${secondary_app_internal_update_name}image_index=0" + "${secondary_app_internal_update_name}slot=${internal_slot_secondary}" + "${secondary_app_internal_update_name}version_MCUBOOT+XIP=${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION}" + "${secondary_app_external_update_name}load_address=$" + "${secondary_app_external_update_name}image_index=${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER}" + "${secondary_app_external_update_name}slot=${external_slot_secondary}" + "${secondary_app_external_update_name}version_MCUBOOT+XIP=${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION}" + ) + + list(APPEND bin_files + "${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.internal.signed.bin" + "${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.external.signed.bin" + "${CMAKE_BINARY_DIR}/mcuboot_secondary_app/zephyr/${CONFIG_KERNEL_BIN_NAME}.internal.signed.bin" + "${CMAKE_BINARY_DIR}/mcuboot_secondary_app/zephyr/${CONFIG_KERNEL_BIN_NAME}.external.signed.bin" + ) + list(APPEND zip_names "${app_internal_update_name};${app_external_update_name};${secondary_app_internal_update_name};${secondary_app_external_update_name}") + list(APPEND signed_targets ${DEFAULT_IMAGE}_extra_byproducts mcuboot_secondary_app_extra_byproducts) + set(exclude_files EXCLUDE + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.internal.signed.bin + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.external.signed.bin + ${CMAKE_BINARY_DIR}/mcuboot_secondary_app/zephyr/${CONFIG_KERNEL_BIN_NAME}.internal.signed.bin + ${CMAKE_BINARY_DIR}/mcuboot_secondary_app/zephyr/${CONFIG_KERNEL_BIN_NAME}.external.signed.bin + ) + set(include_files INCLUDE + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin + ${CMAKE_BINARY_DIR}/mcuboot_secondary_app/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin + ) + endif() else() - # Application in DirectXIP mode - set(generate_script_app_params - "${app_update_name}load_address=$" - "${app_update_name}version_MCUBOOT+XIP=${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION}" - "${app_update_name}image_index=0" - "${app_update_name}slot=0" - "${secondary_app_update_name}load_address=$" - "${secondary_app_update_name}image_index=0" - "${secondary_app_update_name}slot=1" - "${secondary_app_update_name}version_MCUBOOT+XIP=${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION}" - ) - - list(APPEND bin_files - "${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.signed.bin" - "${CMAKE_BINARY_DIR}/mcuboot_secondary_app/zephyr/${CONFIG_KERNEL_BIN_NAME}.signed.bin" - ) - list(APPEND zip_names "${app_update_name};${secondary_app_update_name}") - list(APPEND signed_targets ${DEFAULT_IMAGE}_extra_byproducts mcuboot_secondary_app_extra_byproducts) - set(exclude_files EXCLUDE - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.signed.bin - ${CMAKE_BINARY_DIR}/mcuboot_secondary_app/zephyr/${CONFIG_KERNEL_BIN_NAME}.signed.bin - ) - set(include_files INCLUDE - ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin - ${CMAKE_BINARY_DIR}/mcuboot_secondary_app/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin - ) + set(app_update_name "${DEFAULT_IMAGE}.bin") + set(secondary_app_update_name mcuboot_secondary_app.bin) + mcuboot_image_number_to_slot(slot_primary ${SB_CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER} n) + mcuboot_image_number_to_slot(slot_secondary ${SB_CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER} y) + + if(NOT SB_CONFIG_MCUBOOT_BUILD_DIRECT_XIP_VARIANT) + # Application + set(generate_script_app_params + "${app_update_name}load_address=$" + "${app_update_name}image_index=${SB_CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER}" + "${app_update_name}slot_index_primary=${slot_primary}" + "${app_update_name}slot_index_secondary=${slot_secondary}" + "${app_update_name}version_MCUBOOT=${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION}" + ) + list(APPEND bin_files "${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.signed.bin") + list(APPEND zip_names ${app_update_name}) + list(APPEND signed_targets ${DEFAULT_IMAGE}_extra_byproducts) + set(exclude_files EXCLUDE ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.signed.bin) + set(include_files INCLUDE ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin) + else() + # Application in DirectXIP mode + set(generate_script_app_params + "${app_update_name}load_address=$" + "${app_update_name}version_MCUBOOT+XIP=${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION}" + "${app_update_name}image_index=${SB_CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER}" + "${app_update_name}slot=${slot_primary}" + "${secondary_app_update_name}load_address=$" + "${secondary_app_update_name}image_index=${SB_CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER}" + "${secondary_app_update_name}slot=${slot_secondary}" + "${secondary_app_update_name}version_MCUBOOT+XIP=${CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION}" + ) + + list(APPEND bin_files + "${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.signed.bin" + "${CMAKE_BINARY_DIR}/mcuboot_secondary_app/zephyr/${CONFIG_KERNEL_BIN_NAME}.signed.bin" + ) + list(APPEND zip_names "${app_update_name};${secondary_app_update_name}") + list(APPEND signed_targets ${DEFAULT_IMAGE}_extra_byproducts mcuboot_secondary_app_extra_byproducts) + set(exclude_files EXCLUDE + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.signed.bin + ${CMAKE_BINARY_DIR}/mcuboot_secondary_app/zephyr/${CONFIG_KERNEL_BIN_NAME}.signed.bin + ) + set(include_files INCLUDE + ${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin + ${CMAKE_BINARY_DIR}/mcuboot_secondary_app/zephyr/${CONFIG_KERNEL_BIN_NAME}.bin + ) + endif() endif() endif() @@ -66,11 +153,15 @@ function(dfu_app_zip_package) set(net_update_name "${image_name}.bin") sysbuild_get(net_core_board IMAGE ${image_name} VAR BOARD CACHE) sysbuild_get(net_update_version IMAGE ${image_name} VAR CONFIG_FW_INFO_FIRMWARE_VERSION KCONFIG) + + mcuboot_image_number_to_slot(net_update_slot_primary ${SB_CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER} n) + mcuboot_image_number_to_slot(net_update_slot_secondary ${SB_CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER} y) + set(generate_script_app_params ${generate_script_app_params} - "${net_update_name}image_index=1" - "${net_update_name}slot_index_primary=3" - "${net_update_name}slot_index_secondary=4" + "${net_update_name}image_index=${SB_CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER}" + "${net_update_name}slot_index_primary=${net_update_slot_primary}" + "${net_update_name}slot_index_secondary=${net_update_slot_secondary}" "${net_update_name}load_address=$" "${net_update_name}version=${net_update_version}" "${net_update_name}board=${net_core_board}" @@ -83,19 +174,14 @@ function(dfu_app_zip_package) if(SB_CONFIG_DFU_ZIP_WIFI_FW_PATCH) # nRF7x Wifi patch - if(SB_CONFIG_NETCORE_APP_UPDATE) - list(APPEND generate_script_app_params - "nrf70.binimage_index=2" - "nrf70.binslot_index_primary=5" - "nrf70.binslot_index_secondary=6" - ) - else() - list(APPEND generate_script_app_params - "nrf70.binimage_index=1" - "nrf70.binslot_index_primary=3" - "nrf70.binslot_index_secondary=4" - ) - endif() + mcuboot_image_number_to_slot(nrf70_patches_slot_primary ${SB_CONFIG_MCUBOOT_WIFI_PATCHES_IMAGE_NUMBER} n) + mcuboot_image_number_to_slot(nrf70_patches_slot_secondary ${SB_CONFIG_MCUBOOT_WIFI_PATCHES_IMAGE_NUMBER} y) + + list(APPEND generate_script_app_params + "nrf70.binimage_index=${SB_CONFIG_MCUBOOT_WIFI_PATCHES_IMAGE_NUMBER}" + "nrf70.binslot_index_primary=${nrf70_patches_slot_primary}" + "nrf70.binslot_index_secondary=${nrf70_patches_slot_secondary}" + ) list(APPEND bin_files "${CMAKE_BINARY_DIR}/nrf70.signed.bin") list(APPEND zip_names "nrf70.bin") diff --git a/sysbuild/CMakeLists.txt b/sysbuild/CMakeLists.txt index cfebc303868e..ac06fd57e9a7 100644 --- a/sysbuild/CMakeLists.txt +++ b/sysbuild/CMakeLists.txt @@ -241,16 +241,54 @@ function(${SYSBUILD_CURRENT_MODULE_NAME}_pre_cmake) if(SB_CONFIG_PARTITION_MANAGER) # Use NCS signing script with support for PM - set(${DEFAULT_IMAGE}_SIGNING_SCRIPT "${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/image_signing.cmake" CACHE INTERNAL "MCUboot signing script" FORCE) + if(SB_CONFIG_QSPI_XIP_SPLIT_IMAGE) + set(${DEFAULT_IMAGE}_SIGNING_SCRIPT "${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/image_signing_split.cmake" CACHE INTERNAL "MCUboot signing script" FORCE) - if(SB_CONFIG_MCUBOOT_BUILD_DIRECT_XIP_VARIANT) - set(mcuboot_secondary_app_SIGNING_SCRIPT "${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/image_signing.cmake" CACHE INTERNAL "MCUboot signing script" FORCE) - elseif(SB_CONFIG_MCUBOOT_MODE_FIRMWARE_UPDATER) - set(firmware_loader_SIGNING_SCRIPT "${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/image_signing_firmware_loader.cmake" CACHE INTERNAL "MCUboot signing script" FORCE) + if(SB_CONFIG_MCUBOOT_BUILD_DIRECT_XIP_VARIANT) + set(mcuboot_secondary_app_SIGNING_SCRIPT "${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/image_signing_split.cmake" CACHE INTERNAL "MCUboot signing script" FORCE) + endif() - set_target_properties(firmware_loader PROPERTIES - IMAGE_CONF_SCRIPT ${ZEPHYR_NRF_MODULE_DIR}/sysbuild/image_configurations/firmware_loader_image_default.cmake - ) + # Share QSPI XIP MCUboot image number with the default image to allow for signing script + # to get the partition manager configuration + set(${DEFAULT_IMAGE}_QSPI_XIP_IMAGE_NUMBER ${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER} CACHE INTERNAL "QSPI XIP image number" FORCE) + + if(SB_CONFIG_MCUBOOT_BUILD_DIRECT_XIP_VARIANT) + set(mcuboot_secondary_app_QSPI_XIP_IMAGE_NUMBER ${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER} CACHE INTERNAL "QSPI XIP image number" FORCE) + endif() + + # Flash drivers are mandatory with QSPI XIP split image support + set_config_bool(${DEFAULT_IMAGE} CONFIG_FLASH y) + set_config_bool(mcuboot CONFIG_FLASH y) + set_config_bool(mcuboot CONFIG_MULTITHREADING y) + set_config_bool(mcuboot CONFIG_MCUBOOT_VERIFY_IMG_ADDRESS n) + + # Set options on default image to allow QSPI XIP execution + set_config_bool(${DEFAULT_IMAGE} CONFIG_XIP y) + set_config_bool(${DEFAULT_IMAGE} CONFIG_CODE_DATA_RELOCATION y) + set_config_bool(${DEFAULT_IMAGE} CONFIG_HAVE_CUSTOM_LINKER_SCRIPT y) + set_config_bool(${DEFAULT_IMAGE} CONFIG_BUILD_NO_GAP_FILL y) + + if(NOT DEFINED SB_CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK) + # If external driver check Kconfig is enabled then users will need to select their own + # Kconfigs (to allow for forked/derivative QSPI NOR drivers), otherwise force enable the + # driver for the default image and MCUboot + set_config_bool(${DEFAULT_IMAGE} CONFIG_NORDIC_QSPI_NOR y) + set_config_bool(${DEFAULT_IMAGE} CONFIG_NORDIC_QSPI_NOR_XIP y) + set_config_bool(mcuboot CONFIG_NORDIC_QSPI_NOR y) + set_config_bool(mcuboot CONFIG_NORDIC_QSPI_NOR_XIP y) + endif() + else() + set(${DEFAULT_IMAGE}_SIGNING_SCRIPT "${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/image_signing.cmake" CACHE INTERNAL "MCUboot signing script" FORCE) + + if(SB_CONFIG_MCUBOOT_BUILD_DIRECT_XIP_VARIANT) + set(mcuboot_secondary_app_SIGNING_SCRIPT "${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/image_signing.cmake" CACHE INTERNAL "MCUboot signing script" FORCE) + elseif(SB_CONFIG_MCUBOOT_MODE_FIRMWARE_UPDATER) + set(firmware_loader_SIGNING_SCRIPT "${ZEPHYR_NRF_MODULE_DIR}/cmake/sysbuild/image_signing_firmware_loader.cmake" CACHE INTERNAL "MCUboot signing script" FORCE) + + set_target_properties(firmware_loader PROPERTIES + IMAGE_CONF_SCRIPT ${ZEPHYR_NRF_MODULE_DIR}/sysbuild/image_configurations/firmware_loader_image_default.cmake + ) + endif() endif() if(SB_CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK) @@ -478,7 +516,7 @@ function(${SYSBUILD_CURRENT_MODULE_NAME}_post_cmake) endif() if(SB_CONFIG_SUPPORT_NETCORE AND NOT SB_CONFIG_NETCORE_EMPTY) - get_property(PM_MCUBOOT_PRIMARY_1_SIZE TARGET partition_manager PROPERTY PM_MCUBOOT_PRIMARY_1_SIZE) + get_property(PM_MCUBOOT_PRIMARY_${SB_CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER}_SIZE TARGET partition_manager PROPERTY PM_MCUBOOT_PRIMARY_${SB_CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER}_SIZE) endif() if(SB_CONFIG_WIFI_PATCHES_EXT_FLASH_STORE) @@ -486,7 +524,12 @@ function(${SYSBUILD_CURRENT_MODULE_NAME}_post_cmake) get_property(PM_NRF70_WIFI_FW_SIZE TARGET partition_manager PROPERTY PM_NRF70_WIFI_FW_SIZE) endif() - if(SB_CONFIG_MCUBOOT_MODE_FIRMWARE_UPDATER) + if(SB_CONFIG_QSPI_XIP_SPLIT_IMAGE) + get_property(PM_MCUBOOT_PRIMARY_${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER}_ADDRESS TARGET partition_manager PROPERTY PM_MCUBOOT_PRIMARY_${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER}_ADDRESS) + get_property(PM_MCUBOOT_PRIMARY_${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER}_SIZE TARGET partition_manager PROPERTY PM_MCUBOOT_PRIMARY_${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER}_SIZE) + get_property(PM_MCUBOOT_SECONDARY_${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER}_ADDRESS TARGET partition_manager PROPERTY PM_MCUBOOT_SECONDARY_${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER}_ADDRESS) + get_property(PM_MCUBOOT_SECONDARY_${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER}_SIZE TARGET partition_manager PROPERTY PM_MCUBOOT_SECONDARY_${SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER}_SIZE) + elseif(SB_CONFIG_MCUBOOT_MODE_FIRMWARE_UPDATER) get_property(PM_MCUBOOT_SECONDARY_ADDRESS TARGET partition_manager PROPERTY PM_MCUBOOT_SECONDARY_ADDRESS) get_property(PM_MCUBOOT_SECONDARY_SIZE TARGET partition_manager PROPERTY PM_MCUBOOT_SECONDARY_SIZE) endif() @@ -495,6 +538,18 @@ function(${SYSBUILD_CURRENT_MODULE_NAME}_post_cmake) if(SB_CONFIG_SUPPORT_NETCORE AND NOT SB_CONFIG_NETCORE_NONE) sysbuild_add_dependencies(FLASH ${DEFAULT_IMAGE} ${SB_CONFIG_NETCORE_IMAGE_NAME}) endif() + + if(SB_CONFIG_QSPI_XIP_SPLIT_IMAGE AND SB_CONFIG_SOC_NRF52840) + # Emit a warning to the user to not relocate interrupts as this can brick nRF52840 devices + message(WARNING " + -------------------------------------------------------------------------------------------- + --- WARNING: SB_CONFIG_QSPI_XIP_SPLIT_IMAGE is enabled and target device is an nRF52840: --- + --- Care must be taken to not relocate any interrupts to the QSPI XIP flash as this can --- + --- cause the SoC to enter an undefined operation state, causing the debug access port --- + --- to become blocked, potentially bricking the device. --- + -------------------------------------------------------------------------------------------- + ") + endif() endif() foreach(image ${IMAGES}) configure_cache(IMAGE ${image}) diff --git a/sysbuild/Kconfig.dfu b/sysbuild/Kconfig.dfu index 59c62f53e650..50e6c868ecd0 100644 --- a/sysbuild/Kconfig.dfu +++ b/sysbuild/Kconfig.dfu @@ -5,6 +5,7 @@ menuconfig DFU_MULTI_IMAGE_PACKAGE_BUILD bool "Create multi-image DFU" depends on BOOTLOADER_MCUBOOT + depends on !QSPI_XIP_SPLIT_IMAGE help Build DFU Multi Image package that contains a manifest file followed by selected update images. diff --git a/sysbuild/Kconfig.mcuboot b/sysbuild/Kconfig.mcuboot index aa3ec2df80da..a04b37b2ed61 100644 --- a/sysbuild/Kconfig.mcuboot +++ b/sysbuild/Kconfig.mcuboot @@ -138,9 +138,9 @@ config MCUBOOT_WIFI_PATCHES_IMAGE_NUMBER config MCUBOOT_QSPI_XIP_IMAGE_NUMBER int - default 3 if QSPI_XIP_SUPPORT && MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 && MCUBOOT_WIFI_PATCHES_IMAGE_NUMBER != -1 - default 2 if QSPI_XIP_SUPPORT && MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 - default 1 if QSPI_XIP_SUPPORT + default 3 if QSPI_XIP_SPLIT_IMAGE && MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 && MCUBOOT_WIFI_PATCHES_IMAGE_NUMBER != -1 + default 2 if QSPI_XIP_SPLIT_IMAGE && MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 + default 1 if QSPI_XIP_SPLIT_IMAGE default -1 config MCUBOOT_MIN_UPDATEABLE_IMAGES diff --git a/sysbuild/Kconfig.xip b/sysbuild/Kconfig.xip index ac1f5317396a..cc415dd8c128 100644 --- a/sysbuild/Kconfig.xip +++ b/sysbuild/Kconfig.xip @@ -1,18 +1,21 @@ -# Copyright (c) 2023 Nordic Semiconductor +# Copyright (c) 2023-2024 Nordic Semiconductor # # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause config SUPPORT_QSPI_XIP bool + default y if SOC_NRF52840 default y if SOC_NRF5340_CPUAPP + default y if SOC_SERIES_NRF91X -menuconfig QSPI_XIP_SUPPORT - bool "QSPI XIP support" - depends on SUPPORT_QSPI_XIP +menuconfig QSPI_XIP_SPLIT_IMAGE + bool "QSPI XIP split image" + depends on SUPPORT_QSPI_XIP && BOOTLOADER_MCUBOOT && PARTITION_MANAGER + depends on PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY help - Configures images and build system to support executing code from - QSPI flash in XIP mode. Will also configure an additional image for - MCUboot (if enabled) to allow for updating the image. + Configures images and build system to support executing code from QSPI flash in XIP + mode. Will also configure an additional image for MCUboot (if enabled) to allow for + updating the image. - Requires `mcuboot_primary_2` and `mcuboot_secondary_2` entries in a - partition manager configuration file. + Requires `mcuboot_primary_X` and `mcuboot_secondary_X` entries in a partition manager + configuration file where X is `SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER`. From 4e8421f70b4fff815ee35670006dcd7dcfae6d4c Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 17 Jul 2024 10:42:49 +0100 Subject: [PATCH 10/72] samples: nrf5340: extxip_smp_svr: Fix wrong variable type Fixes using a variable type that was deprecated a very long time ago in zephyr 2.3 and should not have been used in this sample Signed-off-by: Jamie McCrae --- samples/nrf5340/extxip_smp_svr/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/nrf5340/extxip_smp_svr/CMakeLists.txt b/samples/nrf5340/extxip_smp_svr/CMakeLists.txt index 34dcdc2ebd46..8dab6741f9e6 100644 --- a/samples/nrf5340/extxip_smp_svr/CMakeLists.txt +++ b/samples/nrf5340/extxip_smp_svr/CMakeLists.txt @@ -5,11 +5,11 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(smp_svr_ext_xip) # This project uses orginal sdk-zephyr C source code -target_sources(app PRIVATE $ENV{ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/main.c) -target_sources_ifdef(CONFIG_MCUMGR_TRANSPORT_BT app PRIVATE $ENV{ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c) +target_sources(app PRIVATE ${ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/main.c) +target_sources_ifdef(CONFIG_MCUMGR_TRANSPORT_BT app PRIVATE ${ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c) # This places the application bluetooth.c file and some MCUmgr libraries into QSPI XIP -zephyr_code_relocate(FILES $ENV{ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c LOCATION EXTFLASH_TEXT NOCOPY) +zephyr_code_relocate(FILES ${ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c LOCATION EXTFLASH_TEXT NOCOPY) zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__mgmt LOCATION EXTFLASH_TEXT NOCOPY) zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__transport LOCATION EXTFLASH_TEXT NOCOPY) zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__util LOCATION EXTFLASH_TEXT NOCOPY) @@ -17,7 +17,7 @@ zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__smp LOCATION EXTFLASH_TEXT NO zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__grp__img_mgmt LOCATION EXTFLASH_TEXT NOCOPY) zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__grp__os_mgmt LOCATION EXTFLASH_TEXT NOCOPY) -zephyr_code_relocate(FILES $ENV{ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c LOCATION RAM_DATA) +zephyr_code_relocate(FILES ${ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c LOCATION RAM_DATA) zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__mgmt LOCATION RAM_DATA) zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__transport LOCATION RAM_DATA) zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__util LOCATION RAM_DATA) From a3d8ca0c69f22a0734993ca889f0b0036d266176 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 17 Jul 2024 10:45:00 +0100 Subject: [PATCH 11/72] samples: nrf5340: extxip_smp_svr: Add sysbuild configuration Adds sysbuild configuration to this sample Signed-off-by: Jamie McCrae --- samples/nrf5340/extxip_smp_svr/CMakeLists.txt | 7 ++ samples/nrf5340/extxip_smp_svr/README.rst | 16 +-- samples/nrf5340/extxip_smp_svr/pm_static.yml | 15 +++ .../pm_static_no_network_core.yml | 100 ++++++++++++++++++ samples/nrf5340/extxip_smp_svr/prj.conf | 7 -- .../extxip_smp_svr/prj_no_network_core.conf | 74 +++++++++++++ samples/nrf5340/extxip_smp_svr/sample.yaml | 14 ++- samples/nrf5340/extxip_smp_svr/sysbuild.conf | 13 +++ .../sysbuild/mcuboot/app.overlay | 5 + .../boards/nrf5340dk_nrf5340_cpuapp.overlay | 6 ++ .../nrf5340dk_nrf5340_cpuapp_minimal.conf | 13 +++ .../boards/thingy53_nrf5340_cpuapp.conf | 74 +++++++++++++ .../boards/thingy53_nrf5340_cpuapp.overlay | 6 ++ .../extxip_smp_svr/sysbuild/mcuboot/prj.conf | 48 +++++++++ .../sysbuild/mcuboot/prj_no_network_core.conf | 51 +++++++++ .../sysbuild_no_network_core.conf | 12 +++ 16 files changed, 438 insertions(+), 23 deletions(-) create mode 100644 samples/nrf5340/extxip_smp_svr/pm_static_no_network_core.yml create mode 100644 samples/nrf5340/extxip_smp_svr/prj_no_network_core.conf create mode 100644 samples/nrf5340/extxip_smp_svr/sysbuild.conf create mode 100644 samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/app.overlay create mode 100644 samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay create mode 100644 samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf create mode 100644 samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/thingy53_nrf5340_cpuapp.conf create mode 100644 samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/thingy53_nrf5340_cpuapp.overlay create mode 100644 samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/prj.conf create mode 100644 samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/prj_no_network_core.conf create mode 100644 samples/nrf5340/extxip_smp_svr/sysbuild_no_network_core.conf diff --git a/samples/nrf5340/extxip_smp_svr/CMakeLists.txt b/samples/nrf5340/extxip_smp_svr/CMakeLists.txt index 8dab6741f9e6..548bc68e96bd 100644 --- a/samples/nrf5340/extxip_smp_svr/CMakeLists.txt +++ b/samples/nrf5340/extxip_smp_svr/CMakeLists.txt @@ -1,5 +1,12 @@ cmake_minimum_required(VERSION 3.20.0) +macro(app_set_runner_args) + if(CONFIG_BOARD_THINGY53_NRF5340_CPUAPP) + # Use alternative QSPI configuration file when flashing Thingy53 + board_runner_args(nrfjprog "--qspiini=${CMAKE_CURRENT_SOURCE_DIR}/Qspi_thingy53.ini") + endif() +endmacro() + find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(smp_svr_ext_xip) diff --git a/samples/nrf5340/extxip_smp_svr/README.rst b/samples/nrf5340/extxip_smp_svr/README.rst index b392860f6ff6..a0e5e0dcdf48 100644 --- a/samples/nrf5340/extxip_smp_svr/README.rst +++ b/samples/nrf5340/extxip_smp_svr/README.rst @@ -43,29 +43,17 @@ Building and running .. |sample path| replace:: :file:`samples/nrf5340/extxip_smp_svr` .. include:: /includes/build_and_run.txt -Because sysbuild is currently not supported, you must add the ``--no-sysbuild`` argument when building the sample: .. parsed-literal:: :class: highlight - west build -b *board_target* --no-sysbuild + west build -b *board_target* -The |NCS| build system generates all essential binaries, including the application for internal and external QSPI flash, the networking stack, and the MCUboot. +The |NCS| build system generates all essential binaries, including the application for internal and external QSPI flash, the networking stack, and MCUboot. The build process involves signing all the application binaries except for MCUboot which does not require signing in this configuration. To upload MCUboot and a bundle of images to the nRF5340 SoC, use the ``west flash`` command. -For Thingy:53, however, the QSPI memory requires a dedicated configuration file for flashing. -In such a case, run the following command instead: - -.. code-block:: console - - nrfjprog -f NRF53 --coprocessor CP_NETWORK --sectorerase --program hci_ipc/zephyr/merged_CPUNET.hex --verify - nrfjprog -f NRF53 --sectorerase --program mcuboot/zephyr/zephyr.hex --verify - nrfjprog -f NRF53 --sectorerase --program zephyr/internal_flash_signed.hex --verify - nrfjprog -f NRF53 --qspisectorerase --program zephyr/qspi_flash_signed.hex --qspiini /Qspi_thingy53.ini --verify - nrfjprog -f NRF53 --reset - Testing ======= diff --git a/samples/nrf5340/extxip_smp_svr/pm_static.yml b/samples/nrf5340/extxip_smp_svr/pm_static.yml index 7185a94e29e5..10f5de10ceee 100644 --- a/samples/nrf5340/extxip_smp_svr/pm_static.yml +++ b/samples/nrf5340/extxip_smp_svr/pm_static.yml @@ -64,8 +64,23 @@ mcuboot_primary_2: address: 0x120000 device: MX25R64 end_address: 0x160000 + orig_span: &id003 + - mcuboot_primary_2_pad + - mcuboot_primary_2_app region: external_flash size: 0x40000 + span: *id003 +mcuboot_primary_2_pad: + address: 0x120000 + end_address: 0x120200 + region: external_flash + size: 0x200 +mcuboot_primary_2_app: + address: 0x120200 + device: MX25R64 + end_address: 0x40000 + region: external_flash + size: 0x3FE00 mcuboot_secondary_2: address: 0x160000 device: MX25R64 diff --git a/samples/nrf5340/extxip_smp_svr/pm_static_no_network_core.yml b/samples/nrf5340/extxip_smp_svr/pm_static_no_network_core.yml new file mode 100644 index 000000000000..378a21653b6b --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/pm_static_no_network_core.yml @@ -0,0 +1,100 @@ +app: + address: 0x10200 + end_address: 0xe4000 + region: flash_primary + size: 0xd3e00 +external_flash: + address: 0x120000 + device: MX25R64 + end_address: 0x800000 + region: external_flash + size: 0x6e0000 +mcuboot: + address: 0x0 + end_address: 0x10000 + region: flash_primary + size: 0x10000 +mcuboot_pad: + address: 0x10000 + end_address: 0x10200 + region: flash_primary + size: 0x200 +mcuboot_primary: + address: 0x10000 + end_address: 0xe4000 + orig_span: &id001 + - mcuboot_pad + - app + region: flash_primary + size: 0xd4000 + span: *id001 +mcuboot_primary_1: + address: 0x120000 + device: external_flash + end_address: 0x160000 + orig_span: &id003 + - mcuboot_primary_1_pad + - mcuboot_primary_1_app + region: external_flash + size: 0x40000 + span: *id003 +mcuboot_primary_1_pad: + address: 0x120000 + end_address: 0x120200 + region: external_flash + size: 0x200 +mcuboot_primary_1_app: + address: 0x120200 + device: MX25R64 + end_address: 0x160000 + region: external_flash + size: 0x3FE00 +mcuboot_primary_app: + address: 0x10200 + end_address: 0xe4000 + orig_span: &id002 + - app + region: flash_primary + size: 0xd3e00 + span: *id002 +mcuboot_secondary: + address: 0x0 + device: MX25R64 + end_address: 0xd4000 + region: external_flash + size: 0xd4000 +mcuboot_secondary_1: + address: 0xd4000 + device: MX25R64 + end_address: 0x114000 + region: external_flash + size: 0x40000 +EMPTY_1: + address: 0x114000 + device: MX25R64 + end_address: 0x120000 + region: external_flash + size: 0xc000 +otp: + address: 0xff8100 + end_address: 0xff83fc + region: otp + size: 0x2fc +rpmsg_nrf53_sram: + address: 0x20070000 + end_address: 0x20080000 + placement: + before: + - end + region: sram_primary + size: 0x10000 +settings_storage: + address: 0xf0000 + end_address: 0x100000 + region: flash_primary + size: 0x10000 +sram_primary: + address: 0x20000000 + end_address: 0x20070000 + region: sram_primary + size: 0x70000 diff --git a/samples/nrf5340/extxip_smp_svr/prj.conf b/samples/nrf5340/extxip_smp_svr/prj.conf index c81abd907049..a6a23a4e7290 100644 --- a/samples/nrf5340/extxip_smp_svr/prj.conf +++ b/samples/nrf5340/extxip_smp_svr/prj.conf @@ -83,14 +83,7 @@ CONFIG_DEVMEM_SHELL=n CONFIG_FLASH_SHELL=n # Configuration for split application (internal flash and XIP) -CONFIG_CODE_DATA_RELOCATION=y -CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y CONFIG_CUSTOM_LINKER_SCRIPT="linker_arm_extxip.ld" -CONFIG_BUILD_NO_GAP_FILL=y -CONFIG_XIP=y -CONFIG_NORDIC_QSPI_NOR_XIP=y -CONFIG_UPDATEABLE_IMAGE_NUMBER=3 -CONFIG_XIP_SPLIT_IMAGE=y # Init changes for QSPI XIP code placement CONFIG_FLASH_INIT_PRIORITY=40 diff --git a/samples/nrf5340/extxip_smp_svr/prj_no_network_core.conf b/samples/nrf5340/extxip_smp_svr/prj_no_network_core.conf new file mode 100644 index 000000000000..f940c9c9cbcc --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/prj_no_network_core.conf @@ -0,0 +1,74 @@ +# Enable MCUmgr and dependencies. +CONFIG_NET_BUF=y +CONFIG_ZCBOR=y +CONFIG_CRC=y +CONFIG_MCUMGR=y +CONFIG_STREAM_FLASH=y +CONFIG_FLASH_MAP=y + +# Some command handlers require a large stack. +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2304 +CONFIG_MAIN_STACK_SIZE=2048 + +# Ensure an MCUboot-compatible binary is generated. +CONFIG_BOOTLOADER_MCUBOOT=y + +# Enable flash operations. +CONFIG_FLASH=y + +# Required by the `taskstat` command. +CONFIG_THREAD_MONITOR=y + +# Support for taskstat command +CONFIG_MCUMGR_GRP_OS_TASKSTAT=y + +# Enable statistics and statistic names. +CONFIG_STATS=y +CONFIG_STATS_NAMES=y + +# Enable most core commands. +CONFIG_FLASH=y +CONFIG_IMG_MANAGER=y +CONFIG_MCUMGR_GRP_IMG=y +CONFIG_MCUMGR_GRP_OS=y +CONFIG_MCUMGR_GRP_STAT=y + +# Enable logging +CONFIG_LOG=y +CONFIG_MCUBOOT_UTIL_LOG_LEVEL_WRN=y + +# Disable debug logging +CONFIG_LOG_MAX_LEVEL=3 + +# Enable the Shell mcumgr transport. +CONFIG_BASE64=y +CONFIG_SHELL=y +CONFIG_SHELL_BACKEND_SERIAL=y +CONFIG_MCUMGR_TRANSPORT_SHELL=y +CONFIG_MCUMGR_TRANSPORT_SHELL_RX_BUF_COUNT=8 + +CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE=2475 +CONFIG_MCUMGR_GRP_OS_MCUMGR_PARAMS=y +CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE=4608 + +# Enable the storage erase command. +CONFIG_MCUMGR_GRP_ZBASIC=y +CONFIG_MCUMGR_GRP_ZBASIC_STORAGE_ERASE=y + +# Disable shell commands that are not needed +CONFIG_CLOCK_CONTROL_NRF_SHELL=n +CONFIG_DEVICE_SHELL=n +CONFIG_DEVMEM_SHELL=n +CONFIG_FLASH_SHELL=n + +# Configuration for split application (internal flash and XIP) +CONFIG_CODE_DATA_RELOCATION=y +CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y +CONFIG_CUSTOM_LINKER_SCRIPT="linker_arm_extxip.ld" +CONFIG_BUILD_NO_GAP_FILL=y +CONFIG_XIP=y +CONFIG_NORDIC_QSPI_NOR_XIP=y + +# Init changes for QSPI XIP code placement +CONFIG_FLASH_INIT_PRIORITY=40 +CONFIG_SHELL_BACKEND_SERIAL_INIT_PRIORITY=50 diff --git a/samples/nrf5340/extxip_smp_svr/sample.yaml b/samples/nrf5340/extxip_smp_svr/sample.yaml index 055e07957760..5a415d3b61b7 100644 --- a/samples/nrf5340/extxip_smp_svr/sample.yaml +++ b/samples/nrf5340/extxip_smp_svr/sample.yaml @@ -2,17 +2,27 @@ sample: description: Simple Management Protocol sample name: smp svr common: + sysbuild: true harness: console harness_config: type: one_line ordered: true regex: - " smp_sample: build time:" + platform_allow: + - nrf5340dk/nrf5340/cpuapp + integration_platforms: + - nrf5340dk/nrf5340/cpuapp tests: sample.mcumgr.smp_svr.ext_xip: platform_allow: - - nrf5340dk/nrf5340/cpuapp - thingy53/nrf5340/cpuapp integration_platforms: - - nrf5340dk/nrf5340/cpuapp - thingy53/nrf5340/cpuapp + sample.mcumgr.smp_svr.ext_xip.no_network_core: + platform_allow: + - thingy53/nrf5340/cpuapp + integration_platforms: + - thingy53/nrf5340/cpuapp + extra_args: + - FILE_SUFFIX=no_network_core diff --git a/samples/nrf5340/extxip_smp_svr/sysbuild.conf b/samples/nrf5340/extxip_smp_svr/sysbuild.conf new file mode 100644 index 000000000000..f2deddec3775 --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/sysbuild.conf @@ -0,0 +1,13 @@ +# +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +SB_CONFIG_BOOTLOADER_MCUBOOT=y +SB_CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y +SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y +SB_CONFIG_NETCORE_HCI_IPC=y +SB_CONFIG_NETCORE_APP_UPDATE=y +SB_CONFIG_SECURE_BOOT_NETCORE=y +SB_CONFIG_QSPI_XIP_SPLIT_IMAGE=y diff --git a/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/app.overlay b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/app.overlay new file mode 100644 index 000000000000..74d3dfbfd22f --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/app.overlay @@ -0,0 +1,5 @@ +/ { + chosen { + zephyr,code-partition = &boot_partition; + }; +}; diff --git a/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 000000000000..a9c88d6227f3 --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,6 @@ +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf new file mode 100644 index 000000000000..dd5468106b92 --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf @@ -0,0 +1,13 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# CC3xx is currently not used for nrf53 +CONFIG_HW_CC3XX=n +CONFIG_NRF_CC3XX_PLATFORM=n + +# Required for kernel operation +CONFIG_CLOCK_CONTROL=y +CONFIG_SYS_CLOCK_EXISTS=y diff --git a/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/thingy53_nrf5340_cpuapp.conf b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/thingy53_nrf5340_cpuapp.conf new file mode 100644 index 000000000000..e1065667897d --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/thingy53_nrf5340_cpuapp.conf @@ -0,0 +1,74 @@ +CONFIG_SIZE_OPTIMIZATIONS=y + +CONFIG_SYSTEM_CLOCK_NO_WAIT=y +CONFIG_PM=n + +CONFIG_MAIN_STACK_SIZE=10240 +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +CONFIG_BOOT_MAX_IMG_SECTORS=2048 +CONFIG_BOOT_SIGNATURE_TYPE_RSA=y + +# Flash +CONFIG_FLASH=y +CONFIG_BOOT_ERASE_PROGRESSIVELY=y +CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS=y +CONFIG_FPROTECT=y + +# Serial +CONFIG_SERIAL=y +CONFIG_UART_LINE_CTRL=y + +# MCUBoot serial +CONFIG_GPIO=y +CONFIG_GPIO_NRFX_INTERRUPT=n +CONFIG_MCUBOOT_SERIAL=y +CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y +CONFIG_BOOT_SERIAL_CDC_ACM=y + +# Required by QSPI +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# Required by USB and QSPI +CONFIG_MULTITHREADING=y + +# USB +CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n +CONFIG_USB_DEVICE_REMOTE_WAKEUP=n +CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor ASA" +CONFIG_USB_DEVICE_PRODUCT="Bootloader Thingy:53" +CONFIG_USB_DEVICE_VID=0x1915 +CONFIG_USB_DEVICE_PID=0x5300 +CONFIG_USB_CDC_ACM=y + +# Decrease memory footprint +CONFIG_CBPRINTF_NANO=y +CONFIG_TIMESLICING=n +CONFIG_BOOT_BANNER=n +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_LOG=n +CONFIG_ERRNO=n +CONFIG_PRINTK=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_SPI=n +CONFIG_I2C=n +CONFIG_UART_NRFX=n + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 +CONFIG_BOOT_UPGRADE_ONLY=y +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +# Enable custom command to erase settings partition. +CONFIG_ENABLE_MGMT_PERUSER=y +CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y diff --git a/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/thingy53_nrf5340_cpuapp.overlay b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/thingy53_nrf5340_cpuapp.overlay new file mode 100644 index 000000000000..a9c88d6227f3 --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/boards/thingy53_nrf5340_cpuapp.overlay @@ -0,0 +1,6 @@ +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/prj.conf b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/prj.conf new file mode 100644 index 000000000000..0a81f573fe47 --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/prj.conf @@ -0,0 +1,48 @@ +CONFIG_PM=n + +CONFIG_MAIN_STACK_SIZE=10240 +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_ENCRYPT_IMAGE=n + +CONFIG_BOOT_UPGRADE_ONLY=n +CONFIG_BOOT_BOOTSTRAP=n + +### mbedTLS has its own heap +# CONFIG_HEAP_MEM_POOL_SIZE is not set + +### We never want Zephyr's copy of tinycrypt. If tinycrypt is needed, +### MCUboot has its own copy in tree. +# CONFIG_TINYCRYPT is not set +# CONFIG_TINYCRYPT_ECC_DSA is not set +# CONFIG_TINYCRYPT_SHA256 is not set + +CONFIG_FLASH=y +CONFIG_FPROTECT=y + +### Various Zephyr boards enable features that we don't want. +# CONFIG_BT is not set +# CONFIG_BT_CTLR is not set +# CONFIG_I2C is not set + +CONFIG_LOG=y +CONFIG_LOG_MODE_MINIMAL=y # former CONFIG_MODE_MINIMAL +### Ensure Zephyr logging changes don't use more resources +CONFIG_LOG_DEFAULT_LEVEL=0 +### Use info log level by default +CONFIG_MCUBOOT_LOG_LEVEL_INF=y +### Decrease footprint by ~4 KB in comparison to CBPRINTF_COMPLETE=y +CONFIG_CBPRINTF_NANO=y +### Use the minimal C library to reduce flash usage +CONFIG_MINIMAL_LIBC=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0 + +# NCS boot banner +CONFIG_NCS_APPLICATION_BOOT_BANNER_STRING="MCUboot" + +# Set QSPI flash layout configuration +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +CONFIG_BOOT_MAX_IMG_SECTORS=256 diff --git a/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/prj_no_network_core.conf b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/prj_no_network_core.conf new file mode 100644 index 000000000000..dbbbbc5c42da --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/prj_no_network_core.conf @@ -0,0 +1,51 @@ +CONFIG_PM=n + +CONFIG_MAIN_STACK_SIZE=10240 +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_ENCRYPT_IMAGE=n + +CONFIG_BOOT_UPGRADE_ONLY=n +CONFIG_BOOT_BOOTSTRAP=n + +### mbedTLS has its own heap +# CONFIG_HEAP_MEM_POOL_SIZE is not set + +### We never want Zephyr's copy of tinycrypt. If tinycrypt is needed, +### MCUboot has its own copy in tree. +# CONFIG_TINYCRYPT is not set +# CONFIG_TINYCRYPT_ECC_DSA is not set +# CONFIG_TINYCRYPT_SHA256 is not set + +CONFIG_FLASH=y +CONFIG_FPROTECT=y + +### Various Zephyr boards enable features that we don't want. +# CONFIG_BT is not set +# CONFIG_BT_CTLR is not set +# CONFIG_I2C is not set + +CONFIG_LOG=y +CONFIG_LOG_MODE_MINIMAL=y # former CONFIG_MODE_MINIMAL +### Ensure Zephyr logging changes don't use more resources +CONFIG_LOG_DEFAULT_LEVEL=0 +### Use info log level by default +CONFIG_MCUBOOT_LOG_LEVEL_INF=y +### Decrease footprint by ~4 KB in comparison to CBPRINTF_COMPLETE=y +CONFIG_CBPRINTF_NANO=y +### Use the minimal C library to reduce flash usage +CONFIG_MINIMAL_LIBC=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0 + +# NCS boot banner +CONFIG_NCS_APPLICATION_BOOT_BANNER_STRING="MCUboot" + +# Set QSPI flash layout configuration +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# Disable image access hooks as these are for network core images +CONFIG_BOOT_IMAGE_ACCESS_HOOKS=n + +CONFIG_BOOT_MAX_IMG_SECTORS=256 diff --git a/samples/nrf5340/extxip_smp_svr/sysbuild_no_network_core.conf b/samples/nrf5340/extxip_smp_svr/sysbuild_no_network_core.conf new file mode 100644 index 000000000000..8d79e5037920 --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/sysbuild_no_network_core.conf @@ -0,0 +1,12 @@ +# +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +SB_CONFIG_BOOTLOADER_MCUBOOT=y +SB_CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y +SB_CONFIG_NETCORE_NONE=y +SB_CONFIG_SECURE_BOOT_NETCORE=n +SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y +SB_CONFIG_QSPI_XIP_SPLIT_IMAGE=y From dd7e886316d9fa9b5ddc1dd04ce58c880b6b4da8 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 18 Jul 2024 09:28:52 +0100 Subject: [PATCH 12/72] samples: nrf5340: extxip_smp_svr: Add directXIP sysbuild configuration Adds configuration to allow running this sample in directXIP mode Signed-off-by: Jamie McCrae --- .../boards/nrf5340dk_nrf5340_cpuapp.overlay | 5 - .../boards/thingy53_nrf5340_cpuapp.overlay | 5 - .../extxip_smp_svr/linker_arm_extxip.ld | 14 +- .../pm_static_no_network_core_directxip.yml | 124 ++++++++++++++++++ .../extxip_smp_svr/prj_no_network_core.conf | 1 - .../prj_no_network_core_directxip.conf | 73 +++++++++++ samples/nrf5340/extxip_smp_svr/sample.yaml | 7 + .../prj_no_network_core_directxip.conf | 51 +++++++ .../sysbuild_no_network_core_directxip.conf | 13 ++ 9 files changed, 281 insertions(+), 12 deletions(-) delete mode 100644 samples/nrf5340/extxip_smp_svr/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay delete mode 100644 samples/nrf5340/extxip_smp_svr/child_image/mcuboot/boards/thingy53_nrf5340_cpuapp.overlay create mode 100644 samples/nrf5340/extxip_smp_svr/pm_static_no_network_core_directxip.yml create mode 100644 samples/nrf5340/extxip_smp_svr/prj_no_network_core_directxip.conf create mode 100644 samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/prj_no_network_core_directxip.conf create mode 100644 samples/nrf5340/extxip_smp_svr/sysbuild_no_network_core_directxip.conf diff --git a/samples/nrf5340/extxip_smp_svr/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/samples/nrf5340/extxip_smp_svr/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay deleted file mode 100644 index fcc2e240fd9e..000000000000 --- a/samples/nrf5340/extxip_smp_svr/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,5 +0,0 @@ -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/samples/nrf5340/extxip_smp_svr/child_image/mcuboot/boards/thingy53_nrf5340_cpuapp.overlay b/samples/nrf5340/extxip_smp_svr/child_image/mcuboot/boards/thingy53_nrf5340_cpuapp.overlay deleted file mode 100644 index fcc2e240fd9e..000000000000 --- a/samples/nrf5340/extxip_smp_svr/child_image/mcuboot/boards/thingy53_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,5 +0,0 @@ -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/samples/nrf5340/extxip_smp_svr/linker_arm_extxip.ld b/samples/nrf5340/extxip_smp_svr/linker_arm_extxip.ld index 48c2feab8739..05a61c10018b 100644 --- a/samples/nrf5340/extxip_smp_svr/linker_arm_extxip.ld +++ b/samples/nrf5340/extxip_smp_svr/linker_arm_extxip.ld @@ -30,7 +30,18 @@ PROVIDE(z_arm_platform_init = SystemInit); */ MEMORY { - /* This maps in mcuboot_primary_2 partition defined in pm_static.yaml +#if CONFIG_NCS_IS_VARIANT_IMAGE + /* This maps in mcuboot_secondary_1 partition defined in pm_static_no_network_core_directxip.yml + * components for ORIGIN calculation: + * - 0x10000000: offset of QSPI external memory in SoC memory mapping. + * - 0xD4000: mcuboot_secondary_1 offset in QSPI external memory + * - 0x200: image header size. + * The size of this region is size of mcuboot_secondary_1 reduced by the + * image header size. + */ + EXTFLASH (wx) : ORIGIN = 0x100D4200, LENGTH = 0x3FE00 +#else + /* This maps in mcuboot_primary_2 partition defined in pm_static.yml * components for ORIGIN calculation: * - 0x10000000: offset of QSPI external memory in SoC memory mapping. * - 0x120000: mcuboot_primary_2 offset in QSPI external memory @@ -39,6 +50,7 @@ MEMORY * image header size. */ EXTFLASH (wx) : ORIGIN = 0x10120200, LENGTH = 0x3FE00 +#endif } #include diff --git a/samples/nrf5340/extxip_smp_svr/pm_static_no_network_core_directxip.yml b/samples/nrf5340/extxip_smp_svr/pm_static_no_network_core_directxip.yml new file mode 100644 index 000000000000..af5ee2586c0e --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/pm_static_no_network_core_directxip.yml @@ -0,0 +1,124 @@ +app: + address: 0x10200 + end_address: 0x7a000 + region: flash_primary + size: 0x69e00 +external_flash: + address: 0x120000 + device: MX25R64 + end_address: 0x800000 + region: external_flash + size: 0x6e0000 +mcuboot: + address: 0x0 + end_address: 0x10000 + region: flash_primary + size: 0x10000 +mcuboot_pad: + address: 0x10000 + end_address: 0x10200 + region: flash_primary + size: 0x200 +mcuboot_primary: + address: 0x10000 + end_address: 0x7a000 + orig_span: &id001 + - mcuboot_pad + - app + region: flash_primary + size: 0x6a000 + span: *id001 +mcuboot_primary_app: + address: 0x10200 + end_address: 0x7a000 + orig_span: &id002 + - app + region: flash_primary + size: 0x69e00 + span: *id002 +mcuboot_secondary_pad: + address: 0x7a000 + end_address: 0x7a200 + region: flash_primary + size: 0x200 +mcuboot_secondary: + address: 0x7a000 + end_address: 0xe4000 + orig_span: &id003 + - mcuboot_secondary_pad + - mcuboot_secondary_app + region: flash_primary + size: 0x6a000 + span: *id003 +mcuboot_secondary_app: + address: 0x7a200 + end_address: 0xe4000 + region: flash_primary + size: 0x69e00 +EMPTY_3: + address: 0xe4000 + end_address: 0x100000 + region: flash_primary + size: 0x1c000 +mcuboot_primary_1: + address: 0x120000 + device: external_flash + end_address: 0x160000 + orig_span: &id004 + - mcuboot_primary_1_pad + - mcuboot_primary_1_app + region: external_flash + size: 0x40000 + span: *id004 +mcuboot_primary_1_pad: + address: 0x120000 + end_address: 0x120200 + region: external_flash + size: 0x200 +mcuboot_primary_1_app: + address: 0x120200 + device: MX25R64 + end_address: 0x160000 + region: external_flash + size: 0x3FE00 +mcuboot_secondary_1: + address: 0xd4000 + device: MX25R64 + end_address: 0x114000 + region: external_flash + size: 0x40000 +EMPTY_1: + address: 0x0 + device: MX25R64 + end_address: 0xd4000 + region: external_flash + size: 0xd4000 +EMPTY_2: + address: 0x114000 + device: MX25R64 + end_address: 0x120000 + region: external_flash + size: 0xc000 +otp: + address: 0xff8100 + end_address: 0xff83fc + region: otp + size: 0x2fc +rpmsg_nrf53_sram: + address: 0x20070000 + end_address: 0x20080000 + placement: + before: + - end + region: sram_primary + size: 0x10000 +settings_storage: + address: 0xf0000 + end_address: 0x100000 + region: flash_primary + size: 0x10000 +sram_primary: + address: 0x20000000 + end_address: 0x20070000 + region: sram_primary + size: 0x70000 diff --git a/samples/nrf5340/extxip_smp_svr/prj_no_network_core.conf b/samples/nrf5340/extxip_smp_svr/prj_no_network_core.conf index f940c9c9cbcc..fc465a85a765 100644 --- a/samples/nrf5340/extxip_smp_svr/prj_no_network_core.conf +++ b/samples/nrf5340/extxip_smp_svr/prj_no_network_core.conf @@ -67,7 +67,6 @@ CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y CONFIG_CUSTOM_LINKER_SCRIPT="linker_arm_extxip.ld" CONFIG_BUILD_NO_GAP_FILL=y CONFIG_XIP=y -CONFIG_NORDIC_QSPI_NOR_XIP=y # Init changes for QSPI XIP code placement CONFIG_FLASH_INIT_PRIORITY=40 diff --git a/samples/nrf5340/extxip_smp_svr/prj_no_network_core_directxip.conf b/samples/nrf5340/extxip_smp_svr/prj_no_network_core_directxip.conf new file mode 100644 index 000000000000..fc465a85a765 --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/prj_no_network_core_directxip.conf @@ -0,0 +1,73 @@ +# Enable MCUmgr and dependencies. +CONFIG_NET_BUF=y +CONFIG_ZCBOR=y +CONFIG_CRC=y +CONFIG_MCUMGR=y +CONFIG_STREAM_FLASH=y +CONFIG_FLASH_MAP=y + +# Some command handlers require a large stack. +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2304 +CONFIG_MAIN_STACK_SIZE=2048 + +# Ensure an MCUboot-compatible binary is generated. +CONFIG_BOOTLOADER_MCUBOOT=y + +# Enable flash operations. +CONFIG_FLASH=y + +# Required by the `taskstat` command. +CONFIG_THREAD_MONITOR=y + +# Support for taskstat command +CONFIG_MCUMGR_GRP_OS_TASKSTAT=y + +# Enable statistics and statistic names. +CONFIG_STATS=y +CONFIG_STATS_NAMES=y + +# Enable most core commands. +CONFIG_FLASH=y +CONFIG_IMG_MANAGER=y +CONFIG_MCUMGR_GRP_IMG=y +CONFIG_MCUMGR_GRP_OS=y +CONFIG_MCUMGR_GRP_STAT=y + +# Enable logging +CONFIG_LOG=y +CONFIG_MCUBOOT_UTIL_LOG_LEVEL_WRN=y + +# Disable debug logging +CONFIG_LOG_MAX_LEVEL=3 + +# Enable the Shell mcumgr transport. +CONFIG_BASE64=y +CONFIG_SHELL=y +CONFIG_SHELL_BACKEND_SERIAL=y +CONFIG_MCUMGR_TRANSPORT_SHELL=y +CONFIG_MCUMGR_TRANSPORT_SHELL_RX_BUF_COUNT=8 + +CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE=2475 +CONFIG_MCUMGR_GRP_OS_MCUMGR_PARAMS=y +CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE=4608 + +# Enable the storage erase command. +CONFIG_MCUMGR_GRP_ZBASIC=y +CONFIG_MCUMGR_GRP_ZBASIC_STORAGE_ERASE=y + +# Disable shell commands that are not needed +CONFIG_CLOCK_CONTROL_NRF_SHELL=n +CONFIG_DEVICE_SHELL=n +CONFIG_DEVMEM_SHELL=n +CONFIG_FLASH_SHELL=n + +# Configuration for split application (internal flash and XIP) +CONFIG_CODE_DATA_RELOCATION=y +CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y +CONFIG_CUSTOM_LINKER_SCRIPT="linker_arm_extxip.ld" +CONFIG_BUILD_NO_GAP_FILL=y +CONFIG_XIP=y + +# Init changes for QSPI XIP code placement +CONFIG_FLASH_INIT_PRIORITY=40 +CONFIG_SHELL_BACKEND_SERIAL_INIT_PRIORITY=50 diff --git a/samples/nrf5340/extxip_smp_svr/sample.yaml b/samples/nrf5340/extxip_smp_svr/sample.yaml index 5a415d3b61b7..647d2d89cf8f 100644 --- a/samples/nrf5340/extxip_smp_svr/sample.yaml +++ b/samples/nrf5340/extxip_smp_svr/sample.yaml @@ -26,3 +26,10 @@ tests: - thingy53/nrf5340/cpuapp extra_args: - FILE_SUFFIX=no_network_core + sample.mcumgr.smp_svr.ext_xip.no_network_core.directxip: + platform_allow: + - thingy53/nrf5340/cpuapp + integration_platforms: + - thingy53/nrf5340/cpuapp + extra_args: + - FILE_SUFFIX=no_network_core_directxip diff --git a/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/prj_no_network_core_directxip.conf b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/prj_no_network_core_directxip.conf new file mode 100644 index 000000000000..dbbbbc5c42da --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/sysbuild/mcuboot/prj_no_network_core_directxip.conf @@ -0,0 +1,51 @@ +CONFIG_PM=n + +CONFIG_MAIN_STACK_SIZE=10240 +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_ENCRYPT_IMAGE=n + +CONFIG_BOOT_UPGRADE_ONLY=n +CONFIG_BOOT_BOOTSTRAP=n + +### mbedTLS has its own heap +# CONFIG_HEAP_MEM_POOL_SIZE is not set + +### We never want Zephyr's copy of tinycrypt. If tinycrypt is needed, +### MCUboot has its own copy in tree. +# CONFIG_TINYCRYPT is not set +# CONFIG_TINYCRYPT_ECC_DSA is not set +# CONFIG_TINYCRYPT_SHA256 is not set + +CONFIG_FLASH=y +CONFIG_FPROTECT=y + +### Various Zephyr boards enable features that we don't want. +# CONFIG_BT is not set +# CONFIG_BT_CTLR is not set +# CONFIG_I2C is not set + +CONFIG_LOG=y +CONFIG_LOG_MODE_MINIMAL=y # former CONFIG_MODE_MINIMAL +### Ensure Zephyr logging changes don't use more resources +CONFIG_LOG_DEFAULT_LEVEL=0 +### Use info log level by default +CONFIG_MCUBOOT_LOG_LEVEL_INF=y +### Decrease footprint by ~4 KB in comparison to CBPRINTF_COMPLETE=y +CONFIG_CBPRINTF_NANO=y +### Use the minimal C library to reduce flash usage +CONFIG_MINIMAL_LIBC=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0 + +# NCS boot banner +CONFIG_NCS_APPLICATION_BOOT_BANNER_STRING="MCUboot" + +# Set QSPI flash layout configuration +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# Disable image access hooks as these are for network core images +CONFIG_BOOT_IMAGE_ACCESS_HOOKS=n + +CONFIG_BOOT_MAX_IMG_SECTORS=256 diff --git a/samples/nrf5340/extxip_smp_svr/sysbuild_no_network_core_directxip.conf b/samples/nrf5340/extxip_smp_svr/sysbuild_no_network_core_directxip.conf new file mode 100644 index 000000000000..08baaacb048c --- /dev/null +++ b/samples/nrf5340/extxip_smp_svr/sysbuild_no_network_core_directxip.conf @@ -0,0 +1,13 @@ +# +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +SB_CONFIG_BOOTLOADER_MCUBOOT=y +SB_CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y +SB_CONFIG_NETCORE_NONE=y +SB_CONFIG_SECURE_BOOT_NETCORE=n +SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y +SB_CONFIG_MCUBOOT_MODE_DIRECT_XIP=y +SB_CONFIG_QSPI_XIP_SPLIT_IMAGE=y From fc291b45feb49ca6ea649eca85c35e6b0e5ad547 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 19 Jul 2024 08:13:26 +0100 Subject: [PATCH 13/72] doc: nrf: app_dev: Add QSPI XIP split image documentation Adds documentation on how to use the QSPI XIP split image feature in custom applications Signed-off-by: Jamie McCrae --- doc/nrf/app_dev/bootloaders_dfu/index.rst | 1 + .../bootloaders_dfu/qspi_xip_split_image.rst | 290 ++++++++++++++++++ samples/nrf5340/extxip_smp_svr/README.rst | 2 +- 3 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 doc/nrf/app_dev/bootloaders_dfu/qspi_xip_split_image.rst diff --git a/doc/nrf/app_dev/bootloaders_dfu/index.rst b/doc/nrf/app_dev/bootloaders_dfu/index.rst index f8852af1abe3..1e919eb8571a 100644 --- a/doc/nrf/app_dev/bootloaders_dfu/index.rst +++ b/doc/nrf/app_dev/bootloaders_dfu/index.rst @@ -50,3 +50,4 @@ To learn more, refer to the following documentation pages: :caption: Subpages: mcuboot_nsib/bootloader_mcuboot_nsib + qspi_xip_split_image diff --git a/doc/nrf/app_dev/bootloaders_dfu/qspi_xip_split_image.rst b/doc/nrf/app_dev/bootloaders_dfu/qspi_xip_split_image.rst new file mode 100644 index 000000000000..961b95b6b291 --- /dev/null +++ b/doc/nrf/app_dev/bootloaders_dfu/qspi_xip_split_image.rst @@ -0,0 +1,290 @@ +.. _qspi_xip_split_image: + +Using QSPI XIP split image +########################## + +.. contents:: + :local: + :depth: 2 + +The QSPI XIP split image feature lets you gain more flash storage space for applications by splitting application code into two parts: + +* Code that runs on the internal flash memory. +* Code that runs on supported external flash memory over the Quad Serial Peripheral Interface (QSPI) using Execute in Place (XIP). + +This feature is supported on nRF52840, nRF5340, and the SoCs of the nRF91 Series. + +.. warning:: + On the nRF52840, do not relocate interrupts to the QSPI XIP flash. + Doing so can lock up or brick the device by making the debug access port inaccessible. + +The QSPI XIP split images are supported in :doc:`MCUboot `, which allows for updating them over-the-air. + +For the nRF5340 DK and Nordic Thingy:53, you can also check out the :ref:`SMP Server with external XIP ` sample, which demonstrates this feature. + +Requirements +************ + +To use this feature, meet the following requirements: + +* Board based on nRF52840, nRF5340, or nRF91 Series SoCs, with file structure compatible with :ref:`Hardware model v2 (HWMv2) ` +* External QSPI flash chip with supported commands connected to QSPI pins +* QSPI flash chip in always-on mode (meaning, no DPM or low-power modes) +* :doc:`MCUboot configuration ` in the Swap using move mode (``MCUBOOT_SWAP_USING_MOVE``), the Upgrade only mode (``MCUBOOT_OVERWRITE_ONLY``), or in the direct-XIP mode +* :ref:`Static partition manager file ` +* Linker file with QSPI XIP flash offset and size +* :ref:`configuration_system_overview_sysbuild` + +.. caution:: + Currently, MCUboot images cannot be linked together. + This means that both parts of the firmware update must be loaded properly before an update is initiated. + If one part fails to update, the image on the device will be unbootable and that will likely brick the device. + +Network core image updates +************************** + +The QSPI XIP split image feature supports network core image updates on nRF5340 devices if MCUboot is configured for using either the swap-using-move or the upgrade-only mode. + +.. _qspi_xip_split_image_pm_static_files: + +.. rst-class:: numbered-step + +Create the Partition Manager static files +***************************************** + +Create the following files: + +* A static :ref:`partition_manager` file to set up the partitions that will be used on the device. + The following three files from the :ref:`SMP Server with external XIP ` sample provide an example of the Partition Manager layouts for nRF5340: + + .. tabs:: + + .. group-tab:: Swap using move with network core support + .. literalinclude:: ../../../../samples/nrf5340/extxip_smp_svr/pm_static.yml + :language: yaml + + .. group-tab:: Swap using move without network core support + + .. literalinclude:: ../../../../samples/nrf5340/extxip_smp_svr/pm_static_no_network_core.yml + :language: yaml + + .. group-tab:: Direct-XIP without network core support + + .. literalinclude:: ../../../../samples/nrf5340/extxip_smp_svr/pm_static_no_network_core_directxip.yml + :language: yaml + +* A board overlay file to set the chosen Partition Manager external flash device: + + .. literalinclude:: ../../../../samples/nrf5340/extxip_smp_svr/boards/nrf5340dk_nrf5340_cpuapp.overlay + :language: dts + + You can either place this file as a board overlay in the :file:`boards` folder of the application or name it :file:`app.overlay` and place it in the application folder so that it applies to all board targets. + +.. rst-class:: numbered-step + +Create a linker file +******************** + +Create a linker file that has the same information as the static Partition Manager file for the external QSPI flash device. +The following code example from the :ref:`SMP Server with external XIP ` sample shows how to set up a linker file for direct-XIP mode, with the direct-XIP secondary image configuration in the ``CONFIG_NCS_IS_VARIANT_IMAGE`` section. +You can omit this section if you are using other MCUboot operating modes. + +Place this file in the application directory with a name similar to :file:`linker_arm_extxip.ld`. + +.. literalinclude:: ../../../../samples/nrf5340/extxip_smp_svr/linker_arm_extxip.ld + +.. rst-class:: numbered-step + +Set additional Kconfig options +****************************** + +Set additional Kconfig option in the application's :file:`prj.conf` to allow it to execute code from XIP: + +.. code-block:: cfg + + # Update the filename here if you have given it a different name + CONFIG_CUSTOM_LINKER_SCRIPT="linker_arm_extxip.ld" + +.. rst-class:: numbered-step + +Configure sysbuild +****************** + +Configure :ref:`configuration_system_overview_sysbuild` to enable the required Kconfig options for this functionality: + +1. Create a :file:`sysbuild.conf` file in the application directory withs the following options, depending on the required functionality: + + .. tabs:: + + .. group-tab:: Swap using move with network core support + + .. code-block:: cfg + + SB_CONFIG_BOOTLOADER_MCUBOOT=y + SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y + SB_CONFIG_NETCORE_APP_UPDATE=y + SB_CONFIG_SECURE_BOOT_NETCORE=y + SB_CONFIG_QSPI_XIP_SPLIT_IMAGE=y + + # This will enable the hci_ipc image for the network core, change to the desired image + SB_CONFIG_NETCORE_HCI_IPC=y + + .. group-tab:: Swap using move without network core support + + .. code-block:: cfg + + SB_CONFIG_BOOTLOADER_MCUBOOT=y + SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y + SB_CONFIG_QSPI_XIP_SPLIT_IMAGE=y + + .. group-tab:: Direct-XIP without network core support + + .. code-block:: cfg + + SB_CONFIG_BOOTLOADER_MCUBOOT=y + SB_CONFIG_MCUBOOT_MODE_DIRECT_XIP=y + SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y + SB_CONFIG_QSPI_XIP_SPLIT_IMAGE=y + +#. Create a :file:`sysbuild.cmake` file. + This file applies the devicetree overlay file for enabling the external flash device for the Partition Manager (created in :ref:`qspi_xip_split_image_pm_static_files`) to MCUboot. + The following examples assume you created the :file:`app.overlay` file valid for all board targets; adjust as needed if you created as a board overlay instead. + + .. tabs:: + + .. group-tab:: With networe core support + + .. code-block:: cmake + + list(APPEND mcuboot_EXTRA_DTC_OVERLAY_FILE "${CMAKE_CURRENT_SOURCE_DIR}/app.overlay") + + .. group-tab:: Without networe core support + + .. code-block:: cmake + + list(APPEND mcuboot_EXTRA_DTC_OVERLAY_FILE "${CMAKE_CURRENT_SOURCE_DIR}/app.overlay") + set(mcuboot_CONFIG_BOOT_IMAGE_ACCESS_HOOKS n) + +.. rst-class:: numbered-step + +Relocate code to QSPI flash +*************************** + +Relocate the code to run from the QSPI flash inside the applications :file:`CMakeLists.txt` file using the ``zephyr_code_relocate`` function. +This can be used to relocate files and libraries. + +.. tabs:: + + .. group-tab:: Relocating files + + .. code-block:: cmake + + zephyr_code_relocate(FILES src/complex_sensor_calculcation_code.c LOCATION EXTFLASH_TEXT NOCOPY) + zephyr_code_relocate(FILES src/complex_sensor_calculcation_code.c LOCATION RAM_DATA) + + .. note:: + This assumes that the application has a :file:`src/complex_sensor_calculcation_code.c`` file. + + .. group-tab:: Relocating libraries + + .. code-block:: cmake + + zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__mgmt LOCATION EXTFLASH_TEXT NOCOPY) + zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__mgmt LOCATION RAM_DATA) + + .. note:: + The library name comes from the Zephyr code. + +.. rst-class:: numbered-step + +Set QSPI flash initialization priority +************************************** + +Set the initialization priority of the QSPI flash so that it is configured before any code on the device runs, otherwise the application operation is going to be undefined. + +There is no built-in check for this setting. +Therefore, you must manually set the priority based on the relocated code. +For example, if you relocate the shell subsystem, its initialization priority must be higher than the priority of QSPI, and the value of :kconfig:option:`CONFIG_SHELL_BACKEND_SERIAL_INIT_PRIORITY` must be greater than :kconfig:option:`CONFIG_NORDIC_QSPI_NOR_INIT_PRIORITY`. + +.. note:: + Not all libraries or subsystems can be relocated. + Any code that runs early in the boot process or uses ``SYS_INIT()`` with a non-configurable init priority cannot be relocated. + Library and subsystem code needs to be manually checked before relocating it. + +Programming with the QSPI XIP split image +***************************************** + +Programming of the application is supported using the :ref:`standard procedure `. +The standard procedure will program the firmware using the default nrfjprog configuration which, for QSPI, is PP4IO mode. + +Programming using a different SPI mode +====================================== + +If you are using an a different SPI mode on the QSPI interface, such as DSPI, you must use a custom :file:`Qspi.ini` file. +The following is an example for the Thingy:53, which supports DSPI and PP: + +.. literalinclude:: ../../../../samples/nrf5340/extxip_smp_svr/Qspi_thingy53.ini + +To use this file when programming, add the following lines to the application's :file:`CMakeLists.txt` file before the ``find_package()`` line: + +.. code-block:: cmake + + macro(app_set_runner_args) + # Replace with the filename of your ini file + board_runner_args(nrfjprog "--qspiini=${CMAKE_CURRENT_SOURCE_DIR}/Qspi_thingy53.ini") + endmacro() + +This will enable programming the target board successfully when using ``west flash``. + +Firmware updates +**************** + +The build system will automatically generate the signed update files that can be loaded to a device to run the newer version of the application. +The :file:`dfu_application.zip` file also contains these files and you can use the `nRF Connect for Mobile`_ application (available for Android and iOS) to upload the firmware over Bluetooth® Low Energy. + +File descriptions +***************** + +The following table lists the files generated when building a QSPI XIP split-image application. + +In some file names, ```` is the name of the application and ```` is the value of :kconfig:option:`CONFIG_KERNEL_BIN_NAME`. + ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| File name and location | Description | ++========================================================================+====================================================================================================================================================+ +| :file:`/zephyr/.hex` | Initial HEX output file, unsigned, containing internal and external QSPI flash data. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`/zephyr/.internal.hex` | Initial HEX output file, unsigned, containing internal flash data. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`/zephyr/.external.hex` | Initial HEX output file, unsigned, containing external QSPI flash data. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`/zephyr/.internal.signed.hex` | Signed internal flash data HEX file. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`/zephyr/.external.signed.hex` | Signed external QSPI flash data HEX file. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`/zephyr/.signed.hex` | Signed internal and external QSPI flash data HEX file. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`/zephyr/.internal.signed.bin` | Signed internal flash data binary file (for firmware updates). | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`/zephyr/.external.signed.bin` | Signed external QSPI flash data binary file (for firmware updates). | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`mcuboot_secondary_app/zephyr/.hex` | Initial HEX output file, unsigned, containing internal and external QSPI flash data for direct-XIP mode secondary slot image. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`mcuboot_secondary_app/zephyr/.internal.hex` | Initial HEX output file, unsigned, containing internal flash data for direct-XIP mode secondary slot image. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`mcuboot_secondary_app/zephyr/.external.hex` | Initial HEX output file, unsigned, containing external QSPI flash data for direct-XIP mode secondary slot image. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`mcuboot_secondary_app/zephyr/.internal.signed.hex` | Signed internal flash data HEX file for direct-XIP mode secondary slot image. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`mcuboot_secondary_app/zephyr/.external.signed.hex` | Signed external QSPI flash data HEX file for direct-XIP mode secondary slot image. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`mcuboot_secondary_app/zephyr/.signed.hex` | Signed internal and external QSPI flash data HEX file for direct-XIP mode secondary slot image. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`mcuboot_secondary_app/zephyr/.internal.signed.bin` | Signed internal flash data binary file (for firmware updates) for direct-XIP mode secondary slot image. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`mcuboot_secondary_app/zephyr/.external.signed.bin` | Signed external QSPI flash data binary file (for firmware updates) for direct-XIP mode secondary slot image. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`merged.hex` | Merged HEX file containing all images, includes both internal and external QSPI flash data for all images. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ +| :file:`dfu_application.zip` | Created if ``SB_CONFIG_DFU_ZIP`` is set, will contain the internal and external QSPI flash FOTA update images if ``SB_CONFIG_DFU_ZIP_APP`` is set. | ++------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/samples/nrf5340/extxip_smp_svr/README.rst b/samples/nrf5340/extxip_smp_svr/README.rst index a0e5e0dcdf48..b7aa67b9d240 100644 --- a/samples/nrf5340/extxip_smp_svr/README.rst +++ b/samples/nrf5340/extxip_smp_svr/README.rst @@ -7,7 +7,7 @@ nRF5340: SMP Server with external XIP :local: :depth: 2 -This sample demonstrates how to split an application that partially resides on internal flash and Quad Serial Peripheral Interface (QSPI) flash by using the Simple Management Protocol (SMP) server. +This sample demonstrates how to split an application that partially resides on internal flash and Quad Serial Peripheral Interface (QSPI) flash by using Execute in place (XIP) and the Simple Management Protocol (SMP) server. Requirements ************ From ec08f642cac58dd7c01ed20d034032de8d6c3de5 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 19 Jul 2024 08:14:19 +0100 Subject: [PATCH 14/72] doc: nrf: releases: migration: sysbuild: Add QSPI XIP split image info Adds information on how to adjust applications that make use of the QSPI XIP split image feature Signed-off-by: Jamie McCrae --- .../migration/migration_sysbuild.rst | 214 +++++++++++------- 1 file changed, 137 insertions(+), 77 deletions(-) diff --git a/doc/nrf/releases_and_maturity/migration/migration_sysbuild.rst b/doc/nrf/releases_and_maturity/migration/migration_sysbuild.rst index 3a1ea1f7a1ee..9784975f1bf3 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_sysbuild.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_sysbuild.rst @@ -335,27 +335,75 @@ You must update your application to select the required Kconfig options at the s .. _child_parent_to_sysbuild_migration_partition_manager: -Partition manager +Partition Manager ================= -Support for using partition manager for an image was moved to sysbuild. +Support for using the Partition Manager for an image has been moved to sysbuild. The following Kconfig options are available: -+-----------------------------------------------------------------+----------------------------------------------------------------------------+ -| Kconfig option | Description | -+=================================================================+============================================================================+ -| ``SB_CONFIG_PARTITION_MANAGER`` | Enables partition manager support | -+-----------------------------------------------------------------+----------------------------------------------------------------------------+ -| ``SB_CONFIG_PM_MCUBOOT_PAD`` | MCUboot image header padding | -+-----------------------------------------------------------------+----------------------------------------------------------------------------+ -| ``SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY`` | Places the secondary MCUboot update partition in external flash | -+-----------------------------------------------------------------+----------------------------------------------------------------------------+ -| ``SB_CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK`` | Will force override the external flash driver check | -+-----------------------------------------------------------------+----------------------------------------------------------------------------+ ++---------------------------------------------------+-----------------------------------------------------------------+ +| Kconfig option | Description | ++===================================================+=================================================================+ +| ``SB_CONFIG_PARTITION_MANAGER`` | Enables partition manager support | ++---------------------------------------------------+-----------------------------------------------------------------+ +| ``SB_CONFIG_PM_MCUBOOT_PAD`` | MCUboot image header padding | ++---------------------------------------------------+-----------------------------------------------------------------+ +| ``SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY`` | Places the secondary MCUboot update partition in external flash | ++---------------------------------------------------+-----------------------------------------------------------------+ +| ``SB_CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK`` | Will force override the external flash driver check | ++---------------------------------------------------+-----------------------------------------------------------------+ You must update your applications to select the required Kconfig options at the sysbuild level for applications to work. If these options are not set, firmware updates may not work or images may fail to boot. +.. _child_parent_to_sysbuild_migration_qspi_xip: + +QSPI XIP flash split code +------------------------- + +Support for using an application image based on the Quad Serial Peripheral Interface (QSPI) with the Execute in place (XIP) flash memory split has been moved to sysbuild. +The following Kconfig options are available: + ++------------------------------------+------------------------------------------------------------------------------------------------------------+ +| Kconfig option | Description | ++====================================+============================================================================================================+ +| ``SB_CONFIG_QSPI_XIP_SPLIT_IMAGE`` | Enables splitting application into internal flash and external QSPI XIP flash images with MCUboot signing. | ++------------------------------------+------------------------------------------------------------------------------------------------------------+ + +You must update your applications to select the required Kconfig options at the sysbuild level for applications to work. +If these options are not set, the QSPI XIP flash code sections will not be generated. +The MCUboot image number is now dependent upon what images are present in a build, and the Kconfig option ``SB_CONFIG_MCUBOOT_QSPI_XIP_IMAGE_NUMBER`` gives the image number of this section. + +The format for the Partition Manager static partition file has also changed. +There must now be a ``pad`` section and an ``app`` section which form the primary section in a span. +Here's an example from the :ref:`SMP Server with external XIP ` sample: + +.. code-block:: yaml + + mcuboot_primary_2: + address: 0x120000 + device: MX25R64 + end_address: 0x160000 + + orig_span: &id003 + + - mcuboot_primary_2_pad + + - mcuboot_primary_2_app + region: external_flash + size: 0x40000 + + span: *id003 + +mcuboot_primary_2_pad: + + address: 0x120000 + + end_address: 0x120200 + + region: external_flash + + size: 0x200 + +mcuboot_primary_2_app: + + address: 0x120200 + + device: MX25R64 + + end_address: 0x40000 + + region: external_flash + + size: 0x3FE00 + +For more details about the QSPI XIP flash split image feature, see :ref:`qspi_xip_split_image`. + .. _child_parent_to_sysbuild_migration_filename_changes: Filename changes @@ -365,55 +413,67 @@ Some output file names have changed from child/parent image configurations or ha This is because sysbuild properly namespaces images in a project. The changes to final output files (ignoring artifacts and intermediary files) are as follows: -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Child/parent file | Sysbuild file | -+=====================================================+==============================================================================================================================================================+ -| ``zephyr/app_update.bin`` | ``/zephyr/.signed.bin`` where ```` is the applications Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/app_signed.hex`` | ``/zephyr/.signed.hex`` where ```` is the applications Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/app_test_update.hex`` | No equivalent | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/app_moved_test_update.hex`` | No equivalent | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/net_core_app_update.bin`` | ``signed_by_mcuboot_and_b0_.bin`` where ```` is the name of the network core application | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/net_core_app_signed.hex`` | ``signed_by_b0_.hex`` where ```` is the name of the network core application | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/net_core_app_test_update.hex`` | No equivalent | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/net_core_app_moved_test_update.hex`` | No equivalent | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/mcuboot_secondary_app_update.bin`` | ``mcuboot_secondary_app/zephyr/.signed.bin`` where ```` is the applications Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/mcuboot_secondary_app_signed.hex`` | ``mcuboot_secondary_app/zephyr/.signed.hex`` where ```` is the applications Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/matter.ota`` | ``.ota`` where ```` is the value of Kconfig ``SB_CONFIG_MATTER_OTA_IMAGE_FILE_NAME`` | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/signed_by_b0_s0_image.hex`` | ``signed_by_b0_.hex`` where ```` is the name of the application | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/signed_by_b0_s1_image.hex`` | ``signed_by_b0_s1_image.hex`` | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/signed_by_b0_s0_image.bin`` | ``signed_by_b0_.bin`` where ```` is the name of the application | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/signed_by_b0_s1_image.bin`` | ``signed_by_b0_s1_image.bin`` | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``/zephyr/signed_by_b0_app.hex`` | ``signed_by_b0_.hex`` where ```` is the name of the network core application | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``/zephyr/signed_by_b0_app.bin`` | ``signed_by_b0_.bin`` where ```` is the name of the network core application | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/merged.hex`` | ``merged.hex`` | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``/zephyr/merged_CPUNET.hex`` | ``merged_CPUNET.hex`` | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/merged_domains.hex`` | No equivalent, use ``merged.hex`` for application core and ``merged_CPUNET.hex`` for network core | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/dfu_multi_image.bin`` | ``dfu_multi_image.bin`` | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/dfu_application.zip`` | ``dfu_application.zip`` | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``zephyr/dfu_mcuboot.zip`` | ``dfu_mcuboot.zip`` | -+-----------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Child/parent file | Sysbuild file | ++=====================================================+===============================================================================================================================================================+ +| ``zephyr/app_update.bin`` | ``/zephyr/.signed.bin`` where ```` is the application's Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/app_signed.hex`` | ``/zephyr/.signed.hex`` where ```` is the application's Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/app_test_update.hex`` | No equivalent | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/app_moved_test_update.hex`` | No equivalent | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/net_core_app_update.bin`` | ``signed_by_mcuboot_and_b0_.bin`` where ```` is the name of the network core application | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/net_core_app_signed.hex`` | ``signed_by_b0_.hex`` where ```` is the name of the network core application | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/net_core_app_test_update.hex`` | No equivalent | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/net_core_app_moved_test_update.hex`` | No equivalent | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/mcuboot_secondary_app_update.bin`` | ``mcuboot_secondary_app/zephyr/.signed.bin`` where ```` is the application's Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/mcuboot_secondary_app_signed.hex`` | ``mcuboot_secondary_app/zephyr/.signed.hex`` where ```` is the application's Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/matter.ota`` | ``.ota`` where ```` is the value of Kconfig ``SB_CONFIG_MATTER_OTA_IMAGE_FILE_NAME`` | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/signed_by_b0_s0_image.hex`` | ``signed_by_b0_.hex`` where ```` is the name of the application | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/signed_by_b0_s1_image.hex`` | ``signed_by_b0_s1_image.hex`` | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/signed_by_b0_s0_image.bin`` | ``signed_by_b0_.bin`` where ```` is the name of the application | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/signed_by_b0_s1_image.bin`` | ``signed_by_b0_s1_image.bin`` | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``/zephyr/signed_by_b0_app.hex`` | ``signed_by_b0_.hex`` where ```` is the name of the network core application | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``/zephyr/signed_by_b0_app.bin`` | ``signed_by_b0_.bin`` where ```` is the name of the network core application | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/internal_flash.hex`` | ``/zephyr/.internal.hex`` where ```` is the application's Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/internal_flash_signed.hex`` | ``/zephyr/.internal.signed.hex`` where ```` is the application's Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/internal_flash_update.bin`` | ``/zephyr/.internal.signed.bin`` where ```` is the application's Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/qspi_flash.hex`` | ``/zephyr/.external.hex`` where ```` is the application's Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/qspi_flash_signed.hex`` | ``/zephyr/.external.signed.hex`` where ```` is the application's Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/qspi_flash_update.bin`` | ``/zephyr/.external.signed.bin`` where ```` is the application's Kconfig :kconfig:option:`CONFIG_KERNEL_BIN_NAME` value | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/merged.hex`` | ``merged.hex`` | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``/zephyr/merged_CPUNET.hex`` | ``merged_CPUNET.hex`` | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/merged_domains.hex`` | No equivalent, use ``merged.hex`` for application core and ``merged_CPUNET.hex`` for network core | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/dfu_multi_image.bin`` | ``dfu_multi_image.bin`` | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/dfu_application.zip`` | ``dfu_application.zip`` | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``zephyr/dfu_mcuboot.zip`` | ``dfu_mcuboot.zip`` | ++-----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ Example output files ==================== @@ -544,21 +604,21 @@ In Sysbuild, elements like file suffixes, shields, and snippets without an image To apply them to a single image, they must be prefixed with the image name. Without doing this, projects with multiple images (for example, those with MCUboot) might fail to build due to invalid configuration for other images. -+-------------------------------+----------------------------------+-----------------------+ -| Configuration parameter | Child/parent | Sysbuild | -+===============================+==================================+=======================+ -| ``-DFILE_SUFFIX=...`` | Applies only to main application | Applies to all images | -+-------------------------------+----------------------------------+-----------------------+ -| ``-D_FILE_SUFFIX=...`` | Applies only to |Applies only to | -+-------------------------------+----------------------------------+-----------------------+ -| ``-DSNIPPET=...`` | Applies only to main application | Applies to all images | -+-------------------------------+----------------------------------+-----------------------+ -| ``-D_SNIPPET=...`` | Applies only to |Applies only to | -+-------------------------------+----------------------------------+-----------------------+ -| ``-DSHIELD=...`` | Applies only to main application | Applies to all images | -+-------------------------------+----------------------------------+-----------------------+ -| ``-D_SHIELD=...`` | Applies only to |Applies only to | -+-------------------------------+----------------------------------+-----------------------+ ++-------------------------------+----------------------------------+-------------------------+ +| Configuration parameter | Child/parent | Sysbuild | ++===============================+==================================+=========================+ +| ``-DFILE_SUFFIX=...`` | Applies only to main application | Applies to all images | ++-------------------------------+----------------------------------+-------------------------+ +| ``-D_FILE_SUFFIX=...`` | Applies only to | Applies only to | ++-------------------------------+----------------------------------+-------------------------+ +| ``-DSNIPPET=...`` | Applies only to main application | Applies to all images | ++-------------------------------+----------------------------------+-------------------------+ +| ``-D_SNIPPET=...`` | Applies only to | Applies only to | ++-------------------------------+----------------------------------+-------------------------+ +| ``-DSHIELD=...`` | Applies only to main application | Applies to all images | ++-------------------------------+----------------------------------+-------------------------+ +| ``-D_SHIELD=...`` | Applies only to | Applies only to | ++-------------------------------+----------------------------------+-------------------------+ Configuration values that specify Kconfig fragment or overlay files (for example, :makevar:`EXTRA_CONF_FILE` and :makevar:`EXTRA_DTC_OVERLAY_FILE`) cannot be applied globally using either child/parent image or sysbuild. They function the same in both systems: From 5c9687d22829846657f2dbe7fc77bc3d0616df6a Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 22 Jul 2024 07:48:03 +0100 Subject: [PATCH 15/72] sysbuild: Fix typo Fixes a typo referring to child/parent image in sysbuild Signed-off-by: Jamie McCrae --- sysbuild/Kconfig.sysbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sysbuild/Kconfig.sysbuild b/sysbuild/Kconfig.sysbuild index 16f80cfe2ba9..5ec893beab5d 100644 --- a/sysbuild/Kconfig.sysbuild +++ b/sysbuild/Kconfig.sysbuild @@ -31,7 +31,7 @@ config PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY help Place the secondary partition of MCUboot in the external flash instead of the internal flash. This option should only be enabled by the user - in the parent image. + in sysbuild. config PM_OVERRIDE_EXTERNAL_DRIVER_CHECK bool "Override external driver check" From c7fd80b344e5aca72742889d77ee3b37ba6c1055 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 22 Jul 2024 08:27:11 +0100 Subject: [PATCH 16/72] doc: release: Add note on nRF5340 extxip sample Adds a note that the sample has been updated to use sysbuild Signed-off-by: Jamie McCrae --- .../releases/release-notes-changelog.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index 369f65bda8b0..03c8a4d8042a 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -46,7 +46,8 @@ Build and configuration system Bootloaders and DFU =================== -|no_changes_yet_note| +* Added documentation for :ref:`qspi_xip_split_image` functionality. +* Added a section in the sysbuild-related migration guide about the migration of :ref:`child_parent_to_sysbuild_migration_qspi_xip` from child/parent image to sysbuild. See also the `MCUboot`_ section. @@ -427,7 +428,10 @@ nRF RPC nRF5340 samples --------------- -|no_changes_yet_note| +* :ref:`smp_svr_ext_xip` sample: + + * This sample has been converted to support sysbuild. + * Support has been added to demonstrate direct-XIP building and building without network core support. Peripheral samples ------------------ From c92ac8948876c44aa416fb0ca62fd41bf1512e57 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 8 Aug 2024 10:11:51 +0100 Subject: [PATCH 17/72] doc: nrf: nrf5340: qspi_xip: Update for sysbuild changes Updates document for working with this feature using sysbuild Signed-off-by: Jamie McCrae --- .../nrf53/qspi_xip_guide_nrf5340.rst | 202 ++++++------------ 1 file changed, 65 insertions(+), 137 deletions(-) diff --git a/doc/nrf/app_dev/device_guides/nrf53/qspi_xip_guide_nrf5340.rst b/doc/nrf/app_dev/device_guides/nrf53/qspi_xip_guide_nrf5340.rst index 909477b704c4..363888c79d7d 100644 --- a/doc/nrf/app_dev/device_guides/nrf53/qspi_xip_guide_nrf5340.rst +++ b/doc/nrf/app_dev/device_guides/nrf53/qspi_xip_guide_nrf5340.rst @@ -24,20 +24,34 @@ Enabling configuration options Application configuration must support an external XIP and image splitting. -Enable the following options: +Enable the following sysbuild options in a ``sysbuild.conf`` file: -* :kconfig:option:`CONFIG_CODE_DATA_RELOCATION` -* :kconfig:option:`CONFIG_HAVE_CUSTOM_LINKER_SCRIPT` -* :kconfig:option:`CONFIG_BUILD_NO_GAP_FILL` -* :kconfig:option:`CONFIG_XIP` -* :kconfig:option:`CONFIG_NORDIC_QSPI_NOR_XIP` -* :kconfig:option:`CONFIG_XIP_SPLIT_IMAGE` -* :kconfig:option:`CONFIG_BOOTLOADER_MCUBOOT` - This option enables the MCUboot build and support for the application. +.. tabs:: -Additionally, set the following options: + .. group-tab:: Swap using move with network core support + + .. code-block:: cfg + + SB_CONFIG_BOOTLOADER_MCUBOOT=y + SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y + SB_CONFIG_NETCORE_APP_UPDATE=y + SB_CONFIG_SECURE_BOOT_NETCORE=y + SB_CONFIG_QSPI_XIP_SPLIT_IMAGE=y + + # This will enable the hci_ipc image for the network core, change to the desired image + SB_CONFIG_NETCORE_HCI_IPC=y + + .. group-tab:: Swap using move without network core support + + .. code-block:: cfg + + SB_CONFIG_BOOTLOADER_MCUBOOT=y + SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y + SB_CONFIG_QSPI_XIP_SPLIT_IMAGE=y + +Additionally, set the following application options: * :kconfig:option:`CONFIG_CUSTOM_LINKER_SCRIPT` to ``""`` -* :kconfig:option:`CONFIG_UPDATEABLE_IMAGE_NUMBER` to ``3`` * :kconfig:option:`CONFIG_FLASH_INIT_PRIORITY` to ``40`` - You must ensure the QSPI device initialization priority, as it makes the external XIP code accessible before it is executed. If any initialization code is expected to be run from the QSPI XIP, then its initialization priority value must be lower than the QSPI device initialization priority. @@ -108,6 +122,7 @@ The configuration must have 3 images with 2 slots each: These slots should be named ``mcuboot_primary_1`` and ``mcuboot_secondary_1``. * The third set of slots is for the QSPI XIP part of the application. These slots should be named ``mcuboot_primary_2`` and ``mcuboot_secondary_2``. + There should also be ``mcuboot_primary_2_pad`` (which should be the same size as ``mcuboot_pad``) and ``mcuboot_primary_2_app``. This means a basic dual image configuration for the nRF5340 DK needs to describe an external QSPI XIP code partition as ``mcuboot_primary_2`` partition. Additionally, ensure that: @@ -118,109 +133,8 @@ Additionally, ensure that: See the following snippet for an example of the static configuration for partition manager: -.. code-block:: console - - app: - address: 0x10200 - end_address: 0xe4000 - region: flash_primary - size: 0xd3e00 - external_flash: - address: 0x120000 - device: MX25R64 - end_address: 0x800000 - region: external_flash - size: 0x6e0000 - mcuboot: - address: 0x0 - end_address: 0x10000 - region: flash_primary - size: 0x10000 - mcuboot_pad: - address: 0x10000 - end_address: 0x10200 - region: flash_primary - size: 0x200 - mcuboot_primary: - address: 0x10000 - end_address: 0xf0000 - orig_span: &id001 - - mcuboot_pad - - app - region: flash_primary - size: 0xe0000 - span: *id001 - mcuboot_primary_1: - address: 0x0 - device: flash_ctrl - end_address: 0x40000 - region: ram_flash - size: 0x40000 - mcuboot_primary_app: - address: 0x10200 - end_address: 0xf0000 - orig_span: &id002 - - app - region: flash_primary - size: 0xdfe00 - span: *id002 - mcuboot_secondary: - address: 0x0 - device: MX25R64 - end_address: 0xe0000 - region: external_flash - size: 0xe0000 - mcuboot_secondary_1: - address: 0xe0000 - device: MX25R64 - end_address: 0x120000 - region: external_flash - size: 0x40000 - mcuboot_primary_2: - address: 0x120000 - device: MX25R64 - end_address: 0x160000 - region: external_flash - size: 0x40000 - mcuboot_secondary_2: - address: 0x160000 - device: MX25R64 - end_address: 0x1a0000 - region: external_flash - size: 0x40000 - otp: - address: 0xff8100 - end_address: 0xff83fc - region: otp - size: 0x2fc - pcd_sram: - address: 0x20000000 - end_address: 0x20002000 - region: sram_primary - size: 0x2000 - ram_flash: - address: 0x40000 - end_address: 0x40000 - region: ram_flash - size: 0x0 - rpmsg_nrf53_sram: - address: 0x20070000 - end_address: 0x20080000 - placement: - before: - - end - region: sram_primary - size: 0x10000 - settings_storage: - address: 0xf0000 - end_address: 0x100000 - region: flash_primary - size: 0x10000 - sram_primary: - address: 0x20002000 - end_address: 0x20070000 - region: sram_primary - size: 0x6e000 +.. literalinclude:: ../../../../../samples/nrf5340/extxip_smp_svr/pm_static.yml + :language: yaml Configuring linker script ************************* @@ -282,43 +196,52 @@ Similarly, it is possible to relocate certain libraries, for example: Building the project ******************** -You must use child image when building your project, as XIP QSPI does not currently support sysbuild. +Use the standard :ref:`building` procedure. +The XIP QSPI sample supports and uses sysbuild by default. -Flashing the project -******************** +Programming the project +*********************** -For the nRF5340 DK and other boards equipped with flash working in the QSPI mode, use the ``west flash`` command. -For other cases, flashing needs to be done manually. +For the nRF5340 DK and other boards equipped with flash working in the QSPI mode, use the :ref:`standard programming command ` (``west flash``). +For other cases, set up a configuration file for nrfjprog, as described in the following section. -Flashing to external flash in SPI/DSPI mode -=========================================== +Programming to external flash in SPI/DSPI mode +============================================== -Flashing an application with ``west`` triggers the ``nrfjprog`` runner. -The runner uses the default system settings that configure the application in the QSPI mode when flashing the external flash. -You can change this behavior by using a custom :file:`Qspi.ini` configuration file, however, it will prevent flashing through west. +Programming an application with west triggers the nrfjprog runner. +The runner uses the default system settings that configure the application in the QSPI mode when programming the external flash. +You can change this behavior by using a custom :file:`Qspi.ini` configuration file. .. note:: The :file:`Qspi.ini` file is required to work on the Nordic Thingy:53. -If you wish to use the :file:`Qspi.ini` file, you will need to manually flash the HEX files in the repository. -For example, for the :ref:`smp_svr_ext_xip` sample, you need to flash the following files (paths are relative to the build directory): +This file can specify the mode to use when programming the QSPI flash. +For example, the following code is from the file for the Thingy:53 and uses ``PP`` for programming and ``READ2IO`` for reading: + +.. literalinclude:: ../../../../../samples/nrf5340/extxip_smp_svr/Qspi_thingy53.ini + :language: yaml -* :file:`/zephyr/merged_CPUNET.hex` +To use this file automatically in a project, update the ``CMakeLists.txt`` file by :ref:`adding the mention of the new file `. +This way, the file can be applied globally for every board built with a project or applied to specific boards if a project supports multiple board targets, each with different configurations. +The following code shows how to set the configuration file used when flashing the Thingy:53 only. - * For Bluetooth stack application the path is :file:` hci_ipc`. -* :file:`mcuboot/zephyr/zephyr.hex` -* :file:`zephyr/internal_flash_signed.hex` -* :file:`zephyr/qspi_flash_signed.hex` +.. note:: + This code must be placed before the ``find_package`` line. -Use the following commands to flash and verify the Simple Management Protocol (SMP) server sample: +.. code-block:: cmake -.. code-block:: console + cmake_minimum_required(VERSION 3.20.0) - nrfjprog -f NRF53 --coprocessor CP_NETWORK --sectorerase --program hci_ipc/zephyr/merged_CPUNET.hex --verify - nrfjprog -f NRF53 --sectorerase --program mcuboot/zephyr/zephyr.hex --verify - nrfjprog -f NRF53 --sectorerase --program zephyr/internal_flash_signed.hex --verify - nrfjprog -f NRF53 --qspisectorerase --program zephyr/qspi_flash_signed.hex --qspiini /Qspi.ini --verify - nrfjprog -f NRF53 --reset + macro(app_set_runner_args) + if(CONFIG_BOARD_THINGY53_NRF5340_CPUAPP) + # Use alternative QSPI configuration file when flashing Thingy53 + board_runner_args(nrfjprog "--qspiini=${CMAKE_CURRENT_SOURCE_DIR}/Qspi_thingy53.ini") + endif() + endmacro() + + find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + + project(smp_svr_ext_xip) .. note:: The external flash chip must be connected to the dedicated QSPI peripheral port pins of the nRF5340 SoC. @@ -391,3 +314,8 @@ The following table lists performance numbers that were measured under different +-----------------+-----------------+--------+--------------+--------+-----------+--------------------+--------------------+--------------------------+--------------------------+ | 128 MHz | External flash | Yes | 48 MHz | Quad | 36.4 | 8.85 | 13.9 | 966 | 911 | +-----------------+-----------------+--------+--------------+--------+-----------+--------------------+--------------------+--------------------------+--------------------------+ + +Additional information +********************** + +For additional information regarding the QSPI XIP mode of |NCS| and how to use it, see :ref:`qspi_xip_split_image`. From c5a1205810c7e2bc533f90df2cb120094de3df01 Mon Sep 17 00:00:00 2001 From: Sylwester Konczyk Date: Fri, 23 Aug 2024 12:22:53 +0200 Subject: [PATCH 18/72] tests: suit: Defect fix in cache_sink tests Ref: NCSDK-28335 Signed-off-by: Sylwester Konczyk --- tests/subsys/suit/cache_sink/src/main.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/subsys/suit/cache_sink/src/main.c b/tests/subsys/suit/cache_sink/src/main.c index fbe80d1a8492..f0437eecc132 100644 --- a/tests/subsys/suit/cache_sink/src/main.c +++ b/tests/subsys/suit/cache_sink/src/main.c @@ -12,7 +12,6 @@ #include #include -#ifndef CONFIG_BOARD_NATIVE_POSIX static const uint8_t corrupted_cache_header_ok_size_nok[] = { 0xBF, /* map(*) */ 0x75, /* text(21) */ @@ -52,7 +51,6 @@ static const uint8_t corrupted_cache_malformed_zcbor[] = { 0x92, 0x83, 0x09, 0x86, 0x70, 0x19, 0x23, /* payload(31) */ 0xFF, /* primitive(*) - end marker */ 0xFF}; /* Alignment to erase block size (16 bytes) */ -#endif static uint8_t uri[] = "http://databucket.com"; static uint8_t data[] = {0x43, 0x60, 0x02, 0x11, 0x35, 0x85, 0x37, 0x85, 0x76, @@ -102,7 +100,6 @@ static uint8_t data3[] = { 0x2e, 0x09, 0x7d, 0xf0, 0x5c, 0x0c, 0xa9, 0xa5, 0x9a, 0x8a, 0xe0, 0xa3, 0xa8, 0x23, 0xc1, 0x41, 0x4e, 0x5e, 0x3f, 0xf7, 0x39, 0xa4, 0xc5, 0x5b, 0xec}; -#ifndef CONFIG_BOARD_NATIVE_POSIX void setup_dfu_test_corrupted_cache(const uint8_t *corrupted_cache, size_t corrupted_cache_size) { /* Erase the area, to met the preconditions in the next test. */ @@ -122,7 +119,6 @@ void setup_dfu_test_corrupted_cache(const uint8_t *corrupted_cache, size_t corru corrupted_cache_size); zassert_equal(res, 0, "Mem compare after write failed"); } -#endif void clear_dfu_test_partitions(void *f) { @@ -159,7 +155,6 @@ bool is_cache_partition_1_empty(void) ZTEST_SUITE(cache_rw_initialization_tests, NULL, NULL, NULL, clear_dfu_test_partitions, NULL); -#ifndef CONFIG_BOARD_NATIVE_POSIX ZTEST_SUITE(cache_sink_recovery_tests, NULL, NULL, NULL, clear_dfu_test_partitions, NULL); ZTEST(cache_sink_recovery_tests, test_cache_recovery_header_ok_size_nok) @@ -169,6 +164,8 @@ ZTEST(cache_sink_recovery_tests, test_cache_recovery_header_ok_size_nok) setup_dfu_test_corrupted_cache(corrupted_cache_header_ok_size_nok, sizeof(corrupted_cache_header_ok_size_nok)); + suit_dfu_cache_validate_content(); + zassert_true(is_cache_partition_1_empty(), "Corrupted cache partition was not recovered"); int ret = suit_dfu_cache_sink_get(&sink, 1, uri3, sizeof(uri3), true); @@ -190,11 +187,11 @@ ZTEST(cache_sink_recovery_tests, test_cache_recovery_malformed_zcbor) setup_dfu_test_corrupted_cache(corrupted_cache_malformed_zcbor, sizeof(corrupted_cache_malformed_zcbor)); + suit_dfu_cache_validate_content(); + zassert_true(is_cache_partition_1_empty(), "Corrupted cache partition was not recovered"); } -#endif - ZTEST_SUITE(cache_sink_tests, NULL, NULL, NULL, clear_dfu_test_partitions, NULL); ZTEST(cache_sink_tests, test_cache_drop_slot_ok) From 1d0d4fcc91a804ddd4cad84bef16fdc788f314f7 Mon Sep 17 00:00:00 2001 From: Piotr Krzyzanowski Date: Mon, 26 Aug 2024 11:10:01 +0200 Subject: [PATCH 19/72] tests: drivers: sensor: multicore_temp Add a multicore_temp - temperature sensor driver stress test Signed-off-by: Piotr Krzyzanowski --- .github/test-spec.yml | 1 + CODEOWNERS | 1 + scripts/ci/tags.yaml | 8 ++++ .../sensor/multicore_temp/CMakeLists.txt | 12 ++++++ .../sensor/multicore_temp/Kconfig.sysbuild | 10 +++++ .../boards/nrf54h20dk_nrf54h20_cpuapp.overlay | 3 ++ .../boards/nrf54h20dk_nrf54h20_cpurad.overlay | 3 ++ tests/drivers/sensor/multicore_temp/prj.conf | 3 ++ .../multicore_temp/remote/CMakeLists.txt | 11 ++++++ .../boards/nrf54h20dk_nrf54h20_cpuapp.overlay | 3 ++ .../boards/nrf54h20dk_nrf54h20_cpurad.overlay | 3 ++ .../sensor/multicore_temp/remote/prj.conf | 3 ++ .../drivers/sensor/multicore_temp/src/main.c | 38 +++++++++++++++++++ .../sensor/multicore_temp/sysbuild.cmake | 18 +++++++++ .../sysbuild/nrf54h20dk_nrf54h20_cpuapp.conf | 1 + .../sysbuild/nrf54h20dk_nrf54h20_cpurad.conf | 1 + .../sensor/multicore_temp/testcase.yaml | 24 ++++++++++++ 17 files changed, 143 insertions(+) create mode 100644 tests/drivers/sensor/multicore_temp/CMakeLists.txt create mode 100644 tests/drivers/sensor/multicore_temp/Kconfig.sysbuild create mode 100644 tests/drivers/sensor/multicore_temp/boards/nrf54h20dk_nrf54h20_cpuapp.overlay create mode 100644 tests/drivers/sensor/multicore_temp/boards/nrf54h20dk_nrf54h20_cpurad.overlay create mode 100644 tests/drivers/sensor/multicore_temp/prj.conf create mode 100644 tests/drivers/sensor/multicore_temp/remote/CMakeLists.txt create mode 100644 tests/drivers/sensor/multicore_temp/remote/boards/nrf54h20dk_nrf54h20_cpuapp.overlay create mode 100644 tests/drivers/sensor/multicore_temp/remote/boards/nrf54h20dk_nrf54h20_cpurad.overlay create mode 100644 tests/drivers/sensor/multicore_temp/remote/prj.conf create mode 100644 tests/drivers/sensor/multicore_temp/src/main.c create mode 100644 tests/drivers/sensor/multicore_temp/sysbuild.cmake create mode 100644 tests/drivers/sensor/multicore_temp/sysbuild/nrf54h20dk_nrf54h20_cpuapp.conf create mode 100644 tests/drivers/sensor/multicore_temp/sysbuild/nrf54h20dk_nrf54h20_cpurad.conf create mode 100644 tests/drivers/sensor/multicore_temp/testcase.yaml diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 0c6a2c816b44..f9fda6e95ff8 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -558,6 +558,7 @@ - "tests/subsys/event_manager_proxy/**/*" - "tests/benchmarks/multicore/**/*" - "tests/drivers/pwm/**/*" + - "tests/drivers/sensor/**/*" "CI-ps-test": - "samples/nrf_rpc/protocols_serialization/**/*" diff --git a/CODEOWNERS b/CODEOWNERS index 9c90255a79a1..642c75d71d63 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -321,6 +321,7 @@ Kconfig* @tejlmand /tests/drivers/lpuart/ @nordic-krch /tests/drivers/nrfx_integration_test/ @anangl /tests/drivers/pwm/gpio_loopback/ @nrfconnect/ncs-low-level-test +/tests/drivers/sensor/multicore_temp/ @nrfconnect/ncs-low-level-test /tests/lib/at_cmd_parser/ @rlubos /tests/lib/at_parser/ @MirkoCovizzi /tests/lib/at_cmd_custom/ @eivindj-nordic diff --git a/scripts/ci/tags.yaml b/scripts/ci/tags.yaml index 8d6d56ae8693..950a4284ffdf 100644 --- a/scripts/ci/tags.yaml +++ b/scripts/ci/tags.yaml @@ -1204,6 +1204,14 @@ ci_tests_drivers_pwm: - zephyr/drivers/pwm/ - zephyr/soc/nordic/ +ci_tests_drivers_sensor: + files: + - modules/hal/nordic/nrfs/ + - nrf/tests/drivers/sensor/ + - zephyr/drivers/sensor/nordic/temp/ + - zephyr/soc/nordic/ + - zephyr/tests/drivers/sensor/ + ci_samples_peripheral_lpuart: files: - modules/hal/nordic/nrfx/ diff --git a/tests/drivers/sensor/multicore_temp/CMakeLists.txt b/tests/drivers/sensor/multicore_temp/CMakeLists.txt new file mode 100644 index 000000000000..fa4a19f53ef5 --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(multicore_temp) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/drivers/sensor/multicore_temp/Kconfig.sysbuild b/tests/drivers/sensor/multicore_temp/Kconfig.sysbuild new file mode 100644 index 000000000000..0898eb292938 --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +source "${ZEPHYR_BASE}/share/sysbuild/Kconfig" + +config REMOTE_BOARD + string "The board used for remote target" diff --git a/tests/drivers/sensor/multicore_temp/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/tests/drivers/sensor/multicore_temp/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 000000000000..012c93a8fa81 --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,3 @@ +temp_sensor: &temp_nrfs { + status = "okay"; +}; diff --git a/tests/drivers/sensor/multicore_temp/boards/nrf54h20dk_nrf54h20_cpurad.overlay b/tests/drivers/sensor/multicore_temp/boards/nrf54h20dk_nrf54h20_cpurad.overlay new file mode 100644 index 000000000000..012c93a8fa81 --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/boards/nrf54h20dk_nrf54h20_cpurad.overlay @@ -0,0 +1,3 @@ +temp_sensor: &temp_nrfs { + status = "okay"; +}; diff --git a/tests/drivers/sensor/multicore_temp/prj.conf b/tests/drivers/sensor/multicore_temp/prj.conf new file mode 100644 index 000000000000..6dc34b1c8a25 --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/prj.conf @@ -0,0 +1,3 @@ +CONFIG_ZTEST=y +CONFIG_NRFS=y +CONFIG_SENSOR=y diff --git a/tests/drivers/sensor/multicore_temp/remote/CMakeLists.txt b/tests/drivers/sensor/multicore_temp/remote/CMakeLists.txt new file mode 100644 index 000000000000..fd79eeff4f0a --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/remote/CMakeLists.txt @@ -0,0 +1,11 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(remote) +target_sources(app PRIVATE ../src/main.c) diff --git a/tests/drivers/sensor/multicore_temp/remote/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/tests/drivers/sensor/multicore_temp/remote/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 000000000000..012c93a8fa81 --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/remote/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,3 @@ +temp_sensor: &temp_nrfs { + status = "okay"; +}; diff --git a/tests/drivers/sensor/multicore_temp/remote/boards/nrf54h20dk_nrf54h20_cpurad.overlay b/tests/drivers/sensor/multicore_temp/remote/boards/nrf54h20dk_nrf54h20_cpurad.overlay new file mode 100644 index 000000000000..012c93a8fa81 --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/remote/boards/nrf54h20dk_nrf54h20_cpurad.overlay @@ -0,0 +1,3 @@ +temp_sensor: &temp_nrfs { + status = "okay"; +}; diff --git a/tests/drivers/sensor/multicore_temp/remote/prj.conf b/tests/drivers/sensor/multicore_temp/remote/prj.conf new file mode 100644 index 000000000000..6dc34b1c8a25 --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/remote/prj.conf @@ -0,0 +1,3 @@ +CONFIG_ZTEST=y +CONFIG_NRFS=y +CONFIG_SENSOR=y diff --git a/tests/drivers/sensor/multicore_temp/src/main.c b/tests/drivers/sensor/multicore_temp/src/main.c new file mode 100644 index 000000000000..5d40e55f2aa8 --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/src/main.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include + +#define NUMBER_OF_READOUT 1000 + +static const struct device *temp_dev = DEVICE_DT_GET(DT_NODELABEL(temp_sensor)); + +ZTEST(multicore_temp, test_driver_stress) +{ + int rc; + struct sensor_value val; + int32_t temp_val; + + TC_PRINT("Running on %s\n", CONFIG_BOARD_TARGET); + + zassert_true(device_is_ready(temp_dev), "Device %s is not ready.", temp_dev->name); + + for (uint32_t i = 1; i <= NUMBER_OF_READOUT; i++) { + rc = sensor_sample_fetch_chan(temp_dev, SENSOR_CHAN_DIE_TEMP); + zassert_ok(rc, "Cannot fetch chan sample: %d.", rc); + + rc = sensor_channel_get(temp_dev, SENSOR_CHAN_DIE_TEMP, &val); + zassert_ok(rc, "Cannot read from channel %d: %d.", SENSOR_CHAN_DIE_TEMP, rc); + + temp_val = (val.val1 * 100) + (val.val2 / 10000); + TC_PRINT("%d: Temperature: %d.%02u\n", i, temp_val / 100, abs(temp_val) % 100); + } + TC_PRINT("Temperature was successfully read %d times.\n", NUMBER_OF_READOUT); +} + +ZTEST_SUITE(multicore_temp, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/drivers/sensor/multicore_temp/sysbuild.cmake b/tests/drivers/sensor/multicore_temp/sysbuild.cmake new file mode 100644 index 000000000000..514e41dd6e57 --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/sysbuild.cmake @@ -0,0 +1,18 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +if("${SB_CONFIG_REMOTE_BOARD}" STREQUAL "") + message(FATAL_ERROR "REMOTE_BOARD must be set to a valid board name") +endif() + +ExternalZephyrProject_Add( + APPLICATION remote + SOURCE_DIR ${APP_DIR}/remote + BOARD ${SB_CONFIG_REMOTE_BOARD} +) + +add_dependencies(multicore_temp remote) +sysbuild_add_dependencies(FLASH multicore_temp remote) diff --git a/tests/drivers/sensor/multicore_temp/sysbuild/nrf54h20dk_nrf54h20_cpuapp.conf b/tests/drivers/sensor/multicore_temp/sysbuild/nrf54h20dk_nrf54h20_cpuapp.conf new file mode 100644 index 000000000000..896239e180ef --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/sysbuild/nrf54h20dk_nrf54h20_cpuapp.conf @@ -0,0 +1 @@ +SB_CONFIG_REMOTE_BOARD="nrf54h20dk/nrf54h20/cpuapp" diff --git a/tests/drivers/sensor/multicore_temp/sysbuild/nrf54h20dk_nrf54h20_cpurad.conf b/tests/drivers/sensor/multicore_temp/sysbuild/nrf54h20dk_nrf54h20_cpurad.conf new file mode 100644 index 000000000000..dd863e78d993 --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/sysbuild/nrf54h20dk_nrf54h20_cpurad.conf @@ -0,0 +1 @@ +SB_CONFIG_REMOTE_BOARD="nrf54h20dk/nrf54h20/cpurad" diff --git a/tests/drivers/sensor/multicore_temp/testcase.yaml b/tests/drivers/sensor/multicore_temp/testcase.yaml new file mode 100644 index 000000000000..da935add38cf --- /dev/null +++ b/tests/drivers/sensor/multicore_temp/testcase.yaml @@ -0,0 +1,24 @@ +common: + sysbuild: true + tags: + - drivers + - sensors + - ci_tests_drivers_sensor + filter: dt_nodelabel_enabled("temp_sensor") + +tests: + drivers.sensor.multicore_temp.nrf54h20dk_cpuapp_cpurad: + platform_allow: + - nrf54h20dk/nrf54h20/cpuapp + integration_platforms: + - nrf54h20dk/nrf54h20/cpuapp + extra_args: + SB_CONF_FILE=sysbuild/nrf54h20dk_nrf54h20_cpurad.conf + + drivers.sensor.multicore_temp.nrf54h20dk_cpurad_cpuapp: + platform_allow: + - nrf54h20dk/nrf54h20/cpurad + integration_platforms: + - nrf54h20dk/nrf54h20/cpurad + extra_args: + SB_CONF_FILE=sysbuild/nrf54h20dk_nrf54h20_cpuapp.conf From 6a250364a0dbda19e576bf36828d621bdf746e71 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Fri, 23 Aug 2024 10:08:33 +0200 Subject: [PATCH 20/72] doc: drivers: ipc_uart: don't redefine uart0 as an ipc_uart The ipc_uart should be a separate node in device tree not redefined uart0. This commit fixes doc for ipc_driver to not endorse use case which leds to issues related to using uart0. Signed-off-by: Andrzej Kuros --- doc/nrf/drivers/uart_ipc.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/doc/nrf/drivers/uart_ipc.rst b/doc/nrf/drivers/uart_ipc.rst index 139fdfe06e99..9a71651b2be0 100644 --- a/doc/nrf/drivers/uart_ipc.rst +++ b/doc/nrf/drivers/uart_ipc.rst @@ -23,11 +23,13 @@ A configuration example: .. code-block:: devicetree - &uart0 { - status = "okay"; - compatible = "nordic,nrf-ipc-uart"; - ipc = <&ipc0>; - ept-name = "remote shell"; + / { + uart_ipc: uart_ipc { + status = "okay"; + compatible = "nordic,nrf-ipc-uart"; + ipc = <&ipc0>; + ept-name = "remote shell"; + }; }; The following configuration options are available for this driver: From 5f1f73aeac7aabe3597f4fbdb590aaf4889c9965 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Fri, 23 Aug 2024 10:08:49 +0200 Subject: [PATCH 21/72] samples: dtm: nrf5340_cpunet do not redefine uart0 as ipc_uart Making the `uart0` a `compatible = "nordic,nrf-ipc-uart";` does not release the `uart0` for other purposes. On nrf5340_cpunet when when an overlay that uses TWIM0 is used the fact that `uart0` node is still used (regardless that redefined to use ipc uart not the hardware uart driver) leads to compilation error. To overcome this issue the `uart0` is no more redefined but a new device tree node `uart_ipc` is provided. From application's point of view this is an additional uart that is used by dtm. The `uart0` present in device tree can be used for other purpose or disabled. Signed-off-by: Andrzej Kuros --- .../boards/nrf5340dk_nrf5340_cpunet.overlay | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/samples/bluetooth/direct_test_mode/boards/nrf5340dk_nrf5340_cpunet.overlay b/samples/bluetooth/direct_test_mode/boards/nrf5340dk_nrf5340_cpunet.overlay index 1efb596c95d1..308f22ea8c5c 100644 --- a/samples/bluetooth/direct_test_mode/boards/nrf5340dk_nrf5340_cpunet.overlay +++ b/samples/bluetooth/direct_test_mode/boards/nrf5340dk_nrf5340_cpunet.overlay @@ -6,16 +6,16 @@ / { chosen { - ncs,dtm-uart = &uart0; + ncs,dtm-uart = &uart_ipc; }; -}; -&uart0 { - status = "okay"; - compatible = "nordic,nrf-ipc-uart"; - ipc = <&ipc0>; - ept-name = "remote shell"; - current-speed = <19200>; + uart_ipc: uart_ipc { + status = "okay"; + compatible = "nordic,nrf-ipc-uart"; + ipc = <&ipc0>; + ept-name = "remote shell"; + current-speed = <19200>; + }; }; &radio { From ce9869e41b466d87f9c011662fb577e4a534c91f Mon Sep 17 00:00:00 2001 From: Tommi Rantanen Date: Thu, 22 Aug 2024 13:45:42 +0300 Subject: [PATCH 22/72] lib: lte_link_control: Change XMONITOR parsing to use at_parser Manually search for correct number of commas has been used for XMONITOR parsing. Changing this to use at_parser. Signed-off-by: Tommi Rantanen --- lib/lte_link_control/lte_lc.c | 73 +++++++++---------- tests/lib/lte_lc_api/src/lte_lc_api_test.c | 82 ++++++++++++++++++---- 2 files changed, 99 insertions(+), 56 deletions(-) diff --git a/lib/lte_link_control/lte_lc.c b/lib/lte_link_control/lte_lc.c index 784e7cf23438..46be0d309acc 100644 --- a/lib/lte_link_control/lte_lc.c +++ b/lib/lte_link_control/lte_lc.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "lte_lc_helpers.h" @@ -870,12 +871,13 @@ int lte_lc_psm_get(int *tau, int *active_time) { int err; struct lte_lc_psm_cfg psm_cfg; + struct at_parser parser; char active_time_str[9] = {0}; char tau_ext_str[9] = {0}; char tau_legacy_str[9] = {0}; + int len; + int reg_status = 0; static char response[160] = { 0 }; - const char ch = ','; - char *comma_ptr; if ((tau == NULL) || (active_time == NULL)) { return -EINVAL; @@ -884,7 +886,7 @@ int lte_lc_psm_get(int *tau, int *active_time) /* Format of XMONITOR AT command response: * %XMONITOR: ,[,,,,,,, * ,,,,,, - * ,] + * ,] * We need to parse the three last parameters, Active-Time, Periodic-TAU-ext and * Periodic-TAU. */ @@ -897,59 +899,48 @@ int lte_lc_psm_get(int *tau, int *active_time) return -EFAULT; } - comma_ptr = strchr(response, ch); - if (!comma_ptr) { - /* Not an AT error, thus must be that just a received: - * optional part is included in a response only when is 1 or 5. - */ - LOG_DBG("Not registered: cannot get current PSM configuration"); - return -EBADMSG; - } + err = at_parser_init(&parser, response); + __ASSERT_NO_MSG(err == 0); - /* Skip over first 13 fields in AT cmd response by counting delimiters (commas). */ - for (int i = 0; i < 12; i++) { - if (comma_ptr) { - comma_ptr = strchr(comma_ptr + 1, ch); - } else { - LOG_ERR("AT command parsing failed"); - return -EBADMSG; - } + /* Check registration status */ + err = at_parser_num_get(&parser, 1, ®_status); + if (err) { + LOG_ERR("AT command parsing failed, error: %d", err); + return -EBADMSG; + } else if (reg_status != LTE_LC_NW_REG_REGISTERED_HOME && + reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING) { + LOG_WRN("No PSM parameters because device not registered, status: %d", reg_status); + return -EBADMSG; } - /* The last three fields of AT response looks something like this: - * ,"00011110","00000111","01001001" - * comma_ptr now points the comma before Active-Time. Discard the comma and the quote mark, - * hence + 2, and copy Active-Time into active_time_str. Find the next comma and repeat for - * Periodic-TAU-ext and so forth. - */ - - if (comma_ptr) { - strncpy(active_time_str, comma_ptr + 2, 8); - } else { - LOG_ERR("AT command parsing failed"); + /* */ + len = sizeof(active_time_str); + err = at_parser_string_get(&parser, 14, active_time_str, &len); + if (err) { + LOG_ERR("AT command parsing failed, error: %d", err); return -EBADMSG; } - comma_ptr = strchr(comma_ptr + 1, ch); - if (comma_ptr) { - strncpy(tau_ext_str, comma_ptr + 2, 8); - } else { - LOG_ERR("AT command parsing failed"); + /* */ + len = sizeof(tau_ext_str); + err = at_parser_string_get(&parser, 15, tau_ext_str, &len); + if (err) { + LOG_ERR("AT command parsing failed, error: %d", err); return -EBADMSG; } - comma_ptr = strchr(comma_ptr + 1, ch); - if (comma_ptr) { - strncpy(tau_legacy_str, comma_ptr + 2, 8); - } else { - LOG_ERR("AT command parsing failed"); + /* */ + len = sizeof(tau_legacy_str); + err = at_parser_string_get(&parser, 16, tau_legacy_str, &len); + if (err) { + LOG_ERR("AT command parsing failed, error: %d", err); return -EBADMSG; } err = parse_psm(active_time_str, tau_ext_str, tau_legacy_str, &psm_cfg); if (err) { LOG_ERR("Failed to parse PSM configuration, error: %d", err); - return err; + return -EBADMSG; } *tau = psm_cfg.tau; diff --git a/tests/lib/lte_lc_api/src/lte_lc_api_test.c b/tests/lib/lte_lc_api/src/lte_lc_api_test.c index 9fb2da6e932e..5ca158c634f1 100644 --- a/tests/lib/lte_lc_api/src/lte_lc_api_test.c +++ b/tests/lib/lte_lc_api/src/lte_lc_api_test.c @@ -906,14 +906,15 @@ void test_lte_lc_psm_get_null_fail(void) TEST_ASSERT_EQUAL(-EINVAL, ret); } -void test_lte_lc_psm_get_badmsg_no_comma_fail(void) +void test_lte_lc_psm_get_badmsg_no_reg_status_number_fail(void) { int ret; int tau; int active_time; + /* as string instead of number to make getting it fail */ static const char xmonitor_resp[] = - "%XMONITOR: 1"; + "%XMONITOR: invalid"; __cmock_nrf_modem_at_cmd_ExpectAndReturn(NULL, 0, "AT%%XMONITOR", 0); __cmock_nrf_modem_at_cmd_IgnoreArg_buf(); __cmock_nrf_modem_at_cmd_IgnoreArg_len(); @@ -924,7 +925,7 @@ void test_lte_lc_psm_get_badmsg_no_comma_fail(void) TEST_ASSERT_EQUAL(-EBADMSG, ret); } -void test_lte_lc_psm_get_badmsg_no_edrx_value_fail(void) +void test_lte_lc_psm_get_badmsg_no_active_time_fail(void) { int ret; int tau; @@ -932,7 +933,7 @@ void test_lte_lc_psm_get_badmsg_no_edrx_value_fail(void) static const char xmonitor_resp[] = "%XMONITOR: 1,\"Operator\",\"OP\",\"20065\",\"002F\",7,20,\"0012BEEF\"," - "334,6200,66,44"; + "334,6200,66,44,\"\""; __cmock_nrf_modem_at_cmd_ExpectAndReturn(NULL, 0, "AT%%XMONITOR", 0); __cmock_nrf_modem_at_cmd_IgnoreArg_buf(); __cmock_nrf_modem_at_cmd_IgnoreArg_len(); @@ -943,7 +944,7 @@ void test_lte_lc_psm_get_badmsg_no_edrx_value_fail(void) TEST_ASSERT_EQUAL(-EBADMSG, ret); } -void test_lte_lc_psm_get_badmsg_no_active_time_fail(void) +void test_lte_lc_psm_get_badmsg_no_tau_ext_fail(void) { int ret; int tau; @@ -951,7 +952,7 @@ void test_lte_lc_psm_get_badmsg_no_active_time_fail(void) static const char xmonitor_resp[] = "%XMONITOR: 1,\"Operator\",\"OP\",\"20065\",\"002F\",7,20,\"0012BEEF\"," - "334,6200,66,44,\"\""; + "334,6200,66,44,\"\",\"00000101\""; __cmock_nrf_modem_at_cmd_ExpectAndReturn(NULL, 0, "AT%%XMONITOR", 0); __cmock_nrf_modem_at_cmd_IgnoreArg_buf(); __cmock_nrf_modem_at_cmd_IgnoreArg_len(); @@ -962,7 +963,7 @@ void test_lte_lc_psm_get_badmsg_no_active_time_fail(void) TEST_ASSERT_EQUAL(-EBADMSG, ret); } -void test_lte_lc_psm_get_badmsg_no_tau_ext_fail(void) +void test_lte_lc_psm_get_badmsg_no_legacy_tau_fail(void) { int ret; int tau; @@ -970,7 +971,7 @@ void test_lte_lc_psm_get_badmsg_no_tau_ext_fail(void) static const char xmonitor_resp[] = "%XMONITOR: 1,\"Operator\",\"OP\",\"20065\",\"002F\",7,20,\"0012BEEF\"," - "334,6200,66,44,\"\",\"00000101\""; + "334,6200,66,44,\"\",\"00000101\",\"00010011\""; __cmock_nrf_modem_at_cmd_ExpectAndReturn(NULL, 0, "AT%%XMONITOR", 0); __cmock_nrf_modem_at_cmd_IgnoreArg_buf(); __cmock_nrf_modem_at_cmd_IgnoreArg_len(); @@ -981,7 +982,7 @@ void test_lte_lc_psm_get_badmsg_no_tau_ext_fail(void) TEST_ASSERT_EQUAL(-EBADMSG, ret); } -void test_lte_lc_psm_get_badmsg_no_legacy_tau_fail(void) +void test_lte_lc_psm_get_badmsg_legacy_tau_len_not_8_fail(void) { int ret; int tau; @@ -989,7 +990,7 @@ void test_lte_lc_psm_get_badmsg_no_legacy_tau_fail(void) static const char xmonitor_resp[] = "%XMONITOR: 1,\"Operator\",\"OP\",\"20065\",\"002F\",7,20,\"0012BEEF\"," - "334,6200,66,44,\"\",\"00000101\",\"00010011\""; + "334,6200,66,44,\"\",\"00000101\",\"00010011\",\"001001\""; __cmock_nrf_modem_at_cmd_ExpectAndReturn(NULL, 0, "AT%%XMONITOR", 0); __cmock_nrf_modem_at_cmd_IgnoreArg_buf(); __cmock_nrf_modem_at_cmd_IgnoreArg_len(); @@ -1000,7 +1001,7 @@ void test_lte_lc_psm_get_badmsg_no_legacy_tau_fail(void) TEST_ASSERT_EQUAL(-EBADMSG, ret); } -void test_lte_lc_psm_get_inval_legacy_tau_len_not_8_fail(void) +void test_lte_lc_psm_get_badmsg_tau_ext_len_not_8_fail(void) { int ret; int tau; @@ -1008,7 +1009,7 @@ void test_lte_lc_psm_get_inval_legacy_tau_len_not_8_fail(void) static const char xmonitor_resp[] = "%XMONITOR: 1,\"Operator\",\"OP\",\"20065\",\"002F\",7,20,\"0012BEEF\"," - "334,6200,66,44,\"\",\"00000101\",\"00010011\",\"001001\""; + "334,6200,66,44,\"\",\"00000101\",\"001001\",\"00100101\""; __cmock_nrf_modem_at_cmd_ExpectAndReturn(NULL, 0, "AT%%XMONITOR", 0); __cmock_nrf_modem_at_cmd_IgnoreArg_buf(); __cmock_nrf_modem_at_cmd_IgnoreArg_len(); @@ -1016,7 +1017,30 @@ void test_lte_lc_psm_get_inval_legacy_tau_len_not_8_fail(void) (char *)xmonitor_resp, sizeof(xmonitor_resp)); ret = lte_lc_psm_get(&tau, &active_time); - TEST_ASSERT_EQUAL(-EINVAL, ret); + TEST_ASSERT_EQUAL(-EBADMSG, ret); +} + +void test_lte_lc_psm_get_badmsg_invalid_reg_status_fail(void) +{ + int ret; + int tau; + int active_time; + + /* is unknown to make sure we don't parse the rest of the response. + * the rest of the response is intentionally valid so that we would see a successful + * return value if unknown status would be accepted. + */ + static const char xmonitor_resp[] = + "%XMONITOR: 4,\"Operator\",\"OP\",\"20065\",\"002F\",7,20,\"0012BEEF\"," + "334,6200,66,44,\"\",\"00000101\",\"00010011\",\"00100101\""; + __cmock_nrf_modem_at_cmd_ExpectAndReturn(NULL, 0, "AT%%XMONITOR", 0); + __cmock_nrf_modem_at_cmd_IgnoreArg_buf(); + __cmock_nrf_modem_at_cmd_IgnoreArg_len(); + __cmock_nrf_modem_at_cmd_ReturnArrayThruPtr_buf( + (char *)xmonitor_resp, sizeof(xmonitor_resp)); + + ret = lte_lc_psm_get(&tau, &active_time); + TEST_ASSERT_EQUAL(-EBADMSG, ret); } void test_lte_lc_proprietary_psm_req_enable_success(void) @@ -1869,7 +1893,7 @@ void test_lte_lc_cereg_with_xmonitor(void) strcpy(at_notif, "+CEREG: 5,\"4321\",\"87654321\",9,,,\"11100000\",\"11100000\"\r\n"); static const char xmonitor_resp[] = - "%XMONITOR: 1,\"Operator\",\"OP\",\"20065\",\"4321\",9,20,\"12345678\"," + "%XMONITOR: 5,\"Operator\",\"OP\",\"20065\",\"4321\",9,20,\"12345678\"," "334,6200,66,44,\"\"," "\"11100000\",\"11100000\",\"01001001\""; @@ -1913,7 +1937,7 @@ void test_lte_lc_cereg_with_xmonitor_badmsg(void) strcpy(at_notif, "+CEREG: 1,\"5678\",\"87654321\",9,,,\"11100000\",\"11100000\"\r\n"); static const char xmonitor_resp[] = - "%XMONITOR: 1,\"Operator\",\"OP\",\"20065\",\"4321\",9,20,\"12345678\"," + "%XMONITOR: 1,\"Operator\",\"OP\",\"20065\",\"5678\",9,20,\"87654321\"," "334,6200,66,44,\"\"," "\"11100000\",\"11100000\""; @@ -1969,6 +1993,34 @@ void test_lte_lc_cereg_with_xmonitor_fail(void) k_sleep(K_MSEC(1)); } +void test_lte_lc_cereg_with_xmonitor_tau_ext_not_8_fail(void) +{ + strcpy(at_notif, "+CEREG: 1,\"5678\",\"87654321\",9,,,\"11100000\",\"111000\"\r\n"); + + static const char xmonitor_resp[] = + "%XMONITOR: 1,\"Operator\",\"OP\",\"20065\",\"5678\",9,20,\"87654321\"," + "334,6200,66,44,\"\"," + "\"11100000\",\"001001\",\"01001001\""; + + lte_lc_callback_count_expected = 1; + + test_event_data[0].type = LTE_LC_EVT_NW_REG_STATUS; + test_event_data[0].nw_reg_status = LTE_LC_NW_REG_REGISTERED_HOME; + + /* No LTE_LC_EVT_CELL_UPDATE because same values */ + /* No LTE_LC_EVT_LTE_MODE_UPDATE because same values */ + /* No LTE_LC_EVT_PSM_UPDATE because XMONITOR parsing fails */ + + __cmock_nrf_modem_at_cmd_ExpectAndReturn(NULL, 0, "AT%%XMONITOR", 0); + __cmock_nrf_modem_at_cmd_IgnoreArg_buf(); + __cmock_nrf_modem_at_cmd_IgnoreArg_len(); + __cmock_nrf_modem_at_cmd_ReturnArrayThruPtr_buf( + (char *)xmonitor_resp, sizeof(xmonitor_resp)); + + at_monitor_dispatch(at_notif); + k_sleep(K_MSEC(1)); +} + /* Test the following CEREG syntax: * - Empty: , , , , * - Exists: , From 7ba1ad5311dbec052696fe7920e2041e63b9e8ff Mon Sep 17 00:00:00 2001 From: Tony Le Date: Wed, 21 Aug 2024 13:17:28 -0700 Subject: [PATCH 23/72] samples: cellular: nrf_cloud_multi_service: renamed Wi-Fi overlays Renamed the overlay_nrf7002ek_wifi_no_lte.conf file to overlay_nrf700x_wifi_mqtt_no_lte.conf and the overlay_nrf7002ek_wifi_coap_no_lte.conf file to overlay_nrf700x_wifi_coap_no_lte.conf to indicate that they work with many Wi-Fi hardware combinations. Added a test configuration for nRF7002 DK in sample.yaml file. Jira: IRIS-6925 Signed-off-by: Tony Le --- .../releases/release-notes-changelog.rst | 2 + .../nrf_cloud_multi_service/README.rst | 96 ++++++++++++++----- ... => overlay_nrf700x_wifi_coap_no_lte.conf} | 0 ... => overlay_nrf700x_wifi_mqtt_no_lte.conf} | 0 .../nrf_cloud_multi_service/sample.yaml | 11 ++- 5 files changed, 82 insertions(+), 27 deletions(-) rename samples/cellular/nrf_cloud_multi_service/{overlay_nrf7002ek_wifi_coap_no_lte.conf => overlay_nrf700x_wifi_coap_no_lte.conf} (100%) rename samples/cellular/nrf_cloud_multi_service/{overlay_nrf7002ek_wifi_no_lte.conf => overlay_nrf700x_wifi_mqtt_no_lte.conf} (100%) diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index 03c8a4d8042a..defe472c04dc 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -350,6 +350,8 @@ Cellular samples * Wi-Fi overlays from newlibc to picolib. * Handling of JITP association to improve speed and reliability. + * Renamed the :file:`overlay_nrf7002ek_wifi_no_lte.conf` overlay to :file:`overlay_nrf700x_wifi_mqtt_no_lte.conf`. + * Renamed the :file:`overlay_nrf7002ek_wifi_coap_no_lte.conf` overlay to :file:`overlay_nrf700x_wifi_coap_no_lte.conf`. * :ref:`nrf_cloud_rest_device_message` sample: diff --git a/samples/cellular/nrf_cloud_multi_service/README.rst b/samples/cellular/nrf_cloud_multi_service/README.rst index 21a671c192d2..16de26b54763 100644 --- a/samples/cellular/nrf_cloud_multi_service/README.rst +++ b/samples/cellular/nrf_cloud_multi_service/README.rst @@ -815,68 +815,112 @@ Once the sample is built and flashed, proceed to :ref:`nrf_cloud_multi_service_s .. _nrf_cloud_multi_service_building_wifi_conn: -Building with experimental support for Wi-Fi connectivity for nRF5340 DK with nRF7002 EK -======================================================================================== +Building with experimental support for Wi-Fi connectivity +========================================================= This sample :ref:`experimentally ` supports connecting to nRF Cloud using Wi-Fi instead of using LTE. -An overlay for this is only provided for the nRF5340 DK with the nRF7002 EK shield attached. +Overlays for this are provided for the nRF7002 DK, and the nRF5340 DK with the nRF7002 EK shield attached. -It is possible to use Wi-Fi with other hardware combinations (such as the nRF7002 DK), but you must adjust heap and stack usage accordingly. -See the :file:`src/prj.conf` configuration file and the :file:`overlay_nrf7002ek_wifi_no_lte.conf` overlay for additional details. +It is possible to use Wi-Fi with other hardware combinations, but you must adjust heap and stack usage accordingly. +See the :file:`src/prj.conf` configuration file and the :file:`overlay_nrf700x_wifi_mqtt_no_lte.conf` overlay for additional details. .. important:: Connecting to nRF Cloud using Wi-Fi currently requires that device credentials are used insecurely. - The provided overlay for Wi-Fi connectivity uses the :ref:`TLS Credentials Subsystem ` (with the PSA Protected Storage backend, see :kconfig:option:`CONFIG_TLS_CREDENTIALS_BACKEND_PROTECTED_STORAGE`) to store credentials when not in use. + The provided overlays for Wi-Fi connectivity use the :ref:`TLS Credentials Subsystem ` (with the PSA Protected Storage backend, see :kconfig:option:`CONFIG_TLS_CREDENTIALS_BACKEND_PROTECTED_STORAGE`) to store credentials when not in use. Even though this is more secure than :ref:`hard-coded credentials `, the device private key still has to be loaded into unprotected memory during TLS connections. This overlay also enables the :ref:`TLS Credentials Shell ` for run-time credential installation. -If you are certain you understand the risks, you can configure your build to use Wi-Fi connectivity on the nRF5340 DK with the nRF7002 EK shield by using the ``--board nrf5340dk/nrf5340/cpuapp/ns`` target and the ``-DSHIELD=nrf7002ek``, ``-DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf``, and ``-DEXTRA_CONF_FILE=overlay_nrf7002ek_wifi_no_lte.conf`` options. +If you are certain you understand the risks, you can configure your build to use Wi-Fi connectivity using the ``-DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf`` and ``-DEXTRA_CONF_FILE=overlay_nrf700x_wifi_mqtt_no_lte.conf`` options. +On the nRF5340 DK with the nRF7002 EK shield, you need to also use the ``-DSHIELD=nrf7002ek`` option. You must also configure a (globally unique) device ID at build time by enabling the :kconfig:option:`CONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME` Kconfig option and setting :kconfig:option:`CONFIG_NRF_CLOUD_CLIENT_ID` to the device ID. -For example, for a device with the device ID ``698d4c11-0ccc-4f04-89cd-6882724e3f6f``: +For example, for a device ID ``698d4c11-0ccc-4f04-89cd-6882724e3f6f``: .. tabs:: - .. group-tab:: MQTT + .. group-tab:: nRF5340 DK with the nRF7002 EK shield .. tabs:: - .. group-tab:: Bash + .. group-tab:: MQTT - .. parsed-literal:: - :class: highlight + .. tabs:: - west build --board nrf5340dk/nrf5340/cpuapp/ns -p always -- -DSHIELD=nrf7002ek -DEXTRA_CONF_FILE=overlay_nrf7002ek_wifi_no_lte.conf -DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf -DCONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME=y -DCONFIG_NRF_CLOUD_CLIENT_ID=\"698d4c11-0ccc-4f04-89cd-6882724e3f6f\" + .. group-tab:: Bash - .. group-tab:: PowerShell + .. parsed-literal:: + :class: highlight - .. parsed-literal:: - :class: highlight + west build --board nrf5340dk/nrf5340/cpuapp/ns -p always -- -DSHIELD=nrf7002ek -DEXTRA_CONF_FILE=overlay_nrf700x_wifi_mqtt_no_lte.conf -DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf -DCONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME=y -DCONFIG_NRF_CLOUD_CLIENT_ID=\"698d4c11-0ccc-4f04-89cd-6882724e3f6f\" - west build --board nrf5340dk/nrf5340/cpuapp/ns -p always -- -DSHIELD=nrf7002ek -DEXTRA_CONF_FILE=overlay_nrf7002ek_wifi_no_lte.conf -DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf -DCONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME=y "-DCONFIG_NRF_CLOUD_CLIENT_ID=\`"698d4c11-0ccc-4f04-89cd-6882724e3f6f\`"" + .. group-tab:: PowerShell - .. group-tab:: CoAP + .. parsed-literal:: + :class: highlight + + west build --board nrf5340dk/nrf5340/cpuapp/ns -p always -- -DSHIELD=nrf7002ek -DEXTRA_CONF_FILE=overlay_nrf700x_wifi_mqtt_no_lte.conf -DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf -DCONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME=y "-DCONFIG_NRF_CLOUD_CLIENT_ID=\`"698d4c11-0ccc-4f04-89cd-6882724e3f6f\`"" + + .. group-tab:: CoAP + + .. tabs:: + + .. group-tab:: Bash + + .. parsed-literal:: + :class: highlight + + west build --board nrf5340dk/nrf5340/cpuapp/ns -p always -- -DSHIELD=nrf7002ek -DEXTRA_CONF_FILE=overlay_nrf700x_wifi_coap_no_lte.conf -DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf -DCONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME=y -DCONFIG_NRF_CLOUD_CLIENT_ID=\"698d4c11-0ccc-4f04-89cd-6882724e3f6f\" + + .. group-tab:: PowerShell + + .. parsed-literal:: + :class: highlight + + west build --board nrf5340dk/nrf5340/cpuapp/ns -p always -- -DSHIELD=nrf7002ek -DEXTRA_CONF_FILE=overlay_nrf700x_wifi_coap_no_lte.conf -DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf -DCONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME=y "-DCONFIG_NRF_CLOUD_CLIENT_ID=\`"698d4c11-0ccc-4f04-89cd-6882724e3f6f\`"" + + .. group-tab:: nRF7002 DK .. tabs:: - .. group-tab:: Bash + .. group-tab:: MQTT + + .. tabs:: + + .. group-tab:: Bash + + .. parsed-literal:: + :class: highlight + + west build --board nrf7002dk/nrf5340/cpuapp/ns -p always -- -DEXTRA_CONF_FILE=overlay_nrf700x_wifi_mqtt_no_lte.conf -DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf -DCONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME=y -DCONFIG_NRF_CLOUD_CLIENT_ID=\"698d4c11-0ccc-4f04-89cd-6882724e3f6f\" + + .. group-tab:: PowerShell + + .. parsed-literal:: + :class: highlight - .. parsed-literal:: - :class: highlight + west build --board nrf7002dk/nrf5340/cpuapp/ns -p always -- -DEXTRA_CONF_FILE=overlay_nrf700x_wifi_mqtt_no_lte.conf -DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf -DCONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME=y "-DCONFIG_NRF_CLOUD_CLIENT_ID=\`"698d4c11-0ccc-4f04-89cd-6882724e3f6f\`"" - west build --board nrf5340dk/nrf5340/cpuapp/ns -p always -- -DSHIELD=nrf7002ek -DEXTRA_CONF_FILE=overlay_nrf7002ek_wifi_coap_no_lte.conf -DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf -DCONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME=y -DCONFIG_NRF_CLOUD_CLIENT_ID=\"698d4c11-0ccc-4f04-89cd-6882724e3f6f\" + .. group-tab:: CoAP - .. group-tab:: PowerShell + .. tabs:: - .. parsed-literal:: - :class: highlight + .. group-tab:: Bash - west build --board nrf5340dk/nrf5340/cpuapp/ns -p always -- -DSHIELD=nrf7002ek -DEXTRA_CONF_FILE=overlay_nrf7002ek_wifi_coap_no_lte.conf -DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf -DCONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME=y "-DCONFIG_NRF_CLOUD_CLIENT_ID=\`"698d4c11-0ccc-4f04-89cd-6882724e3f6f\`"" + .. parsed-literal:: + :class: highlight + + west build --board nrf7002dk/nrf5340/cpuapp/ns -p always -- -DEXTRA_CONF_FILE=overlay_nrf700x_wifi_coap_no_lte.conf -DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf -DCONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME=y -DCONFIG_NRF_CLOUD_CLIENT_ID=\"698d4c11-0ccc-4f04-89cd-6882724e3f6f\" + + .. group-tab:: PowerShell + + .. parsed-literal:: + :class: highlight + west build --board nrf7002dk/nrf5340/cpuapp/ns -p always -- -DEXTRA_CONF_FILE=overlay_nrf700x_wifi_coap_no_lte.conf -DSB_CONF_FILE=sysbuild_nrf700x-wifi-conn.conf -DCONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME=y "-DCONFIG_NRF_CLOUD_CLIENT_ID=\`"698d4c11-0ccc-4f04-89cd-6882724e3f6f\`"" Once the sample is built and flashed, proceed to :ref:`nrf_cloud_multi_service_standard_onboarding` for instructions on how to onboard your device. diff --git a/samples/cellular/nrf_cloud_multi_service/overlay_nrf7002ek_wifi_coap_no_lte.conf b/samples/cellular/nrf_cloud_multi_service/overlay_nrf700x_wifi_coap_no_lte.conf similarity index 100% rename from samples/cellular/nrf_cloud_multi_service/overlay_nrf7002ek_wifi_coap_no_lte.conf rename to samples/cellular/nrf_cloud_multi_service/overlay_nrf700x_wifi_coap_no_lte.conf diff --git a/samples/cellular/nrf_cloud_multi_service/overlay_nrf7002ek_wifi_no_lte.conf b/samples/cellular/nrf_cloud_multi_service/overlay_nrf700x_wifi_mqtt_no_lte.conf similarity index 100% rename from samples/cellular/nrf_cloud_multi_service/overlay_nrf7002ek_wifi_no_lte.conf rename to samples/cellular/nrf_cloud_multi_service/overlay_nrf700x_wifi_mqtt_no_lte.conf diff --git a/samples/cellular/nrf_cloud_multi_service/sample.yaml b/samples/cellular/nrf_cloud_multi_service/sample.yaml index 338f3f47d5b8..e047566b2fb6 100644 --- a/samples/cellular/nrf_cloud_multi_service/sample.yaml +++ b/samples/cellular/nrf_cloud_multi_service/sample.yaml @@ -95,6 +95,15 @@ tests: - nrf5340dk/nrf5340/cpuapp/ns platform_allow: nrf5340dk/nrf5340/cpuapp/ns extra_args: nrf_cloud_multi_service_SHIELD=nrf7002ek - EXTRA_CONF_FILE="overlay_nrf7002ek_wifi_no_lte.conf" + EXTRA_CONF_FILE="overlay_nrf700x_wifi_mqtt_no_lte.conf" + SB_CONF_FILE="sysbuild_nrf700x-wifi-conn.conf" + tags: ci_build sysbuild ci_samples_cellular + sample.cellular.nrf7002dk_wifi.conn: + sysbuild: true + build_only: true + integration_platforms: + - nrf7002dk/nrf5340/cpuapp/ns + platform_allow: nrf7002dk/nrf5340/cpuapp/ns + extra_args: EXTRA_CONF_FILE="overlay_nrf700x_wifi_mqtt_no_lte.conf" SB_CONF_FILE="sysbuild_nrf700x-wifi-conn.conf" tags: ci_build sysbuild ci_samples_cellular From f41e333f6692d5760b470cc86247ed85bc00ab28 Mon Sep 17 00:00:00 2001 From: Arkadiusz Balys Date: Fri, 23 Aug 2024 11:42:58 +0200 Subject: [PATCH 24/72] samples: matter: Enable NS build for all Matter samples Enabled TF-M and NS build for Matter Lock, Matter Light Bulb, Matter Light Switch, Matter Thermostat, and Matter Window Covering samples. Aligned DTS and config overlays. Signed-off-by: Arkadiusz Balys --- .../releases/release-notes-changelog.rst | 5 +- samples/matter/light_bulb/Kconfig.sysbuild | 13 ++ samples/matter/light_bulb/README.rst | 7 + .../nrf54l15pdk_nrf54l15_cpuapp_ns.conf | 30 ++++ .../nrf54l15pdk_nrf54l15_cpuapp_ns.overlay | 83 +++++++++++ ..._static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml | 141 ++++++++++++++++++ samples/matter/light_bulb/sample.yaml | 3 +- samples/matter/light_switch/Kconfig.sysbuild | 13 ++ samples/matter/light_switch/README.rst | 7 + .../nrf54l15pdk_nrf54l15_cpuapp_ns.conf | 30 ++++ .../nrf54l15pdk_nrf54l15_cpuapp_ns.overlay | 52 +++++++ ..._static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml | 141 ++++++++++++++++++ samples/matter/light_switch/sample.yaml | 3 +- samples/matter/lock/Kconfig.sysbuild | 13 ++ samples/matter/lock/README.rst | 7 + .../nrf54l15pdk_nrf54l15_cpuapp_ns.conf | 30 ++++ .../nrf54l15pdk_nrf54l15_cpuapp_ns.overlay | 52 +++++++ ..._static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml | 141 ++++++++++++++++++ samples/matter/lock/sample.yaml | 6 +- .../nrf54l15pdk_nrf54l15_cpuapp_ns.conf | 6 + ..._static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml | 28 ++++ samples/matter/template/sample.yaml | 3 +- samples/matter/thermostat/Kconfig.sysbuild | 13 ++ samples/matter/thermostat/README.rst | 7 + .../nrf54l15pdk_nrf54l15_cpuapp_ns.conf | 30 ++++ .../nrf54l15pdk_nrf54l15_cpuapp_ns.overlay | 52 +++++++ ..._static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml | 141 ++++++++++++++++++ samples/matter/thermostat/sample.yaml | 3 +- .../matter/window_covering/Kconfig.sysbuild | 13 ++ samples/matter/window_covering/README.rst | 8 + .../nrf54l15pdk_nrf54l15_cpuapp_ns.conf | 30 ++++ .../nrf54l15pdk_nrf54l15_cpuapp_ns.overlay | 87 +++++++++++ ..._static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml | 141 ++++++++++++++++++ samples/matter/window_covering/sample.yaml | 3 +- scripts/quarantine_integration.yaml | 10 ++ 35 files changed, 1341 insertions(+), 11 deletions(-) create mode 100644 samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf create mode 100644 samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay create mode 100644 samples/matter/light_bulb/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml create mode 100644 samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf create mode 100644 samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay create mode 100644 samples/matter/light_switch/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml create mode 100644 samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf create mode 100644 samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay create mode 100644 samples/matter/lock/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml create mode 100644 samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf create mode 100644 samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay create mode 100644 samples/matter/thermostat/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml create mode 100644 samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf create mode 100644 samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay create mode 100644 samples/matter/window_covering/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index defe472c04dc..cf38e9c8af2e 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -403,15 +403,12 @@ Matter samples * The :kconfig:option:`CONFIG_NCS_SAMPLE_MATTER_ZAP_FILES_PATH` Kconfig option, which specifies ZAP files location for the sample. By default, the option points to the :file:`src/default_zap` directory and can be changed to any path relative to sample's location that contains the ZAP file and :file:`zap-generated` directory. + * Support for :ref:`Trusted Firmware-M ` on the nRF54L15 PDK. * :ref:`matter_lock_sample` sample: * Added :ref:`Matter Lock schedule snippet `, and updated the documentation to use the snippet. -* :ref:`matter_template_sample` sample: - - * Added support for :ref:`Trusted Firmware-M ` on the nRF54L15 PDK. - Networking samples ------------------ diff --git a/samples/matter/light_bulb/Kconfig.sysbuild b/samples/matter/light_bulb/Kconfig.sysbuild index a80885725bab..89a4d1718b14 100644 --- a/samples/matter/light_bulb/Kconfig.sysbuild +++ b/samples/matter/light_bulb/Kconfig.sysbuild @@ -59,6 +59,19 @@ config DFU_MULTI_IMAGE_PACKAGE_NET default y endif # SOC_SERIES_NRF53X + +if BOARD_NRF54L15PDK_NRF54L15_CPUAPP_NS + +# Disable checking the external drivers for NS build. +config PM_OVERRIDE_EXTERNAL_DRIVER_CHECK + default y + +# override the mcuboot pad size, because it is not set globally for NS build. +config PM_MCUBOOT_PAD + default 0x800 + +endif #BOARD_NRF54L15PDK_NRF54L15_CPUAPP_NS + endif # BOOTLOADER_MCUBOOT #### Enable generating factory data diff --git a/samples/matter/light_bulb/README.rst b/samples/matter/light_bulb/README.rst index 5a70ee8c7977..a1b5d2164607 100644 --- a/samples/matter/light_bulb/README.rst +++ b/samples/matter/light_bulb/README.rst @@ -110,6 +110,13 @@ The sample supports the following configurations: .. matter_light_bulb_sample_configuration_file_types_end +Matter light bulb with Trusted Firmware-M +========================================= + +.. include:: ../template/README.rst + :start-after: matter_template_build_with_tfm_start + :end-before: matter_template_build_with_tfm_end + Device Firmware Upgrade support =============================== diff --git a/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf b/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf new file mode 100644 index 000000000000..8c66150d797c --- /dev/null +++ b/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf @@ -0,0 +1,30 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# Multirole is the only currently supported role by SoftDevice. +CONFIG_BT_LL_SOFTDEVICE_MULTIROLE=y + +CONFIG_FPU=n +CONFIG_PM=n +CONFIG_HWINFO_NRF=n + +CONFIG_NRF_802154_TEMPERATURE_UPDATE=n + +# TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L +CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n + +# TODO: KRKNWK-19382: Disable NFC commissioning due to an issue with definitions for ns build. +CONFIG_CHIP_NFC_COMMISSIONING=n + +# nRF54L15 requires bigger stack sizes than nRF52/nRF53 families +CONFIG_CHIP_MALLOC_SYS_HEAP_SIZE=10240 +CONFIG_MPSL_WORK_STACK_SIZE=2048 + +# Enable DAC key migration by default for ns build +CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY=y + +# Set the NVS sector count to match the settings partition size that is 40 kB for this application. +CONFIG_SETTINGS_NVS_SECTOR_COUNT=10 diff --git a/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay b/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay new file mode 100644 index 000000000000..f1081e02550c --- /dev/null +++ b/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + aliases { + // Configure PWM module for led1 (LED2 on the board) + pwm-led1 = &pwm_led1; + + // Use watchdog wdt31 as the application watchdog + watchdog0 = &wdt31; + }; + + chosen { + nordic,pm-ext-flash = &mx25r64; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led1: pwm_led_1 { + pwms = <&pwm20 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; +}; + +// restore full RRAM and SRAM space - by default some parts are dedicated to FLRP +&cpuapp_rram { + reg = <0x0 DT_SIZE_K(1524)>; +}; + +&cpuapp_sram { + reg = <0x20000000 DT_SIZE_K(256)>; + ranges = <0x0 0x20000000 0x40000>; +}; + +// TODO: re-enable HWFC once it's fixed +&uart20 { + /delete-property/ hw-flow-control; +}; + +&mx25r64 { + status = "okay"; +}; + +&pwm20 { + status = "okay"; + pinctrl-0 = <&pwm_default>; + pinctrl-1 = <&pwm_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&pinctrl { + pwm_default: pwm_default { + group1 { + psels = ; + }; + }; + pwm_sleep: pwm_sleep { + group1 { + psels = ; + low-power-enable; + }; + }; +}; + +&wdt31 { + status = "okay"; +}; + +// Change IRQ ids to handle button interrupts. + +// The default values for nRF54L15 are 219 and 269, +// but with TF-M they are reserved for the secure domain +// (218 and 268 are reserved for the non-secure domain). +&gpiote20 { + interrupts = <218 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&gpiote30 { + interrupts = <268 NRF_DEFAULT_IRQ_PRIORITY>; +}; diff --git a/samples/matter/light_bulb/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml b/samples/matter/light_bulb/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml new file mode 100644 index 000000000000..ba713218b5c4 --- /dev/null +++ b/samples/matter/light_bulb/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml @@ -0,0 +1,141 @@ +### Partitions +mcuboot: + address: 0x0 + region: flash_primary + size: 0xc000 +mcuboot_pad: + address: 0xc000 + region: flash_primary + size: 0x800 +tfm: + address: 0xc800 + region: flash_primary + size: 0x1F800 +app: + address: 0x2C000 + region: flash_primary + size: 0x13E000 +factory_data: + address: 0x16A000 + region: flash_primary + size: 0x1000 +settings_storage: + address: 0x16B000 + region: flash_primary + size: 0xa000 +tfm_storage: + address: 0x175000 + orig_span: &id006 + - tfm_ps + - tfm_its + - tfm_otp_nv_counters + region: flash_primary + size: 0x8000 + span: *id006 +external_flash: + address: 0x15E000 + size: 0x6A2000 + device: MX25R64 + region: external_flash +### Bootloader configuration +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - tfm + - app + span: *id001 + address: 0xc000 + region: flash_primary + size: 0x15E000 +mcuboot_primary_app: + orig_span: &id002 + - app + - tfm + span: *id002 + address: 0xc800 + region: flash_primary + size: 0x15D800 +mcuboot_secondary: + address: 0x0 + orig_span: &id003 + - mcuboot_secondary_pad + - mcuboot_secondary_app + region: external_flash + size: 0x15E000 + span: *id003 +mcuboot_secondary_pad: + region: external_flash + address: 0x0 + size: 0x800 +mcuboot_secondary_app: + region: external_flash + address: 0x800 + size: 0x15D800 +### TFM configuration +tfm_secure: + address: 0xc000 + orig_span: &id004 + - mcuboot_pad + - tfm + region: flash_primary + size: 0x20000 + span: *id004 +tfm_nonsecure: + address: 0x2C000 + orig_span: &id005 + - app + region: flash_primary + size: 0x13E000 + span: *id005 +tfm_its: + address: 0x175000 + inside: + - tfm_storage + placement: + before: + - tfm_otp_nv_counters + region: flash_primary + size: 0x2000 +tfm_otp_nv_counters: + address: 0x177000 + inside: + - tfm_storage + placement: + before: + - tfm_ps + region: flash_primary + size: 0x2000 +tfm_ps: + address: 0x179000 + inside: + - tfm_storage + region: flash_primary + size: 0x4000 +### RAM +sram_secure: + address: 0x20000000 + orig_span: &id007 + - tfm_sram + region: sram_primary + size: 0xF000 + span: *id007 +sram_nonsecure: + address: 0x2000F000 + orig_span: &id008 + - sram_primary + region: sram_primary + size: 0x31000 + span: *id008 +tfm_sram: + address: 0x20000000 + inside: + - sram_secure + placement: + after: + - start + region: sram_primary + size: 0xF000 +sram_primary: + address: 0x2000F000 + region: sram_primary + size: 0x31000 diff --git a/samples/matter/light_bulb/sample.yaml b/samples/matter/light_bulb/sample.yaml index 7f7005b570b9..80ebd0ad5c15 100644 --- a/samples/matter/light_bulb/sample.yaml +++ b/samples/matter/light_bulb/sample.yaml @@ -10,8 +10,9 @@ tests: - nrf5340dk/nrf5340/cpuapp - nrf7002dk/nrf5340/cpuapp - nrf54l15pdk/nrf54l15/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp/ns platform_allow: nrf52840dk/nrf52840 nrf5340dk/nrf5340/cpuapp nrf7002dk/nrf5340/cpuapp - nrf54l15pdk/nrf54l15/cpuapp + nrf54l15pdk/nrf54l15/cpuapp nrf54l15pdk/nrf54l15/cpuapp/ns tags: sysbuild ci_samples_matter sample.matter.light_bulb.release: sysbuild: true diff --git a/samples/matter/light_switch/Kconfig.sysbuild b/samples/matter/light_switch/Kconfig.sysbuild index a80885725bab..89a4d1718b14 100644 --- a/samples/matter/light_switch/Kconfig.sysbuild +++ b/samples/matter/light_switch/Kconfig.sysbuild @@ -59,6 +59,19 @@ config DFU_MULTI_IMAGE_PACKAGE_NET default y endif # SOC_SERIES_NRF53X + +if BOARD_NRF54L15PDK_NRF54L15_CPUAPP_NS + +# Disable checking the external drivers for NS build. +config PM_OVERRIDE_EXTERNAL_DRIVER_CHECK + default y + +# override the mcuboot pad size, because it is not set globally for NS build. +config PM_MCUBOOT_PAD + default 0x800 + +endif #BOARD_NRF54L15PDK_NRF54L15_CPUAPP_NS + endif # BOOTLOADER_MCUBOOT #### Enable generating factory data diff --git a/samples/matter/light_switch/README.rst b/samples/matter/light_switch/README.rst index 801903cd87e7..4a5a5ea67d82 100644 --- a/samples/matter/light_switch/README.rst +++ b/samples/matter/light_switch/README.rst @@ -117,6 +117,13 @@ Matter light switch custom configurations :start-after: matter_light_bulb_sample_configuration_file_types_start :end-before: matter_light_bulb_sample_configuration_file_types_end +Matter light switch with Trusted Firmware-M +=========================================== + +.. include:: ../template/README.rst + :start-after: matter_template_build_with_tfm_start + :end-before: matter_template_build_with_tfm_end + .. _matter_light_switch_snippets: Snippets diff --git a/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf b/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf new file mode 100644 index 000000000000..8c66150d797c --- /dev/null +++ b/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf @@ -0,0 +1,30 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# Multirole is the only currently supported role by SoftDevice. +CONFIG_BT_LL_SOFTDEVICE_MULTIROLE=y + +CONFIG_FPU=n +CONFIG_PM=n +CONFIG_HWINFO_NRF=n + +CONFIG_NRF_802154_TEMPERATURE_UPDATE=n + +# TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L +CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n + +# TODO: KRKNWK-19382: Disable NFC commissioning due to an issue with definitions for ns build. +CONFIG_CHIP_NFC_COMMISSIONING=n + +# nRF54L15 requires bigger stack sizes than nRF52/nRF53 families +CONFIG_CHIP_MALLOC_SYS_HEAP_SIZE=10240 +CONFIG_MPSL_WORK_STACK_SIZE=2048 + +# Enable DAC key migration by default for ns build +CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY=y + +# Set the NVS sector count to match the settings partition size that is 40 kB for this application. +CONFIG_SETTINGS_NVS_SECTOR_COUNT=10 diff --git a/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay b/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay new file mode 100644 index 000000000000..3ec96169ec55 --- /dev/null +++ b/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + aliases { + // Use watchdog wdt31 as the application watchdog + watchdog0 = &wdt31; + }; + + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; + +// restore full RRAM and SRAM space - by default some parts are dedicated to FLRP +&cpuapp_rram { + reg = <0x0 DT_SIZE_K(1524)>; +}; + +&cpuapp_sram { + reg = <0x20000000 DT_SIZE_K(256)>; + ranges = <0x0 0x20000000 0x40000>; +}; + +// TODO: re-enable HWFC once it's fixed +&uart20 { + /delete-property/ hw-flow-control; +}; + +&mx25r64 { + status = "okay"; +}; + +&wdt31 { + status = "okay"; +}; + +// Change IRQ ids to handle button interrupts. + +// The default values for nRF54L15 are 219 and 269, +// but with TF-M they are reserved for the secure domain +// (218 and 268 are reserved for the non-secure domain). +&gpiote20 { + interrupts = <218 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&gpiote30 { + interrupts = <268 NRF_DEFAULT_IRQ_PRIORITY>; +}; diff --git a/samples/matter/light_switch/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml b/samples/matter/light_switch/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml new file mode 100644 index 000000000000..ba713218b5c4 --- /dev/null +++ b/samples/matter/light_switch/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml @@ -0,0 +1,141 @@ +### Partitions +mcuboot: + address: 0x0 + region: flash_primary + size: 0xc000 +mcuboot_pad: + address: 0xc000 + region: flash_primary + size: 0x800 +tfm: + address: 0xc800 + region: flash_primary + size: 0x1F800 +app: + address: 0x2C000 + region: flash_primary + size: 0x13E000 +factory_data: + address: 0x16A000 + region: flash_primary + size: 0x1000 +settings_storage: + address: 0x16B000 + region: flash_primary + size: 0xa000 +tfm_storage: + address: 0x175000 + orig_span: &id006 + - tfm_ps + - tfm_its + - tfm_otp_nv_counters + region: flash_primary + size: 0x8000 + span: *id006 +external_flash: + address: 0x15E000 + size: 0x6A2000 + device: MX25R64 + region: external_flash +### Bootloader configuration +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - tfm + - app + span: *id001 + address: 0xc000 + region: flash_primary + size: 0x15E000 +mcuboot_primary_app: + orig_span: &id002 + - app + - tfm + span: *id002 + address: 0xc800 + region: flash_primary + size: 0x15D800 +mcuboot_secondary: + address: 0x0 + orig_span: &id003 + - mcuboot_secondary_pad + - mcuboot_secondary_app + region: external_flash + size: 0x15E000 + span: *id003 +mcuboot_secondary_pad: + region: external_flash + address: 0x0 + size: 0x800 +mcuboot_secondary_app: + region: external_flash + address: 0x800 + size: 0x15D800 +### TFM configuration +tfm_secure: + address: 0xc000 + orig_span: &id004 + - mcuboot_pad + - tfm + region: flash_primary + size: 0x20000 + span: *id004 +tfm_nonsecure: + address: 0x2C000 + orig_span: &id005 + - app + region: flash_primary + size: 0x13E000 + span: *id005 +tfm_its: + address: 0x175000 + inside: + - tfm_storage + placement: + before: + - tfm_otp_nv_counters + region: flash_primary + size: 0x2000 +tfm_otp_nv_counters: + address: 0x177000 + inside: + - tfm_storage + placement: + before: + - tfm_ps + region: flash_primary + size: 0x2000 +tfm_ps: + address: 0x179000 + inside: + - tfm_storage + region: flash_primary + size: 0x4000 +### RAM +sram_secure: + address: 0x20000000 + orig_span: &id007 + - tfm_sram + region: sram_primary + size: 0xF000 + span: *id007 +sram_nonsecure: + address: 0x2000F000 + orig_span: &id008 + - sram_primary + region: sram_primary + size: 0x31000 + span: *id008 +tfm_sram: + address: 0x20000000 + inside: + - sram_secure + placement: + after: + - start + region: sram_primary + size: 0xF000 +sram_primary: + address: 0x2000F000 + region: sram_primary + size: 0x31000 diff --git a/samples/matter/light_switch/sample.yaml b/samples/matter/light_switch/sample.yaml index e088bcdf8be3..03c9b8ee5bbe 100644 --- a/samples/matter/light_switch/sample.yaml +++ b/samples/matter/light_switch/sample.yaml @@ -10,8 +10,9 @@ tests: - nrf5340dk/nrf5340/cpuapp - nrf7002dk/nrf5340/cpuapp - nrf54l15pdk/nrf54l15/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp/ns platform_allow: nrf52840dk/nrf52840 nrf5340dk/nrf5340/cpuapp nrf7002dk/nrf5340/cpuapp - nrf54l15pdk/nrf54l15/cpuapp + nrf54l15pdk/nrf54l15/cpuapp nrf54l15pdk/nrf54l15/cpuapp/ns tags: sysbuild ci_samples_matter sample.matter.light_switch.release: sysbuild: true diff --git a/samples/matter/lock/Kconfig.sysbuild b/samples/matter/lock/Kconfig.sysbuild index 0c2b074489aa..33c92a1a1f0e 100644 --- a/samples/matter/lock/Kconfig.sysbuild +++ b/samples/matter/lock/Kconfig.sysbuild @@ -59,6 +59,19 @@ config DFU_MULTI_IMAGE_PACKAGE_NET default y endif # SOC_SERIES_NRF53X + +if BOARD_NRF54L15PDK_NRF54L15_CPUAPP_NS + +# Disable checking the external drivers for NS build. +config PM_OVERRIDE_EXTERNAL_DRIVER_CHECK + default y + +# override the mcuboot pad size, because it is not set globally for NS build. +config PM_MCUBOOT_PAD + default 0x800 + +endif #BOARD_NRF54L15PDK_NRF54L15_CPUAPP_NS + endif # BOOTLOADER_MCUBOOT #### Enable generating factory data diff --git a/samples/matter/lock/README.rst b/samples/matter/lock/README.rst index dd8934131fe8..e023c2d7a969 100644 --- a/samples/matter/lock/README.rst +++ b/samples/matter/lock/README.rst @@ -248,6 +248,13 @@ The sample supports the following configurations: .. matter_door_lock_sample_configuration_file_types_end +Matter lock with Trusted Firmware-M +=================================== + +.. include:: ../template/README.rst + :start-after: matter_template_build_with_tfm_start + :end-before: matter_template_build_with_tfm_end + .. _matter_lock_snippets: Snippets diff --git a/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf b/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf new file mode 100644 index 000000000000..8c66150d797c --- /dev/null +++ b/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf @@ -0,0 +1,30 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# Multirole is the only currently supported role by SoftDevice. +CONFIG_BT_LL_SOFTDEVICE_MULTIROLE=y + +CONFIG_FPU=n +CONFIG_PM=n +CONFIG_HWINFO_NRF=n + +CONFIG_NRF_802154_TEMPERATURE_UPDATE=n + +# TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L +CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n + +# TODO: KRKNWK-19382: Disable NFC commissioning due to an issue with definitions for ns build. +CONFIG_CHIP_NFC_COMMISSIONING=n + +# nRF54L15 requires bigger stack sizes than nRF52/nRF53 families +CONFIG_CHIP_MALLOC_SYS_HEAP_SIZE=10240 +CONFIG_MPSL_WORK_STACK_SIZE=2048 + +# Enable DAC key migration by default for ns build +CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY=y + +# Set the NVS sector count to match the settings partition size that is 40 kB for this application. +CONFIG_SETTINGS_NVS_SECTOR_COUNT=10 diff --git a/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay b/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay new file mode 100644 index 000000000000..3ec96169ec55 --- /dev/null +++ b/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + aliases { + // Use watchdog wdt31 as the application watchdog + watchdog0 = &wdt31; + }; + + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; + +// restore full RRAM and SRAM space - by default some parts are dedicated to FLRP +&cpuapp_rram { + reg = <0x0 DT_SIZE_K(1524)>; +}; + +&cpuapp_sram { + reg = <0x20000000 DT_SIZE_K(256)>; + ranges = <0x0 0x20000000 0x40000>; +}; + +// TODO: re-enable HWFC once it's fixed +&uart20 { + /delete-property/ hw-flow-control; +}; + +&mx25r64 { + status = "okay"; +}; + +&wdt31 { + status = "okay"; +}; + +// Change IRQ ids to handle button interrupts. + +// The default values for nRF54L15 are 219 and 269, +// but with TF-M they are reserved for the secure domain +// (218 and 268 are reserved for the non-secure domain). +&gpiote20 { + interrupts = <218 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&gpiote30 { + interrupts = <268 NRF_DEFAULT_IRQ_PRIORITY>; +}; diff --git a/samples/matter/lock/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml b/samples/matter/lock/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml new file mode 100644 index 000000000000..ba713218b5c4 --- /dev/null +++ b/samples/matter/lock/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml @@ -0,0 +1,141 @@ +### Partitions +mcuboot: + address: 0x0 + region: flash_primary + size: 0xc000 +mcuboot_pad: + address: 0xc000 + region: flash_primary + size: 0x800 +tfm: + address: 0xc800 + region: flash_primary + size: 0x1F800 +app: + address: 0x2C000 + region: flash_primary + size: 0x13E000 +factory_data: + address: 0x16A000 + region: flash_primary + size: 0x1000 +settings_storage: + address: 0x16B000 + region: flash_primary + size: 0xa000 +tfm_storage: + address: 0x175000 + orig_span: &id006 + - tfm_ps + - tfm_its + - tfm_otp_nv_counters + region: flash_primary + size: 0x8000 + span: *id006 +external_flash: + address: 0x15E000 + size: 0x6A2000 + device: MX25R64 + region: external_flash +### Bootloader configuration +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - tfm + - app + span: *id001 + address: 0xc000 + region: flash_primary + size: 0x15E000 +mcuboot_primary_app: + orig_span: &id002 + - app + - tfm + span: *id002 + address: 0xc800 + region: flash_primary + size: 0x15D800 +mcuboot_secondary: + address: 0x0 + orig_span: &id003 + - mcuboot_secondary_pad + - mcuboot_secondary_app + region: external_flash + size: 0x15E000 + span: *id003 +mcuboot_secondary_pad: + region: external_flash + address: 0x0 + size: 0x800 +mcuboot_secondary_app: + region: external_flash + address: 0x800 + size: 0x15D800 +### TFM configuration +tfm_secure: + address: 0xc000 + orig_span: &id004 + - mcuboot_pad + - tfm + region: flash_primary + size: 0x20000 + span: *id004 +tfm_nonsecure: + address: 0x2C000 + orig_span: &id005 + - app + region: flash_primary + size: 0x13E000 + span: *id005 +tfm_its: + address: 0x175000 + inside: + - tfm_storage + placement: + before: + - tfm_otp_nv_counters + region: flash_primary + size: 0x2000 +tfm_otp_nv_counters: + address: 0x177000 + inside: + - tfm_storage + placement: + before: + - tfm_ps + region: flash_primary + size: 0x2000 +tfm_ps: + address: 0x179000 + inside: + - tfm_storage + region: flash_primary + size: 0x4000 +### RAM +sram_secure: + address: 0x20000000 + orig_span: &id007 + - tfm_sram + region: sram_primary + size: 0xF000 + span: *id007 +sram_nonsecure: + address: 0x2000F000 + orig_span: &id008 + - sram_primary + region: sram_primary + size: 0x31000 + span: *id008 +tfm_sram: + address: 0x20000000 + inside: + - sram_secure + placement: + after: + - start + region: sram_primary + size: 0xF000 +sram_primary: + address: 0x2000F000 + region: sram_primary + size: 0x31000 diff --git a/samples/matter/lock/sample.yaml b/samples/matter/lock/sample.yaml index a6c28e5edec4..1972d7a80dfc 100644 --- a/samples/matter/lock/sample.yaml +++ b/samples/matter/lock/sample.yaml @@ -12,9 +12,10 @@ tests: - nrf7002dk/nrf5340/cpuapp/nrf7001 - nrf54l15pdk/nrf54l15/cpuapp - nrf54h20dk/nrf54h20/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp/ns platform_allow: nrf52840dk/nrf52840 nrf5340dk/nrf5340/cpuapp nrf7002dk/nrf5340/cpuapp nrf7002dk/nrf5340/cpuapp/nrf7001 nrf54l15pdk/nrf54l15/cpuapp - nrf54h20dk/nrf54h20/cpuapp + nrf54h20dk/nrf54h20/cpuapp nrf54l15pdk/nrf54l15/cpuapp/ns tags: sysbuild ci_samples_matter sample.matter.lock.release: sysbuild: true @@ -27,9 +28,10 @@ tests: - nrf7002dk/nrf5340/cpuapp/nrf7001 - nrf54l15pdk/nrf54l15/cpuapp - nrf54h20dk/nrf54h20/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp/ns platform_allow: nrf52840dk/nrf52840 nrf5340dk/nrf5340/cpuapp nrf7002dk/nrf5340/cpuapp nrf7002dk/nrf5340/cpuapp/nrf7001 nrf54l15pdk/nrf54l15/cpuapp - nrf54h20dk/nrf54h20/cpuapp + nrf54h20dk/nrf54h20/cpuapp nrf54l15pdk/nrf54l15/cpuapp/ns tags: sysbuild ci_samples_matter sample.matter.lock.lto: sysbuild: true diff --git a/samples/matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf b/samples/matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf index f527d09c7282..1239440d3854 100644 --- a/samples/matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf +++ b/samples/matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf @@ -19,3 +19,9 @@ CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n # nRF54L15 requires bigger stack sizes than nRF52/nRF53 families CONFIG_CHIP_MALLOC_SYS_HEAP_SIZE=10240 CONFIG_MPSL_WORK_STACK_SIZE=2048 + +# Enable DAC key migration by default for ns build +CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY=y + +# Set the NVS sector count to match the settings partition size that is 40 kB for this application. +CONFIG_SETTINGS_NVS_SECTOR_COUNT=10 diff --git a/samples/matter/template/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml b/samples/matter/template/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml index 774d9fa6a8ee..ba713218b5c4 100644 --- a/samples/matter/template/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml +++ b/samples/matter/template/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml @@ -111,3 +111,31 @@ tfm_ps: - tfm_storage region: flash_primary size: 0x4000 +### RAM +sram_secure: + address: 0x20000000 + orig_span: &id007 + - tfm_sram + region: sram_primary + size: 0xF000 + span: *id007 +sram_nonsecure: + address: 0x2000F000 + orig_span: &id008 + - sram_primary + region: sram_primary + size: 0x31000 + span: *id008 +tfm_sram: + address: 0x20000000 + inside: + - sram_secure + placement: + after: + - start + region: sram_primary + size: 0xF000 +sram_primary: + address: 0x2000F000 + region: sram_primary + size: 0x31000 diff --git a/samples/matter/template/sample.yaml b/samples/matter/template/sample.yaml index 1ba339f2824f..28b58987b2d3 100644 --- a/samples/matter/template/sample.yaml +++ b/samples/matter/template/sample.yaml @@ -12,8 +12,9 @@ tests: - nrf7002dk/nrf5340/cpuapp - nrf54l15pdk/nrf54l15/cpuapp - nrf54h20dk/nrf54h20/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp/ns platform_allow: nrf52840dk/nrf52840 nrf5340dk/nrf5340/cpuapp nrf7002dk/nrf5340/cpuapp - nrf54l15pdk/nrf54l15/cpuapp nrf54h20dk/nrf54h20/cpuapp + nrf54l15pdk/nrf54l15/cpuapp nrf54h20dk/nrf54h20/cpuapp nrf54l15pdk/nrf54l15/cpuapp/ns tags: sysbuild ci_samples_matter sample.matter.template.release: sysbuild: true diff --git a/samples/matter/thermostat/Kconfig.sysbuild b/samples/matter/thermostat/Kconfig.sysbuild index a631ac470e1d..9a2491b8ae4f 100644 --- a/samples/matter/thermostat/Kconfig.sysbuild +++ b/samples/matter/thermostat/Kconfig.sysbuild @@ -59,6 +59,19 @@ config DFU_MULTI_IMAGE_PACKAGE_NET default y endif # SOC_SERIES_NRF53X + +if BOARD_NRF54L15PDK_NRF54L15_CPUAPP_NS + +# Disable checking the external drivers for NS build. +config PM_OVERRIDE_EXTERNAL_DRIVER_CHECK + default y + +# override the mcuboot pad size, because it is not set globally for NS build. +config PM_MCUBOOT_PAD + default 0x800 + +endif #BOARD_NRF54L15PDK_NRF54L15_CPUAPP_NS + endif # BOOTLOADER_MCUBOOT #### Enable generating factory data diff --git a/samples/matter/thermostat/README.rst b/samples/matter/thermostat/README.rst index f5dfe1f0aa23..4dae6951ef97 100644 --- a/samples/matter/thermostat/README.rst +++ b/samples/matter/thermostat/README.rst @@ -112,6 +112,13 @@ Matter thermostat custom configurations :start-after: matter_light_bulb_sample_configuration_file_types_start :end-before: matter_light_bulb_sample_configuration_file_types_end +Matter thermostat with Trusted Firmware-M +========================================= + +.. include:: ../template/README.rst + :start-after: matter_template_build_with_tfm_start + :end-before: matter_template_build_with_tfm_end + Device Firmware Upgrade support =============================== diff --git a/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf b/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf new file mode 100644 index 000000000000..8c66150d797c --- /dev/null +++ b/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf @@ -0,0 +1,30 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# Multirole is the only currently supported role by SoftDevice. +CONFIG_BT_LL_SOFTDEVICE_MULTIROLE=y + +CONFIG_FPU=n +CONFIG_PM=n +CONFIG_HWINFO_NRF=n + +CONFIG_NRF_802154_TEMPERATURE_UPDATE=n + +# TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L +CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n + +# TODO: KRKNWK-19382: Disable NFC commissioning due to an issue with definitions for ns build. +CONFIG_CHIP_NFC_COMMISSIONING=n + +# nRF54L15 requires bigger stack sizes than nRF52/nRF53 families +CONFIG_CHIP_MALLOC_SYS_HEAP_SIZE=10240 +CONFIG_MPSL_WORK_STACK_SIZE=2048 + +# Enable DAC key migration by default for ns build +CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY=y + +# Set the NVS sector count to match the settings partition size that is 40 kB for this application. +CONFIG_SETTINGS_NVS_SECTOR_COUNT=10 diff --git a/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay b/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay new file mode 100644 index 000000000000..3ec96169ec55 --- /dev/null +++ b/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + aliases { + // Use watchdog wdt31 as the application watchdog + watchdog0 = &wdt31; + }; + + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; + +// restore full RRAM and SRAM space - by default some parts are dedicated to FLRP +&cpuapp_rram { + reg = <0x0 DT_SIZE_K(1524)>; +}; + +&cpuapp_sram { + reg = <0x20000000 DT_SIZE_K(256)>; + ranges = <0x0 0x20000000 0x40000>; +}; + +// TODO: re-enable HWFC once it's fixed +&uart20 { + /delete-property/ hw-flow-control; +}; + +&mx25r64 { + status = "okay"; +}; + +&wdt31 { + status = "okay"; +}; + +// Change IRQ ids to handle button interrupts. + +// The default values for nRF54L15 are 219 and 269, +// but with TF-M they are reserved for the secure domain +// (218 and 268 are reserved for the non-secure domain). +&gpiote20 { + interrupts = <218 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&gpiote30 { + interrupts = <268 NRF_DEFAULT_IRQ_PRIORITY>; +}; diff --git a/samples/matter/thermostat/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml b/samples/matter/thermostat/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml new file mode 100644 index 000000000000..ba713218b5c4 --- /dev/null +++ b/samples/matter/thermostat/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml @@ -0,0 +1,141 @@ +### Partitions +mcuboot: + address: 0x0 + region: flash_primary + size: 0xc000 +mcuboot_pad: + address: 0xc000 + region: flash_primary + size: 0x800 +tfm: + address: 0xc800 + region: flash_primary + size: 0x1F800 +app: + address: 0x2C000 + region: flash_primary + size: 0x13E000 +factory_data: + address: 0x16A000 + region: flash_primary + size: 0x1000 +settings_storage: + address: 0x16B000 + region: flash_primary + size: 0xa000 +tfm_storage: + address: 0x175000 + orig_span: &id006 + - tfm_ps + - tfm_its + - tfm_otp_nv_counters + region: flash_primary + size: 0x8000 + span: *id006 +external_flash: + address: 0x15E000 + size: 0x6A2000 + device: MX25R64 + region: external_flash +### Bootloader configuration +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - tfm + - app + span: *id001 + address: 0xc000 + region: flash_primary + size: 0x15E000 +mcuboot_primary_app: + orig_span: &id002 + - app + - tfm + span: *id002 + address: 0xc800 + region: flash_primary + size: 0x15D800 +mcuboot_secondary: + address: 0x0 + orig_span: &id003 + - mcuboot_secondary_pad + - mcuboot_secondary_app + region: external_flash + size: 0x15E000 + span: *id003 +mcuboot_secondary_pad: + region: external_flash + address: 0x0 + size: 0x800 +mcuboot_secondary_app: + region: external_flash + address: 0x800 + size: 0x15D800 +### TFM configuration +tfm_secure: + address: 0xc000 + orig_span: &id004 + - mcuboot_pad + - tfm + region: flash_primary + size: 0x20000 + span: *id004 +tfm_nonsecure: + address: 0x2C000 + orig_span: &id005 + - app + region: flash_primary + size: 0x13E000 + span: *id005 +tfm_its: + address: 0x175000 + inside: + - tfm_storage + placement: + before: + - tfm_otp_nv_counters + region: flash_primary + size: 0x2000 +tfm_otp_nv_counters: + address: 0x177000 + inside: + - tfm_storage + placement: + before: + - tfm_ps + region: flash_primary + size: 0x2000 +tfm_ps: + address: 0x179000 + inside: + - tfm_storage + region: flash_primary + size: 0x4000 +### RAM +sram_secure: + address: 0x20000000 + orig_span: &id007 + - tfm_sram + region: sram_primary + size: 0xF000 + span: *id007 +sram_nonsecure: + address: 0x2000F000 + orig_span: &id008 + - sram_primary + region: sram_primary + size: 0x31000 + span: *id008 +tfm_sram: + address: 0x20000000 + inside: + - sram_secure + placement: + after: + - start + region: sram_primary + size: 0xF000 +sram_primary: + address: 0x2000F000 + region: sram_primary + size: 0x31000 diff --git a/samples/matter/thermostat/sample.yaml b/samples/matter/thermostat/sample.yaml index a008af9c0354..8d4f990d1436 100644 --- a/samples/matter/thermostat/sample.yaml +++ b/samples/matter/thermostat/sample.yaml @@ -10,8 +10,9 @@ tests: - nrf5340dk/nrf5340/cpuapp - nrf7002dk/nrf5340/cpuapp - nrf54l15pdk/nrf54l15/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp/ns platform_allow: nrf52840dk/nrf52840 nrf5340dk/nrf5340/cpuapp nrf7002dk/nrf5340/cpuapp - nrf54l15pdk/nrf54l15/cpuapp + nrf54l15pdk/nrf54l15/cpuapp nrf54l15pdk/nrf54l15/cpuapp/ns tags: sysbuild ci_samples_matter sample.matter.thermostat.release: sysbuild: true diff --git a/samples/matter/window_covering/Kconfig.sysbuild b/samples/matter/window_covering/Kconfig.sysbuild index a80885725bab..89a4d1718b14 100644 --- a/samples/matter/window_covering/Kconfig.sysbuild +++ b/samples/matter/window_covering/Kconfig.sysbuild @@ -59,6 +59,19 @@ config DFU_MULTI_IMAGE_PACKAGE_NET default y endif # SOC_SERIES_NRF53X + +if BOARD_NRF54L15PDK_NRF54L15_CPUAPP_NS + +# Disable checking the external drivers for NS build. +config PM_OVERRIDE_EXTERNAL_DRIVER_CHECK + default y + +# override the mcuboot pad size, because it is not set globally for NS build. +config PM_MCUBOOT_PAD + default 0x800 + +endif #BOARD_NRF54L15PDK_NRF54L15_CPUAPP_NS + endif # BOOTLOADER_MCUBOOT #### Enable generating factory data diff --git a/samples/matter/window_covering/README.rst b/samples/matter/window_covering/README.rst index 9904977b8a3d..fc0c0ad34b2c 100644 --- a/samples/matter/window_covering/README.rst +++ b/samples/matter/window_covering/README.rst @@ -93,6 +93,14 @@ Matter window covering custom configurations :start-after: matter_light_bulb_sample_configuration_file_types_start :end-before: matter_light_bulb_sample_configuration_file_types_end +Matter window covering with Trusted Firmware-M +============================================== + +.. include:: ../template/README.rst + :start-after: matter_template_build_with_tfm_start + :end-before: matter_template_build_with_tfm_end + + Device Firmware Upgrade support =============================== diff --git a/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf b/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf new file mode 100644 index 000000000000..8c66150d797c --- /dev/null +++ b/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf @@ -0,0 +1,30 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# Multirole is the only currently supported role by SoftDevice. +CONFIG_BT_LL_SOFTDEVICE_MULTIROLE=y + +CONFIG_FPU=n +CONFIG_PM=n +CONFIG_HWINFO_NRF=n + +CONFIG_NRF_802154_TEMPERATURE_UPDATE=n + +# TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L +CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n + +# TODO: KRKNWK-19382: Disable NFC commissioning due to an issue with definitions for ns build. +CONFIG_CHIP_NFC_COMMISSIONING=n + +# nRF54L15 requires bigger stack sizes than nRF52/nRF53 families +CONFIG_CHIP_MALLOC_SYS_HEAP_SIZE=10240 +CONFIG_MPSL_WORK_STACK_SIZE=2048 + +# Enable DAC key migration by default for ns build +CONFIG_CHIP_CRYPTO_PSA_MIGRATE_DAC_PRIV_KEY=y + +# Set the NVS sector count to match the settings partition size that is 40 kB for this application. +CONFIG_SETTINGS_NVS_SECTOR_COUNT=10 diff --git a/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay b/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay new file mode 100644 index 000000000000..ee12614d6519 --- /dev/null +++ b/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.overlay @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + aliases { + // Configure PWM module for led1 (LED2 on the board) + pwm-led1 = &pwm_led1; + pwm-led2 = &pwm_led2; + + // Use watchdog wdt31 as the application watchdog + watchdog0 = &wdt31; + }; + + chosen { + nordic,pm-ext-flash = &mx25r64; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led1: pwm_led_1 { + pwms = <&pwm20 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + pwm_led2: pwm_led_2 { + pwms = <&pwm20 2 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; +}; + +// restore full RRAM and SRAM space - by default some parts are dedicated to FLRP +&cpuapp_rram { + reg = <0x0 DT_SIZE_K(1524)>; +}; + +&cpuapp_sram { + reg = <0x20000000 DT_SIZE_K(256)>; + ranges = <0x0 0x20000000 0x40000>; +}; + +// TODO: re-enable HWFC once it's fixed +&uart20 { + /delete-property/ hw-flow-control; +}; + +&mx25r64 { + status = "okay"; +}; + +&pwm20 { + status = "okay"; + pinctrl-0 = <&pwm_default>; + pinctrl-1 = <&pwm_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&pinctrl { + pwm_default: pwm_default { + group1 { + psels = , ; + }; + }; + pwm_sleep: pwm_sleep { + group1 { + psels = , ; + low-power-enable; + }; + }; +}; + +&wdt31 { + status = "okay"; +}; + +// Change IRQ ids to handle button interrupts. + +// The default values for nRF54L15 are 219 and 269, +// but with TF-M they are reserved for the secure domain +// (218 and 268 are reserved for the non-secure domain). +&gpiote20 { + interrupts = <218 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&gpiote30 { + interrupts = <268 NRF_DEFAULT_IRQ_PRIORITY>; +}; diff --git a/samples/matter/window_covering/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml b/samples/matter/window_covering/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml new file mode 100644 index 000000000000..ba713218b5c4 --- /dev/null +++ b/samples/matter/window_covering/pm_static_nrf54l15pdk_nrf54l15_cpuapp_ns.yml @@ -0,0 +1,141 @@ +### Partitions +mcuboot: + address: 0x0 + region: flash_primary + size: 0xc000 +mcuboot_pad: + address: 0xc000 + region: flash_primary + size: 0x800 +tfm: + address: 0xc800 + region: flash_primary + size: 0x1F800 +app: + address: 0x2C000 + region: flash_primary + size: 0x13E000 +factory_data: + address: 0x16A000 + region: flash_primary + size: 0x1000 +settings_storage: + address: 0x16B000 + region: flash_primary + size: 0xa000 +tfm_storage: + address: 0x175000 + orig_span: &id006 + - tfm_ps + - tfm_its + - tfm_otp_nv_counters + region: flash_primary + size: 0x8000 + span: *id006 +external_flash: + address: 0x15E000 + size: 0x6A2000 + device: MX25R64 + region: external_flash +### Bootloader configuration +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - tfm + - app + span: *id001 + address: 0xc000 + region: flash_primary + size: 0x15E000 +mcuboot_primary_app: + orig_span: &id002 + - app + - tfm + span: *id002 + address: 0xc800 + region: flash_primary + size: 0x15D800 +mcuboot_secondary: + address: 0x0 + orig_span: &id003 + - mcuboot_secondary_pad + - mcuboot_secondary_app + region: external_flash + size: 0x15E000 + span: *id003 +mcuboot_secondary_pad: + region: external_flash + address: 0x0 + size: 0x800 +mcuboot_secondary_app: + region: external_flash + address: 0x800 + size: 0x15D800 +### TFM configuration +tfm_secure: + address: 0xc000 + orig_span: &id004 + - mcuboot_pad + - tfm + region: flash_primary + size: 0x20000 + span: *id004 +tfm_nonsecure: + address: 0x2C000 + orig_span: &id005 + - app + region: flash_primary + size: 0x13E000 + span: *id005 +tfm_its: + address: 0x175000 + inside: + - tfm_storage + placement: + before: + - tfm_otp_nv_counters + region: flash_primary + size: 0x2000 +tfm_otp_nv_counters: + address: 0x177000 + inside: + - tfm_storage + placement: + before: + - tfm_ps + region: flash_primary + size: 0x2000 +tfm_ps: + address: 0x179000 + inside: + - tfm_storage + region: flash_primary + size: 0x4000 +### RAM +sram_secure: + address: 0x20000000 + orig_span: &id007 + - tfm_sram + region: sram_primary + size: 0xF000 + span: *id007 +sram_nonsecure: + address: 0x2000F000 + orig_span: &id008 + - sram_primary + region: sram_primary + size: 0x31000 + span: *id008 +tfm_sram: + address: 0x20000000 + inside: + - sram_secure + placement: + after: + - start + region: sram_primary + size: 0xF000 +sram_primary: + address: 0x2000F000 + region: sram_primary + size: 0x31000 diff --git a/samples/matter/window_covering/sample.yaml b/samples/matter/window_covering/sample.yaml index c48d967354f7..426e6b712872 100644 --- a/samples/matter/window_covering/sample.yaml +++ b/samples/matter/window_covering/sample.yaml @@ -9,8 +9,9 @@ tests: - nrf52840dk/nrf52840 - nrf5340dk/nrf5340/cpuapp - nrf54l15pdk/nrf54l15/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp/ns platform_allow: nrf52840dk/nrf52840 nrf5340dk/nrf5340/cpuapp - nrf54l15pdk/nrf54l15/cpuapp + nrf54l15pdk/nrf54l15/cpuapp nrf54l15pdk/nrf54l15/cpuapp/ns tags: sysbuild ci_samples_matter sample.matter.window_cover.release: sysbuild: true diff --git a/scripts/quarantine_integration.yaml b/scripts/quarantine_integration.yaml index 4080f6444c6c..5232e3f1ed97 100644 --- a/scripts/quarantine_integration.yaml +++ b/scripts/quarantine_integration.yaml @@ -106,6 +106,16 @@ - nrf54l15pdk/nrf54l15/cpuapp comment: "Configurations excluded to limit resources usage in integration builds" +- scenarios: + - sample.matter.template.debug + - sample.matter.light_bulb.debug + - sample.matter.light_switch.debug + - sample.matter.thermostat.debug + - sample.matter.window_cover.debug + platforms: + - nrf54l15pdk/nrf54l15/cpuapp/ns + comment: "Configurations excluded to limit resources usage in integration Matter ns builds" + - scenarios: - sample.nrf7002.iot_devices - sample.nrf7002.high_performance From 7066e6ec0707711b4bef9a4effdc78210866b7df Mon Sep 17 00:00:00 2001 From: Arkadiusz Balys Date: Mon, 26 Aug 2024 09:26:21 +0200 Subject: [PATCH 25/72] samples: matter: Remove redundant temperature update config Removed the CONFIG_NRF_802154_TEMPERATURE_UPDATE config from nRF54L15 configuration overlays because it is not needed anymore. Signed-off-by: Arkadiusz Balys --- .../matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp.conf | 2 -- .../light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf | 2 -- .../matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp.conf | 2 -- .../light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf | 2 -- samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp.conf | 2 -- samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf | 2 -- samples/matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp.conf | 2 -- .../matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf | 2 -- .../matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp.conf | 2 -- .../thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf | 2 -- .../window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp.conf | 2 -- .../window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf | 2 -- 12 files changed, 24 deletions(-) diff --git a/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp.conf b/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp.conf index 6a72f1476d69..6a65a38fc170 100644 --- a/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp.conf +++ b/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp.conf @@ -11,8 +11,6 @@ CONFIG_FPU=n CONFIG_PM=n CONFIG_HWINFO_NRF=n -CONFIG_NRF_802154_TEMPERATURE_UPDATE=n - # TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n diff --git a/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf b/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf index 8c66150d797c..6b7c14c77cd6 100644 --- a/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf +++ b/samples/matter/light_bulb/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf @@ -11,8 +11,6 @@ CONFIG_FPU=n CONFIG_PM=n CONFIG_HWINFO_NRF=n -CONFIG_NRF_802154_TEMPERATURE_UPDATE=n - # TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n diff --git a/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp.conf b/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp.conf index e10191a1e306..7341bab056dc 100644 --- a/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp.conf +++ b/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp.conf @@ -11,8 +11,6 @@ CONFIG_FPU=n CONFIG_PM=n CONFIG_HWINFO_NRF=n -CONFIG_NRF_802154_TEMPERATURE_UPDATE=n - # TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n diff --git a/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf b/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf index 8c66150d797c..6b7c14c77cd6 100644 --- a/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf +++ b/samples/matter/light_switch/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf @@ -11,8 +11,6 @@ CONFIG_FPU=n CONFIG_PM=n CONFIG_HWINFO_NRF=n -CONFIG_NRF_802154_TEMPERATURE_UPDATE=n - # TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n diff --git a/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp.conf b/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp.conf index e10191a1e306..7341bab056dc 100644 --- a/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp.conf +++ b/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp.conf @@ -11,8 +11,6 @@ CONFIG_FPU=n CONFIG_PM=n CONFIG_HWINFO_NRF=n -CONFIG_NRF_802154_TEMPERATURE_UPDATE=n - # TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n diff --git a/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf b/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf index 8c66150d797c..6b7c14c77cd6 100644 --- a/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf +++ b/samples/matter/lock/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf @@ -11,8 +11,6 @@ CONFIG_FPU=n CONFIG_PM=n CONFIG_HWINFO_NRF=n -CONFIG_NRF_802154_TEMPERATURE_UPDATE=n - # TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n diff --git a/samples/matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp.conf b/samples/matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp.conf index e10191a1e306..7341bab056dc 100644 --- a/samples/matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp.conf +++ b/samples/matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp.conf @@ -11,8 +11,6 @@ CONFIG_FPU=n CONFIG_PM=n CONFIG_HWINFO_NRF=n -CONFIG_NRF_802154_TEMPERATURE_UPDATE=n - # TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n diff --git a/samples/matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf b/samples/matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf index 1239440d3854..e32a97ff4b38 100644 --- a/samples/matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf +++ b/samples/matter/template/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf @@ -11,8 +11,6 @@ CONFIG_FPU=n CONFIG_PM=n CONFIG_HWINFO_NRF=n -CONFIG_NRF_802154_TEMPERATURE_UPDATE=n - # TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n diff --git a/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp.conf b/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp.conf index e10191a1e306..7341bab056dc 100644 --- a/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp.conf +++ b/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp.conf @@ -11,8 +11,6 @@ CONFIG_FPU=n CONFIG_PM=n CONFIG_HWINFO_NRF=n -CONFIG_NRF_802154_TEMPERATURE_UPDATE=n - # TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n diff --git a/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf b/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf index 8c66150d797c..6b7c14c77cd6 100644 --- a/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf +++ b/samples/matter/thermostat/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf @@ -11,8 +11,6 @@ CONFIG_FPU=n CONFIG_PM=n CONFIG_HWINFO_NRF=n -CONFIG_NRF_802154_TEMPERATURE_UPDATE=n - # TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n diff --git a/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp.conf b/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp.conf index e10191a1e306..7341bab056dc 100644 --- a/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp.conf +++ b/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp.conf @@ -11,8 +11,6 @@ CONFIG_FPU=n CONFIG_PM=n CONFIG_HWINFO_NRF=n -CONFIG_NRF_802154_TEMPERATURE_UPDATE=n - # TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n diff --git a/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf b/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf index 8c66150d797c..6b7c14c77cd6 100644 --- a/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf +++ b/samples/matter/window_covering/boards/nrf54l15pdk_nrf54l15_cpuapp_ns.conf @@ -11,8 +11,6 @@ CONFIG_FPU=n CONFIG_PM=n CONFIG_HWINFO_NRF=n -CONFIG_NRF_802154_TEMPERATURE_UPDATE=n - # TODO: Workaround to be removed once Zephyr's CONFIG_FPROTECT is supported on nRF54L CONFIG_CHIP_FACTORY_DATA_WRITE_PROTECT=n From b60eb4900e62bb7c771397adb152552849052b18 Mon Sep 17 00:00:00 2001 From: Marcin Kajor Date: Thu, 22 Aug 2024 17:31:38 +0200 Subject: [PATCH 26/72] samples: matter: Multiple door lock's schedules refinements * increase maximum number of secure entries that can be stored * align the maximum asset size for scheduled access feature * align the OT and Matter stack sizes * allow for re-setting of the same schedule with different data * added missing serialization of mAvailable flag - it was not stored because of that * refactor the *Schedule structs to avoid boiler plate code * decrease the log level for schedule prints Signed-off-by: Marcin Kajor --- .../common/src/persistent_storage/Kconfig | 2 +- samples/matter/lock/Kconfig | 20 +++ .../lock/src/access/access_data_types.cpp | 90 ----------- .../lock/src/access/access_data_types.h | 147 ++++++++---------- .../src/access/access_manager_schedules.cpp | 45 +++--- 5 files changed, 117 insertions(+), 187 deletions(-) diff --git a/samples/matter/common/src/persistent_storage/Kconfig b/samples/matter/common/src/persistent_storage/Kconfig index 919febdda3c6..49283831d304 100644 --- a/samples/matter/common/src/persistent_storage/Kconfig +++ b/samples/matter/common/src/persistent_storage/Kconfig @@ -31,7 +31,7 @@ if NCS_SAMPLE_MATTER_SECURE_STORAGE_BACKEND config NCS_SAMPLE_MATTER_SECURE_STORAGE_MAX_ENTRY_NUMBER int "Maximum number of entries that can be stored securely" - default 30 + default 64 config NCS_SAMPLE_MATTER_SECURE_STORAGE_PSA_KEY_VALUE_OFFSET hex "The PSA key offset dedicated for Matter application" diff --git a/samples/matter/lock/Kconfig b/samples/matter/lock/Kconfig index 44214fd1baa1..98cef1942973 100644 --- a/samples/matter/lock/Kconfig +++ b/samples/matter/lock/Kconfig @@ -148,6 +148,26 @@ config NCS_SAMPLE_MATTER_SECURE_STORAGE_BACKEND config NCS_SAMPLE_MATTER_SETTINGS_STORAGE_BACKEND default n if !CHIP_WIFI +# Increase the storage capacity if the schedules are enabled with secure storage +# This also implies increasing of the OT and Matter stacks because some operations +# performed during commissioning seem to allocate stack buffers based on the +# maximum possible secure asset size. +if LOCK_SCHEDULES && NCS_SAMPLE_MATTER_SECURE_STORAGE_BACKEND + +config NCS_SAMPLE_MATTER_SECURE_STORAGE_MAX_ENTRY_NUMBER + default 128 + +config TRUSTED_STORAGE_BACKEND_AEAD_MAX_DATA_SIZE + default 3072 + +config OPENTHREAD_THREAD_STACK_SIZE + default 5120 + +config CHIP_TASK_STACK_SIZE + default 9216 + +endif + source "${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/config/nrfconnect/chip-module/Kconfig.features" source "${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/config/nrfconnect/chip-module/Kconfig.defaults" source "${ZEPHYR_NRF_MODULE_DIR}/samples/matter/common/src/Kconfig" diff --git a/samples/matter/lock/src/access/access_data_types.cpp b/samples/matter/lock/src/access/access_data_types.cpp index d335b2659e8a..468a30ec88ff 100644 --- a/samples/matter/lock/src/access/access_data_types.cpp +++ b/samples/matter/lock/src/access/access_data_types.cpp @@ -180,8 +180,6 @@ CHIP_ERROR User::Deserialize(const void *buff, size_t buffSize) CHIP_ERROR WeekDaySchedule::FillFromPlugin(EmberAfPluginDoorLockWeekDaySchedule &plugin) { - static_assert(sizeof(EmberAfPluginDoorLockWeekDaySchedule) == RequiredBufferSize()); - mData.mFields.mDaysMask = static_cast(plugin.daysMask); mData.mFields.mStartHour = plugin.startHour; mData.mFields.mStartMinute = plugin.startMinute; @@ -193,8 +191,6 @@ CHIP_ERROR WeekDaySchedule::FillFromPlugin(EmberAfPluginDoorLockWeekDaySchedule CHIP_ERROR YearDaySchedule::FillFromPlugin(EmberAfPluginDoorLockYearDaySchedule &plugin) { - static_assert(sizeof(EmberAfPluginDoorLockYearDaySchedule) == RequiredBufferSize()); - mData.mFields.mLocalStartTime = plugin.localStartTime; mData.mFields.mLocalEndTime = plugin.localEndTime; @@ -203,8 +199,6 @@ CHIP_ERROR YearDaySchedule::FillFromPlugin(EmberAfPluginDoorLockYearDaySchedule CHIP_ERROR HolidaySchedule::FillFromPlugin(EmberAfPluginDoorLockHolidaySchedule &plugin) { - static_assert(sizeof(EmberAfPluginDoorLockHolidaySchedule) == RequiredBufferSize()); - mData.mFields.mLocalStartTime = plugin.localStartTime; mData.mFields.mLocalEndTime = plugin.localEndTime; mData.mFields.mOperatingMode = static_cast(plugin.operatingMode); @@ -214,8 +208,6 @@ CHIP_ERROR HolidaySchedule::FillFromPlugin(EmberAfPluginDoorLockHolidaySchedule CHIP_ERROR WeekDaySchedule::ConvertToPlugin(EmberAfPluginDoorLockWeekDaySchedule &plugin) const { - static_assert(sizeof(EmberAfPluginDoorLockWeekDaySchedule) == RequiredBufferSize()); - plugin.daysMask = static_cast(mData.mFields.mDaysMask); plugin.startHour = mData.mFields.mStartHour; plugin.startMinute = mData.mFields.mStartMinute; @@ -227,8 +219,6 @@ CHIP_ERROR WeekDaySchedule::ConvertToPlugin(EmberAfPluginDoorLockWeekDaySchedule CHIP_ERROR YearDaySchedule::ConvertToPlugin(EmberAfPluginDoorLockYearDaySchedule &plugin) const { - static_assert(sizeof(EmberAfPluginDoorLockYearDaySchedule) == RequiredBufferSize()); - plugin.localStartTime = mData.mFields.mLocalStartTime; plugin.localEndTime = mData.mFields.mLocalEndTime; @@ -237,8 +227,6 @@ CHIP_ERROR YearDaySchedule::ConvertToPlugin(EmberAfPluginDoorLockYearDaySchedule CHIP_ERROR HolidaySchedule::ConvertToPlugin(EmberAfPluginDoorLockHolidaySchedule &plugin) const { - static_assert(sizeof(EmberAfPluginDoorLockHolidaySchedule) == RequiredBufferSize()); - plugin.localStartTime = mData.mFields.mLocalStartTime; plugin.localEndTime = mData.mFields.mLocalEndTime; plugin.operatingMode = static_cast(mData.mFields.mOperatingMode); @@ -246,84 +234,6 @@ CHIP_ERROR HolidaySchedule::ConvertToPlugin(EmberAfPluginDoorLockHolidaySchedule return CHIP_NO_ERROR; } -size_t WeekDaySchedule::Serialize(void *buff, size_t buffSize) -{ - if (!buff || buffSize < RequiredBufferSize()) { - return 0; - } - - memcpy(buff, mData.mRaw, sizeof(mData.mRaw)); - - return sizeof(mData.mRaw); -} - -size_t YearDaySchedule::Serialize(void *buff, size_t buffSize) -{ - if (!buff || buffSize < RequiredBufferSize()) { - return 0; - } - - memcpy(buff, mData.mRaw, sizeof(mData.mRaw)); - - return sizeof(mData.mRaw); -} - -size_t HolidaySchedule::Serialize(void *buff, size_t buffSize) -{ - if (!buff || buffSize < RequiredBufferSize()) { - return 0; - } - - memcpy(buff, mData.mRaw, sizeof(mData.mRaw)); - - return sizeof(mData.mRaw); -} - -CHIP_ERROR WeekDaySchedule::Deserialize(const void *buff, size_t buffSize) -{ - if (!buff) { - return CHIP_ERROR_INVALID_ARGUMENT; - } - - if (buffSize > RequiredBufferSize()) { - return CHIP_ERROR_BUFFER_TOO_SMALL; - } - - memcpy(mData.mRaw, buff, sizeof(mData.mRaw)); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR YearDaySchedule::Deserialize(const void *buff, size_t buffSize) -{ - if (!buff) { - return CHIP_ERROR_INVALID_ARGUMENT; - } - - if (buffSize > RequiredBufferSize()) { - return CHIP_ERROR_BUFFER_TOO_SMALL; - } - - memcpy(mData.mRaw, buff, sizeof(mData.mRaw)); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR HolidaySchedule::Deserialize(const void *buff, size_t buffSize) -{ - if (!buff) { - return CHIP_ERROR_INVALID_ARGUMENT; - } - - if (buffSize > RequiredBufferSize()) { - return CHIP_ERROR_BUFFER_TOO_SMALL; - } - - memcpy(mData.mRaw, buff, sizeof(mData.mRaw)); - - return CHIP_NO_ERROR; -} - #endif /* CONFIG_LOCK_SCHEDULES */ } /* namespace DoorLockData */ diff --git a/samples/matter/lock/src/access/access_data_types.h b/samples/matter/lock/src/access/access_data_types.h index 6cfd5051b1eb..c27f59dcb05f 100644 --- a/samples/matter/lock/src/access/access_data_types.h +++ b/samples/matter/lock/src/access/access_data_types.h @@ -117,8 +117,71 @@ struct Credential { */ CHIP_ERROR Deserialize(const void *buff, size_t buffSize); }; +/* A base class for specific schedule types that implements the common schedule serialization. */ +template class Schedule { +public: + /** + * @brief Serialize all fields into data buffer. + * + * `buffSize` must be set to at least the RequiredBufferSize size. + * + * @param buff buffer to store serialized data. + * @param buffSize size of input buffer. + * @return size_t output serialized data length, 0 value means error. + */ + size_t Serialize(void *buff, size_t buffSize) + { + if (!buff || buffSize < Impl()->RequiredBufferSize()) { + return 0; + } + + size_t offset = 0; + + pack(buff, Impl()->mData.mRaw, sizeof(Impl()->mData.mRaw), offset); + pack(buff, &(Impl()->mAvailable), sizeof(Impl()->mAvailable), offset); + + return offset; + } + + /** + * @brief Deserialize all fields from given buffer. + * + * `buffSize` must be set to at least the RequiredBufferSize size. + * + * @param buff buffer containing serialized data (by invoking serialized method). + * @param buffSize size of output buffer. + * @return CHIP_ERROR_BUFFER_TOO_SMALL if provided buffSize is too small. + * @return CHIP_ERROR_INVALID_ARGUMENT if arguments are wrong. + * @return CHIP_NO_ERROR if deserialization has been finished successfully. + */ + CHIP_ERROR Deserialize(const void *buff, size_t buffSize) + { + if (!buff) { + return CHIP_ERROR_INVALID_ARGUMENT; + } + + if (buffSize > Impl()->RequiredBufferSize()) { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + + size_t offset = 0; + + unpack(Impl()->mData.mRaw, sizeof(Impl()->mData.mRaw), buff, offset); + unpack(&(Impl()->mAvailable), sizeof(Impl()->mAvailable), buff, offset); + + return CHIP_NO_ERROR; + } -struct WeekDaySchedule { +private: + /** + * @brief Get the derived class handle. + * + * @return Pointer to the derived class. + */ + T *Impl() { return static_cast(this); }; +}; + +struct WeekDaySchedule : public Schedule { union Data { struct Fields { uint8_t mDaysMask; @@ -141,7 +204,7 @@ struct WeekDaySchedule { * * @return size of single credential entry. */ - constexpr static size_t RequiredBufferSize() { return sizeof(Data); } + constexpr static size_t RequiredBufferSize() { return sizeof(Data) + sizeof(bool); } /** * @brief fill User entry with data from the EmberAfPluginDoorLockWeekDaySchedule plugin @@ -158,33 +221,9 @@ struct WeekDaySchedule { * @return CHIP_NO_ERROR if conversion has been finished successfully. */ CHIP_ERROR ConvertToPlugin(EmberAfPluginDoorLockWeekDaySchedule &plugin) const; - - /** - * @brief Serialize all fields into data buffer. - * - * `buffSize` must be set to at least the RequiredBufferSize size. - * - * @param buff buffer to store serialized data. - * @param buffSize size of input buffer. - * @return size_t output serialized data length, 0 value means error. - */ - size_t Serialize(void *buff, size_t buffSize); - - /** - * @brief Deserialize all fields from given buffer. - * - * `buffSize` must be set to at least the RequiredBufferSize size. - * - * @param buff buffer containing serialized data (by invoking serialized method). - * @param buffSize size of output buffer. - * @return CHIP_ERROR_BUFFER_TOO_SMALL if provided buffSize is too small. - * @return CHIP_ERROR_INVALID_ARGUMENT if arguments are wrong. - * @return CHIP_NO_ERROR if deserialization has been finished successfully. - */ - CHIP_ERROR Deserialize(const void *buff, size_t buffSize); }; -struct YearDaySchedule { +struct YearDaySchedule : public Schedule { union Data { struct Fields { uint32_t mLocalStartTime; @@ -204,7 +243,7 @@ struct YearDaySchedule { * * @return size of single credential entry. */ - constexpr static size_t RequiredBufferSize() { return sizeof(Data); } + constexpr static size_t RequiredBufferSize() { return sizeof(Data) + sizeof(bool); } /** * @brief fill User entry with data from one the EmberAfPluginDoorLockYearDaySchedule plugin. @@ -221,33 +260,9 @@ struct YearDaySchedule { * @return CHIP_NO_ERROR if conversion has been finished successfully. */ CHIP_ERROR ConvertToPlugin(EmberAfPluginDoorLockYearDaySchedule &plugin) const; - - /** - * @brief Serialize all fields into data buffer. - * - * `buffSize` must be set to at least the RequiredBufferSize size. - * - * @param buff buffer to store serialized data. - * @param buffSize size of input buffer. - * @return size_t output serialized data length, 0 value means error. - */ - size_t Serialize(void *buff, size_t buffSize); - - /** - * @brief Deserialize all fields from given buffer. - * - * `buffSize` must be set to at least the RequiredBufferSize size. - * - * @param buff buffer containing serialized data (by invoking serialized method). - * @param buffSize size of output buffer. - * @return CHIP_ERROR_BUFFER_TOO_SMALL if provided buffSize is too small. - * @return CHIP_ERROR_INVALID_ARGUMENT if arguments are wrong. - * @return CHIP_NO_ERROR if deserialization has been finished successfully. - */ - CHIP_ERROR Deserialize(const void *buff, size_t buffSize); }; -struct HolidaySchedule { +struct HolidaySchedule : public Schedule { union Data { struct Fields { uint32_t mLocalStartTime; @@ -268,7 +283,7 @@ struct HolidaySchedule { * * @return size of single credential entry. */ - constexpr static size_t RequiredBufferSize() { return sizeof(Data); } + constexpr static size_t RequiredBufferSize() { return sizeof(Data) + sizeof(bool); } /** * @brief fill User entry with data from one the EmberAfPluginDoorLockHolidaySchedule plugin. @@ -285,30 +300,6 @@ struct HolidaySchedule { * @return CHIP_NO_ERROR if conversion has been finished successfully. */ CHIP_ERROR ConvertToPlugin(EmberAfPluginDoorLockHolidaySchedule &plugin) const; - - /** - * @brief Serialize all fields into data buffer. - * - * `buffSize` must be set to at least the RequiredBufferSize size. - * - * @param buff buffer to store serialized data. - * @param buffSize size of input buffer. - * @return size_t output serialized data length, 0 value means error. - */ - size_t Serialize(void *buff, size_t buffSize); - - /** - * @brief Deserialize all fields from given buffer. - * - * `buffSize` must be set to at least the RequiredBufferSize size. - * - * @param buff buffer containing serialized data (by invoking serialized method). - * @param buffSize size of output buffer. - * @return CHIP_ERROR_BUFFER_TOO_SMALL if provided buffSize is too small. - * @return CHIP_ERROR_INVALID_ARGUMENT if arguments are wrong. - * @return CHIP_NO_ERROR if deserialization has been finished successfully. - */ - CHIP_ERROR Deserialize(const void *buff, size_t buffSize); }; struct User { diff --git a/samples/matter/lock/src/access/access_manager_schedules.cpp b/samples/matter/lock/src/access/access_manager_schedules.cpp index c742783dd4df..96c1cd3f5632 100644 --- a/samples/matter/lock/src/access/access_manager_schedules.cpp +++ b/samples/matter/lock/src/access/access_manager_schedules.cpp @@ -24,9 +24,12 @@ DlStatus AccessManager::GetWeekDaySchedule(uint8_t weekdayIndex, VerifyOrReturnError(userIndex > 0 && userIndex <= CONFIG_LOCK_MAX_NUM_USERS, DlStatus::kFailure); VerifyOrReturnError(weekdayIndex > 0 && weekdayIndex <= CONFIG_LOCK_MAX_WEEKDAY_SCHEDULES_PER_USER, DlStatus::kFailure); - VerifyOrReturnError(!mWeekDaySchedule[userIndex - 1][weekdayIndex - 1].mAvailable, DlStatus::kNotFound); - if (CHIP_NO_ERROR != mWeekDaySchedule[userIndex - 1][weekdayIndex - 1].ConvertToPlugin(schedule)) { + auto &sch = mWeekDaySchedule[userIndex - 1][weekdayIndex - 1]; + + VerifyOrReturnError(!sch.mAvailable, DlStatus::kNotFound); + + if (CHIP_NO_ERROR != sch.ConvertToPlugin(schedule)) { return DlStatus::kNotFound; } @@ -47,16 +50,16 @@ DlStatus AccessManager::SetWeekDaySchedule(uint8_t weekdayIndex, if (DlScheduleStatus::kAvailable == status && !schedule.mAvailable) { schedule.mAvailable = true; - memset(schedule.mData.mRaw, 0, DoorLockData::WeekDaySchedule::RequiredBufferSize()); + memset(schedule.mData.mRaw, 0, sizeof(schedule.mData.mRaw)); if (!AccessStorage::Instance().Remove(AccessStorage::Type::WeekDaySchedule, userIndex, weekdayIndex)) { LOG_ERR("Cannot remove the WeekDay schedule"); return DlStatus::kFailure; } return DlStatus::kSuccess; + } else if (DlScheduleStatus::kOccupied == status && !schedule.mAvailable) { + LOG_DBG("Modifying week day schedule of index: %d for user %d", weekdayIndex, userIndex); } - VerifyOrReturnError(schedule.mAvailable, DlStatus::kOccupied); - schedule.mData.mFields.mDaysMask = static_cast(daysMask); schedule.mData.mFields.mStartHour = startHour; schedule.mData.mFields.mStartMinute = startMinute; @@ -104,9 +107,12 @@ DlStatus AccessManager::GetYearDaySchedule(uint8_t yearDayIndex, VerifyOrReturnError(userIndex > 0 && userIndex <= CONFIG_LOCK_MAX_NUM_USERS, DlStatus::kFailure); VerifyOrReturnError(yearDayIndex > 0 && yearDayIndex <= CONFIG_LOCK_MAX_YEARDAY_SCHEDULES_PER_USER, DlStatus::kFailure); - VerifyOrReturnError(!mYearDaySchedule[userIndex - 1][yearDayIndex - 1].mAvailable, DlStatus::kNotFound); - if (CHIP_NO_ERROR != mYearDaySchedule[userIndex - 1][yearDayIndex - 1].ConvertToPlugin(schedule)) { + auto &sch = mYearDaySchedule[userIndex - 1][yearDayIndex - 1]; + + VerifyOrReturnError(!sch.mAvailable, DlStatus::kNotFound); + + if (CHIP_NO_ERROR != sch.ConvertToPlugin(schedule)) { return DlStatus::kNotFound; } @@ -126,16 +132,16 @@ DlStatus AccessManager::SetYearDaySchedule(uint8_t yeardayIndex, if (DlScheduleStatus::kAvailable == status && !schedule.mAvailable) { schedule.mAvailable = true; - memset(schedule.mData.mRaw, 0, DoorLockData::YearDaySchedule::RequiredBufferSize()); + memset(schedule.mData.mRaw, 0, sizeof(schedule.mData.mRaw)); if (!AccessStorage::Instance().Remove(AccessStorage::Type::YearDaySchedule, userIndex, yeardayIndex)) { LOG_ERR("Cannot remove the YearDay schedule"); return DlStatus::kFailure; } return DlStatus::kSuccess; + } else if (DlScheduleStatus::kOccupied == status && !schedule.mAvailable) { + LOG_DBG("Modifying year day schedule of index: %d for user %d", yeardayIndex, userIndex); } - VerifyOrReturnError(schedule.mAvailable, DlStatus::kOccupied); - schedule.mData.mFields.mLocalStartTime = localStartTime; schedule.mData.mFields.mLocalEndTime = localEndTime; schedule.mAvailable = false; @@ -178,9 +184,12 @@ DlStatus AccessManager::GetHolidaySchedule(uint8_t holidayIndex, EmberAfPluginDoorLockHolidaySchedule &schedule) { VerifyOrReturnError(holidayIndex > 0 && holidayIndex <= CONFIG_LOCK_MAX_HOLIDAY_SCHEDULES, DlStatus::kFailure); - VerifyOrReturnError(!mHolidaySchedule[holidayIndex - 1].mAvailable, DlStatus::kNotFound); - if (CHIP_NO_ERROR != mHolidaySchedule[holidayIndex - 1].ConvertToPlugin(schedule)) { + auto &sch = mHolidaySchedule[holidayIndex - 1]; + + VerifyOrReturnError(!sch.mAvailable, DlStatus::kNotFound); + + if (CHIP_NO_ERROR != sch.ConvertToPlugin(schedule)) { return DlStatus::kNotFound; } @@ -198,16 +207,16 @@ DlStatus AccessManager::SetHolidaySchedule(uint8_t holidayIndex, if (DlScheduleStatus::kAvailable == status && !schedule.mAvailable) { schedule.mAvailable = true; - memset(schedule.mData.mRaw, 0, DoorLockData::HolidaySchedule::RequiredBufferSize()); + memset(schedule.mData.mRaw, 0, sizeof(schedule.mData.mRaw)); if (!AccessStorage::Instance().Remove(AccessStorage::Type::HolidaySchedule, holidayIndex)) { LOG_ERR("Cannot remove the Holiday schedule"); return DlStatus::kFailure; } return DlStatus::kSuccess; + } else if (DlScheduleStatus::kOccupied == status && !schedule.mAvailable) { + LOG_DBG("Modifying holiday schedule of index: %d", holidayIndex); } - VerifyOrReturnError(schedule.mAvailable, DlStatus::kOccupied); - schedule.mData.mFields.mLocalStartTime = localStartTime; schedule.mData.mFields.mLocalEndTime = localEndTime; schedule.mData.mFields.mOperatingMode = static_cast(operatingMode); @@ -369,7 +378,7 @@ void AccessManager::PrintSchedule(ScheduleType scheduleType, uint case ScheduleType::WeekDay: { auto *schedule = &mWeekDaySchedule[userIndex - 1][scheduleIndex - 1]; if (schedule) { - LOG_INF("-- WeekDay Schedule %d for user %d, days %08u, start %d:%d, end %d:%d", scheduleIndex, + LOG_DBG("-- WeekDay Schedule %d for user %d, days %08u, start %d:%d, end %d:%d", scheduleIndex, userIndex, static_cast(schedule->mData.mFields.mDaysMask), schedule->mData.mFields.mStartHour, schedule->mData.mFields.mStartMinute, schedule->mData.mFields.mEndHour, schedule->mData.mFields.mEndMinute); @@ -378,7 +387,7 @@ void AccessManager::PrintSchedule(ScheduleType scheduleType, uint case ScheduleType::YearDay: { auto *schedule = &mYearDaySchedule[userIndex - 1][scheduleIndex - 1]; if (schedule) { - LOG_INF("-- YearDay Schedule %d for user %d, starting time: %u, ending time: %u", scheduleIndex, + LOG_DBG("-- YearDay Schedule %d for user %d, starting time: %u, ending time: %u", scheduleIndex, userIndex, schedule->mData.mFields.mLocalStartTime, schedule->mData.mFields.mLocalEndTime); } @@ -386,7 +395,7 @@ void AccessManager::PrintSchedule(ScheduleType scheduleType, uint case ScheduleType::Holiday: { auto *schedule = &mHolidaySchedule[scheduleIndex - 1]; if (schedule) { - LOG_INF("-- Holiday Schedule %d, Local start time: %u, Local end time: %u, Operating mode: %d", + LOG_DBG("-- Holiday Schedule %d, Local start time: %u, Local end time: %u, Operating mode: %d", scheduleIndex, schedule->mData.mFields.mLocalStartTime, schedule->mData.mFields.mLocalEndTime, static_cast(schedule->mData.mFields.mOperatingMode)); From 487453fe7ee76f161270b0967ef129a6c3244aa7 Mon Sep 17 00:00:00 2001 From: Mirko Covizzi Date: Mon, 26 Aug 2024 14:52:54 +0200 Subject: [PATCH 27/72] lib: at_parser: move generated code and ignore formatting Moves the generated `at_match.c` to the `generated` directory and adds this directory to the excluded list for Checkpatch, so that the generated file does not require reformatting. This makes versioning easier since it removes the reformatting step necessary to comply with Checkpatch. Signed-off-by: Mirko Covizzi --- .checkpatch.conf | 1 + lib/at_parser/CMakeLists.txt | 2 +- lib/at_parser/at_match.re | 315 ++++++------ lib/at_parser/{ => generated}/at_match.c | 621 ++++++++++------------- 4 files changed, 432 insertions(+), 507 deletions(-) rename lib/at_parser/{ => generated}/at_match.c (56%) diff --git a/.checkpatch.conf b/.checkpatch.conf index 3cd6a860530e..971cf6ba56db 100644 --- a/.checkpatch.conf +++ b/.checkpatch.conf @@ -49,4 +49,5 @@ --exclude doc/nrf/.*/.*/.*/images --exclude doc/nrf/.*/.*/.*/.*/images --exclude applications/nrf5340_audio/src/utils/macros +--exclude lib/at_parser/generated --exclude lib/bin/lwm2m_carrier/include diff --git a/lib/at_parser/CMakeLists.txt b/lib/at_parser/CMakeLists.txt index 0c519da83477..3b3fb7d02fc0 100644 --- a/lib/at_parser/CMakeLists.txt +++ b/lib/at_parser/CMakeLists.txt @@ -7,7 +7,7 @@ zephyr_library() zephyr_library_sources( at_parser.c - at_match.c + generated/at_match.c ) zephyr_include_directories(include) diff --git a/lib/at_parser/at_match.re b/lib/at_parser/at_match.re index 0de4c8d590ee..9120f61737f6 100644 --- a/lib/at_parser/at_match.re +++ b/lib/at_parser/at_match.re @@ -4,87 +4,82 @@ * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ -/* at_match.c generated by re2c 3.0 +/* at_match.c generated by re2c 3.0-1 * * Generated with: - * re2c at_match.re -o at_match.c -W --no-debug-info --tags - * - * Reformatted with: - * clang-format-15 -i at_match.c - * Using the following additional .clangformat options: - * IndentGotoLabels: false - * SpaceBeforeInheritanceColon: False + * re2c at_match.re -o generated/at_match.c -W --tags --no-debug-info --no-generation-date \ + * --no-version */ -#include "at_match.h" +#include "../at_match.h" struct at_token at_match_cmd(const char *at, const char **remainder) { const char *cursor = at; const char *marker = NULL; - /*!local:re2c - re2c:define:YYCTYPE = "unsigned char"; - re2c:define:YYCURSOR = cursor; - re2c:define:YYMARKER = marker; - re2c:yyfill:enable = 0; - - AT_CASE_INS = [Aa][Tt]; - CMD = [#%+][A-Za-z0-9]+; - - cmd_test = AT_CASE_INS CMD "=?"; - cmd_read = AT_CASE_INS CMD "?"; - cmd_set = AT_CASE_INS CMD "="; - cmd_set_no_subparams = AT_CASE_INS CMD?; - notif = CMD ":"; - - * { return (struct at_token){ .type = AT_TOKEN_TYPE_INVALID }; } - - cmd_test - { - if (remainder) *remainder = cursor; - return (struct at_token){ - .start = at, .len = cursor - at - 2, - .type = AT_TOKEN_TYPE_CMD_TEST - }; - } - - cmd_read - { - if (remainder) *remainder = cursor; - return (struct at_token){ - .start = at, .len = cursor - at - 1, - .type = AT_TOKEN_TYPE_CMD_READ - }; - } - - cmd_set - { - if (remainder) *remainder = cursor; - return (struct at_token){ - .start = at, .len = cursor - at - 1, - .type = AT_TOKEN_TYPE_CMD_SET - }; - } - - cmd_set_no_subparams - { - if (remainder) *remainder = cursor; - return (struct at_token){ - .start = at, .len = cursor - at, - .type = AT_TOKEN_TYPE_CMD_SET - }; - } - - notif - { - if (remainder) *remainder = cursor; - return (struct at_token){ - .start = at, .len = cursor - at - 1, - .type = AT_TOKEN_TYPE_NOTIF - }; - } - */ +/*!local:re2c + re2c:define:YYCTYPE = "unsigned char"; + re2c:define:YYCURSOR = cursor; + re2c:define:YYMARKER = marker; + re2c:yyfill:enable = 0; + + AT_CASE_INS = [Aa][Tt]; + CMD = [#%+][A-Za-z0-9]+; + + cmd_test = AT_CASE_INS CMD "=?"; + cmd_read = AT_CASE_INS CMD "?"; + cmd_set = AT_CASE_INS CMD "="; + cmd_set_no_subparams = AT_CASE_INS CMD?; + notif = CMD ":"; + + * { return (struct at_token){ .type = AT_TOKEN_TYPE_INVALID }; } + + cmd_test + { + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = at, .len = cursor - at - 2, + .type = AT_TOKEN_TYPE_CMD_TEST + }; + } + + cmd_read + { + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = at, .len = cursor - at - 1, + .type = AT_TOKEN_TYPE_CMD_READ + }; + } + + cmd_set + { + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = at, .len = cursor - at - 1, + .type = AT_TOKEN_TYPE_CMD_SET + }; + } + + cmd_set_no_subparams + { + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = at, .len = cursor - at, + .type = AT_TOKEN_TYPE_CMD_SET + }; + } + + notif + { + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = at, .len = cursor - at - 1, + .type = AT_TOKEN_TYPE_NOTIF + }; + } +*/ } struct at_token at_match_subparam(const char *at, const char **remainder) @@ -94,75 +89,75 @@ struct at_token at_match_subparam(const char *at, const char **remainder) const char *t1; const char *t2; - /*!stags:re2c format = 'const char *@@;\n'; */ - - /*!local:re2c - re2c:define:YYCTYPE = "unsigned char"; - re2c:define:YYCURSOR = cursor; - re2c:define:YYMARKER = marker; - re2c:yyfill:enable = 0; - - SPACE = " "; - INT = "0"|[+\-]?[1-9][0-9]*; - COMMA = ","; - QUOTE = "\""; - QUOTED_STR = QUOTE @t1 [^"\x00]* @t2 QUOTE; - OPEN_PAR = "("; - CLOSE_PAR = ")"; - ARRAY = OPEN_PAR [^()\x00]+ CLOSE_PAR; - - int = SPACE? @t1 INT @t2 COMMA?; - quoted_str = SPACE? QUOTED_STR COMMA?; - array = SPACE? @t1 ARRAY @t2 COMMA?; - empty = SPACE? @t1 @t2 COMMA; - - * { return (struct at_token){ .type = AT_TOKEN_TYPE_INVALID }; } - - int - { - char last = *(cursor - 1); - - if (remainder) *remainder = cursor; - return (struct at_token){ - .start = t1, .len = t2 - t1, - .type = AT_TOKEN_TYPE_INT, - .var = last == ',' ? AT_TOKEN_VAR_COMMA : AT_TOKEN_VAR_NO_COMMA - }; - } - - quoted_str - { - char last = *(cursor - 1); - - if (remainder) *remainder = cursor; - return (struct at_token){ - .start = t1, .len = t2 - t1, - .type = AT_TOKEN_TYPE_QUOTED_STRING, - .var = last == ',' ? AT_TOKEN_VAR_COMMA : AT_TOKEN_VAR_NO_COMMA - }; - } - - array - { - char last = *(cursor - 1); - - if (remainder) *remainder = cursor; - return (struct at_token){ - .start = t1, .len = t2 - t1, - .type = AT_TOKEN_TYPE_ARRAY, - .var = last == ',' ? AT_TOKEN_VAR_COMMA : AT_TOKEN_VAR_NO_COMMA - }; - } - - empty - { - if (remainder) *remainder = cursor; - return (struct at_token){ - .start = t1, .len = t2 - t1, - .type = AT_TOKEN_TYPE_EMPTY, .var = AT_TOKEN_VAR_COMMA - }; - } - */ +/*!stags:re2c format = 'const char *@@;'; */ + +/*!local:re2c + re2c:define:YYCTYPE = "unsigned char"; + re2c:define:YYCURSOR = cursor; + re2c:define:YYMARKER = marker; + re2c:yyfill:enable = 0; + + SPACE = " "; + INT = "0"|[+\-]?[1-9][0-9]*; + COMMA = ","; + QUOTE = "\""; + QUOTED_STR = QUOTE @t1 [^"\x00]* @t2 QUOTE; + OPEN_PAR = "("; + CLOSE_PAR = ")"; + ARRAY = OPEN_PAR [^()\x00]+ CLOSE_PAR; + + int = SPACE? @t1 INT @t2 COMMA?; + quoted_str = SPACE? QUOTED_STR COMMA?; + array = SPACE? @t1 ARRAY @t2 COMMA?; + empty = SPACE? @t1 @t2 COMMA; + + * { return (struct at_token){ .type = AT_TOKEN_TYPE_INVALID }; } + + int + { + char last = *(cursor - 1); + + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = t1, .len = t2 - t1, + .type = AT_TOKEN_TYPE_INT, + .var = last == ',' ? AT_TOKEN_VAR_COMMA : AT_TOKEN_VAR_NO_COMMA + }; + } + + quoted_str + { + char last = *(cursor - 1); + + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = t1, .len = t2 - t1, + .type = AT_TOKEN_TYPE_QUOTED_STRING, + .var = last == ',' ? AT_TOKEN_VAR_COMMA : AT_TOKEN_VAR_NO_COMMA + }; + } + + array + { + char last = *(cursor - 1); + + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = t1, .len = t2 - t1, + .type = AT_TOKEN_TYPE_ARRAY, + .var = last == ',' ? AT_TOKEN_VAR_COMMA : AT_TOKEN_VAR_NO_COMMA + }; + } + + empty + { + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = t1, .len = t2 - t1, + .type = AT_TOKEN_TYPE_EMPTY, .var = AT_TOKEN_VAR_COMMA + }; + } +*/ } struct at_token at_match_str(const char *at, const char **remainder) @@ -172,29 +167,29 @@ struct at_token at_match_str(const char *at, const char **remainder) const char *t1; const char *t2; - /*!stags:re2c format = 'const char *@@;\n'; */ +/*!stags:re2c format = 'const char *@@;'; */ - /*!local:re2c - re2c:define:YYCTYPE = "unsigned char"; - re2c:define:YYCURSOR = cursor; - re2c:define:YYMARKER = marker; - re2c:yyfill:enable = 0; +/*!local:re2c + re2c:define:YYCTYPE = "unsigned char"; + re2c:define:YYCURSOR = cursor; + re2c:define:YYMARKER = marker; + re2c:yyfill:enable = 0; - SPACE = " "; - CRLF = "\r\n"; - STR = [A-Za-z0-9][A-Za-z_\-.0-9 ]*; + SPACE = " "; + CRLF = "\r\n"; + STR = [A-Za-z0-9][A-Za-z_\-.0-9 ]*; - str = SPACE? @t1 STR @t2 CRLF?; + str = SPACE? @t1 STR @t2 CRLF?; - * { return (struct at_token){ .type = AT_TOKEN_TYPE_INVALID }; } + * { return (struct at_token){ .type = AT_TOKEN_TYPE_INVALID }; } - str - { - if (remainder) *remainder = t2; - return (struct at_token){ - .start = t1, .len = t2 - t1, - .type = AT_TOKEN_TYPE_STRING, - }; - } - */ + str + { + if (remainder) *remainder = t2; + return (struct at_token){ + .start = t1, .len = t2 - t1, + .type = AT_TOKEN_TYPE_STRING, + }; + } +*/ } diff --git a/lib/at_parser/at_match.c b/lib/at_parser/generated/at_match.c similarity index 56% rename from lib/at_parser/at_match.c rename to lib/at_parser/generated/at_match.c index 5a4c387ad7e2..dd48dc01f7ff 100644 --- a/lib/at_parser/at_match.c +++ b/lib/at_parser/generated/at_match.c @@ -1,53 +1,45 @@ +/* Generated by re2c */ /* * Copyright (c) 2024 Nordic Semiconductor ASA * * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ -/* at_match.c generated by re2c 3.0 +/* at_match.c generated by re2c 3.0-1 * * Generated with: - * re2c at_match.re -o at_match.c -W --no-debug-info --tags - * - * Reformatted with: - * clang-format-15 -i at_match.c - * Using the following additional .clangformat options: - * IndentGotoLabels: false - * SpaceBeforeInheritanceColon: False + * re2c at_match.re -o generated/at_match.c -W --tags --no-debug-info --no-generation-date \ + * --no-version */ -#include "at_match.h" +#include "../at_match.h" struct at_token at_match_cmd(const char *at, const char **remainder) { const char *cursor = at; const char *marker = NULL; - { - unsigned char yych; - unsigned int yyaccept = 0; - yych = *cursor; - switch (yych) { +{ + unsigned char yych; + unsigned int yyaccept = 0; + yych = *cursor; + switch (yych) { case '#': case '%': - case '+': - goto yy3; + case '+': goto yy3; case 'A': - case 'a': - goto yy4; - default: - goto yy1; - } + case 'a': goto yy4; + default: goto yy1; + } yy1: - ++cursor; -yy2: { - return (struct at_token){.type = AT_TOKEN_TYPE_INVALID}; -} + ++cursor; +yy2: + { return (struct at_token){ .type = AT_TOKEN_TYPE_INVALID }; } yy3: - yyaccept = 0; - yych = *(marker = ++cursor); - switch (yych) { + yyaccept = 0; + yych = *(marker = ++cursor); + switch (yych) { case '0': case '1': case '2': @@ -109,23 +101,19 @@ yy2: { case 'w': case 'x': case 'y': - case 'z': - goto yy5; - default: - goto yy2; - } + case 'z': goto yy5; + default: goto yy2; + } yy4: - yych = *++cursor; - switch (yych) { + yych = *++cursor; + switch (yych) { case 'T': - case 't': - goto yy7; - default: - goto yy2; - } + case 't': goto yy7; + default: goto yy2; + } yy5: - yych = *++cursor; - switch (yych) { + yych = *++cursor; + switch (yych) { case '0': case '1': case '2': @@ -187,49 +175,46 @@ yy2: { case 'w': case 'x': case 'y': - case 'z': - goto yy5; - case ':': - goto yy9; - default: - goto yy6; - } + case 'z': goto yy5; + case ':': goto yy9; + default: goto yy6; + } yy6: - cursor = marker; - if (yyaccept == 0) { - goto yy2; - } else { - goto yy8; - } + cursor = marker; + if (yyaccept == 0) { + goto yy2; + } else { + goto yy8; + } yy7: - yyaccept = 1; - yych = *(marker = ++cursor); - switch (yych) { + yyaccept = 1; + yych = *(marker = ++cursor); + switch (yych) { case '#': case '%': - case '+': - goto yy10; - default: - goto yy8; - } -yy8: { - if (remainder) { - *remainder = cursor; + case '+': goto yy10; + default: goto yy8; + } +yy8: + { + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = at, .len = cursor - at, + .type = AT_TOKEN_TYPE_CMD_SET + }; } - return (struct at_token){.start = at, .len = cursor - at, .type = AT_TOKEN_TYPE_CMD_SET}; -} yy9: - ++cursor; - { - if (remainder) { - *remainder = cursor; - } - return (struct at_token){ - .start = at, .len = cursor - at - 1, .type = AT_TOKEN_TYPE_NOTIF}; - } + ++cursor; + { + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = at, .len = cursor - at - 1, + .type = AT_TOKEN_TYPE_NOTIF + }; + } yy10: - yych = *++cursor; - switch (yych) { + yych = *++cursor; + switch (yych) { case '0': case '1': case '2': @@ -291,14 +276,12 @@ yy8: { case 'w': case 'x': case 'y': - case 'z': - goto yy11; - default: - goto yy6; - } + case 'z': goto yy11; + default: goto yy6; + } yy11: - yych = *++cursor; - switch (yych) { + yych = *++cursor; + switch (yych) { case '0': case '1': case '2': @@ -360,53 +343,47 @@ yy8: { case 'w': case 'x': case 'y': - case 'z': - goto yy11; - case '=': - goto yy12; - case '?': - goto yy14; - default: - goto yy8; - } + case 'z': goto yy11; + case '=': goto yy12; + case '?': goto yy14; + default: goto yy8; + } yy12: - yych = *++cursor; - switch (yych) { - case '?': - goto yy15; - default: - goto yy13; - } -yy13: { - if (remainder) { - *remainder = cursor; - } - return (struct at_token){ - .start = at, .len = cursor - at - 1, .type = AT_TOKEN_TYPE_CMD_SET}; -} + yych = *++cursor; + switch (yych) { + case '?': goto yy15; + default: goto yy13; + } +yy13: + { + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = at, .len = cursor - at - 1, + .type = AT_TOKEN_TYPE_CMD_SET + }; + } yy14: - ++cursor; - { - if (remainder) { - *remainder = cursor; - } - return (struct at_token){.start = at, - .len = cursor - at - 1, - .type = AT_TOKEN_TYPE_CMD_READ}; - } + ++cursor; + { + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = at, .len = cursor - at - 1, + .type = AT_TOKEN_TYPE_CMD_READ + }; + } yy15: - ++cursor; - { - if (remainder) { - *remainder = cursor; - } - return (struct at_token){.start = at, - .len = cursor - at - 2, - .type = AT_TOKEN_TYPE_CMD_TEST}; - } + ++cursor; + { + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = at, .len = cursor - at - 2, + .type = AT_TOKEN_TYPE_CMD_TEST + }; } } +} + struct at_token at_match_subparam(const char *at, const char **remainder) { const char *cursor = at; @@ -414,18 +391,15 @@ struct at_token at_match_subparam(const char *at, const char **remainder) const char *t1; const char *t2; - const char *yyt1; - const char *yyt2; +const char *yyt1;const char *yyt2; - { - unsigned char yych; - yych = *cursor; - switch (yych) { - case ' ': - goto yy19; - case '"': - goto yy20; +{ + unsigned char yych; + yych = *cursor; + switch (yych) { + case ' ': goto yy19; + case '"': goto yy20; case '(': yyt2 = cursor; goto yy21; @@ -433,8 +407,7 @@ struct at_token at_match_subparam(const char *at, const char **remainder) case '-': yyt2 = cursor; goto yy22; - case ',': - goto yy23; + case ',': goto yy23; case '0': yyt2 = cursor; goto yy24; @@ -449,19 +422,16 @@ struct at_token at_match_subparam(const char *at, const char **remainder) case '9': yyt2 = cursor; goto yy26; - default: - goto yy17; - } + default: goto yy17; + } yy17: - ++cursor; -yy18: { - return (struct at_token){.type = AT_TOKEN_TYPE_INVALID}; -} + ++cursor; +yy18: + { return (struct at_token){ .type = AT_TOKEN_TYPE_INVALID }; } yy19: - yych = *(marker = ++cursor); - switch (yych) { - case '"': - goto yy27; + yych = *(marker = ++cursor); + switch (yych) { + case '"': goto yy27; case '(': yyt2 = cursor; goto yy29; @@ -469,8 +439,7 @@ yy18: { case '-': yyt2 = cursor; goto yy30; - case ',': - goto yy23; + case ',': goto yy23; case '0': yyt2 = cursor; goto yy24; @@ -485,34 +454,30 @@ yy18: { case '9': yyt2 = cursor; goto yy26; - default: - goto yy18; - } + default: goto yy18; + } yy20: - yych = *(marker = ++cursor); - switch (yych) { - case 0x00: - goto yy18; + yych = *(marker = ++cursor); + switch (yych) { + case 0x00: goto yy18; case '"': yyt1 = yyt2 = cursor; goto yy32; default: yyt1 = cursor; goto yy31; - } + } yy21: - yych = *(marker = ++cursor); - switch (yych) { + yych = *(marker = ++cursor); + switch (yych) { case 0x00: case '(': - case ')': - goto yy18; - default: - goto yy34; - } + case ')': goto yy18; + default: goto yy34; + } yy22: - yych = *++cursor; - switch (yych) { + yych = *++cursor; + switch (yych) { case '1': case '2': case '3': @@ -521,51 +486,43 @@ yy18: { case '6': case '7': case '8': - case '9': - goto yy26; - default: - goto yy18; - } + case '9': goto yy26; + default: goto yy18; + } yy23: - ++cursor; - t1 = cursor - 1; - t2 = cursor - 1; - { - if (remainder) { - *remainder = cursor; - } - return (struct at_token){.start = t1, - .len = t2 - t1, - .type = AT_TOKEN_TYPE_EMPTY, - .var = AT_TOKEN_VAR_COMMA}; - } + ++cursor; + t1 = cursor - 1; + t2 = cursor - 1; + { + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = t1, .len = t2 - t1, + .type = AT_TOKEN_TYPE_EMPTY, .var = AT_TOKEN_VAR_COMMA + }; + } yy24: - yych = *++cursor; - yyt1 = cursor; - switch (yych) { - case ',': - goto yy36; - default: - goto yy25; - } + yych = *++cursor; + yyt1 = cursor; + switch (yych) { + case ',': goto yy36; + default: goto yy25; + } yy25: - t1 = yyt2; - t2 = yyt1; - { - char last = *(cursor - 1); + t1 = yyt2; + t2 = yyt1; + { + char last = *(cursor - 1); - if (remainder) { - *remainder = cursor; - } - return (struct at_token){.start = t1, - .len = t2 - t1, - .type = AT_TOKEN_TYPE_INT, - .var = last == ',' ? AT_TOKEN_VAR_COMMA - : AT_TOKEN_VAR_NO_COMMA}; - } + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = t1, .len = t2 - t1, + .type = AT_TOKEN_TYPE_INT, + .var = last == ',' ? AT_TOKEN_VAR_COMMA : AT_TOKEN_VAR_NO_COMMA + }; + } yy26: - yych = *++cursor; - switch (yych) { + yych = *++cursor; + switch (yych) { case ',': yyt1 = cursor; goto yy36; @@ -578,38 +535,34 @@ yy18: { case '6': case '7': case '8': - case '9': - goto yy26; + case '9': goto yy26; default: yyt1 = cursor; goto yy25; - } + } yy27: - yych = *++cursor; - switch (yych) { - case 0x00: - goto yy28; + yych = *++cursor; + switch (yych) { + case 0x00: goto yy28; case '"': yyt1 = yyt2 = cursor; goto yy32; default: yyt1 = cursor; goto yy31; - } + } yy28: - cursor = marker; - goto yy18; + cursor = marker; + goto yy18; yy29: - yych = *++cursor; - switch (yych) { - case ')': - goto yy28; - default: - goto yy35; - } + yych = *++cursor; + switch (yych) { + case ')': goto yy28; + default: goto yy35; + } yy30: - yych = *++cursor; - switch (yych) { + yych = *++cursor; + switch (yych) { case '1': case '2': case '3': @@ -618,91 +571,77 @@ yy18: { case '6': case '7': case '8': - case '9': - goto yy26; - default: - goto yy28; - } + case '9': goto yy26; + default: goto yy28; + } yy31: - yych = *++cursor; - switch (yych) { - case 0x00: - goto yy28; + yych = *++cursor; + switch (yych) { + case 0x00: goto yy28; case '"': yyt2 = cursor; goto yy32; - default: - goto yy31; - } + default: goto yy31; + } yy32: - yych = *++cursor; - switch (yych) { - case ',': - goto yy37; - default: - goto yy33; - } + yych = *++cursor; + switch (yych) { + case ',': goto yy37; + default: goto yy33; + } yy33: - t1 = yyt1; - t2 = yyt2; - { - char last = *(cursor - 1); + t1 = yyt1; + t2 = yyt2; + { + char last = *(cursor - 1); - if (remainder) { - *remainder = cursor; - } - return (struct at_token){.start = t1, - .len = t2 - t1, - .type = AT_TOKEN_TYPE_QUOTED_STRING, - .var = last == ',' ? AT_TOKEN_VAR_COMMA - : AT_TOKEN_VAR_NO_COMMA}; - } + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = t1, .len = t2 - t1, + .type = AT_TOKEN_TYPE_QUOTED_STRING, + .var = last == ',' ? AT_TOKEN_VAR_COMMA : AT_TOKEN_VAR_NO_COMMA + }; + } yy34: - yych = *++cursor; + yych = *++cursor; yy35: - switch (yych) { + switch (yych) { case 0x00: - case '(': - goto yy28; - case ')': - goto yy38; - default: - goto yy34; - } + case '(': goto yy28; + case ')': goto yy38; + default: goto yy34; + } yy36: - ++cursor; - goto yy25; + ++cursor; + goto yy25; yy37: - ++cursor; - goto yy33; + ++cursor; + goto yy33; yy38: - yych = *++cursor; - yyt1 = cursor; - switch (yych) { - case ',': - goto yy40; - default: - goto yy39; - } + yych = *++cursor; + yyt1 = cursor; + switch (yych) { + case ',': goto yy40; + default: goto yy39; + } yy39: - t1 = yyt2; - t2 = yyt1; - { - char last = *(cursor - 1); + t1 = yyt2; + t2 = yyt1; + { + char last = *(cursor - 1); - if (remainder) { - *remainder = cursor; - } - return (struct at_token){.start = t1, - .len = t2 - t1, - .type = AT_TOKEN_TYPE_ARRAY, - .var = last == ',' ? AT_TOKEN_VAR_COMMA - : AT_TOKEN_VAR_NO_COMMA}; - } -yy40: - ++cursor; - goto yy39; + if (remainder) *remainder = cursor; + return (struct at_token){ + .start = t1, .len = t2 - t1, + .type = AT_TOKEN_TYPE_ARRAY, + .var = last == ',' ? AT_TOKEN_VAR_COMMA : AT_TOKEN_VAR_NO_COMMA + }; } +yy40: + ++cursor; + goto yy39; +} + } struct at_token at_match_str(const char *at, const char **remainder) @@ -712,16 +651,14 @@ struct at_token at_match_str(const char *at, const char **remainder) const char *t1; const char *t2; - const char *yyt1; - const char *yyt2; +const char *yyt1;const char *yyt2; - { - unsigned char yych; - yych = *cursor; - switch (yych) { - case ' ': - goto yy44; +{ + unsigned char yych; + yych = *cursor; + switch (yych) { + case ' ': goto yy44; case '0': case '1': case '2': @@ -786,17 +723,15 @@ struct at_token at_match_str(const char *at, const char **remainder) case 'z': yyt1 = cursor; goto yy45; - default: - goto yy42; - } + default: goto yy42; + } yy42: - ++cursor; -yy43: { - return (struct at_token){.type = AT_TOKEN_TYPE_INVALID}; -} + ++cursor; +yy43: + { return (struct at_token){ .type = AT_TOKEN_TYPE_INVALID }; } yy44: - yych = *++cursor; - switch (yych) { + yych = *++cursor; + switch (yych) { case '0': case '1': case '2': @@ -861,12 +796,11 @@ yy43: { case 'z': yyt1 = cursor; goto yy45; - default: - goto yy43; - } + default: goto yy43; + } yy45: - yych = *(marker = ++cursor); - switch (yych) { + yych = *(marker = ++cursor); + switch (yych) { case '\r': yyt2 = cursor; goto yy47; @@ -935,39 +869,34 @@ yy43: { case 'w': case 'x': case 'y': - case 'z': - goto yy45; + case 'z': goto yy45; default: yyt2 = cursor; goto yy46; - } + } yy46: - t1 = yyt1; - t2 = yyt2; - { - if (remainder) { - *remainder = t2; - } - return (struct at_token){ - .start = t1, - .len = t2 - t1, - .type = AT_TOKEN_TYPE_STRING, - }; - } + t1 = yyt1; + t2 = yyt2; + { + if (remainder) *remainder = t2; + return (struct at_token){ + .start = t1, .len = t2 - t1, + .type = AT_TOKEN_TYPE_STRING, + }; + } yy47: - yych = *++cursor; - switch (yych) { - case '\n': - goto yy49; - default: - goto yy48; - } + yych = *++cursor; + switch (yych) { + case '\n': goto yy49; + default: goto yy48; + } yy48: - cursor = marker; - yyt2 = cursor; - goto yy46; + cursor = marker; + yyt2 = cursor; + goto yy46; yy49: - ++cursor; - goto yy46; - } + ++cursor; + goto yy46; +} + } From 59f75a70bd551c7b3317e1d4b9c086a398e0c8b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ku=C5=BAnia?= Date: Fri, 23 Aug 2024 13:28:50 +0200 Subject: [PATCH 28/72] samples: 802154_phy_test: remote shell to nRF54H20 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added the remote shell to 802154_phy_test sample to make it consistent with nRF5340. Signed-off-by: Rafał Kuźnia --- .../boards/nrf54h20dk_nrf54h20_cpurad.conf | 14 ++++++ .../boards/nrf54h20dk_nrf54h20_cpurad.overlay | 8 ++++ .../modules/app_rpc/zephyr/Kconfig | 6 +-- .../modules/app_rpc/zephyr/src/app_rpc.c | 4 +- .../peripheral/802154_phy_test/sysbuild.cmake | 28 +----------- .../peripheral/802154_phy_test/sysbuild.conf | 1 + .../boards/nrf5340dk_nrf5340_cpuapp.conf | 8 ++++ .../boards/nrf54h20dk_nrf54h20_cpuapp.overlay | 44 +++++++++++++++++++ .../sysbuild/remote_shell/prj.conf | 5 --- 9 files changed, 81 insertions(+), 37 deletions(-) create mode 100644 samples/peripheral/802154_phy_test/sysbuild/remote_shell/boards/nrf5340dk_nrf5340_cpuapp.conf create mode 100644 samples/peripheral/802154_phy_test/sysbuild/remote_shell/boards/nrf54h20dk_nrf54h20_cpuapp.overlay diff --git a/samples/peripheral/802154_phy_test/boards/nrf54h20dk_nrf54h20_cpurad.conf b/samples/peripheral/802154_phy_test/boards/nrf54h20dk_nrf54h20_cpurad.conf index 58fbae21ac12..a64d7ef71869 100644 --- a/samples/peripheral/802154_phy_test/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ b/samples/peripheral/802154_phy_test/boards/nrf54h20dk_nrf54h20_cpurad.conf @@ -9,3 +9,17 @@ CONFIG_SHELL_PROMPT_UART=">" # currently unsupported for nRF54H20 CONFIG_PTT_CACHE_MGMT=n CONFIG_PTT_CLK_OUT=n + +CONFIG_SHELL_PROMPT_IPC=">" +CONFIG_SHELL_IPC=y +CONFIG_SHELL_LOG_BACKEND=y +CONFIG_SHELL_BACKEND_SERIAL=n + +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y +CONFIG_SHELL_IPC_BACKEND_RX_RING_BUFFER_SIZE=1024 + +CONFIG_HEAP_MEM_POOL_SIZE=4096 + +# Enable application specific RPC operations +CONFIG_APP_RPC=y diff --git a/samples/peripheral/802154_phy_test/boards/nrf54h20dk_nrf54h20_cpurad.overlay b/samples/peripheral/802154_phy_test/boards/nrf54h20dk_nrf54h20_cpurad.overlay index e822e0a1b266..1840ae2ea69e 100644 --- a/samples/peripheral/802154_phy_test/boards/nrf54h20dk_nrf54h20_cpurad.overlay +++ b/samples/peripheral/802154_phy_test/boards/nrf54h20dk_nrf54h20_cpurad.overlay @@ -55,6 +55,10 @@ sw2 = &button2; sw3 = &button3; }; + + chosen { + zephyr,shell-ipc = &ipc0; + }; }; &gpio9 { @@ -68,3 +72,7 @@ &gpiote130 { status = "okay"; }; + +&uart135 { + status = "disabled"; +}; diff --git a/samples/peripheral/802154_phy_test/modules/app_rpc/zephyr/Kconfig b/samples/peripheral/802154_phy_test/modules/app_rpc/zephyr/Kconfig index d08fd3540a1d..f8433c3031c5 100644 --- a/samples/peripheral/802154_phy_test/modules/app_rpc/zephyr/Kconfig +++ b/samples/peripheral/802154_phy_test/modules/app_rpc/zephyr/Kconfig @@ -6,6 +6,6 @@ config APP_RPC bool "Enables application module features requiring interaction between cores" - depends on SOC_NRF5340_CPUNET || SOC_NRF5340_CPUAPP - select NRF_RPC if SOC_NRF5340_CPUNET || SOC_NRF5340_CPUAPP - select NRF_RPC_CBOR if SOC_NRF5340_CPUNET || SOC_NRF5340_CPUAPP + depends on SOC_NRF5340_CPUNET || SOC_NRF5340_CPUAPP || SOC_NRF54H20_CPUAPP || SOC_NRF54H20_CPURAD + select NRF_RPC + select NRF_RPC_CBOR diff --git a/samples/peripheral/802154_phy_test/modules/app_rpc/zephyr/src/app_rpc.c b/samples/peripheral/802154_phy_test/modules/app_rpc/zephyr/src/app_rpc.c index 234d9fb84189..d4ae8ea478e7 100644 --- a/samples/peripheral/802154_phy_test/modules/app_rpc/zephyr/src/app_rpc.c +++ b/samples/peripheral/802154_phy_test/modules/app_rpc/zephyr/src/app_rpc.c @@ -13,8 +13,8 @@ #include #endif -#define IS_RPC_CLIENT CONFIG_SOC_NRF5340_CPUNET -#define IS_RPC_SERVER CONFIG_SOC_NRF5340_CPUAPP +#define IS_RPC_CLIENT (CONFIG_SOC_NRF5340_CPUNET || CONFIG_SOC_NRF54H20_CPURAD) +#define IS_RPC_SERVER (CONFIG_SOC_NRF5340_CPUAPP || CONFIG_SOC_NRF54H20_CPUAPP) NRF_RPC_IPC_TRANSPORT(app_rpc_tr, DEVICE_DT_GET(DT_NODELABEL(ipc0)), "app_rpc_tr_ept"); NRF_RPC_GROUP_DEFINE(app_rpc_grp, "app_rpc_grp", &app_rpc_tr, NULL, NULL, NULL); diff --git a/samples/peripheral/802154_phy_test/sysbuild.cmake b/samples/peripheral/802154_phy_test/sysbuild.cmake index c5c044b79330..4247e8fad5fa 100644 --- a/samples/peripheral/802154_phy_test/sysbuild.cmake +++ b/samples/peripheral/802154_phy_test/sysbuild.cmake @@ -6,30 +6,4 @@ get_property(PM_DOMAINS GLOBAL PROPERTY PM_DOMAINS) zephyr_get(EXTRA_ZEPHYR_MODULES) -set(EXTRA_ZEPHYR_MODULES "${EXTRA_ZEPHYR_MODULES};${CMAKE_CURRENT_LIST_DIR}/modules/app_rpc" CACHE INTERNAL "extra modules directories") - -# Include app core image if enabled -if(SB_CONFIG_SOC_NRF5340_CPUNET) - # Get application core board target - string(REPLACE "/" ";" split_board_qualifiers "${BOARD_QUALIFIERS}") - list(GET split_board_qualifiers 1 target_soc) - set(board_target_appcore "${BOARD}/${target_soc}/cpuapp") - set(target_soc) - - ExternalZephyrProject_Add( - APPLICATION remote_shell - SOURCE_DIR ${ZEPHYR_NRF_MODULE_DIR}/samples/nrf5340/remote_shell - BOARD ${board_target_appcore} - BOARD_REVISION ${BOARD_REVISION} - ) - - if(NOT "CPUAPP" IN_LIST PM_DOMAINS) - list(APPEND PM_DOMAINS CPUAPP) - endif() - - set_property(GLOBAL APPEND PROPERTY PM_CPUAPP_IMAGES "remote_shell") - set_property(GLOBAL PROPERTY DOMAIN_APP_CPUAPP "remote_shell") - set(CPUAPP_PM_DOMAIN_DYNAMIC_PARTITION remote_shell CACHE INTERNAL "") -endif() - -set_property(GLOBAL PROPERTY PM_DOMAINS ${PM_DOMAINS}) +set(remote_shell_EXTRA_ZEPHYR_MODULES "${EXTRA_ZEPHYR_MODULES};${CMAKE_CURRENT_LIST_DIR}/modules/app_rpc" CACHE INTERNAL "extra modules directories") diff --git a/samples/peripheral/802154_phy_test/sysbuild.conf b/samples/peripheral/802154_phy_test/sysbuild.conf index 71b8f9f9b757..cdcfc9a4e895 100644 --- a/samples/peripheral/802154_phy_test/sysbuild.conf +++ b/samples/peripheral/802154_phy_test/sysbuild.conf @@ -5,3 +5,4 @@ # SB_CONFIG_PARTITION_MANAGER=n +SB_CONFIG_APPCORE_REMOTE_SHELL=y diff --git a/samples/peripheral/802154_phy_test/sysbuild/remote_shell/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/peripheral/802154_phy_test/sysbuild/remote_shell/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 000000000000..aa291ff16e58 --- /dev/null +++ b/samples/peripheral/802154_phy_test/sysbuild/remote_shell/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,8 @@ +# +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +CONFIG_BOARD_ENABLE_CPUNET=y +CONFIG_NRFX_UARTE0=y diff --git a/samples/peripheral/802154_phy_test/sysbuild/remote_shell/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/samples/peripheral/802154_phy_test/sysbuild/remote_shell/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 000000000000..8b878731fcbb --- /dev/null +++ b/samples/peripheral/802154_phy_test/sysbuild/remote_shell/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/delete-node/ &button0; +/delete-node/ &button1; +/delete-node/ &button2; +/delete-node/ &button3; +/delete-node/ &led0; +/delete-node/ &led1; +/delete-node/ &led2; +/delete-node/ &led3; + +/ { + chosen { + zephyr,shell-ipc = &ipc0; + ncs,remote-shell-uart = &uart136; + }; + + aliases { + /delete-property/ led0; + /delete-property/ led1; + /delete-property/ led2; + /delete-property/ led3; + /delete-property/ sw0; + /delete-property/ sw1; + /delete-property/ sw2; + /delete-property/ sw3; + }; +}; + +&pwm130 { + status = "disabled"; +}; + +&gpio9 { + status = "disabled"; +}; + +&gpio0 { + status = "disabled"; +}; diff --git a/samples/peripheral/802154_phy_test/sysbuild/remote_shell/prj.conf b/samples/peripheral/802154_phy_test/sysbuild/remote_shell/prj.conf index 81b263e42b68..2d7544a153c6 100644 --- a/samples/peripheral/802154_phy_test/sysbuild/remote_shell/prj.conf +++ b/samples/peripheral/802154_phy_test/sysbuild/remote_shell/prj.conf @@ -12,9 +12,6 @@ CONFIG_RING_BUFFER=y CONFIG_MBOX=y CONFIG_IPC_SERVICE=y -CONFIG_IPC_SERVICE_BACKEND_RPMSG=y - -CONFIG_NRFX_UARTE0=y CONFIG_HEAP_MEM_POOL_SIZE=4096 @@ -27,8 +24,6 @@ CONFIG_LOG_BACKEND_UART=n CONFIG_REMOTE_SHELL_TX_RING_BUFFER_SIZE=1024 -CONFIG_BOARD_ENABLE_CPUNET=y - # Enable application specific RPC operations CONFIG_APP_RPC=y CONFIG_REBOOT=y From 2e5e36f0c469d9fa72d3c6920b74d9f63b621441 Mon Sep 17 00:00:00 2001 From: Kamil Piszczek Date: Mon, 19 Aug 2024 13:10:57 +0200 Subject: [PATCH 29/72] bluetooth: fast_pair: Kconfig defaults cleanup Cleaned up the Bluetooth Fast Pair Kconfig file and removed the defaults from the Kconfig options that have a prompt. The Fast Pair builds now by default in the most minimial configuration. The Fast Pair use case layer selects now the necessary Kconfig options to satisfy the Fast Pair use case requirements. Ref: NCSDK-28101 Signed-off-by: Kamil Piszczek --- doc/nrf/external_comp/bt_fast_pair.rst | 9 ++-- .../bluetooth_services/services/fast_pair.rst | 17 ++------ .../releases/release-notes-changelog.rst | 19 ++++++++- .../locator_tag/configuration/prj.conf | 1 - .../configuration/prj_release.conf | 1 - .../services/fast_pair/Kconfig.fast_pair | 42 +++++-------------- 6 files changed, 35 insertions(+), 54 deletions(-) diff --git a/doc/nrf/external_comp/bt_fast_pair.rst b/doc/nrf/external_comp/bt_fast_pair.rst index 8c484c92a298..37044c987ab2 100644 --- a/doc/nrf/external_comp/bt_fast_pair.rst +++ b/doc/nrf/external_comp/bt_fast_pair.rst @@ -247,13 +247,12 @@ Apart from the callback registration and enabling the Fast Pair subsystem, no ad Personalized Name extension =========================== -To support the Personalized Name extension, ensure that the :kconfig:option:`CONFIG_BT_FAST_PAIR_PN` Kconfig option is enabled in your project. -This extension is enabled by default. +To support the Personalized Name extension, enable the :kconfig:option:`CONFIG_BT_FAST_PAIR_PN` Kconfig option in your project. FMDN extension ============== -Enable the :kconfig:option:`CONFIG_BT_FAST_PAIR_FMDN` Kconfig option to support the FMDN extension in your project. +To support the FMDN extension, enable the :kconfig:option:`CONFIG_BT_FAST_PAIR_FMDN` Kconfig option in your project. Managing the activation state ----------------------------- @@ -615,8 +614,8 @@ The Fast Pair specification allows the `Fast Pair Procedure`_ to operate in a sp In this mode, the Provider and Seeker skip the steps that involve Bluetooth pairing and bonding. In this case, the `Fast Pair Procedure`_ is only used to pass the Account Key from the Seeker to the Provider device. -You can disable the :kconfig:option:`CONFIG_BT_FAST_PAIR_REQ_PAIRING` configuration option to support the `Fast Pair Procedure`_ without Bluetooth pairing and bonding. -By default, the :kconfig:option:`CONFIG_BT_FAST_PAIR_REQ_PAIRING` configuration option is enabled, and the standard mode of the procedure is required by the Provider. +You can enable the :kconfig:option:`CONFIG_BT_FAST_PAIR_REQ_PAIRING` configuration option to restrict the `Fast Pair Procedure`_ and allow it to execute only with the Bluetooth pairing and bonding step. +By default, the :kconfig:option:`CONFIG_BT_FAST_PAIR_REQ_PAIRING` configuration option is disabled, and the procedure is not restricted by the Provider. Using the information callbacks =============================== diff --git a/doc/nrf/libraries/bluetooth_services/services/fast_pair.rst b/doc/nrf/libraries/bluetooth_services/services/fast_pair.rst index a7919192fee4..e335cfe537e8 100644 --- a/doc/nrf/libraries/bluetooth_services/services/fast_pair.rst +++ b/doc/nrf/libraries/bluetooth_services/services/fast_pair.rst @@ -39,22 +39,15 @@ The Fast Pair Service is enabled with :kconfig:option:`CONFIG_BT_FAST_PAIR` Kcon With the :kconfig:option:`CONFIG_BT_FAST_PAIR` Kconfig option enabled, the following Kconfig options are available for this service: * :kconfig:option:`CONFIG_BT_FAST_PAIR_GATT_SERVICE_MODEL_ID` - The option adds the Model ID characteristic to the Fast Pair GATT service. - It is enabled by default unless the :kconfig:option:`CONFIG_BT_FAST_PAIR_FMDN` Kconfig option is enabled. - This is done to align default configuration with `Fast Pair Device Feature Requirements for Locator Tags`_ documentation. * :kconfig:option:`CONFIG_BT_FAST_PAIR_REQ_PAIRING` - The option enforces the requirement for Bluetooth pairing and bonding during the `Fast Pair Procedure`_. - This option is enabled by default. See the :ref:`ug_bt_fast_pair_gatt_service_no_ble_pairing` for more details. * :kconfig:option:`CONFIG_BT_FAST_PAIR_SUBSEQUENT_PAIRING` - The option adds support for the Fast Pair subsequent pairing feature. - It is enabled by default unless the :kconfig:option:`CONFIG_BT_FAST_PAIR_FMDN` Kconfig option is enabled. - This aligns the default configuration with the `Fast Pair Device Feature Requirements for Locator Tags`_ documentation. * :kconfig:option:`CONFIG_BT_FAST_PAIR_STORAGE_USER_RESET_ACTION` - The option enables user reset action that is executed together with the Fast Pair factory reset operation. See the :ref:`ug_bt_fast_pair_factory_reset_custom_user_reset_action` for more details. * :kconfig:option:`CONFIG_BT_FAST_PAIR_STORAGE_ACCOUNT_KEY_MAX` - The option configures maximum number of stored Account Keys. * :kconfig:option:`CONFIG_BT_FAST_PAIR_CRYPTO_TINYCRYPT`, :kconfig:option:`CONFIG_BT_FAST_PAIR_CRYPTO_OBERON`, and :kconfig:option:`CONFIG_BT_FAST_PAIR_CRYPTO_PSA` - These options are used to select the cryptographic backend for Fast Pair. The Oberon backend is used by default. * :kconfig:option:`CONFIG_BT_FAST_PAIR_PN` - The option enables the `Fast Pair Personalized Name extension`_. - It is enabled by default unless the :kconfig:option:`CONFIG_BT_FAST_PAIR_FMDN` Kconfig option is enabled. - This is done to align default configuration with `Fast Pair Device Feature Requirements for Locator Tags`_ documentation. * :kconfig:option:`CONFIG_BT_FAST_PAIR_STORAGE_PN_LEN_MAX` - The option specifies the maximum length of a stored Fast Pair Personalized Name. @@ -137,16 +130,12 @@ The Fast Pair specification requires support for Bluetooth® Low Energy pairing Firmware Revision characteristic -------------------------------- -The Fast Pair specification requires enabling GATT Device Information Service and the Firmware Revision characteristic. -For this reason, the default values of the Kconfig options :kconfig:option:`CONFIG_BT_DIS` and :kconfig:option:`CONFIG_BT_DIS_FW_REV`, respectively, are set to enabled. -The default value of :kconfig:option:`CONFIG_BT_DIS_FW_REV_STR` is set to :kconfig:option:`CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION` if :kconfig:option:`CONFIG_BOOTLOADER_MCUBOOT` is enabled. -The option is enforced by sysbuild when ``SB_CONFIG_BOOTLOADER_MCUBOOT`` is enabled. +The Fast Pair specification requires enabling GATT Device Information Service and the Firmware Revision characteristic for selected Fast Pair use cases (for example, the input device use case). +For this reason, the relevant use case Kconfig options (for example, the :kconfig:option:`CONFIG_BT_FAST_PAIR_USE_CASE_INPUT_DEVICE` Kconfig option) select the :kconfig:option:`CONFIG_BT_DIS` and :kconfig:option:`CONFIG_BT_DIS_FW_REV` Kconfig options. +If the target project uses Zephyr's :ref:`application version management `, the default value of the :kconfig:option:`CONFIG_BT_DIS_FW_REV_STR` Kconfig option is set according to the versioning information found in the :file:`VERSION` file. Otherwise, it is set to ``0.0.0+0``. -This requirement does not apply for the locator tag use case as specified in the `Fast Pair Device Feature Requirements for Locator Tags`_ documentation. -As a result, these Kconfig overrides are not applied when the :kconfig:option:`CONFIG_BT_FAST_PAIR_FMDN` Kconfig option is enabled. - MTU configuration ----------------- diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index cf38e9c8af2e..e535837506dc 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -534,8 +534,23 @@ Bluetooth libraries and services * The :kconfig:option:`CONFIG_BT_FAST_PAIR_USE_CASE` Kconfig choice option allowing the user to select their target Fast Pair use case. The :kconfig:option:`CONFIG_BT_FAST_PAIR_USE_CASE_UNKNOWN`, :kconfig:option:`CONFIG_BT_FAST_PAIR_USE_CASE_INPUT_DEVICE`, :kconfig:option:`CONFIG_BT_FAST_PAIR_USE_CASE_LOCATOR_TAG` and :kconfig:option:`CONFIG_BT_FAST_PAIR_USE_CASE_MOUSE` Kconfig options represent the supported use cases that can be selected as part of this Kconfig choice option. - * Removed the MbedTLS cryptographic backend support in Fast Pair, because it is superseded by the PSA backend. - Consequently, the :kconfig:option:`CONFIG_BT_FAST_PAIR_CRYPTO_MBEDTLS` Kconfig option has also been removed. + * Removed: + + * The MbedTLS cryptographic backend support in Fast Pair, because it is superseded by the PSA backend. + Consequently, the :kconfig:option:`CONFIG_BT_FAST_PAIR_CRYPTO_MBEDTLS` Kconfig option has also been removed. + * The default overrides for the :kconfig:option:`CONFIG_BT_DIS` and :kconfig:option:`CONFIG_BT_DIS_FW_REV` Kconfig options that enable these options together with the Google Fast Pair Service. + This configuration is now selected only by the Fast Pair use cases that require the Device Information Service (DIS). + * The default override for the :kconfig:option:`CONFIG_BT_DIS_FW_REV_STR` Kconfig option that was set to :kconfig:option:`CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION` if :kconfig:option:`CONFIG_BOOTLOADER_MCUBOOT` was enabled. + The default override is now handled in the Kconfig of the Zephyr Device Information Service (DIS) module and is based on Zephyr's :ref:`zephyr:app-version-details` that uses the :file:`VERSION` file. + + * Updated the default values of the following Fast Pair Kconfig options: + + * :kconfig:option:`CONFIG_BT_FAST_PAIR_SUBSEQUENT_PAIRING` + * :kconfig:option:`CONFIG_BT_FAST_PAIR_REQ_PAIRING` + * :kconfig:option:`CONFIG_BT_FAST_PAIR_PN` + * :kconfig:option:`CONFIG_BT_FAST_PAIR_GATT_SERVICE_MODEL_ID` + + These Kconfig options are now disabled by default and are selected only by the Fast Pair use cases that require them. * :ref:`bt_le_adv_prov_readme`: diff --git a/samples/bluetooth/fast_pair/locator_tag/configuration/prj.conf b/samples/bluetooth/fast_pair/locator_tag/configuration/prj.conf index 04ae53cbcb07..3122fed7cc53 100644 --- a/samples/bluetooth/fast_pair/locator_tag/configuration/prj.conf +++ b/samples/bluetooth/fast_pair/locator_tag/configuration/prj.conf @@ -58,7 +58,6 @@ CONFIG_BT_EXT_ADV_MAX_ADV_SET=2 CONFIG_BT_FAST_PAIR=y CONFIG_BT_FAST_PAIR_USE_CASE_LOCATOR_TAG=y -CONFIG_BT_FAST_PAIR_REQ_PAIRING=n CONFIG_BT_FAST_PAIR_LOG_LEVEL_DBG=y CONFIG_BT_FAST_PAIR_STORAGE_USER_RESET_ACTION=y CONFIG_BT_FAST_PAIR_FMDN_BATTERY_DULT=y diff --git a/samples/bluetooth/fast_pair/locator_tag/configuration/prj_release.conf b/samples/bluetooth/fast_pair/locator_tag/configuration/prj_release.conf index 328b7255dafd..fd63b539eaa4 100644 --- a/samples/bluetooth/fast_pair/locator_tag/configuration/prj_release.conf +++ b/samples/bluetooth/fast_pair/locator_tag/configuration/prj_release.conf @@ -70,7 +70,6 @@ CONFIG_BT_EXT_ADV_MAX_ADV_SET=2 CONFIG_BT_FAST_PAIR=y CONFIG_BT_FAST_PAIR_USE_CASE_LOCATOR_TAG=y -CONFIG_BT_FAST_PAIR_REQ_PAIRING=n CONFIG_BT_FAST_PAIR_STORAGE_USER_RESET_ACTION=y CONFIG_BT_FAST_PAIR_FMDN_BATTERY_DULT=y CONFIG_BT_FAST_PAIR_FMDN_RING_COMP_THREE=y diff --git a/subsys/bluetooth/services/fast_pair/Kconfig.fast_pair b/subsys/bluetooth/services/fast_pair/Kconfig.fast_pair index 4749aa59ecfa..a9f69c395f7e 100644 --- a/subsys/bluetooth/services/fast_pair/Kconfig.fast_pair +++ b/subsys/bluetooth/services/fast_pair/Kconfig.fast_pair @@ -16,7 +16,6 @@ rsource "use_case/Kconfig" config BT_FAST_PAIR_SUBSEQUENT_PAIRING bool "Fast Pair subsequent pairing [EXPERIMENTAL]" - default y if !BT_FAST_PAIR_FMDN select EXPERIMENTAL help Enable support for the subsequent pairing feature. Subsequent pairing @@ -26,7 +25,6 @@ config BT_FAST_PAIR_SUBSEQUENT_PAIRING config BT_FAST_PAIR_REQ_PAIRING bool "Require Bluetooth Pairing during Fast Pair Procedure" - default y help Require the Bluetooth Pairing during the Fast Pair Procedure. With this option enabled, the Fast Pair modules rejects the Fast Pair @@ -34,7 +32,6 @@ config BT_FAST_PAIR_REQ_PAIRING config BT_FAST_PAIR_PN bool "Fast Pair Personalized Name extension [EXPERIMENTAL]" - default y if !BT_FAST_PAIR_FMDN select BT_FAST_PAIR_GATT_SERVICE_ADDITIONAL_DATA select BT_FAST_PAIR_STORAGE_PN select EXPERIMENTAL @@ -45,23 +42,6 @@ rsource "fp_crypto/Kconfig.fp_crypto" rsource "fp_storage/Kconfig.fp_storage" rsource "fmdn/Kconfig" -if !BT_FAST_PAIR_FMDN - -config BT_DIS - default y - -config BT_DIS_FW_REV - default y - help - Firmware revision characteristic is required by the Fast Pair specification. Enable it - by default if Fast Pair Service is enabled to simplify configuration. - -config BT_DIS_FW_REV_STR - default MCUBOOT_IMGTOOL_SIGN_VERSION if BOOTLOADER_MCUBOOT - default "0.0.0+0" - -endif # !BT_FAST_PAIR_FMDN - config BT_FAST_PAIR_ACTIVATION bool default y @@ -102,6 +82,17 @@ config BT_FAST_PAIR_GATT_SERVICE if BT_FAST_PAIR_GATT_SERVICE +config BT_FAST_PAIR_GATT_SERVICE_MODEL_ID + bool "Fast Pair Service's Model ID GATT characteristic" + help + Add Fast Pair Service's Model ID GATT characteristic. + +config BT_FAST_PAIR_GATT_SERVICE_ADDITIONAL_DATA + bool + help + Add Fast Pair Service's Additional Data GATT characteristic. + +# Override of the Bluetooth configuration defaults for the Google Fast Pair GATT service. config BT_GATT_AUTO_SEC_REQ default n help @@ -128,17 +119,6 @@ config BT_CTLR_DATA_LENGTH_MAX help If Fast Pair is enabled, use MTU value of 83 (recommended by the specification). -config BT_FAST_PAIR_GATT_SERVICE_MODEL_ID - bool "Fast Pair Service's Model ID GATT characteristic" - default y if !BT_FAST_PAIR_FMDN - help - Add Fast Pair Service's Model ID GATT characteristic. - -config BT_FAST_PAIR_GATT_SERVICE_ADDITIONAL_DATA - bool - help - Add Fast Pair Service's Additional Data GATT characteristic. - endif # BT_FAST_PAIR_GATT_SERVICE config BT_FAST_PAIR_REGISTRATION_DATA From 5e45476977c181a3a0a710269500e60f75980316 Mon Sep 17 00:00:00 2001 From: Kamil Piszczek Date: Mon, 19 Aug 2024 14:29:29 +0200 Subject: [PATCH 30/72] bluetooth: fast_pair: use_case: locator_tag: add restrictions Added restrictions for the unsupported Fast Pair features to the Fast Pair Locator Tag use case. Signed-off-by: Kamil Piszczek --- .../services/fast_pair/use_case/Kconfig | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/subsys/bluetooth/services/fast_pair/use_case/Kconfig b/subsys/bluetooth/services/fast_pair/use_case/Kconfig index d54dabd3d5c3..4854f93f77c0 100644 --- a/subsys/bluetooth/services/fast_pair/use_case/Kconfig +++ b/subsys/bluetooth/services/fast_pair/use_case/Kconfig @@ -42,6 +42,9 @@ config BT_FAST_PAIR_USE_CASE_LOCATOR_TAG bool "Locator tag use case" select BT_FAST_PAIR_FMDN select BT_FAST_PAIR_FMDN_DULT + select BT_FAST_PAIR_USE_CASE_UNSUPPORTED_GATT_SERVICE_MODEL_ID + select BT_FAST_PAIR_USE_CASE_UNSUPPORTED_SUBSEQUENT_PAIRING + select BT_FAST_PAIR_USE_CASE_UNSUPPORTED_PN help Select the locator tag Fast Pair use case. Locator tag is a small electronic device that can be attached to an object or a person, and is designed to help locate them in case @@ -67,3 +70,16 @@ config BT_FAST_PAIR_USE_CASE_MOUSE in the Google Fast Pair specification. endchoice + +# Collection of unsupported Fast Pair features that can be selected by the use case Kconfig. +config BT_FAST_PAIR_USE_CASE_UNSUPPORTED_GATT_SERVICE_MODEL_ID + bool + depends on !BT_FAST_PAIR_GATT_SERVICE_MODEL_ID + +config BT_FAST_PAIR_USE_CASE_UNSUPPORTED_SUBSEQUENT_PAIRING + bool + depends on !BT_FAST_PAIR_SUBSEQUENT_PAIRING + +config BT_FAST_PAIR_USE_CASE_UNSUPPORTED_PN + bool + depends on !BT_FAST_PAIR_PN From a64d7447469d04ddde5c25e69197ed03e003091a Mon Sep 17 00:00:00 2001 From: Marcin Kajor Date: Mon, 26 Aug 2024 12:23:16 +0200 Subject: [PATCH 31/72] manifest: pull Matter patch with additional WiFi log Print the log with the error code and failure reason. This might help when debugging WiFi connection failures. Signed-off-by: Marcin Kajor --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 0126de27e78f..21ceb18967b4 100644 --- a/west.yml +++ b/west.yml @@ -169,7 +169,7 @@ manifest: - name: matter repo-path: sdk-connectedhomeip path: modules/lib/matter - revision: b6d6e9a8885ce8390e1847e7a986ecbbdcbc277d + revision: 67cbbed0c3095608ef2aab88cf2473cb5d6fb06d west-commands: scripts/west/west-commands.yml submodules: - name: nlio From 80313b92565ff312f1b01b8f075f4bcfd857e018 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 1 Aug 2024 15:15:24 +0100 Subject: [PATCH 32/72] compress: Add lzma files Adds lzma decompression files taken from lamz2407.7z relating to lzma, the license for these files is as follows: LZMA SDK is written and placed in the public domain by Igor Pavlov. Some code in LZMA SDK is based on public domain code from another developers: 1) PPMd var.H (2001): Dmitry Shkarin 2) SHA-256: Wei Dai (Crypto++ library) Anyone is free to copy, modify, publish, use, compile, sell, or distribute the original LZMA SDK code, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. LZMA SDK code is compatible with open source licenses, for example, you can include it to GNU GPL or GNU LGPL code. Signed-off-by: Jamie McCrae --- subsys/nrf_compress/lzma/7zTypes.h | 571 +++++++++++ subsys/nrf_compress/lzma/Compiler.h | 226 +++++ subsys/nrf_compress/lzma/LICENSE | 12 + subsys/nrf_compress/lzma/Lzma2Dec.c | 485 +++++++++ subsys/nrf_compress/lzma/Lzma2Dec.h | 120 +++ subsys/nrf_compress/lzma/LzmaDec.c | 1418 +++++++++++++++++++++++++++ subsys/nrf_compress/lzma/LzmaDec.h | 234 +++++ subsys/nrf_compress/lzma/Precomp.h | 127 +++ 8 files changed, 3193 insertions(+) create mode 100644 subsys/nrf_compress/lzma/7zTypes.h create mode 100644 subsys/nrf_compress/lzma/Compiler.h create mode 100644 subsys/nrf_compress/lzma/LICENSE create mode 100644 subsys/nrf_compress/lzma/Lzma2Dec.c create mode 100644 subsys/nrf_compress/lzma/Lzma2Dec.h create mode 100644 subsys/nrf_compress/lzma/LzmaDec.c create mode 100644 subsys/nrf_compress/lzma/LzmaDec.h create mode 100644 subsys/nrf_compress/lzma/Precomp.h diff --git a/subsys/nrf_compress/lzma/7zTypes.h b/subsys/nrf_compress/lzma/7zTypes.h new file mode 100644 index 000000000000..21ebd45b69f4 --- /dev/null +++ b/subsys/nrf_compress/lzma/7zTypes.h @@ -0,0 +1,571 @@ +/* 7zTypes.h -- Basic types +2024-01-24 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_7Z_TYPES_H +#define ZIP7_7Z_TYPES_H + +#ifdef _WIN32 +/* #include */ +#else +#include +#endif + +#include + +#ifndef EXTERN_C_BEGIN +#ifdef __cplusplus +#define EXTERN_C_BEGIN extern "C" { +#define EXTERN_C_END } +#else +#define EXTERN_C_BEGIN +#define EXTERN_C_END +#endif +#endif + +EXTERN_C_BEGIN + +#define SZ_OK 0 + +#define SZ_ERROR_DATA 1 +#define SZ_ERROR_MEM 2 +#define SZ_ERROR_CRC 3 +#define SZ_ERROR_UNSUPPORTED 4 +#define SZ_ERROR_PARAM 5 +#define SZ_ERROR_INPUT_EOF 6 +#define SZ_ERROR_OUTPUT_EOF 7 +#define SZ_ERROR_READ 8 +#define SZ_ERROR_WRITE 9 +#define SZ_ERROR_PROGRESS 10 +#define SZ_ERROR_FAIL 11 +#define SZ_ERROR_THREAD 12 + +#define SZ_ERROR_ARCHIVE 16 +#define SZ_ERROR_NO_ARCHIVE 17 + +typedef int SRes; + +#ifdef _MSC_VER +#if _MSC_VER > 1200 +#define MY_ALIGN(n) __declspec(align(n)) +#else +#define MY_ALIGN(n) +#endif +#else +/* +// C11/C++11: +#include +#define MY_ALIGN(n) alignas(n) +*/ +#define MY_ALIGN(n) __attribute__((aligned(n))) +#endif + +#ifdef _WIN32 + +/* typedef DWORD WRes; */ +typedef unsigned WRes; +#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x) + +// #define MY_HRES_ERROR_INTERNAL_ERROR MY_SRes_HRESULT_FROM_WRes(ERROR_INTERNAL_ERROR) + +#else // _WIN32 + +// #define ENV_HAVE_LSTAT +typedef int WRes; + +// (FACILITY_ERRNO = 0x800) is 7zip's FACILITY constant to represent (errno) errors in HRESULT +#define MY_FACILITY_ERRNO 0x800 +#define MY_FACILITY_WIN32 7 +#define MY_FACILITY_WRes MY_FACILITY_ERRNO + +#define MY_HRESULT_FROM_errno_CONST_ERROR(x) \ + ((HRESULT)(((HRESULT)(x) & 0x0000FFFF) | (MY_FACILITY_WRes << 16) | (HRESULT)0x80000000)) + +#define MY_SRes_HRESULT_FROM_WRes(x) \ + ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : MY_HRESULT_FROM_errno_CONST_ERROR(x)) + +// we call macro HRESULT_FROM_WIN32 for system errors (WRes) that are (errno) +#define HRESULT_FROM_WIN32(x) MY_SRes_HRESULT_FROM_WRes(x) + +/* +#define ERROR_FILE_NOT_FOUND 2L +#define ERROR_ACCESS_DENIED 5L +#define ERROR_NO_MORE_FILES 18L +#define ERROR_LOCK_VIOLATION 33L +#define ERROR_FILE_EXISTS 80L +#define ERROR_DISK_FULL 112L +#define ERROR_NEGATIVE_SEEK 131L +#define ERROR_ALREADY_EXISTS 183L +#define ERROR_DIRECTORY 267L +#define ERROR_TOO_MANY_POSTS 298L + +#define ERROR_INTERNAL_ERROR 1359L +#define ERROR_INVALID_REPARSE_DATA 4392L +#define ERROR_REPARSE_TAG_INVALID 4393L +#define ERROR_REPARSE_TAG_MISMATCH 4394L +*/ + +// we use errno equivalents for some WIN32 errors: + +#define ERROR_INVALID_PARAMETER EINVAL +#define ERROR_INVALID_FUNCTION EINVAL +#define ERROR_ALREADY_EXISTS EEXIST +#define ERROR_FILE_EXISTS EEXIST +#define ERROR_PATH_NOT_FOUND ENOENT +#define ERROR_FILE_NOT_FOUND ENOENT +#define ERROR_DISK_FULL ENOSPC +// #define ERROR_INVALID_HANDLE EBADF + +// we use FACILITY_WIN32 for errors that has no errno equivalent +// Too many posts were made to a semaphore. +#define ERROR_TOO_MANY_POSTS ((HRESULT)0x8007012AL) +#define ERROR_INVALID_REPARSE_DATA ((HRESULT)0x80071128L) +#define ERROR_REPARSE_TAG_INVALID ((HRESULT)0x80071129L) + +// if (MY_FACILITY_WRes != FACILITY_WIN32), +// we use FACILITY_WIN32 for COM errors: +#define E_OUTOFMEMORY ((HRESULT)0x8007000EL) +#define E_INVALIDARG ((HRESULT)0x80070057L) +#define MY_E_ERROR_NEGATIVE_SEEK ((HRESULT)0x80070083L) + +/* +// we can use FACILITY_ERRNO for some COM errors, that have errno equivalents: +#define E_OUTOFMEMORY MY_HRESULT_FROM_errno_CONST_ERROR(ENOMEM) +#define E_INVALIDARG MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL) +#define MY_E_ERROR_NEGATIVE_SEEK MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL) +*/ + +#define TEXT(quote) quote + +#define FILE_ATTRIBUTE_READONLY 0x0001 +#define FILE_ATTRIBUTE_HIDDEN 0x0002 +#define FILE_ATTRIBUTE_SYSTEM 0x0004 +#define FILE_ATTRIBUTE_DIRECTORY 0x0010 +#define FILE_ATTRIBUTE_ARCHIVE 0x0020 +#define FILE_ATTRIBUTE_DEVICE 0x0040 +#define FILE_ATTRIBUTE_NORMAL 0x0080 +#define FILE_ATTRIBUTE_TEMPORARY 0x0100 +#define FILE_ATTRIBUTE_SPARSE_FILE 0x0200 +#define FILE_ATTRIBUTE_REPARSE_POINT 0x0400 +#define FILE_ATTRIBUTE_COMPRESSED 0x0800 +#define FILE_ATTRIBUTE_OFFLINE 0x1000 +#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x2000 +#define FILE_ATTRIBUTE_ENCRYPTED 0x4000 + +#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 /* trick for Unix */ + +#endif + +#ifndef RINOK +#define RINOK(x) \ + { \ + const int _result_ = (x); \ + if (_result_ != 0) \ + return _result_; \ + } +#endif + +#ifndef RINOK_WRes +#define RINOK_WRes(x) \ + { \ + const WRes _result_ = (x); \ + if (_result_ != 0) \ + return _result_; \ + } +#endif + +typedef unsigned char Byte; +typedef short Int16; +typedef unsigned short UInt16; + +#ifdef Z7_DECL_Int32_AS_long +typedef long Int32; +typedef unsigned long UInt32; +#else +typedef int Int32; +typedef unsigned int UInt32; +#endif + +#ifndef _WIN32 + +typedef int INT; +typedef Int32 INT32; +typedef unsigned int UINT; +typedef UInt32 UINT32; +typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit for _WIN32 compatibility +typedef UINT32 ULONG; + +#undef DWORD +typedef UINT32 DWORD; + +#define VOID void + +#define HRESULT LONG + +typedef void *LPVOID; +// typedef void VOID; +// typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; +// gcc / clang on Unix : sizeof(long==sizeof(void*) in 32 or 64 bits) +typedef long INT_PTR; +typedef unsigned long UINT_PTR; +typedef long LONG_PTR; +typedef unsigned long DWORD_PTR; + +typedef size_t SIZE_T; + +#endif // _WIN32 + +#define MY_HRES_ERROR_INTERNAL_ERROR ((HRESULT)0x8007054FL) + +#ifdef Z7_DECL_Int64_AS_long + +typedef long Int64; +typedef unsigned long UInt64; + +#else + +#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(__clang__) +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#else +#if defined(__clang__) || defined(__GNUC__) +#include +typedef int64_t Int64; +typedef uint64_t UInt64; +#else +typedef long long int Int64; +typedef unsigned long long int UInt64; +// #define UINT64_CONST(n) n ## ULL +#endif +#endif + +#endif + +#define UINT64_CONST(n) n + +#ifdef Z7_DECL_SizeT_AS_unsigned_int +typedef unsigned int SizeT; +#else +typedef size_t SizeT; +#endif + +/* +#if (defined(_MSC_VER) && _MSC_VER <= 1200) +typedef size_t MY_uintptr_t; +#else +#include +typedef uintptr_t MY_uintptr_t; +#endif +*/ + +typedef int BoolInt; +/* typedef BoolInt Bool; */ +#define True 1 +#define False 0 + +#ifdef _WIN32 +#define Z7_STDCALL __stdcall +#else +#define Z7_STDCALL +#endif + +#ifdef _MSC_VER + +#if _MSC_VER >= 1300 +#define Z7_NO_INLINE __declspec(noinline) +#else +#define Z7_NO_INLINE +#endif + +#define Z7_FORCE_INLINE __forceinline + +#define Z7_CDECL __cdecl +#define Z7_FASTCALL __fastcall + +#else // _MSC_VER + +#if (defined(__GNUC__) && (__GNUC__ >= 4)) || (defined(__clang__) && (__clang_major__ >= 4)) || \ + defined(__INTEL_COMPILER) || defined(__xlC__) +#define Z7_NO_INLINE __attribute__((noinline)) +#define Z7_FORCE_INLINE __attribute__((always_inline)) inline +#else +#define Z7_NO_INLINE +#define Z7_FORCE_INLINE +#endif + +#define Z7_CDECL + +#if defined(_M_IX86) || defined(__i386__) +// #define Z7_FASTCALL __attribute__((fastcall)) +// #define Z7_FASTCALL __attribute__((cdecl)) +#define Z7_FASTCALL +#elif defined(MY_CPU_AMD64) +// #define Z7_FASTCALL __attribute__((ms_abi)) +#define Z7_FASTCALL +#else +#define Z7_FASTCALL +#endif + +#endif // _MSC_VER + +/* The following interfaces use first parameter as pointer to structure */ + +// #define Z7_C_IFACE_CONST_QUAL +#define Z7_C_IFACE_CONST_QUAL const + +#define Z7_C_IFACE_DECL(a) \ + struct a##_; \ + typedef Z7_C_IFACE_CONST_QUAL struct a##_ *a##Ptr; \ + typedef struct a##_ a; \ + struct a##_ + +Z7_C_IFACE_DECL(IByteIn) +{ + Byte (*Read)(IByteInPtr p); /* reads one byte, returns 0 in case of EOF or error */ +}; +#define IByteIn_Read(p) (p)->Read(p) + +Z7_C_IFACE_DECL(IByteOut) +{ + void (*Write)(IByteOutPtr p, Byte b); +}; +#define IByteOut_Write(p, b) (p)->Write(p, b) + +Z7_C_IFACE_DECL(ISeqInStream) +{ + SRes (*Read)(ISeqInStreamPtr p, void *buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) < input(*size)) is allowed */ +}; +#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size) + +/* try to read as much as avail in stream and limited by (*processedSize) */ +SRes SeqInStream_ReadMax(ISeqInStreamPtr stream, void *buf, size_t *processedSize); +/* it can return SZ_ERROR_INPUT_EOF */ +// SRes SeqInStream_Read(ISeqInStreamPtr stream, void *buf, size_t size); +// SRes SeqInStream_Read2(ISeqInStreamPtr stream, void *buf, size_t size, SRes errorType); +SRes SeqInStream_ReadByte(ISeqInStreamPtr stream, Byte *buf); + +Z7_C_IFACE_DECL(ISeqOutStream) +{ + size_t (*Write)(ISeqOutStreamPtr p, const void *buf, size_t size); + /* Returns: result - the number of actually written bytes. + (result < size) means error */ +}; +#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size) + +typedef enum { + SZ_SEEK_SET = 0, + SZ_SEEK_CUR = 1, + SZ_SEEK_END = 2 +} ESzSeek; + +Z7_C_IFACE_DECL(ISeekInStream) +{ + SRes (*Read)(ISeekInStreamPtr p, void *buf, size_t *size); /* same as ISeqInStream::Read */ + SRes (*Seek)(ISeekInStreamPtr p, Int64 *pos, ESzSeek origin); +}; +#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size) +#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) + +Z7_C_IFACE_DECL(ILookInStream) +{ + SRes (*Look)(ILookInStreamPtr p, const void **buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) > input(*size)) is not allowed + (output(*size) < input(*size)) is allowed */ + SRes (*Skip)(ILookInStreamPtr p, size_t offset); + /* offset must be <= output(*size) of Look */ + SRes (*Read)(ILookInStreamPtr p, void *buf, size_t *size); + /* reads directly (without buffer). It's same as ISeqInStream::Read */ + SRes (*Seek)(ILookInStreamPtr p, Int64 *pos, ESzSeek origin); +}; + +#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size) +#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset) +#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size) +#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) + +SRes LookInStream_LookRead(ILookInStreamPtr stream, void *buf, size_t *size); +SRes LookInStream_SeekTo(ILookInStreamPtr stream, UInt64 offset); + +/* reads via ILookInStream::Read */ +SRes LookInStream_Read2(ILookInStreamPtr stream, void *buf, size_t size, SRes errorType); +SRes LookInStream_Read(ILookInStreamPtr stream, void *buf, size_t size); + +typedef struct { + ILookInStream vt; + ISeekInStreamPtr realStream; + + size_t pos; + size_t size; /* it's data size */ + + /* the following variables must be set outside */ + Byte *buf; + size_t bufSize; +} CLookToRead2; + +void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead); + +#define LookToRead2_INIT(p) \ + { \ + (p)->pos = (p)->size = 0; \ + } + +typedef struct { + ISeqInStream vt; + ILookInStreamPtr realStream; +} CSecToLook; + +void SecToLook_CreateVTable(CSecToLook *p); + +typedef struct { + ISeqInStream vt; + ILookInStreamPtr realStream; +} CSecToRead; + +void SecToRead_CreateVTable(CSecToRead *p); + +Z7_C_IFACE_DECL(ICompressProgress) +{ + SRes (*Progress)(ICompressProgressPtr p, UInt64 inSize, UInt64 outSize); + /* Returns: result. (result != SZ_OK) means break. + Value (UInt64)(Int64)-1 for size means unknown value. */ +}; + +#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize) + +typedef struct ISzAlloc ISzAlloc; +typedef const ISzAlloc *ISzAllocPtr; + +struct ISzAlloc { + void *(*Alloc)(ISzAllocPtr p, size_t size); + void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */ +}; + +#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size) +#define ISzAlloc_Free(p, a) (p)->Free(p, a) + +/* deprecated */ +#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size) +#define IAlloc_Free(p, a) ISzAlloc_Free(p, a) + +#ifndef MY_offsetof +#ifdef offsetof +#define MY_offsetof(type, m) offsetof(type, m) +/* +#define MY_offsetof(type, m) FIELD_OFFSET(type, m) +*/ +#else +#define MY_offsetof(type, m) ((size_t) & (((type *)0)->m)) +#endif +#endif + +#ifndef Z7_container_of + +/* +#define Z7_container_of(ptr, type, m) container_of(ptr, type, m) +#define Z7_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m) +#define Z7_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m))) +#define Z7_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - +MY_offsetof(type, m)))) +*/ + +/* + GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly" + GCC 3.4.4 : classes with constructor + GCC 4.8.1 : classes with non-public variable members" +*/ + +#define Z7_container_of(ptr, type, m) \ + ((type *)(void *)((char *)(void *)(1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) + +#define Z7_container_of_CONST(ptr, type, m) \ + ((const type *)(const void *)((const char *)(const void *)(1 ? (ptr) \ + : &((type *)NULL)->m) - \ + MY_offsetof(type, m))) + +/* +#define Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m) \ + ((type *)(void *)(const void *)((const char *)(const void *) \ + (1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) +*/ + +#endif + +#define Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(void *)(ptr)) + +// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +#define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of(ptr, type, m) +// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m) + +#define Z7_CONTAINER_FROM_VTBL_CONST(ptr, type, m) Z7_container_of_CONST(ptr, type, m) + +#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +/* +#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL(ptr, type, m) +*/ +#if defined(__clang__) || defined(__GNUC__) +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \ + _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") +#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL _Pragma("GCC diagnostic pop") +#else +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL +#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL +#endif + +#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(ptr, type, m, p) \ + Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \ + type *p = Z7_CONTAINER_FROM_VTBL(ptr, type, m); \ + Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL + +#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(type) \ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(pp, type, vt, p) + +// #define ZIP7_DECLARE_HANDLE(name) typedef void *name; +#define Z7_DECLARE_HANDLE(name) \ + struct name##_dummy { \ + int unused; \ + }; \ + typedef struct name##_dummy *name; + +#define Z7_memset_0_ARRAY(a) memset((a), 0, sizeof(a)) + +#ifndef Z7_ARRAY_SIZE +#define Z7_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#ifdef _WIN32 + +#define CHAR_PATH_SEPARATOR '\\' +#define WCHAR_PATH_SEPARATOR L'\\' +#define STRING_PATH_SEPARATOR "\\" +#define WSTRING_PATH_SEPARATOR L"\\" + +#else + +#define CHAR_PATH_SEPARATOR '/' +#define WCHAR_PATH_SEPARATOR L'/' +#define STRING_PATH_SEPARATOR "/" +#define WSTRING_PATH_SEPARATOR L"/" + +#endif + +#define k_PropVar_TimePrec_0 0 +#define k_PropVar_TimePrec_Unix 1 +#define k_PropVar_TimePrec_DOS 2 +#define k_PropVar_TimePrec_HighPrec 3 +#define k_PropVar_TimePrec_Base 16 +#define k_PropVar_TimePrec_100ns (k_PropVar_TimePrec_Base + 7) +#define k_PropVar_TimePrec_1ns (k_PropVar_TimePrec_Base + 9) + +EXTERN_C_END + +#endif + +/* +#ifndef Z7_ST +#ifdef _7ZIP_ST +#define Z7_ST +#endif +#endif +*/ diff --git a/subsys/nrf_compress/lzma/Compiler.h b/subsys/nrf_compress/lzma/Compiler.h new file mode 100644 index 000000000000..b7c385228e6a --- /dev/null +++ b/subsys/nrf_compress/lzma/Compiler.h @@ -0,0 +1,226 @@ +/* Compiler.h : Compiler specific defines and pragmas +2024-01-22 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_COMPILER_H +#define ZIP7_INC_COMPILER_H + +#if defined(__clang__) +#define Z7_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +#endif +#if defined(__clang__) && defined(__apple_build_version__) +#define Z7_APPLE_CLANG_VERSION Z7_CLANG_VERSION +#elif defined(__clang__) +#define Z7_LLVM_CLANG_VERSION Z7_CLANG_VERSION +#elif defined(__GNUC__) +#define Z7_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#ifdef _MSC_VER +#if !defined(__clang__) && !defined(__GNUC__) +#define Z7_MSC_VER_ORIGINAL _MSC_VER +#endif +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) +#define Z7_MINGW +#endif + +#if defined(__LCC__) && (defined(__MCST__) || defined(__e2k__)) +#define Z7_MCST_LCC +#define Z7_MCST_LCC_VERSION (__LCC__ * 100 + __LCC_MINOR__) +#endif + +/* +#if defined(__AVX2__) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) \ + || defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400) + #define Z7_COMPILER_AVX2_SUPPORTED + #endif +#endif +*/ + +// #pragma GCC diagnostic ignored "-Wunknown-pragmas" + +#ifdef __clang__ +// padding size of '' with 4 bytes to alignment boundary +#pragma GCC diagnostic ignored "-Wpadded" + +#if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13) && defined(__FreeBSD__) +// freebsd: +#pragma GCC diagnostic ignored "-Wexcess-padding" +#endif + +#if __clang_major__ >= 16 +#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage" +#endif + +#if __clang_major__ == 13 +#if defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16) +// cheri +#pragma GCC diagnostic ignored "-Wcapability-to-integer-cast" +#endif +#endif + +#if __clang_major__ == 13 +// for +#pragma GCC diagnostic ignored "-Wreserved-identifier" +#endif + +#endif // __clang__ + +#if defined(_WIN32) && defined(__clang__) && __clang_major__ >= 16 +// #pragma GCC diagnostic ignored "-Wcast-function-type-strict" +#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION \ + _Pragma("GCC diagnostic ignored \"-Wcast-function-type-strict\"") +#else +#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION +#endif + +typedef void (*Z7_void_Function)(void); +#if defined(__clang__) || defined(__GNUC__) +#define Z7_CAST_FUNC_C (Z7_void_Function) +#elif defined(_MSC_VER) && _MSC_VER > 1920 +#define Z7_CAST_FUNC_C (void *) +// #pragma warning(disable : 4191) // 'type cast': unsafe conversion from 'FARPROC' to 'void +// (__cdecl *)()' +#else +#define Z7_CAST_FUNC_C +#endif +/* +#if (defined(__GNUC__) && (__GNUC__ >= 8)) || defined(__clang__) + // #pragma GCC diagnostic ignored "-Wcast-function-type" +#endif +*/ +#ifdef __GNUC__ +#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40000) && (Z7_GCC_VERSION < 70000) +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif +#endif + +#ifdef _MSC_VER + +#ifdef UNDER_CE +#define RPC_NO_WINDOWS_H +/* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */ +#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union +#pragma warning(disable: 4214) // nonstandard extension used : bit field types other than int +#endif + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable: 4464) // relative include path contains '..' +#endif + +// == 1200 : -O1 : for __forceinline +// >= 1900 : -O1 : for printf +#pragma warning(disable: 4710) // function not inlined + +#if _MSC_VER < 1900 +// winnt.h: 'Int64ShllMod32' +#pragma warning(disable: 4514) // unreferenced inline function has been removed +#endif + +#if _MSC_VER < 1300 +// #pragma warning(disable : 4702) // unreachable code +// Bra.c : -O1: +#pragma warning(disable: 4714) // function marked as __forceinline not inlined +#endif + +/* +#if _MSC_VER > 1400 && _MSC_VER <= 1900 +// strcat: This function or variable may be unsafe +// sysinfoapi.h: kit10: GetVersion was declared deprecated +#pragma warning(disable : 4996) +#endif +*/ + +#if _MSC_VER > 1200 +// -Wall warnings + +#pragma warning(disable: 4711) // function selected for automatic inline expansion +#pragma warning(disable: 4820) // '2' bytes padding added after data member + +#if _MSC_VER >= 1400 && _MSC_VER < 1920 +// 1400: string.h: _DBG_MEMCPY_INLINE_ +// 1600 - 191x : smmintrin.h __cplusplus' +// is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' +#pragma warning(disable: 4668) + +// 1400 - 1600 : WinDef.h : 'FARPROC' : +// 1900 - 191x : immintrin.h: _readfsbase_u32 +// no function prototype given : converting '()' to '(void)' +#pragma warning(disable: 4255) +#endif + +#if _MSC_VER >= 1914 +// Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified +#pragma warning(disable: 5045) +#endif + +#endif // _MSC_VER > 1200 +#endif // _MSC_VER + +#if defined(__clang__) && (__clang_major__ >= 4) +#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + _Pragma("clang loop unroll(disable)") _Pragma("clang loop vectorize(disable)") +#define Z7_ATTRIB_NO_VECTORIZE +#elif defined(__GNUC__) && (__GNUC__ >= 5) && \ + (!defined(Z7_MCST_LCC_VERSION) || (Z7_MCST_LCC_VERSION >= 12610)) +#define Z7_ATTRIB_NO_VECTORIZE __attribute__((optimize("no-tree-vectorize"))) +// __attribute__((optimize("no-unroll-loops"))); +#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE +#elif defined(_MSC_VER) && (_MSC_VER >= 1920) +#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE _Pragma("loop( no_vector )") +#define Z7_ATTRIB_NO_VECTORIZE +#else +#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE +#define Z7_ATTRIB_NO_VECTORIZE +#endif + +#if defined(MY_CPU_X86_OR_AMD64) && \ + (defined(__clang__) && (__clang_major__ >= 4) || defined(__GNUC__) && (__GNUC__ >= 5)) +#define Z7_ATTRIB_NO_SSE __attribute__((__target__("no-sse"))) +#else +#define Z7_ATTRIB_NO_SSE +#endif + +#define Z7_ATTRIB_NO_VECTOR \ + Z7_ATTRIB_NO_VECTORIZE \ + Z7_ATTRIB_NO_SSE + +#if defined(__clang__) && (__clang_major__ >= 8) || defined(__GNUC__) && (__GNUC__ >= 1000) +/* || defined(_MSC_VER) && (_MSC_VER >= 1920) */ +// GCC is not good for __builtin_expect() +#define Z7_LIKELY(x) (__builtin_expect((x), 1)) +#define Z7_UNLIKELY(x) (__builtin_expect((x), 0)) +// #define Z7_unlikely [[unlikely]] +// #define Z7_likely [[likely]] +#else +#define Z7_LIKELY(x) (x) +#define Z7_UNLIKELY(x) (x) +// #define Z7_likely +#endif + +#if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30600)) + +#if (Z7_CLANG_VERSION < 130000) +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \ + _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wreserved-id-macro\"") +#else +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreserved-macro-identifier\"") +#endif + +#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER _Pragma("GCC diagnostic pop") +#else +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif + +#define UNUSED_VAR(x) (void)x; +/* #define UNUSED_VAR(x) x=x; */ + +#endif diff --git a/subsys/nrf_compress/lzma/LICENSE b/subsys/nrf_compress/lzma/LICENSE new file mode 100644 index 000000000000..69d143b636c3 --- /dev/null +++ b/subsys/nrf_compress/lzma/LICENSE @@ -0,0 +1,12 @@ +LZMA SDK is written and placed in the public domain by Igor Pavlov. + +Some code in LZMA SDK is based on public domain code from another developers: + 1) PPMd var.H (2001): Dmitry Shkarin + 2) SHA-256: Wei Dai (Crypto++ library) + +Anyone is free to copy, modify, publish, use, compile, sell, or distribute the +original LZMA SDK code, either in source code form or as a compiled binary, for +any purpose, commercial or non-commercial, and by any means. + +LZMA SDK code is compatible with open source licenses, for example, you can +include it to GNU GPL or GNU LGPL code. diff --git a/subsys/nrf_compress/lzma/Lzma2Dec.c b/subsys/nrf_compress/lzma/Lzma2Dec.c new file mode 100644 index 000000000000..4727043be6f5 --- /dev/null +++ b/subsys/nrf_compress/lzma/Lzma2Dec.c @@ -0,0 +1,485 @@ +/* Lzma2Dec.c -- LZMA2 Decoder +2024-03-01 : Igor Pavlov : Public domain */ + +/* #define SHOW_DEBUG_INFO */ + +#include "Precomp.h" + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#include + +#include "Lzma2Dec.h" + +/* +00000000 - End of data +00000001 U U - Uncompressed, reset dic, need reset state and set new prop +00000010 U U - Uncompressed, no reset +100uuuuu U U P P - LZMA, no reset +101uuuuu U U P P - LZMA, reset state +110uuuuu U U P P S - LZMA, reset state + set new prop +111uuuuu U U P P S - LZMA, reset state + set new prop, reset dic + + u, U - Unpack Size + P - Pack Size + S - Props +*/ + +#define LZMA2_CONTROL_COPY_RESET_DIC 1 + +#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0) + +#define LZMA2_LCLP_MAX 4 +#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +typedef enum { + LZMA2_STATE_CONTROL, + LZMA2_STATE_UNPACK0, + LZMA2_STATE_UNPACK1, + LZMA2_STATE_PACK0, + LZMA2_STATE_PACK1, + LZMA2_STATE_PROP, + LZMA2_STATE_DATA, + LZMA2_STATE_DATA_CONT, + LZMA2_STATE_FINISHED, + LZMA2_STATE_ERROR +} ELzma2State; + +static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) +{ + UInt32 dicSize; + if (prop > 40) { + return SZ_ERROR_UNSUPPORTED; + } + dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); + props[0] = (Byte)LZMA2_LCLP_MAX; + props[1] = (Byte)(dicSize); + props[2] = (Byte)(dicSize >> 8); + props[3] = (Byte)(dicSize >> 16); + props[4] = (Byte)(dicSize >> 24); + return SZ_OK; +} + +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) +{ + Byte props[LZMA_PROPS_SIZE]; + RINOK(Lzma2Dec_GetOldProps(prop, props)) + return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); +} + +SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) +{ + Byte props[LZMA_PROPS_SIZE]; + RINOK(Lzma2Dec_GetOldProps(prop, props)) + return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); +} + +void Lzma2Dec_Init(CLzma2Dec *p) +{ + p->state = LZMA2_STATE_CONTROL; + p->needInitLevel = 0xE0; + p->isExtraMode = False; + p->unpackSize = 0; + + // p->decoder.dicPos = 0; // we can use it instead of full init + LzmaDec_Init(&p->decoder); +} + +// ELzma2State +static unsigned Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) +{ + switch (p->state) { + case LZMA2_STATE_CONTROL: + p->isExtraMode = False; + p->control = b; + PRF(printf("\n %8X", (unsigned)p->decoder.dicPos)); + PRF(printf(" %02X", (unsigned)b)); + if (b == 0) { + return LZMA2_STATE_FINISHED; + } + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) { + if (b == LZMA2_CONTROL_COPY_RESET_DIC) { + p->needInitLevel = 0xC0; + } else if (b > 2 || p->needInitLevel == 0xE0) { + return LZMA2_STATE_ERROR; + } + } else { + if (b < p->needInitLevel) { + return LZMA2_STATE_ERROR; + } + p->needInitLevel = 0; + p->unpackSize = (UInt32)(b & 0x1F) << 16; + } + return LZMA2_STATE_UNPACK0; + + case LZMA2_STATE_UNPACK0: + p->unpackSize |= (UInt32)b << 8; + return LZMA2_STATE_UNPACK1; + + case LZMA2_STATE_UNPACK1: + p->unpackSize |= (UInt32)b; + p->unpackSize++; + PRF(printf(" %7u", (unsigned)p->unpackSize)); + return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; + + case LZMA2_STATE_PACK0: + p->packSize = (UInt32)b << 8; + return LZMA2_STATE_PACK1; + + case LZMA2_STATE_PACK1: + p->packSize |= (UInt32)b; + p->packSize++; + // if (p->packSize < 5) return LZMA2_STATE_ERROR; + PRF(printf(" %5u", (unsigned)p->packSize)); + return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA; + + case LZMA2_STATE_PROP: { + unsigned lc, lp; + if (b >= (9 * 5 * 5)) { + return LZMA2_STATE_ERROR; + } + lc = b % 9; + b /= 9; + p->decoder.prop.pb = (Byte)(b / 5); + lp = b % 5; + if (lc + lp > LZMA2_LCLP_MAX) { + return LZMA2_STATE_ERROR; + } + p->decoder.prop.lc = (Byte)lc; + p->decoder.prop.lp = (Byte)lp; + return LZMA2_STATE_DATA; + } + + default: + return LZMA2_STATE_ERROR; + } +} + +static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size) +{ + memcpy(p->dic + p->dicPos, src, size); + p->dicPos += size; + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) { + p->checkDicSize = p->prop.dicSize; + } + p->processedPos += (UInt32)size; +} + +void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState); + +SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT inSize = *srcLen; + *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + + while (p->state != LZMA2_STATE_ERROR) { + SizeT dicPos; + + if (p->state == LZMA2_STATE_FINISHED) { + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return SZ_OK; + } + + dicPos = p->decoder.dicPos; + + if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + + if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) { + if (*srcLen == inSize) { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + (*srcLen)++; + p->state = Lzma2Dec_UpdateState(p, *src++); + if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED) { + break; + } + continue; + } + + { + SizeT inCur = inSize - *srcLen; + SizeT outCur = dicLimit - dicPos; + ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; + + if (outCur >= p->unpackSize) { + outCur = (SizeT)p->unpackSize; + curFinishMode = LZMA_FINISH_END; + } + + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) { + if (inCur == 0) { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + if (p->state == LZMA2_STATE_DATA) { + BoolInt initDic = + (p->control == LZMA2_CONTROL_COPY_RESET_DIC); + LzmaDec_InitDicAndState(&p->decoder, initDic, False); + } + + if (inCur > outCur) { + inCur = outCur; + } + if (inCur == 0) { + break; + } + + LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur); + + src += inCur; + *srcLen += inCur; + p->unpackSize -= (UInt32)inCur; + p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL + : LZMA2_STATE_DATA_CONT; + } else { + SRes res; + + if (p->state == LZMA2_STATE_DATA) { + BoolInt initDic = (p->control >= 0xE0); + BoolInt initState = (p->control >= 0xA0); + LzmaDec_InitDicAndState(&p->decoder, initDic, initState); + p->state = LZMA2_STATE_DATA_CONT; + } + + if (inCur > p->packSize) { + inCur = (SizeT)p->packSize; + } + + res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, + curFinishMode, status); + + src += inCur; + *srcLen += inCur; + p->packSize -= (UInt32)inCur; + outCur = p->decoder.dicPos - dicPos; + p->unpackSize -= (UInt32)outCur; + + if (res != 0) { + break; + } + + if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) { + if (p->packSize == 0) { + break; + } + return SZ_OK; + } + + if (inCur == 0 && outCur == 0) { + if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || + p->unpackSize != 0 || p->packSize != 0) { + break; + } + p->state = LZMA2_STATE_CONTROL; + } + + *status = LZMA_STATUS_NOT_SPECIFIED; + } + } + } + + *status = LZMA_STATUS_NOT_SPECIFIED; + p->state = LZMA2_STATE_ERROR; + return SZ_ERROR_DATA; +} + +ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p, SizeT outSize, const Byte *src, SizeT *srcLen, + int checkFinishBlock) +{ + SizeT inSize = *srcLen; + *srcLen = 0; + + while (p->state != LZMA2_STATE_ERROR) { + if (p->state == LZMA2_STATE_FINISHED) { + return (ELzma2ParseStatus)LZMA_STATUS_FINISHED_WITH_MARK; + } + + if (outSize == 0 && !checkFinishBlock) { + return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED; + } + + if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) { + if (*srcLen == inSize) { + return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT; + } + (*srcLen)++; + + p->state = Lzma2Dec_UpdateState(p, *src++); + + if (p->state == LZMA2_STATE_UNPACK0) { + // if (p->decoder.dicPos != 0) + if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || + p->control >= 0xE0) { + return LZMA2_PARSE_STATUS_NEW_BLOCK; + } + // if (outSize == 0) return LZMA_STATUS_NOT_FINISHED; + } + + // The following code can be commented. + // It's not big problem, if we read additional input bytes. + // It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT + // state. + + if (outSize == 0 && p->state != LZMA2_STATE_FINISHED) { + // checkFinishBlock is true. So we expect that block must be + // finished, We can return LZMA_STATUS_NOT_SPECIFIED or + // LZMA_STATUS_NOT_FINISHED here break; + return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED; + } + + if (p->state == LZMA2_STATE_DATA) { + return LZMA2_PARSE_STATUS_NEW_CHUNK; + } + + continue; + } + + if (outSize == 0) { + return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED; + } + + { + SizeT inCur = inSize - *srcLen; + + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) { + if (inCur == 0) { + return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT; + } + if (inCur > p->unpackSize) { + inCur = p->unpackSize; + } + if (inCur > outSize) { + inCur = outSize; + } + p->decoder.dicPos += inCur; + src += inCur; + *srcLen += inCur; + outSize -= inCur; + p->unpackSize -= (UInt32)inCur; + p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL + : LZMA2_STATE_DATA_CONT; + } else { + p->isExtraMode = True; + + if (inCur == 0) { + if (p->packSize != 0) { + return (ELzma2ParseStatus) + LZMA_STATUS_NEEDS_MORE_INPUT; + } + } else if (p->state == LZMA2_STATE_DATA) { + p->state = LZMA2_STATE_DATA_CONT; + if (*src != 0) { + // first byte of lzma chunk must be Zero + *srcLen += 1; + p->packSize--; + break; + } + } + + if (inCur > p->packSize) { + inCur = (SizeT)p->packSize; + } + + src += inCur; + *srcLen += inCur; + p->packSize -= (UInt32)inCur; + + if (p->packSize == 0) { + SizeT rem = outSize; + if (rem > p->unpackSize) { + rem = p->unpackSize; + } + p->decoder.dicPos += rem; + p->unpackSize -= (UInt32)rem; + outSize -= rem; + if (p->unpackSize == 0) { + p->state = LZMA2_STATE_CONTROL; + } + } + } + } + } + + p->state = LZMA2_STATE_ERROR; + return (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED; +} + +SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT outSize = *destLen, inSize = *srcLen; + *srcLen = *destLen = 0; + + for (;;) { + SizeT inCur = inSize, outCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + + if (p->decoder.dicPos == p->decoder.dicBufSize) { + p->decoder.dicPos = 0; + } + dicPos = p->decoder.dicPos; + curFinishMode = LZMA_FINISH_ANY; + outCur = p->decoder.dicBufSize - dicPos; + + if (outCur >= outSize) { + outCur = outSize; + curFinishMode = finishMode; + } + + res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status); + + src += inCur; + inSize -= inCur; + *srcLen += inCur; + outCur = p->decoder.dicPos - dicPos; + memcpy(dest, p->decoder.dic + dicPos, outCur); + dest += outCur; + outSize -= outCur; + *destLen += outCur; + if (res != 0) { + return res; + } + if (outCur == 0 || outSize == 0) { + return SZ_OK; + } + } +} + +SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, Byte prop, + ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc) +{ + CLzma2Dec p; + SRes res; + SizeT outSize = *destLen, inSize = *srcLen; + *destLen = *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + Lzma2Dec_CONSTRUCT(&p) RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)) p.decoder.dic = dest; + p.decoder.dicBufSize = outSize; + Lzma2Dec_Init(&p); + *srcLen = inSize; + res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + *destLen = p.decoder.dicPos; + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) { + res = SZ_ERROR_INPUT_EOF; + } + Lzma2Dec_FreeProbs(&p, alloc); + return res; +} + +#undef PRF diff --git a/subsys/nrf_compress/lzma/Lzma2Dec.h b/subsys/nrf_compress/lzma/Lzma2Dec.h new file mode 100644 index 000000000000..9f87f932172d --- /dev/null +++ b/subsys/nrf_compress/lzma/Lzma2Dec.h @@ -0,0 +1,120 @@ +/* Lzma2Dec.h -- LZMA2 Decoder +2023-03-03 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZMA2_DEC_H +#define ZIP7_INC_LZMA2_DEC_H + +#include "LzmaDec.h" + +EXTERN_C_BEGIN + +/* ---------- State Interface ---------- */ + +typedef struct { + unsigned state; + Byte control; + Byte needInitLevel; + Byte isExtraMode; + Byte _pad_; + UInt32 packSize; + UInt32 unpackSize; + CLzmaDec decoder; +} CLzma2Dec; + +#define Lzma2Dec_CONSTRUCT(p) LzmaDec_CONSTRUCT(&(p)->decoder) +#define Lzma2Dec_Construct(p) Lzma2Dec_CONSTRUCT(p) +#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc) +#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc) + +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); +SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); +void Lzma2Dec_Init(CLzma2Dec *p); + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen or dicLimit). + LZMA_FINISH_ANY - use smallest number of input bytes + LZMA_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + SZ_ERROR_DATA - Data error +*/ + +SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status); + +SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status); + +/* ---------- LZMA2 block and chunk parsing ---------- */ + +/* +Lzma2Dec_Parse() parses compressed data stream up to next independent block or next chunk data. +It can return LZMA_STATUS_* code or LZMA2_PARSE_STATUS_* code: + - LZMA2_PARSE_STATUS_NEW_BLOCK - there is new block, and 1 additional byte (control byte of next +block header) was read from input. + - LZMA2_PARSE_STATUS_NEW_CHUNK - there is new chunk, and only lzma2 header of new chunk was read. + CLzma2Dec::unpackSize contains unpack size of that chunk +*/ + +typedef enum { + /* + LZMA_STATUS_NOT_SPECIFIED // data error + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED // + LZMA_STATUS_NEEDS_MORE_INPUT + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK // unused + */ + LZMA2_PARSE_STATUS_NEW_BLOCK = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + 1, + LZMA2_PARSE_STATUS_NEW_CHUNK +} ELzma2ParseStatus; + +ELzma2ParseStatus +Lzma2Dec_Parse(CLzma2Dec *p, + SizeT outSize, // output size + const Byte *src, SizeT *srcLen, + int checkFinishBlock // set (checkFinishBlock = 1), if it must read full input data, + // if decoder.dicPos reaches blockMax position. +); + +/* +LZMA2 parser doesn't decode LZMA chunks, so we must read + full input LZMA chunk to decode some part of LZMA chunk. + +Lzma2Dec_GetUnpackExtra() returns the value that shows + max possible number of output bytes that can be output by decoder + at current input positon. +*/ + +#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0) + +/* ---------- One Call Interface ---------- */ + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - use smallest number of input bytes + LZMA_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +*/ + +SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, Byte prop, + ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc); + +EXTERN_C_END + +#endif diff --git a/subsys/nrf_compress/lzma/LzmaDec.c b/subsys/nrf_compress/lzma/LzmaDec.c new file mode 100644 index 000000000000..34e73bebf515 --- /dev/null +++ b/subsys/nrf_compress/lzma/LzmaDec.c @@ -0,0 +1,1418 @@ +/* LzmaDec.c -- LZMA Decoder +2023-04-07 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +/* #include "CpuArch.h" */ +#include "LzmaDec.h" + +// #define kNumTopBits 24 +#define kTopValue ((UInt32)1 << 24) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) + +#define RC_INIT_SIZE 5 + +#ifndef Z7_LZMA_DEC_OPT + +#define kNumMoveBits 5 +#define NORMALIZE \ + if (range < kTopValue) { \ + range <<= 8; \ + code = (code << 8) | (*buf++); \ + } + +#define IF_BIT_0(p) \ + ttt = *(p); \ + NORMALIZE; \ + bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; \ + if (code < bound) +#define UPDATE_0(p) \ + range = bound; \ + *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); +#define UPDATE_1(p) \ + range -= bound; \ + code -= bound; \ + *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); +#define GET_BIT2(p, i, A0, A1) \ + IF_BIT_0(p) \ + { \ + UPDATE_0(p) i = (i + i); \ + A0; \ + } \ + else \ + { \ + UPDATE_1(p) i = (i + i) + 1; \ + A1; \ + } + +#define TREE_GET_BIT(probs, i) \ + { \ + GET_BIT2(probs + i, i, ;, ;); \ + } + +#define REV_BIT(p, i, A0, A1) \ + IF_BIT_0(p + i) \ + { \ + UPDATE_0(p + i) A0; \ + } \ + else \ + { \ + UPDATE_1(p + i) A1; \ + } +#define REV_BIT_VAR(p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m;) +#define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m;, i += m * 2;) +#define REV_BIT_LAST(p, i, m) REV_BIT(p, i, i -= m, ;) + +#define TREE_DECODE(probs, limit, i) \ + { \ + i = 1; \ + do { \ + TREE_GET_BIT(probs, i); \ + } while (i < limit); \ + i -= limit; \ + } + +/* #define Z7_LZMA_SIZE_OPT */ + +#ifdef Z7_LZMA_SIZE_OPT +#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) +#else +#define TREE_6_DECODE(probs, i) \ + { \ + i = 1; \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + i -= 0x40; \ + } +#endif + +#define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol) +#define MATCHED_LITER_DEC \ + matchByte += matchByte; \ + bit = offs; \ + offs &= matchByte; \ + probLit = prob + (offs + bit + symbol); \ + GET_BIT2(probLit, symbol, offs ^= bit;, ;) + +#endif // Z7_LZMA_DEC_OPT + +#define NORMALIZE_CHECK \ + if (range < kTopValue) { \ + if (buf >= bufLimit) \ + return DUMMY_INPUT_EOF; \ + range <<= 8; \ + code = (code << 8) | (*buf++); \ + } + +#define IF_BIT_0_CHECK(p) \ + ttt = *(p); \ + NORMALIZE_CHECK bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; \ + if (code < bound) +#define UPDATE_0_CHECK range = bound; +#define UPDATE_1_CHECK \ + range -= bound; \ + code -= bound; +#define GET_BIT2_CHECK(p, i, A0, A1) \ + IF_BIT_0_CHECK(p) \ + { \ + UPDATE_0_CHECK i = (i + i); \ + A0; \ + } \ + else \ + { \ + UPDATE_1_CHECK i = (i + i) + 1; \ + A1; \ + } +#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ;, ;) +#define TREE_DECODE_CHECK(probs, limit, i) \ + { \ + i = 1; \ + do { \ + GET_BIT_CHECK(probs + i, i) \ + } while (i < limit); \ + i -= limit; \ + } + +#define REV_BIT_CHECK(p, i, m) \ + IF_BIT_0_CHECK(p + i) \ + { \ + UPDATE_0_CHECK i += m; \ + m += m; \ + } \ + else \ + { \ + UPDATE_1_CHECK m += m; \ + i += m; \ + } + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenLow 0 +#define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + +#define LenChoice LenLow +#define LenChoice2 (LenLow + (1 << kLenNumLowBits)) + +#define kNumStates 12 +#define kNumStates2 16 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 +#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols) + +#define kMatchSpecLen_Error_Data (1 << 9) +#define kMatchSpecLen_Error_Fail (kMatchSpecLen_Error_Data - 1) + +/* External ASM code needs same CLzmaProb array layout. So don't change it. */ + +/* (probs_1664) is faster and better for code size at some platforms */ +/* +#ifdef MY_CPU_X86_OR_AMD64 +*/ +#define kStartOffset 1664 +#define GET_PROBS p->probs_1664 +/* +#define GET_PROBS p->probs + kStartOffset +#else +#define kStartOffset 0 +#define GET_PROBS p->probs +#endif +*/ + +#define SpecPos (-kStartOffset) +#define IsRep0Long (SpecPos + kNumFullDistances) +#define RepLenCoder (IsRep0Long + (kNumStates2 << kNumPosBitsMax)) +#define LenCoder (RepLenCoder + kNumLenProbs) +#define IsMatch (LenCoder + kNumLenProbs) +#define Align (IsMatch + (kNumStates2 << kNumPosBitsMax)) +#define IsRep (Align + kAlignTableSize) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define PosSlot (IsRepG2 + kNumStates) +#define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define NUM_BASE_PROBS (Literal + kStartOffset) + +#if Align != 0 && kStartOffset != 0 +#error Stop_Compiling_Bad_LZMA_kAlign +#endif + +#if NUM_BASE_PROBS != 1984 +#error Stop_Compiling_Bad_LZMA_PROBS +#endif + +#define LZMA_LIT_SIZE 0x300 + +#define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) + +#define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4) +#define COMBINED_PS_STATE (posState + state) +#define GET_LEN_STATE (posState) + +#define LZMA_DIC_MIN (1 << 12) + +/* +p->remainLen : shows status of LZMA decoder: + < kMatchSpecLenStart : the number of bytes to be copied with (p->rep0) offset + = kMatchSpecLenStart : the LZMA stream was finished with end mark + = kMatchSpecLenStart + 1 : need init range coder + = kMatchSpecLenStart + 2 : need init range coder and state + = kMatchSpecLen_Error_Fail : Internal Code Failure + = kMatchSpecLen_Error_Data + [0 ... 273] : LZMA Data Error +*/ + +/* ---------- LZMA_DECODE_REAL ---------- */ +/* +LzmaDec_DecodeReal_3() can be implemented in external ASM file. +3 - is the code compatibility version of that function for check at link time. +*/ + +#define LZMA_DECODE_REAL LzmaDec_DecodeReal_3 + +/* +LZMA_DECODE_REAL() +In: + RangeCoder is normalized + if (p->dicPos == limit) + { + LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases. + So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol + is not END_OF_PAYALOAD_MARKER, then the function doesn't write any byte to dictionary, + the function returns SZ_OK, and the caller can use (p->remainLen) and (p->reps[0]) later. + } + +Processing: + The first LZMA symbol will be decoded in any case. + All main checks for limits are at the end of main loop, + It decodes additional LZMA-symbols while (p->buf < bufLimit && dicPos < limit), + RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked. + But if (p->buf < bufLimit), the caller provided at least (LZMA_REQUIRED_INPUT_MAX + 1) bytes for + next iteration before limit (bufLimit + LZMA_REQUIRED_INPUT_MAX), + that is enough for worst case LZMA symbol with one additional RangeCoder normalization for one +bit. So that function never reads bufLimit [LZMA_REQUIRED_INPUT_MAX] byte. + +Out: + RangeCoder is normalized + Result: + SZ_OK - OK + p->remainLen: + < kMatchSpecLenStart : the number of bytes to be copied with (p->reps[0]) offset + = kMatchSpecLenStart : the LZMA stream was finished with end mark + + SZ_ERROR_DATA - error, when the MATCH-Symbol refers out of dictionary + p->remainLen : undefined + p->reps[*] : undefined +*/ + +#ifdef Z7_LZMA_DEC_OPT + +int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit); + +#else + +static int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + CLzmaProb *probs = GET_PROBS; + unsigned state = (unsigned)p->state; + UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; + unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; + unsigned lc = p->prop.lc; + unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc); + + Byte *dic = p->dic; + SizeT dicBufSize = p->dicBufSize; + SizeT dicPos = p->dicPos; + + UInt32 processedPos = p->processedPos; + UInt32 checkDicSize = p->checkDicSize; + unsigned len = 0; + + const Byte *buf = p->buf; + UInt32 range = p->range; + UInt32 code = p->code; + + do { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = CALC_POS_STATE(processedPos, pbMask); + + prob = probs + IsMatch + COMBINED_PS_STATE; + IF_BIT_0(prob) + { + unsigned symbol; + UPDATE_0(prob) + prob = probs + Literal; + if (processedPos != 0 || checkDicSize != 0) { + prob += (UInt32)3 * + ((((processedPos << 8) + + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & + lpMask) + << lc); + } + processedPos++; + + if (state < kNumLitStates) { + state -= (state < 4) ? state : 3; + symbol = 1; +#ifdef Z7_LZMA_SIZE_OPT + do { + NORMAL_LITER_DEC + } while (symbol < 0x100); +#else + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC +#endif + } else { + unsigned matchByte = + dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + unsigned offs = 0x100; + state -= (state < 10) ? 3 : 6; + symbol = 1; +#ifdef Z7_LZMA_SIZE_OPT + do { + unsigned bit; + CLzmaProb *probLit; + MATCHED_LITER_DEC + } while (symbol < 0x100); +#else + { + unsigned bit; + CLzmaProb *probLit; + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + } +#endif + } + + dic[dicPos++] = (Byte)symbol; + continue; + } + + { + UPDATE_1(prob) + prob = probs + IsRep + state; + IF_BIT_0(prob) + { + UPDATE_0(prob) + state += kNumStates; + prob = probs + LenCoder; + } + else + { + UPDATE_1(prob) + prob = probs + IsRepG0 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob) + prob = probs + IsRep0Long + COMBINED_PS_STATE; + IF_BIT_0(prob) + { + UPDATE_0(prob) + + // that case was checked before with kBadRepCode + // if (checkDicSize == 0 && processedPos == 0) { len + // = kMatchSpecLen_Error_Data + 1; break; } The + // caller doesn't allow (dicPos == limit) case here + // so we don't need the following check: + // if (dicPos == limit) { state = state < + // kNumLitStates ? 9 : 11; len = 1; break; } + + dic[dicPos] = dic[dicPos - rep0 + + (dicPos < rep0 ? dicBufSize : 0)]; + dicPos++; + processedPos++; + state = state < kNumLitStates ? 9 : 11; + continue; + } + UPDATE_1(prob) + } + else + { + UInt32 distance; + UPDATE_1(prob) + prob = probs + IsRepG1 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob) + distance = rep1; + } + else + { + UPDATE_1(prob) + prob = probs + IsRepG2 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob) + distance = rep2; + } + else + { + UPDATE_1(prob) + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = probs + RepLenCoder; + } + +#ifdef Z7_LZMA_SIZE_OPT + { + unsigned lim, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0(probLen) + { + UPDATE_0(probLen) + probLen = prob + LenLow + GET_LEN_STATE; + offset = 0; + lim = (1 << kLenNumLowBits); + } + else + { + UPDATE_1(probLen) + probLen = prob + LenChoice2; + IF_BIT_0(probLen) + { + UPDATE_0(probLen) + probLen = prob + LenLow + GET_LEN_STATE + + (1 << kLenNumLowBits); + offset = kLenNumLowSymbols; + lim = (1 << kLenNumLowBits); + } + else + { + UPDATE_1(probLen) + probLen = prob + LenHigh; + offset = kLenNumLowSymbols * 2; + lim = (1 << kLenNumHighBits); + } + } + TREE_DECODE(probLen, lim, len) + len += offset; + } +#else + { + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0(probLen) + { + UPDATE_0(probLen) + probLen = prob + LenLow + GET_LEN_STATE; + len = 1; + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + len -= 8; + } + else + { + UPDATE_1(probLen) + probLen = prob + LenChoice2; + IF_BIT_0(probLen) + { + UPDATE_0(probLen) + probLen = prob + LenLow + GET_LEN_STATE + + (1 << kLenNumLowBits); + len = 1; + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + } + else + { + UPDATE_1(probLen) + probLen = prob + LenHigh; + TREE_DECODE(probLen, (1 << kLenNumHighBits), len) + len += kLenNumLowSymbols * 2; + } + } + } +#endif + + if (state >= kNumStates) { + UInt32 distance; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) + << kNumPosSlotBits); + TREE_6_DECODE(prob, distance) + if (distance >= kStartPosModelIndex) { + unsigned posSlot = (unsigned)distance; + unsigned numDirectBits = (unsigned)(((distance >> 1) - 1)); + distance = (2 | (distance & 1)); + if (posSlot < kEndPosModelIndex) { + distance <<= numDirectBits; + prob = probs + SpecPos; + { + UInt32 m = 1; + distance++; + do { + REV_BIT_VAR(prob, distance, m) + } while (--numDirectBits); + distance -= m; + } + } else { + numDirectBits -= kNumAlignBits; + do { + NORMALIZE + range >>= 1; + + { + UInt32 t; + code -= range; + t = (0 - ((UInt32)code >> + 31)); /* (UInt32)((Int32)code + >> 31) */ + distance = + (distance << 1) + (t + 1); + code += range & t; + } + /* + distance <<= 1; + if (code >= range) + { + code -= range; + distance |= 1; + } + */ + } while (--numDirectBits); + prob = probs + Align; + distance <<= kNumAlignBits; + { + unsigned i = 1; + REV_BIT_CONST(prob, i, 1) + REV_BIT_CONST(prob, i, 2) + REV_BIT_CONST(prob, i, 4) + REV_BIT_LAST(prob, i, 8) + distance |= i; + } + if (distance == (UInt32)0xFFFFFFFF) { + len = kMatchSpecLenStart; + state -= kNumStates; + break; + } + } + } + + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + rep0 = distance + 1; + state = (state < kNumStates + kNumLitStates) ? kNumLitStates + : kNumLitStates + 3; + if (distance >= (checkDicSize == 0 ? processedPos : checkDicSize)) { + len += kMatchSpecLen_Error_Data + kMatchMinLen; + // len = kMatchSpecLen_Error_Data; + // len += kMatchMinLen; + break; + } + } + + len += kMatchMinLen; + + { + SizeT rem; + unsigned curLen; + SizeT pos; + + if ((rem = limit - dicPos) == 0) { + /* + We stop decoding and return SZ_OK, and we can resume + decoding later. Any error conditions can be tested later in + caller code. For more strict mode we can stop decoding with + error + // len += kMatchSpecLen_Error_Data; + */ + break; + } + + curLen = ((rem < len) ? (unsigned)rem : len); + pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0); + + processedPos += (UInt32)curLen; + + len -= curLen; + if (curLen <= dicBufSize - pos) { + Byte *dest = dic + dicPos; + ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; + const Byte *lim = dest + curLen; + dicPos += (SizeT)curLen; + do { + *(dest) = (Byte) * (dest + src); + } while (++dest != lim); + } else { + do { + dic[dicPos++] = dic[pos]; + if (++pos == dicBufSize) { + pos = 0; + } + } while (--curLen != 0); + } + } + } + } while (dicPos < limit && buf < bufLimit); + + NORMALIZE + + p->buf = buf; + p->range = range; + p->code = code; + p->remainLen = (UInt32)len; // & (kMatchSpecLen_Error_Data - 1); // we can write real length + // for error matches too. + p->dicPos = dicPos; + p->processedPos = processedPos; + p->reps[0] = rep0; + p->reps[1] = rep1; + p->reps[2] = rep2; + p->reps[3] = rep3; + p->state = (UInt32)state; + if (len >= kMatchSpecLen_Error_Data) { + return SZ_ERROR_DATA; + } + return SZ_OK; +} +#endif + +static void Z7_FASTCALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) +{ + unsigned len = (unsigned)p->remainLen; + if (len == 0 /* || len >= kMatchSpecLenStart */) { + return; + } + { + SizeT dicPos = p->dicPos; + Byte *dic; + SizeT dicBufSize; + SizeT rep0; /* we use SizeT to avoid the BUG of VC14 for AMD64 */ + { + SizeT rem = limit - dicPos; + if (rem < len) { + len = (unsigned)(rem); + if (len == 0) { + return; + } + } + } + + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) { + p->checkDicSize = p->prop.dicSize; + } + + p->processedPos += (UInt32)len; + p->remainLen -= (UInt32)len; + dic = p->dic; + rep0 = p->reps[0]; + dicBufSize = p->dicBufSize; + do { + dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + dicPos++; + } while (--len); + p->dicPos = dicPos; + } +} + +/* +At staring of new stream we have one of the following symbols: + - Literal - is allowed + - Non-Rep-Match - is allowed only if it's end marker symbol + - Rep-Match - is not allowed +We use early check of (RangeCoder:Code) over kBadRepCode to simplify main decoding code +*/ + +#define kRange0 0xFFFFFFFF +#define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)) +#define kBadRepCode \ + (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))) +#if kBadRepCode != (0xC0000000 - 0x400) +#error Stop_Compiling_Bad_LZMA_Check +#endif + +/* +LzmaDec_DecodeReal2(): + It calls LZMA_DECODE_REAL() and it adjusts limit according (p->checkDicSize). + +We correct (p->checkDicSize) after LZMA_DECODE_REAL() and in LzmaDec_WriteRem(), +and we support the following state of (p->checkDicSize): + if (total_processed < p->prop.dicSize) then + { + (total_processed == p->processedPos) + (p->checkDicSize == 0) + } + else + (p->checkDicSize == p->prop.dicSize) +*/ + +static int Z7_FASTCALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + if (p->checkDicSize == 0) { + UInt32 rem = p->prop.dicSize - p->processedPos; + if (limit - p->dicPos > rem) { + limit = p->dicPos + rem; + } + } + { + int res = LZMA_DECODE_REAL(p, limit, bufLimit); + if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize) { + p->checkDicSize = p->prop.dicSize; + } + return res; + } +} + +typedef enum { + DUMMY_INPUT_EOF, /* need more input data */ + DUMMY_LIT, + DUMMY_MATCH, + DUMMY_REP +} ELzmaDummy; + +#define IS_DUMMY_END_MARKER_POSSIBLE(dummyRes) ((dummyRes) == DUMMY_MATCH) + +static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byte **bufOut) +{ + UInt32 range = p->range; + UInt32 code = p->code; + const Byte *bufLimit = *bufOut; + const CLzmaProb *probs = GET_PROBS; + unsigned state = (unsigned)p->state; + ELzmaDummy res; + + for (;;) { + const CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = + CALC_POS_STATE(p->processedPos, ((unsigned)1 << p->prop.pb) - 1); + + prob = probs + IsMatch + COMBINED_PS_STATE; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + + prob = probs + Literal; + if (p->checkDicSize != 0 || p->processedPos != 0) { + prob += ((UInt32)LZMA_LIT_SIZE * + ((((p->processedPos) & (((unsigned)1 << (p->prop.lp)) - 1)) + << p->prop.lc) + + ((unsigned)p->dic[(p->dicPos == 0 ? p->dicBufSize + : p->dicPos) - + 1] >> + (8 - p->prop.lc)))); + } + + if (state < kNumLitStates) { + unsigned symbol = 1; + do { + GET_BIT_CHECK(prob + symbol, symbol) + } while (symbol < 0x100); + } else { + unsigned matchByte = + p->dic[p->dicPos - p->reps[0] + + (p->dicPos < p->reps[0] ? p->dicBufSize : 0)]; + unsigned offs = 0x100; + unsigned symbol = 1; + do { + unsigned bit; + const CLzmaProb *probLit; + matchByte += matchByte; + bit = offs; + offs &= matchByte; + probLit = prob + (offs + bit + symbol); + GET_BIT2_CHECK(probLit, symbol, offs ^= bit;, ;) + } while (symbol < 0x100); + } + res = DUMMY_LIT; + } + else + { + unsigned len; + UPDATE_1_CHECK + + prob = probs + IsRep + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + state = 0; + prob = probs + LenCoder; + res = DUMMY_MATCH; + } + else + { + UPDATE_1_CHECK + res = DUMMY_REP; + prob = probs + IsRepG0 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + prob = probs + IsRep0Long + COMBINED_PS_STATE; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + break; + } + else + { + UPDATE_1_CHECK + } + } + else + { + UPDATE_1_CHECK + prob = probs + IsRepG1 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + } + else + { + UPDATE_1_CHECK + prob = probs + IsRepG2 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + } + else + { + UPDATE_1_CHECK + } + } + } + state = kNumStates; + prob = probs + RepLenCoder; + } + { + unsigned limit, offset; + const CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK + probLen = prob + LenLow + GET_LEN_STATE; + offset = 0; + limit = 1 << kLenNumLowBits; + } + else + { + UPDATE_1_CHECK + probLen = prob + LenChoice2; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK + probLen = prob + LenLow + GET_LEN_STATE + + (1 << kLenNumLowBits); + offset = kLenNumLowSymbols; + limit = 1 << kLenNumLowBits; + } + else + { + UPDATE_1_CHECK + probLen = prob + LenHigh; + offset = kLenNumLowSymbols * 2; + limit = 1 << kLenNumHighBits; + } + } + TREE_DECODE_CHECK(probLen, limit, len) + len += offset; + } + + if (state < 4) { + unsigned posSlot; + prob = probs + PosSlot + + ((len < kNumLenToPosStates - 1 ? len + : kNumLenToPosStates - 1) + << kNumPosSlotBits); + TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot) + if (posSlot >= kStartPosModelIndex) { + unsigned numDirectBits = ((posSlot >> 1) - 1); + + if (posSlot < kEndPosModelIndex) { + prob = probs + SpecPos + + ((2 | (posSlot & 1)) << numDirectBits); + } else { + numDirectBits -= kNumAlignBits; + do { + NORMALIZE_CHECK + range >>= 1; + code -= range & + (((code - range) >> 31) - 1); + /* if (code >= range) code -= range; */ + } while (--numDirectBits); + prob = probs + Align; + numDirectBits = kNumAlignBits; + } + { + unsigned i = 1; + unsigned m = 1; + do { + REV_BIT_CHECK(prob, i, m) + } while (--numDirectBits); + } + } + } + } + break; + } + NORMALIZE_CHECK + + *bufOut = buf; + return res; +} + +void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState); +void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState) +{ + p->remainLen = kMatchSpecLenStart + 1; + p->tempBufSize = 0; + + if (initDic) { + p->processedPos = 0; + p->checkDicSize = 0; + p->remainLen = kMatchSpecLenStart + 2; + } + if (initState) { + p->remainLen = kMatchSpecLenStart + 2; + } +} + +void LzmaDec_Init(CLzmaDec *p) +{ + p->dicPos = 0; + LzmaDec_InitDicAndState(p, True, True); +} + +/* +LZMA supports optional end_marker. +So the decoder can lookahead for one additional LZMA-Symbol to check end_marker. +That additional LZMA-Symbol can require up to LZMA_REQUIRED_INPUT_MAX bytes in input stream. +When the decoder reaches dicLimit, it looks (finishMode) parameter: + if (finishMode == LZMA_FINISH_ANY), the decoder doesn't lookahead + if (finishMode != LZMA_FINISH_ANY), the decoder lookahead, if end_marker is possible for current +position + +When the decoder lookahead, and the lookahead symbol is not end_marker, we have two ways: + 1) Strict mode (default) : the decoder returns SZ_ERROR_DATA. + 2) The relaxed mode (alternative mode) : we could return SZ_OK, and the caller + must check (status) value. The caller can show the error, + if the end of stream is expected, and the (status) is noit + LZMA_STATUS_FINISHED_WITH_MARK or LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK. +*/ + +#define RETURN_NOT_FINISHED_FOR_FINISH \ + *status = LZMA_STATUS_NOT_FINISHED; \ + return SZ_ERROR_DATA; // for strict mode + // return SZ_OK; // for relaxed mode + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT inSize = *srcLen; + (*srcLen) = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + + if (p->remainLen > kMatchSpecLenStart) { + if (p->remainLen > kMatchSpecLenStart + 2) { + return p->remainLen == kMatchSpecLen_Error_Fail ? SZ_ERROR_FAIL + : SZ_ERROR_DATA; + } + + for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) { + p->tempBuf[p->tempBufSize++] = *src++; + } + if (p->tempBufSize != 0 && p->tempBuf[0] != 0) { + return SZ_ERROR_DATA; + } + if (p->tempBufSize < RC_INIT_SIZE) { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + p->code = ((UInt32)p->tempBuf[1] << 24) | ((UInt32)p->tempBuf[2] << 16) | + ((UInt32)p->tempBuf[3] << 8) | ((UInt32)p->tempBuf[4]); + + if (p->checkDicSize == 0 && p->processedPos == 0 && p->code >= kBadRepCode) { + return SZ_ERROR_DATA; + } + + p->range = 0xFFFFFFFF; + p->tempBufSize = 0; + + if (p->remainLen > kMatchSpecLenStart + 1) { + SizeT numProbs = LzmaProps_GetNumProbs(&p->prop); + SizeT i; + CLzmaProb *probs = p->probs; + for (i = 0; i < numProbs; i++) { + probs[i] = kBitModelTotal >> 1; + } + p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; + p->state = 0; + } + + p->remainLen = 0; + } + + for (;;) { + if (p->remainLen == kMatchSpecLenStart) { + if (p->code != 0) { + return SZ_ERROR_DATA; + } + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return SZ_OK; + } + + LzmaDec_WriteRem(p, dicLimit); + + { + // (p->remainLen == 0 || p->dicPos == dicLimit) + + int checkEndMarkNow = 0; + + if (p->dicPos >= dicLimit) { + if (p->remainLen == 0 && p->code == 0) { + *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; + return SZ_OK; + } + if (finishMode == LZMA_FINISH_ANY) { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + if (p->remainLen != 0) { + RETURN_NOT_FINISHED_FOR_FINISH + } + checkEndMarkNow = 1; + } + + // (p->remainLen == 0) + + if (p->tempBufSize == 0) { + const Byte *bufLimit; + int dummyProcessed = -1; + + if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) { + const Byte *bufOut = src + inSize; + + ELzmaDummy dummyRes = LzmaDec_TryDummy(p, src, &bufOut); + + if (dummyRes == DUMMY_INPUT_EOF) { + size_t i; + if (inSize >= LZMA_REQUIRED_INPUT_MAX) { + break; + } + (*srcLen) += inSize; + p->tempBufSize = (unsigned)inSize; + for (i = 0; i < inSize; i++) { + p->tempBuf[i] = src[i]; + } + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + dummyProcessed = (int)(bufOut - src); + if ((unsigned)dummyProcessed > LZMA_REQUIRED_INPUT_MAX) { + break; + } + + if (checkEndMarkNow && + !IS_DUMMY_END_MARKER_POSSIBLE(dummyRes)) { + unsigned i; + (*srcLen) += (unsigned)dummyProcessed; + p->tempBufSize = (unsigned)dummyProcessed; + for (i = 0; i < (unsigned)dummyProcessed; i++) { + p->tempBuf[i] = src[i]; + } + // p->remainLen = kMatchSpecLen_Error_Data; + RETURN_NOT_FINISHED_FOR_FINISH + } + + bufLimit = src; + // we will decode only one iteration + } else { + bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; + } + + p->buf = src; + + { + int res = LzmaDec_DecodeReal2(p, dicLimit, bufLimit); + + SizeT processed = (SizeT)(p->buf - src); + + if (dummyProcessed < 0) { + if (processed > inSize) { + break; + } + } else if ((unsigned)dummyProcessed != processed) { + break; + } + + src += processed; + inSize -= processed; + (*srcLen) += processed; + + if (res != SZ_OK) { + p->remainLen = kMatchSpecLen_Error_Data; + return SZ_ERROR_DATA; + } + } + continue; + } + + { + // we have some data in (p->tempBuf) + // in strict mode: tempBufSize is not enough for one Symbol + // decoding. in relaxed mode: tempBufSize not larger than required + // for one Symbol decoding. + + unsigned rem = p->tempBufSize; + unsigned ahead = 0; + int dummyProcessed = -1; + + while (rem < LZMA_REQUIRED_INPUT_MAX && ahead < inSize) { + p->tempBuf[rem++] = src[ahead++]; + } + + // ahead - the size of new data copied from (src) to (p->tempBuf) + // rem - the size of temp buffer including new data from (src) + + if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) { + const Byte *bufOut = p->tempBuf + rem; + + ELzmaDummy dummyRes = + LzmaDec_TryDummy(p, p->tempBuf, &bufOut); + + if (dummyRes == DUMMY_INPUT_EOF) { + if (rem >= LZMA_REQUIRED_INPUT_MAX) { + break; + } + p->tempBufSize = rem; + (*srcLen) += (SizeT)ahead; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + dummyProcessed = (int)(bufOut - p->tempBuf); + + if ((unsigned)dummyProcessed < p->tempBufSize) { + break; + } + + if (checkEndMarkNow && + !IS_DUMMY_END_MARKER_POSSIBLE(dummyRes)) { + (*srcLen) += + (unsigned)dummyProcessed - p->tempBufSize; + p->tempBufSize = (unsigned)dummyProcessed; + // p->remainLen = kMatchSpecLen_Error_Data; + RETURN_NOT_FINISHED_FOR_FINISH + } + } + + p->buf = p->tempBuf; + + { + // we decode one symbol from (p->tempBuf) here, so the + // (bufLimit) is equal to (p->buf) + int res = LzmaDec_DecodeReal2(p, dicLimit, p->buf); + + SizeT processed = (SizeT)(p->buf - p->tempBuf); + rem = p->tempBufSize; + + if (dummyProcessed < 0) { + if (processed > LZMA_REQUIRED_INPUT_MAX) { + break; + } + if (processed < rem) { + break; + } + } else if ((unsigned)dummyProcessed != processed) { + break; + } + + processed -= rem; + + src += processed; + inSize -= processed; + (*srcLen) += processed; + p->tempBufSize = 0; + + if (res != SZ_OK) { + p->remainLen = kMatchSpecLen_Error_Data; + return SZ_ERROR_DATA; + } + } + } + } + } + + /* Some unexpected error: internal error of code, memory corruption or hardware failure */ + p->remainLen = kMatchSpecLen_Error_Fail; + return SZ_ERROR_FAIL; +} + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT outSize = *destLen; + SizeT inSize = *srcLen; + *srcLen = *destLen = 0; + for (;;) { + SizeT inSizeCur = inSize, outSizeCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + if (p->dicPos == p->dicBufSize) { + p->dicPos = 0; + } + dicPos = p->dicPos; + if (outSize > p->dicBufSize - dicPos) { + outSizeCur = p->dicBufSize; + curFinishMode = LZMA_FINISH_ANY; + } else { + outSizeCur = dicPos + outSize; + curFinishMode = finishMode; + } + + res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); + src += inSizeCur; + inSize -= inSizeCur; + *srcLen += inSizeCur; + outSizeCur = p->dicPos - dicPos; + memcpy(dest, p->dic + dicPos, outSizeCur); + dest += outSizeCur; + outSize -= outSizeCur; + *destLen += outSizeCur; + if (res != 0) { + return res; + } + if (outSizeCur == 0 || outSize == 0) { + return SZ_OK; + } + } +} + +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->probs); + p->probs = NULL; +} + +static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->dic); + p->dic = NULL; +} + +void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc) +{ + LzmaDec_FreeProbs(p, alloc); + LzmaDec_FreeDict(p, alloc); +} + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) +{ + UInt32 dicSize; + Byte d; + + if (size < LZMA_PROPS_SIZE) { + return SZ_ERROR_UNSUPPORTED; + } else { + dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | + ((UInt32)data[4] << 24); + } + + if (dicSize < LZMA_DIC_MIN) { + dicSize = LZMA_DIC_MIN; + } + p->dicSize = dicSize; + + d = data[0]; + if (d >= (9 * 5 * 5)) { + return SZ_ERROR_UNSUPPORTED; + } + + p->lc = (Byte)(d % 9); + d /= 9; + p->pb = (Byte)(d / 5); + p->lp = (Byte)(d % 5); + + return SZ_OK; +} + +static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc) +{ + UInt32 numProbs = LzmaProps_GetNumProbs(propNew); + if (!p->probs || numProbs != p->numProbs) { + LzmaDec_FreeProbs(p, alloc); + p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb)); + if (!p->probs) { + return SZ_ERROR_MEM; + } + p->probs_1664 = p->probs + 1664; + p->numProbs = numProbs; + } + return SZ_OK; +} + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) +{ + CLzmaProps propNew; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)) + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)) + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) +{ + CLzmaProps propNew; + SizeT dicBufSize; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)) + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)) + + { + UInt32 dictSize = propNew.dicSize; + SizeT mask = ((UInt32)1 << 12) - 1; + if (dictSize >= ((UInt32)1 << 30)) { + mask = ((UInt32)1 << 22) - 1; + } else if (dictSize >= ((UInt32)1 << 22)) { + mask = ((UInt32)1 << 20) - 1; + } + dicBufSize = ((SizeT)dictSize + mask) & ~mask; + if (dicBufSize < dictSize) { + dicBufSize = dictSize; + } + } + + if (!p->dic || dicBufSize != p->dicBufSize) { + LzmaDec_FreeDict(p, alloc); + p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize); + if (!p->dic) { + LzmaDec_FreeProbs(p, alloc); + return SZ_ERROR_MEM; + } + } + p->dicBufSize = dicBufSize; + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, const Byte *propData, + unsigned propSize, ELzmaFinishMode finishMode, ELzmaStatus *status, + ISzAllocPtr alloc) +{ + CLzmaDec p; + SRes res; + SizeT outSize = *destLen, inSize = *srcLen; + *destLen = *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + if (inSize < RC_INIT_SIZE) { + return SZ_ERROR_INPUT_EOF; + } + LzmaDec_CONSTRUCT(&p) RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)) p.dic = + dest; + p.dicBufSize = outSize; + LzmaDec_Init(&p); + *srcLen = inSize; + res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + *destLen = p.dicPos; + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) { + res = SZ_ERROR_INPUT_EOF; + } + LzmaDec_FreeProbs(&p, alloc); + return res; +} diff --git a/subsys/nrf_compress/lzma/LzmaDec.h b/subsys/nrf_compress/lzma/LzmaDec.h new file mode 100644 index 000000000000..13472d67a6b2 --- /dev/null +++ b/subsys/nrf_compress/lzma/LzmaDec.h @@ -0,0 +1,234 @@ +/* LzmaDec.h -- LZMA Decoder +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZMA_DEC_H +#define ZIP7_INC_LZMA_DEC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +/* #define Z7_LZMA_PROB32 */ +/* Z7_LZMA_PROB32 can increase the speed on some CPUs, + but memory usage for CLzmaDec::probs will be doubled in that case */ + +typedef +#ifdef Z7_LZMA_PROB32 + UInt32 +#else + UInt16 +#endif + CLzmaProb; + +/* ---------- LZMA Properties ---------- */ + +#define LZMA_PROPS_SIZE 5 + +typedef struct { + Byte lc; + Byte lp; + Byte pb; + Byte _pad_; + UInt32 dicSize; +} CLzmaProps; + +/* LzmaProps_Decode - decodes properties +Returns: + SZ_OK + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); + +/* ---------- LZMA Decoder state ---------- */ + +/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. + Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ + +#define LZMA_REQUIRED_INPUT_MAX 20 + +typedef struct { + /* Don't change this structure. ASM code can use it. */ + CLzmaProps prop; + CLzmaProb *probs; + CLzmaProb *probs_1664; + Byte *dic; + SizeT dicBufSize; + SizeT dicPos; + const Byte *buf; + UInt32 range; + UInt32 code; + UInt32 processedPos; + UInt32 checkDicSize; + UInt32 reps[4]; + UInt32 state; + UInt32 remainLen; + + UInt32 numProbs; + unsigned tempBufSize; + Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; +} CLzmaDec; + +#define LzmaDec_CONSTRUCT(p) \ + { \ + (p)->dic = NULL; \ + (p)->probs = NULL; \ + } +#define LzmaDec_Construct(p) LzmaDec_CONSTRUCT(p) + +void LzmaDec_Init(CLzmaDec *p); + +/* There are two types of LZMA streams: + - Stream with end mark. That end mark adds about 6 bytes to compressed size. + - Stream without end mark. You must know exact uncompressed size to decompress such stream. */ + +typedef enum { + LZMA_FINISH_ANY, /* finish at any point */ + LZMA_FINISH_END /* block must be finished at the end */ +} ELzmaFinishMode; + +/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! + + You must use LZMA_FINISH_END, when you know that current output buffer + covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. + + If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, + and output value of destLen will be less than output buffer size limit. + You can check status result also. + + You can use multiple checks to test data integrity after full decompression: + 1) Check Result and "status" variable. + 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. + 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. + You must use correct finish mode in that case. */ + +typedef enum { + LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ + LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ + LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ + LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished + without end mark */ +} ELzmaStatus; + +/* ELzmaStatus is used only as output value for function call */ + +/* ---------- Interfaces ---------- */ + +/* There are 3 levels of interfaces: + 1) Dictionary Interface + 2) Buffer Interface + 3) One Call Interface + You can select any of these interfaces, but don't mix functions from different + groups for same object. */ + +/* There are two variants to allocate state for Dictionary Interface: + 1) LzmaDec_Allocate / LzmaDec_Free + 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs + You can use variant 2, if you set dictionary buffer manually. + For Buffer Interface you must always use variant 1. + +LzmaDec_Allocate* can return: + SZ_OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc); +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc); + +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc); +void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc); + +/* ---------- Dictionary Interface ---------- */ + +/* You can use it, if you want to eliminate the overhead for data copying from + dictionary to some other external buffer. + You must work with CLzmaDec variables directly in this interface. + + STEPS: + LzmaDec_Construct() + LzmaDec_Allocate() + for (each new stream) + { + LzmaDec_Init() + while (it needs more decompression) + { + LzmaDec_DecodeToDic() + use data from CLzmaDec::dic and update CLzmaDec::dicPos + } + } + LzmaDec_Free() +*/ + +/* LzmaDec_DecodeToDic + + The decoding to internal dictionary buffer (CLzmaDec::dic). + You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! + +finishMode: + It has meaning only if the decoding reaches output limit (dicLimit). + LZMA_FINISH_ANY - Decode just dicLimit bytes. + LZMA_FINISH_END - Stream must be finished after dicLimit. + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error + SZ_ERROR_FAIL - Some unexpected error: internal error of code, memory corruption or hardware +failure +*/ + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status); + +/* ---------- Buffer Interface ---------- */ + +/* It's zlib-like interface. + See LzmaDec_DecodeToDic description for information about STEPS and return results, + but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need + to work with CLzmaDec variables manually. + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). +*/ + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status); + +/* ---------- One Call Interface ---------- */ + +/* LzmaDecode + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). + SZ_ERROR_FAIL - Some unexpected error: internal error of code, memory corruption or hardware +failure +*/ + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, const Byte *propData, + unsigned propSize, ELzmaFinishMode finishMode, ELzmaStatus *status, + ISzAllocPtr alloc); + +EXTERN_C_END + +#endif diff --git a/subsys/nrf_compress/lzma/Precomp.h b/subsys/nrf_compress/lzma/Precomp.h new file mode 100644 index 000000000000..4408b7fae1a5 --- /dev/null +++ b/subsys/nrf_compress/lzma/Precomp.h @@ -0,0 +1,127 @@ +/* Precomp.h -- precompilation file +2024-01-25 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_PRECOMP_H +#define ZIP7_INC_PRECOMP_H + +/* + this file must be included before another *.h files and before . + this file is included from the following files: + C\*.c + C\Util\*\Precomp.h <- C\Util\*\*.c + CPP\Common\Common.h <- *\StdAfx.h <- *\*.cpp + + this file can set the following macros: + Z7_LARGE_PAGES 1 + Z7_LONG_PATH 1 + Z7_WIN32_WINNT_MIN 0x0500 (or higher) : we require at least win2000+ for 7-Zip + _WIN32_WINNT 0x0500 (or higher) + WINVER _WIN32_WINNT + UNICODE 1 + _UNICODE 1 +*/ + +#include "Compiler.h" + +#ifdef _MSC_VER +// #pragma warning(disable : 4206) // nonstandard extension used : translation unit is empty +#if _MSC_VER >= 1912 +// #pragma warning(disable : 5039) // pointer or reference to potentially throwing function passed +// to 'extern "C"' function under - EHc.Undefined behavior may occur if this function throws an +// exception. +#endif +#endif + +/* +// for debug: +#define UNICODE 1 +#define _UNICODE 1 +#define _WIN32_WINNT 0x0500 // win2000 +#ifndef WINVER + #define WINVER _WIN32_WINNT +#endif +*/ + +#ifdef _WIN32 +/* + this "Precomp.h" file must be included before , + if we want to define _WIN32_WINNT before . +*/ + +#ifndef Z7_LARGE_PAGES +#ifndef Z7_NO_LARGE_PAGES +#define Z7_LARGE_PAGES 1 +#endif +#endif + +#ifndef Z7_LONG_PATH +#ifndef Z7_NO_LONG_PATH +#define Z7_LONG_PATH 1 +#endif +#endif + +#ifndef Z7_DEVICE_FILE +#ifndef Z7_NO_DEVICE_FILE +// #define Z7_DEVICE_FILE 1 +#endif +#endif + +// we don't change macros if included after +#ifndef _WINDOWS_ + +#ifndef Z7_WIN32_WINNT_MIN +#if defined(_M_ARM64) || defined(__aarch64__) +// #define Z7_WIN32_WINNT_MIN 0x0a00 // win10 +#define Z7_WIN32_WINNT_MIN 0x0600 // vista +#elif defined(_M_ARM) && defined(_M_ARMT) && defined(_M_ARM_NT) +// #define Z7_WIN32_WINNT_MIN 0x0602 // win8 +#define Z7_WIN32_WINNT_MIN 0x0600 // vista +#elif defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_M_IA64) +#define Z7_WIN32_WINNT_MIN 0x0503 // win2003 +// #elif defined(_M_IX86) || defined(__i386__) +// #define Z7_WIN32_WINNT_MIN 0x0500 // win2000 +#else // x86 and another(old) systems +#define Z7_WIN32_WINNT_MIN 0x0500 // win2000 +// #define Z7_WIN32_WINNT_MIN 0x0502 // win2003 // for debug +#endif +#endif // Z7_WIN32_WINNT_MIN + +#ifndef Z7_DO_NOT_DEFINE_WIN32_WINNT +#ifdef _WIN32_WINNT +// #error Stop_Compiling_Bad_WIN32_WINNT +#else +#ifndef Z7_NO_DEFINE_WIN32_WINNT +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#define _WIN32_WINNT Z7_WIN32_WINNT_MIN +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif // _WIN32_WINNT + +#ifndef WINVER +#define WINVER _WIN32_WINNT +#endif +#endif // Z7_DO_NOT_DEFINE_WIN32_WINNT + +#ifndef _MBCS +#ifndef Z7_NO_UNICODE +// UNICODE and _UNICODE are used by and by 7-zip code. + +#ifndef UNICODE +#define UNICODE 1 +#endif + +#ifndef _UNICODE +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#define _UNICODE 1 +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif + +#endif // Z7_NO_UNICODE +#endif // _MBCS +#endif // _WINDOWS_ + +// #include "7zWindows.h" + +#endif // _WIN32 + +#endif From d3fc7f13b379fd31d7453ef8be9fcdf9356e4329 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 31 Jul 2024 14:55:26 +0100 Subject: [PATCH 33/72] compress: Add new subsystem Adds a compression subsystem with initial support for lzma2 and lzma1 decompression Signed-off-by: Jamie McCrae --- include/nrf_compress/implementation.h | 192 ++++++++++++++ subsys/CMakeLists.txt | 1 + subsys/Kconfig | 1 + subsys/nrf_compress/CMakeLists.txt | 19 ++ subsys/nrf_compress/Kconfig | 112 +++++++++ subsys/nrf_compress/sections.ld | 3 + subsys/nrf_compress/src/implementation.c | 35 +++ subsys/nrf_compress/src/lzma.c | 308 +++++++++++++++++++++++ 8 files changed, 671 insertions(+) create mode 100644 include/nrf_compress/implementation.h create mode 100644 subsys/nrf_compress/CMakeLists.txt create mode 100644 subsys/nrf_compress/Kconfig create mode 100644 subsys/nrf_compress/sections.ld create mode 100644 subsys/nrf_compress/src/implementation.c create mode 100644 subsys/nrf_compress/src/lzma.c diff --git a/include/nrf_compress/implementation.h b/include/nrf_compress/implementation.h new file mode 100644 index 000000000000..6cada96a7597 --- /dev/null +++ b/include/nrf_compress/implementation.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/** + * @file + * @brief Public API for compression/decompression subsystem + */ + +#ifndef NRF_COMPRESS_IMPLEMENTATION_H_ +#define NRF_COMPRESS_IMPLEMENTATION_H_ + +#include +#include +#include +#include +#include + +/** + * @brief Compression/decompression subsystem + * @defgroup compression_decompression_subsystem Compression/decompression subsystem + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @cond INTERNAL_HIDDEN + * + * For internal use only, skip these in public documentation. + */ + +typedef int (*nrf_compress_init_deinit_func_t)(void *inst); +typedef int (*nrf_compress_reset_func_t)(void *inst); +/** Compression support is not implemented, placeholder for future use */ +typedef int (*nrf_compress_compress_func_t)(void *inst); +typedef size_t (*nrf_compress_decompress_bytes_needed_t)(void *inst); +typedef int (*nrf_compress_decompress_func_t)(void *inst, const uint8_t *input, size_t input_size, + bool last_part, uint32_t *offset, uint8_t **output, + size_t *output_size); + +/** + * @endcond + */ + +/** @brief Supported compression types */ +enum nrf_compress_types { + /** lzma1 or lzma2 */ + NRF_COMPRESS_TYPE_LZMA, + + NRF_COMPRESS_TYPE_COUNT +}; + +struct nrf_compress_implementation { + /** ID of implementation (nrf_compress_types) */ + const uint16_t id; + + /** + * @brief Initialize compression implementation. + * + * @param[in] inst Reserved for future use, must be NULL. + * + * @retval 0 Success. + * @retval -errno Negative errno code on other failure. + */ + const nrf_compress_init_deinit_func_t init; + + /** + * @brief Deinitialize compression implementation. + * + * @param[in] inst Reserved for future use, must be NULL. + * + * @retval 0 Success. + * @retval -errno Negative errno code on other failure. + */ + const nrf_compress_init_deinit_func_t deinit; + + /** + * @brief Reset compression state function. Used to abort current compression + * or decompression task before starting a new one. + * + * @param[in] inst Reserved for future use, must be NULL. + * + * @retval 0 Success. + * @retval -errno Negative errno code on other failure. + */ + const nrf_compress_reset_func_t reset; + +#if defined(CONFIG_NRF_COMPRESS_COMPRESSION) || defined(__DOXYGEN__) + /** @brief Placeholder function for future use, do not use. */ + const nrf_compress_compress_func_t compress; +#endif + +#if defined(CONFIG_NRF_COMPRESS_DECOMPRESSION) || defined(__DOXYGEN__) + /** + * @brief Return chunk size of data to provide to next call of + * nrf_compress_decompress_func_t function. This is the ideal amount + * of data that should be provided to the next function call. Less + * data than this may be provided if more is not available (for + * example, end of data or data is being streamed). + * + * @param[in] inst Reserved for future use, must be NULL. + * + * @retval Positive value Success indicating chunk size. + * @retval -errno Negative errno code on other failure. + */ + const nrf_compress_decompress_bytes_needed_t decompress_bytes_needed; + + /** + * @brief Decompress portion of compressed data. This function will + * need to be called one or more times with compressed data to + * decompress it into its natural form. + * + * @param[in] inst Reserved for future use, must be NULL. + * @param[in] input Input data buffer, containing the compressed data. + * @param[in] input_size Size of the input data buffer. + * @param[in] last_part Last part of compressed data. This should be set to true if + * this is the final part of the input data. + * @param[out] offset Input data offset pointer. This will be updated with the + * amount of bytes used from the input buffer. If this is not + * the last decompression call, then the next call to this + * function should offset the input data buffer by this + * amount of bytes. + * @param[out] output Output data buffer pointer to pointer. This will be set to + * the compression's output buffer when decompressed data is + * available to be used or copied. + * @ param[out] output_size Size of data in output data buffer pointer. Data should + * only be read when the value in this pointer is greater than + * 0. + * + * @retval 0 Success. + * @retval -errno Negative errno code on other failure. + */ + const nrf_compress_decompress_func_t decompress; +#endif +}; + +/** + * @brief Define a compression implementation. + * + * This adds a new entry to the iterable section linker list of compression implementations. + * + * @param name Name of the compression type. + * @param _id ID of the compression type (nrf_compress_types). + * @param _init Initialization function (nrf_compress_init_deinit_func_t). + * @param _deinit Deinitialization function + * (nrf_compress_init_deinit_func_t). + * @param _reset Reset function (nrf_compress_reset_func_t). + * @param _compress Compress function or NULL if no compression support + * (nrf_compress_compress_func_t). + * @param _decompress_bytes_needed Decompression bytes needed function or NULL if no + * decompression support + * (nrf_compress_decompress_bytes_needed_t). + * @param _decompress Decompression function or NULL if no decompression support + * (nrf_compress_decompress_func_t). + */ +#define NRF_COMPRESS_IMPLEMENTATION_DEFINE(name, _id, _init, _deinit, _reset, _compress, \ + _decompress_bytes_needed, _decompress) \ + STRUCT_SECTION_ITERABLE(nrf_compress_implementation, name) = { \ + .id = _id, \ + .init = _init, \ + .deinit = _deinit, \ + .reset = _reset, \ + COND_CODE_1(CONFIG_NRF_COMPRESS_COMPRESSION, ( \ + .compress = _compress, \ + ), ()) \ + COND_CODE_1(CONFIG_NRF_COMPRESS_DECOMPRESSION, ( \ + .decompress_bytes_needed = _decompress_bytes_needed, \ + .decompress = _decompress, \ + ), ()) \ + } +/** + * @brief Find a compression implementation. + * + * @param[in] id Type of compression (nrf_compress_types). + * + * @retval non-NULL Success. + * @retval NULL Compression type not found/supported. + */ +struct nrf_compress_implementation *nrf_compress_implementation_find(uint16_t id); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* NRF_COMPRESS_IMPLEMENTATION_H_ */ diff --git a/subsys/CMakeLists.txt b/subsys/CMakeLists.txt index 7158b343dfc2..7afba217388b 100644 --- a/subsys/CMakeLists.txt +++ b/subsys/CMakeLists.txt @@ -75,3 +75,4 @@ add_subdirectory_ifdef(CONFIG_SDFW_SERVICES_ENABLED sdfw_services) add_subdirectory(suit) add_subdirectory_ifdef(CONFIG_MGMT_SUITFU mgmt/suitfu) add_subdirectory_ifdef(CONFIG_DULT dult) +add_subdirectory_ifdef(CONFIG_NRF_COMPRESS nrf_compress) diff --git a/subsys/Kconfig b/subsys/Kconfig index 4ad732ace0a1..04ba79518fee 100644 --- a/subsys/Kconfig +++ b/subsys/Kconfig @@ -40,4 +40,5 @@ rsource "logging/Kconfig" rsource "sdfw_services/Kconfig" rsource "suit/Kconfig" rsource "dult/Kconfig" +rsource "nrf_compress/Kconfig" endmenu diff --git a/subsys/nrf_compress/CMakeLists.txt b/subsys/nrf_compress/CMakeLists.txt new file mode 100644 index 000000000000..dbc93363ecad --- /dev/null +++ b/subsys/nrf_compress/CMakeLists.txt @@ -0,0 +1,19 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +zephyr_library(nrf_compress) +zephyr_library_sources(src/implementation.c) +zephyr_linker_sources(SECTIONS sections.ld) +zephyr_iterable_section(NAME nrf_compress_implementation KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN CONFIG_LINKER_ITERABLE_SUBALIGN) + +if(CONFIG_NRF_COMPRESS_LZMA) + zephyr_library_include_directories(lzma) + zephyr_library_sources(lzma/LzmaDec.c src/lzma.c) + + if(CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2) + zephyr_library_sources(lzma/Lzma2Dec.c) + endif() +endif() diff --git a/subsys/nrf_compress/Kconfig b/subsys/nrf_compress/Kconfig new file mode 100644 index 000000000000..d73acb8e1309 --- /dev/null +++ b/subsys/nrf_compress/Kconfig @@ -0,0 +1,112 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +menuconfig NRF_COMPRESS + bool "Compression/decompression library" + +if NRF_COMPRESS + +config NRF_COMPRESS_COMPRESSION + bool + help + Enables support for compression functions in library. + +config NRF_COMPRESS_DECOMPRESSION + bool "Decompression support" + help + Enables support for decompression functions in library. + +menu "Type support" + depends on NRF_COMPRESS_COMPRESSION || NRF_COMPRESS_DECOMPRESSION + +config NRF_COMPRESS_TYPE_SELECTED + bool + help + Hidden option to know if at least one implementation has been selected. + +menuconfig NRF_COMPRESS_LZMA + bool "LZMA" + depends on NRF_COMPRESS_DECOMPRESSION + select NRF_COMPRESS_TYPE_SELECTED + help + Enables LZMA support for decompression. + +if NRF_COMPRESS_LZMA + +choice NRF_COMPRESS_LZMA_VERSION + prompt "Version" + default NRF_COMPRESS_LZMA_VERSION_LZMA2 + +config NRF_COMPRESS_LZMA_VERSION_LZMA1 + bool "lzma1" + +config NRF_COMPRESS_LZMA_VERSION_LZMA2 + bool "lzma2" + +endchoice + +endif # NRF_COMPRESS_LZMA + +endmenu + +config NRF_COMPRESS_CHUNK_SIZE + int "Chunk size" + default 2048 + help + The chunk size is the default maximum amount of data that if returned by the + decompress_bytes_needed() function. The value is returned by the decompress bytes + function that is available. Strive to provide the exact amount returned and not more. + If not possible otherwise, for example because of streaming or end of input, a lower + amount can be provided as well. + +config NRF_COMPRESS_MIN_MEMORY_REQUIRED + hex + default 0x26f80 if NRF_COMPRESS_DECOMPRESSION && NRF_COMPRESS_LZMA + default 0 + help + Hidden symbol indicating minimum buffer size for operation if operating in malloc mode. + +choice NRF_COMPRESS_MEMORY_TYPE + prompt "Memory type for buffers" + default NRF_COMPRESS_MEMORY_TYPE_STATIC + +config NRF_COMPRESS_MEMORY_TYPE_STATIC + bool "Static buffers" + help + Use static buffers to hold the data for decompression. This will reduce the + memory available to everything else in the application. + +config NRF_COMPRESS_MEMORY_TYPE_MALLOC + bool "Malloc" + depends on COMMON_LIBC_MALLOC + depends on (COMMON_LIBC_MALLOC_ARENA_SIZE = -1) || (COMMON_LIBC_MALLOC_ARENA_SIZE >= NRF_COMPRESS_MIN_MEMORY_REQUIRED) + help + Use the dynamic memory allocation to hold the data for decompression. If there is + insufficient free contiguous space, decompression will not be usable. + +endchoice + +config NRF_COMPRESS_MEMORY_ALIGNMENT + int "Buffer memory alignment" + default 4 + range 1 32 + help + Memory alignment of the output decompression buffer. Set to 1 to disable. + +config NRF_COMPRESS_CLEANUP + bool "Clean up buffers on deinitialization" + default y + help + If enabled, will clean up all memory buffers in the deinitialization function. This + prevents leakage of the information, for example to other boot targets. + + This option can be disabled if it is not needed and the data contains nothing sensitive. + +module = NRF_COMPRESS +module-str = compression/decompression library +source "subsys/logging/Kconfig.template.log_config" + +endif # NRF_COMPRESS diff --git a/subsys/nrf_compress/sections.ld b/subsys/nrf_compress/sections.ld new file mode 100644 index 000000000000..30b5f6c2e62b --- /dev/null +++ b/subsys/nrf_compress/sections.ld @@ -0,0 +1,3 @@ +#include + +ITERABLE_SECTION_ROM(nrf_compress_implementation, Z_LINK_ITERABLE_SUBALIGN) diff --git a/subsys/nrf_compress/src/implementation.c b/subsys/nrf_compress/src/implementation.c new file mode 100644 index 000000000000..d1095048dff5 --- /dev/null +++ b/subsys/nrf_compress/src/implementation.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include + +#if !defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_STATIC) && \ + !defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_MALLOC) +#error "Missing compression static buffer configuration, please select " \ + "CONFIG_NRF_COMPRESS_MEMORY_TYPE_STATIC or CONFIG_NRF_COMPRESS_MEMORY_TYPE_MALLOC" +#endif + +#if !defined(CONFIG_NRF_COMPRESS_COMPRESSION) && !defined(CONFIG_NRF_COMPRESS_DECOMPRESSION) +#error "Compression library enabled but without compression or decompression support enabled, " \ + "please select CONFIG_NRF_COMPRESS_COMPRESSION and/or CONFIG_NRF_COMPRESS_DECOMPRESSION" +#endif + +#if !defined(CONFIG_NRF_COMPRESS_TYPE_SELECTED) +#error "An implmentation must be selected to use the nRF compression library" +#endif + +struct nrf_compress_implementation *nrf_compress_implementation_find(uint16_t id) +{ + STRUCT_SECTION_FOREACH(nrf_compress_implementation, implementation) { + if (implementation->id == id) { + return implementation; + } + } + + return NULL; +} diff --git a/subsys/nrf_compress/src/lzma.c b/subsys/nrf_compress/src/lzma.c new file mode 100644 index 000000000000..a26620ead2b0 --- /dev/null +++ b/subsys/nrf_compress/src/lzma.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(nrf_compress_lzma, CONFIG_NRF_COMPRESS_LOG_LEVEL); + +/* Header size for lzma2 */ +#define LZMA2_HEADER_SIZE 2 + +/* Assume lp and lc parameters in the compressed images do not sum to a value greater than the + * following constant to limit the memory used by LZMA probability array. + */ +#define MAX_LZMA_LC_PLUS_LP 4 +#define MAX_LZMA_PROB_SIZE (1984 + (0x300 << MAX_LZMA_LC_PLUS_LP)) + +/* Assume the maximum LZMA dictionary size to limit the RAM buffer size for the decompressed + * stream. + */ +#define MAX_LZMA_DICT_SIZE (128 * 1024) + +#if !defined(CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1) && \ + !defined(CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2) +#error "Missing selection of lzma algorithm selection, please select " \ + "CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1 or CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2" +#endif + +#if defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_STATIC) +static uint16_t lzma_probs[MAX_LZMA_PROB_SIZE]; +#endif + +#if defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_MALLOC) && defined(CONFIG_NRF_COMPRESS_CLEANUP) +static size_t malloc_probs_size = 0; +#endif + +static void *lzma_probs_alloc(ISzAllocPtr p, size_t size) +{ +#if defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_STATIC) + if (size > sizeof(lzma_probs)) { + LOG_ERR("Compress library tried to allocate too large a buffer (0x%x)", size); + return NULL; + } + + return lzma_probs; +#else + void *buffer = malloc(size); + + if (buffer == NULL) { + LOG_ERR("Failed to allocate nRF compression library buffer (0x%x)", size); + } + +#ifdef CONFIG_NRF_COMPRESS_CLEANUP + malloc_probs_size = size; +#endif + + return buffer; +#endif +} + +static void lzma_probs_free(ISzAllocPtr p, void *address) +{ +#if defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_MALLOC) +#ifdef CONFIG_NRF_COMPRESS_CLEANUP + memset(address, 0x00, malloc_probs_size); + + malloc_probs_size = 0; +#endif + free(address); +#else +#ifdef CONFIG_NRF_COMPRESS_CLEANUP + memset(lzma_probs, 0x00, sizeof(lzma_probs)); +#endif +#endif +} + +const static ISzAlloc lzma_probs_allocator = { + .Alloc = lzma_probs_alloc, + .Free = lzma_probs_free, +}; + +#if defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_STATIC) +#if CONFIG_NRF_COMPRESS_MEMORY_ALIGNMENT > 1 +static uint8_t __aligned(CONFIG_NRF_COMPRESS_MEMORY_ALIGNMENT) lzma_dict[MAX_LZMA_DICT_SIZE]; +#else +static uint8_t lzma_dict[MAX_LZMA_DICT_SIZE]; +#endif +#else +static uint8_t *lzma_dict = NULL; +#endif + +static bool allocated_probs = false; +#ifdef CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 +static CLzma2Dec lzma_decoder; +#else +static CLzmaDec lzma_decoder; +#endif + +static int lzma_reset(void *inst); + +static int lzma_init(void *inst) +{ + int rc = 0; + + ARG_UNUSED(inst); + +#if defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_MALLOC) + if (lzma_dict != NULL) { + /* Already allocated */ + lzma_reset(inst); + + return rc; + } + +#if CONFIG_NRF_COMPRESS_MEMORY_ALIGNMENT > 1 + lzma_dict = (uint8_t *)aligned_alloc(CONFIG_NRF_COMPRESS_MEMORY_ALIGNMENT, + MAX_LZMA_DICT_SIZE); +#else + lzma_dict = (uint8_t *)malloc(MAX_LZMA_DICT_SIZE); +#endif + + if (lzma_dict == NULL) { + rc = -ENOMEM; + } +#endif + + return rc; +} + +static int lzma_deinit(void *inst) +{ + ARG_UNUSED(inst); + +#if defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_MALLOC) + if (lzma_dict != NULL) { +#ifdef CONFIG_NRF_COMPRESS_CLEANUP + memset(lzma_dict, 0x00, MAX_LZMA_DICT_SIZE); +#endif + + free(lzma_dict); + lzma_dict = NULL; + } +#endif + + lzma_reset(inst); + + return 0; +} + +static int lzma_reset(void *inst) +{ + ARG_UNUSED(inst); + + if (allocated_probs) { + allocated_probs = false; + +#ifdef CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + Lzma2Dec_FreeProbs(&lzma_decoder, &lzma_probs_allocator); +#else + LzmaDec_FreeProbs(&lzma_decoder, &lzma_probs_allocator); +#endif + + lzma_decoder.decoder.dicPos = 0; + } + + return 0; +} + +static size_t lzma_bytes_needed(void *inst) +{ + ARG_UNUSED(inst); + +#if defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_MALLOC) + if (lzma_dict == NULL) { + return 0; + } +#endif + +#ifdef CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + return (allocated_probs ? CONFIG_NRF_COMPRESS_CHUNK_SIZE : LZMA2_HEADER_SIZE); +#else + return (allocated_probs ? CONFIG_NRF_COMPRESS_CHUNK_SIZE : LZMA_PROPS_SIZE); +#endif +} + +static int lzma_decompress(void *inst, const uint8_t *input, size_t input_size, bool last_part, + uint32_t *offset, uint8_t **output, size_t *output_size) +{ + int rc; + ELzmaStatus status; + size_t chunk_size = input_size; + + ARG_UNUSED(inst); + +#if defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_MALLOC) + if (lzma_dict == NULL) { + return -ESRCH; + } +#endif + + if (input == NULL || input_size == 0 || offset == NULL || output == NULL || + output_size == NULL) { + return -EINVAL; + } + + *output = NULL; + *output_size = 0; + + if (!allocated_probs) { +#ifdef CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + rc = Lzma2Dec_AllocateProbs(&lzma_decoder, input[0], &lzma_probs_allocator); +#else + rc = LzmaDec_AllocateProbs(&lzma_decoder, input, LZMA_PROPS_SIZE, + &lzma_probs_allocator); +#endif + + if (rc) { + rc = -EINVAL; + goto done; + } + +#ifdef CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + if (lzma_decoder.decoder.prop.dicSize > MAX_LZMA_DICT_SIZE) { +#else + if (lzma_decoder.prop.dicSize > MAX_LZMA_DICT_SIZE) { +#endif + rc = -EINVAL; +#ifdef CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + Lzma2Dec_FreeProbs(&lzma_decoder, &lzma_probs_allocator); +#else + LzmaDec_FreeProbs(&lzma_decoder, &lzma_probs_allocator); +#endif + goto done; + } + + allocated_probs = true; +#ifdef CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + *offset = LZMA2_HEADER_SIZE; +#else + /* Header and account for uncompressed size */ + *offset = LZMA_PROPS_SIZE + sizeof(uint64_t); +#endif + +#ifdef CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + lzma_decoder.decoder.dic = lzma_dict; + lzma_decoder.decoder.dicBufSize = MAX_LZMA_DICT_SIZE; + Lzma2Dec_Init(&lzma_decoder); +#else + lzma_decoder.dic = lzma_dict; + lzma_decoder.dicBufSize = MAX_LZMA_DICT_SIZE; + LzmaDec_Init(&lzma_decoder); +#endif + + return 0; + } + +#ifdef CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + rc = Lzma2Dec_DecodeToDic(&lzma_decoder, MAX_LZMA_DICT_SIZE, input, &chunk_size, + (last_part ? LZMA_FINISH_END : LZMA_FINISH_ANY), &status); +#else + rc = LzmaDec_DecodeToDic(&lzma_decoder, MAX_LZMA_DICT_SIZE, input, &chunk_size, + (last_part ? LZMA_FINISH_END : LZMA_FINISH_ANY), &status); +#endif + + if (rc) { + rc = -EINVAL; + goto done; + } + + *offset = chunk_size; + + if (last_part && (status == LZMA_STATUS_FINISHED_WITH_MARK || + status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) && + *offset < input_size) { + /* If last block, ensure offset matches complete file size */ + *offset = input_size; + } + +#ifdef CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + if (lzma_decoder.decoder.dicPos >= lzma_decoder.decoder.dicBufSize || + (last_part && input_size == chunk_size)) { + *output = lzma_decoder.decoder.dic; + *output_size = lzma_decoder.decoder.dicPos; + lzma_decoder.decoder.dicPos = 0; + } +#else + if (lzma_decoder.dicPos >= lzma_decoder.dicBufSize || + (last_part && input_size == chunk_size)) { + *output = lzma_decoder.dic; + *output_size = lzma_decoder.dicPos; + lzma_decoder.dicPos = 0; + } +#endif + +done: + return rc; +} + +NRF_COMPRESS_IMPLEMENTATION_DEFINE(lzma, NRF_COMPRESS_TYPE_LZMA, lzma_init, lzma_deinit, + lzma_reset, NULL, lzma_bytes_needed, lzma_decompress); From dec5dc272fd081816b375edb01760afb43f960ba Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 31 Jul 2024 14:49:19 +0100 Subject: [PATCH 34/72] tests: compression: decompression: Add lzma test Adds a test that checks lzma2 decompression is working Signed-off-by: Jamie McCrae --- .../decompression/lzma/CMakeLists.txt | 30 + .../nrf_compress/decompression/lzma/Kconfig | 10 + .../nrf_compress/decompression/lzma/prj.conf | 13 + .../decompression/lzma/src/main.c | 567 ++++++++++++++++++ .../decompression/lzma/testcase.yaml | 20 + 5 files changed, 640 insertions(+) create mode 100644 tests/subsys/nrf_compress/decompression/lzma/CMakeLists.txt create mode 100644 tests/subsys/nrf_compress/decompression/lzma/Kconfig create mode 100644 tests/subsys/nrf_compress/decompression/lzma/prj.conf create mode 100644 tests/subsys/nrf_compress/decompression/lzma/src/main.c create mode 100644 tests/subsys/nrf_compress/decompression/lzma/testcase.yaml diff --git a/tests/subsys/nrf_compress/decompression/lzma/CMakeLists.txt b/tests/subsys/nrf_compress/decompression/lzma/CMakeLists.txt new file mode 100644 index 000000000000..7ae538ba8a4d --- /dev/null +++ b/tests/subsys/nrf_compress/decompression/lzma/CMakeLists.txt @@ -0,0 +1,30 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(decompression) + +target_sources(app PRIVATE src/main.c) + +generate_inc_file_for_target( + app + ${ZEPHYR_NRFXLIB_MODULE_DIR}/tests/subsys/nrf_compress/decompression/dummy_data_input.txt.lzma + ${ZEPHYR_BINARY_DIR}/include/generated/dummy_data_input.inc + ) + +generate_inc_file_for_target( + app + ${ZEPHYR_NRFXLIB_MODULE_DIR}/tests/subsys/nrf_compress/decompression/dummy_data_input_too_large.txt.lzma + ${ZEPHYR_BINARY_DIR}/include/generated/dummy_data_input_too_large.inc + ) + +generate_inc_file_for_target( + app + ${ZEPHYR_NRFXLIB_MODULE_DIR}/tests/subsys/nrf_compress/decompression/dummy_data_input.txt.lzma1 + ${ZEPHYR_BINARY_DIR}/include/generated/dummy_data_input_lzma1.inc + ) diff --git a/tests/subsys/nrf_compress/decompression/lzma/Kconfig b/tests/subsys/nrf_compress/decompression/lzma/Kconfig new file mode 100644 index 000000000000..ebab309d2c21 --- /dev/null +++ b/tests/subsys/nrf_compress/decompression/lzma/Kconfig @@ -0,0 +1,10 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +config NRF_COMPRESS_COMPRESSION + default y + +source "Kconfig.zephyr" diff --git a/tests/subsys/nrf_compress/decompression/lzma/prj.conf b/tests/subsys/nrf_compress/decompression/lzma/prj.conf new file mode 100644 index 000000000000..aef321c8bc8c --- /dev/null +++ b/tests/subsys/nrf_compress/decompression/lzma/prj.conf @@ -0,0 +1,13 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +CONFIG_ZTEST=y +CONFIG_ZTEST_STACK_SIZE=3086 +CONFIG_NRF_COMPRESS=y +CONFIG_NRF_COMPRESS_DECOMPRESSION=y +CONFIG_NRF_COMPRESS_LZMA=y +CONFIG_LOG=y +CONFIG_MBEDTLS=y diff --git a/tests/subsys/nrf_compress/decompression/lzma/src/main.c b/tests/subsys/nrf_compress/decompression/lzma/src/main.c new file mode 100644 index 000000000000..3257e07f6172 --- /dev/null +++ b/tests/subsys/nrf_compress/decompression/lzma/src/main.c @@ -0,0 +1,567 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include +#include + +#define REDUCED_BUFFER_SIZE 512 +#define SHA256_SIZE 32 + +/* Input valid lzma2 compressed data */ +const uint8_t dummy_data_input[] = { +#include "dummy_data_input.inc" +}; + +/* File size and sha256 hash of decompressed data */ +const uint32_t dummy_data_output_size = 66477; +const uint8_t dummy_data_output_sha256[] = { + 0x87, 0xee, 0x2e, 0x17, 0xa5, 0xdb, 0x98, 0xbe, + 0x8c, 0xcb, 0xfe, 0xc9, 0x70, 0x8c, 0x7a, 0x43, + 0x66, 0xda, 0x63, 0xff, 0x48, 0x15, 0x48, 0x88, + 0xd7, 0xed, 0x64, 0x87, 0xba, 0xb9, 0xef, 0xc5 +}; + +/* Input valid lzma2 compressed data whereby the output is larger than the dictionary size */ +const uint8_t dummy_data_too_large_input[] = { +#include "dummy_data_input_too_large.inc" +}; + +/* File size and sha256 hash of decompressed data for too large an output */ +const uint32_t dummy_data_too_large_output_size = 134061; +const uint8_t dummy_data_too_large_output_sha256[] = { + 0xc0, 0xc4, 0xac, 0xc7, 0xac, 0x69, 0x37, 0x4b, + 0x60, 0xb4, 0x87, 0xe9, 0x3d, 0x65, 0xcf, 0xa2, + 0x4b, 0x2b, 0xef, 0xd0, 0xb9, 0xbf, 0xf9, 0xc9, + 0x2f, 0x61, 0x52, 0x17, 0xca, 0x55, 0x03, 0x77 +}; + +#if defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_MALLOC) && !defined(CONFIG_SOC_POSIX) +static uint8_t *large_malloc_object = NULL; +#endif + +/* Input valid lzma1 compressed data */ +const uint8_t dummy_data_lzma1_input[] = { +#include "dummy_data_input_lzma1.inc" +}; + +ZTEST(nrf_compress_decompression, test_valid_implementation) +{ + struct nrf_compress_implementation *implementation = NULL; + + implementation = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + zassert_not_equal(implementation, NULL, "Expected implementation to not be NULL"); +} + +ZTEST(nrf_compress_decompression, test_valid_implementation_elements) +{ + struct nrf_compress_implementation *implementation = NULL; + + implementation = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + zassert_equal(implementation->id, NRF_COMPRESS_TYPE_LZMA, + "Expected id element to have correct value"); + zassert_not_equal(implementation->init, NULL, "Expected init element to not be NULL"); + zassert_not_equal(implementation->deinit, NULL, + "Expected deinit element to not be NULL"); + zassert_not_equal(implementation->reset, NULL, "Expected reset element to not be NULL"); + zassert_equal(implementation->compress, NULL, "Expected compress element to be NULL"); + zassert_not_equal(implementation->decompress_bytes_needed, NULL, + "Expected decompress_bytes_needed element to not be NULL"); + zassert_not_equal(implementation->decompress, NULL, + "Expected decompress to not be NULL"); +} + +ZTEST(nrf_compress_decompression, test_invalid_implementation) +{ + struct nrf_compress_implementation *implementation = NULL; + + implementation = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_COUNT); + + zassert_equal(implementation, NULL, "Expected implementation to be NULL"); + + implementation = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_COUNT + 300); + + zassert_equal(implementation, NULL, "Expected implementation to be NULL"); + + implementation = nrf_compress_implementation_find(((uint16_t)-1)); + + zassert_equal(implementation, NULL, "Expected implementation to be NULL"); +} + +ZTEST(nrf_compress_decompression, test_valid_data_decompression) +{ + int rc; + uint32_t pos; + uint32_t offset; + uint8_t *output; + uint32_t output_size; + uint32_t total_output_size = 0; + uint8_t output_sha[SHA256_SIZE] = { 0 }; + struct nrf_compress_implementation *implementation; + mbedtls_sha256_context ctx; + + mbedtls_sha256_init(&ctx); + rc = mbedtls_sha256_starts(&ctx, false); + zassert_ok(rc, "Expected mbedtls sha256 start to be successful"); + + implementation = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + pos = 0; + + rc = implementation->init(NULL); + zassert_ok(rc, "Expected init to be successful"); + + rc = implementation->decompress_bytes_needed(NULL); + zassert_equal(rc, 2, "Expected to need 2 bytes for LZMA header"); + + rc = implementation->decompress(NULL, &dummy_data_input[pos], rc, false, &offset, &output, + &output_size); + zassert_ok(rc, "Expected header decompress to be successful"); + pos += offset; + + while (pos < sizeof(dummy_data_input)) { + rc = implementation->decompress_bytes_needed(NULL); + zassert_equal(rc, CONFIG_NRF_COMPRESS_CHUNK_SIZE, + "Expected to need chunk size bytes for LZMA data"); + + if ((pos + rc) >= sizeof(dummy_data_input)) { + rc = implementation->decompress(NULL, &dummy_data_input[pos], + (sizeof(dummy_data_input) - pos), true, + &offset, &output, &output_size); + pos += 1; + } else { + rc = implementation->decompress(NULL, &dummy_data_input[pos], rc, false, + &offset, &output, &output_size); + } + + zassert_ok(rc, "Expected data decompress to be successful"); + + total_output_size += output_size; + + if (output_size > 0) { + rc = mbedtls_sha256_update(&ctx, output, output_size); + zassert_ok(rc, "Expected hash update to be successful"); + } + + pos += offset; + } + + rc = implementation->deinit(NULL); + zassert_ok(rc, "Expected deinit to be successful"); + + zassert_equal(total_output_size, dummy_data_output_size, + "Expected decompressed data size to match"); + + rc = mbedtls_sha256_finish(&ctx, output_sha); + mbedtls_sha256_free(&ctx); + zassert_ok(rc, "Expected mbedtls sha256 finish to be successful"); + + zassert_mem_equal(output_sha, dummy_data_output_sha256, SHA256_SIZE, + "Expected hash to match"); +} + +ZTEST(nrf_compress_decompression, test_valid_data_too_large_decompression) +{ + int rc; + uint32_t pos; + uint32_t offset; + uint8_t *output; + uint32_t output_size; + struct nrf_compress_implementation *implementation; + + implementation = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + pos = 0; + + rc = implementation->init(NULL); + zassert_ok(rc, "Expected init to be successful"); + + rc = implementation->decompress_bytes_needed(NULL); + zassert_equal(rc, 2, "Expected to need 2 bytes for LZMA header"); + + rc = implementation->decompress(NULL, &dummy_data_too_large_input[pos], rc, false, &offset, + &output, &output_size); + zassert_ok(rc, "Expected header decompress to be successful"); + pos += offset; + + while (pos < sizeof(dummy_data_too_large_input)) { + rc = implementation->decompress_bytes_needed(NULL); + zassert_equal(rc, CONFIG_NRF_COMPRESS_CHUNK_SIZE, + "Expected to need chunk size bytes for LZMA data"); + + /* Limit input buffer size */ + if (rc > REDUCED_BUFFER_SIZE) { + rc = REDUCED_BUFFER_SIZE; + } + + if ((pos + rc) > sizeof(dummy_data_too_large_input)) { + rc = implementation->decompress(NULL, &dummy_data_too_large_input[pos], + (sizeof(dummy_data_too_large_input) - pos), + true, &offset, &output, &output_size); + pos += 1; + } else { + rc = implementation->decompress(NULL, &dummy_data_too_large_input[pos], rc, + false, &offset, &output, &output_size); + } + + if (rc != -EINVAL) { + zassert_ok(rc, "Expected data decompress to be successful"); + } + + pos += offset; + } + + (void)implementation->deinit(NULL); + + zassert_equal(rc, -EINVAL, "Expected data decompress with too large an output to fail"); +} + +ZTEST(nrf_compress_decompression, test_invalid_data_decompression) +{ + int rc; + uint32_t pos; + uint32_t offset; + uint8_t *output; + uint32_t output_size; + struct nrf_compress_implementation *implementation; + + implementation = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + /* Random offset to make data input invalid */ + pos = 38; + + rc = implementation->init(NULL); + zassert_ok(rc, "Expected init to be successful"); + + rc = implementation->decompress_bytes_needed(NULL); + zassert_equal(rc, 2, "Expected to need 2 bytes for LZMA header"); + + rc = implementation->decompress(NULL, &dummy_data_input[pos], rc, false, &offset, &output, + &output_size); + (void)implementation->deinit(NULL); + zassert_not_ok(rc, "Expected header decompress to be fail"); +} + +ZTEST(nrf_compress_decompression, test_invalid_data_data) +{ + int rc; + uint32_t pos; + uint32_t offset; + uint8_t *output; + uint32_t output_size; + uint32_t total_output_size = 0; + struct nrf_compress_implementation *implementation; + + implementation = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + pos = 0; + + rc = implementation->init(NULL); + zassert_ok(rc, "Expected init to be successful"); + + rc = implementation->decompress_bytes_needed(NULL); + zassert_equal(rc, 2, "Expected to need 2 bytes for LZMA header"); + + rc = implementation->decompress(NULL, &dummy_data_too_large_input[pos], rc, false, &offset, + &output, &output_size); + zassert_ok(rc, "Expected header decompress to be successful"); + pos += offset; + + while (pos < sizeof(dummy_data_input)) { + rc = implementation->decompress_bytes_needed(NULL); + zassert_equal(rc, CONFIG_NRF_COMPRESS_CHUNK_SIZE, + "Expected to need chunk size bytes for LZMA data"); + + /* Limit input buffer size */ + if (rc > REDUCED_BUFFER_SIZE) { + rc = REDUCED_BUFFER_SIZE; + } + + if ((pos + rc) >= sizeof(dummy_data_input)) { + rc = implementation->decompress(NULL, &dummy_data_input[pos], + (sizeof(dummy_data_input) - pos), true, + &offset, &output, &output_size); + pos += 1; + } else if (pos >= REDUCED_BUFFER_SIZE) { + /* Read in manipulated bad data */ + uint8_t bad_data[REDUCED_BUFFER_SIZE]; + uint8_t swap_data; + + memcpy(bad_data, &dummy_data_input[pos], REDUCED_BUFFER_SIZE); + swap_data = bad_data[3]; + bad_data[3] = bad_data[9]; + bad_data[9] = swap_data; + + rc = implementation->decompress(NULL, bad_data, rc, false, &offset, + &output, &output_size); + + zassert_not_ok(rc, "Expected data decompress to fail"); + + goto finish; + } else { + rc = implementation->decompress(NULL, &dummy_data_input[pos], rc, false, + &offset, &output, &output_size); + } + + zassert_ok(rc, "Expected data decompress to be successful"); + + pos += offset; + total_output_size += output_size; + } + +finish: + (void)implementation->deinit(NULL); +} + +ZTEST(nrf_compress_decompression, test_valid_data_decompression_random_sizes) +{ + int rc; + uint32_t pos; + uint32_t offset; + uint8_t *output; + uint32_t output_size; + uint32_t total_output_size = 0; + uint8_t output_sha[SHA256_SIZE] = { 0 }; + struct nrf_compress_implementation *implementation; + uint8_t loop = 0; + uint16_t read_sizes[] = { + 384, + 512, + 64, + 32, + 192, + 256 + }; + + mbedtls_sha256_context ctx; + + mbedtls_sha256_init(&ctx); + rc = mbedtls_sha256_starts(&ctx, false); + zassert_ok(rc, "Expected mbedtls sha256 start to be successful"); + + implementation = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + pos = 0; + + rc = implementation->init(NULL); + zassert_ok(rc, "Expected init to be successful"); + + rc = implementation->decompress_bytes_needed(NULL); + zassert_equal(rc, 2, "Expected to need 2 bytes for LZMA header"); + + rc = implementation->decompress(NULL, &dummy_data_input[pos], rc, false, &offset, &output, + &output_size); + zassert_ok(rc, "Expected header decompress to be successful"); + pos += offset; + + while (pos < sizeof(dummy_data_input)) { + rc = read_sizes[loop % ARRAY_SIZE(read_sizes)]; + ++loop; + + if ((pos + rc) >= sizeof(dummy_data_input)) { + rc = implementation->decompress(NULL, &dummy_data_input[pos], + (sizeof(dummy_data_input) - pos), true, + &offset, &output, &output_size); + pos += 1; + } else { + rc = implementation->decompress(NULL, &dummy_data_input[pos], rc, false, + &offset, &output, &output_size); + } + + zassert_ok(rc, "Expected data decompress to be successful"); + + total_output_size += output_size; + + if (output_size > 0) { + rc = mbedtls_sha256_update(&ctx, output, output_size); + zassert_ok(rc, "Expected hash update to be successful"); + } + + pos += offset; + } + + rc = implementation->deinit(NULL); + zassert_ok(rc, "Expected deinit to be successful"); + + zassert_equal(total_output_size, dummy_data_output_size, + "Expected decompressed data size to match"); + + rc = mbedtls_sha256_finish(&ctx, output_sha); + mbedtls_sha256_free(&ctx); + zassert_ok(rc, "Expected mbedtls sha256 finish to be successful"); + + zassert_mem_equal(output_sha, dummy_data_output_sha256, SHA256_SIZE, + "Expected hash to match"); +} + +ZTEST(nrf_compress_decompression, test_valid_data_decompression_reset) +{ + int rc; + uint32_t pos; + uint32_t offset; + uint8_t *output; + uint32_t output_size; + uint32_t total_output_size = 0; + uint8_t output_sha[SHA256_SIZE] = { 0 }; + struct nrf_compress_implementation *implementation; + mbedtls_sha256_context ctx; + + mbedtls_sha256_init(&ctx); + rc = mbedtls_sha256_starts(&ctx, false); + zassert_ok(rc, "Expected mbedtls sha256 start to be successful"); + + implementation = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + pos = 0; + + rc = implementation->init(NULL); + zassert_ok(rc, "Expected init to be successful"); + + rc = implementation->decompress_bytes_needed(NULL); + zassert_equal(rc, 2, "Expected to need 2 bytes for LZMA header"); + + rc = implementation->decompress(NULL, &dummy_data_input[pos], rc, false, &offset, &output, + &output_size); + zassert_ok(rc, "Expected header decompress to be successful"); + pos += offset; + + rc = implementation->decompress(NULL, &dummy_data_input[pos], REDUCED_BUFFER_SIZE, false, + &offset, &output, &output_size); + zassert_ok(rc, "Expected data decompress to be successful"); + pos += offset; + + rc = implementation->decompress(NULL, &dummy_data_input[pos], REDUCED_BUFFER_SIZE, false, + &offset, &output, &output_size); + zassert_ok(rc, "Expected data decompress to be successful"); + + pos = 0; + implementation->reset(NULL); + + rc = implementation->decompress_bytes_needed(NULL); + zassert_equal(rc, 2, "Expected to need 2 bytes for LZMA header"); + + rc = implementation->decompress(NULL, &dummy_data_input[pos], rc, false, &offset, &output, + &output_size); + zassert_ok(rc, "Expected header decompress to be successful"); + pos += offset; + + while (pos < sizeof(dummy_data_input)) { + rc = implementation->decompress_bytes_needed(NULL); + zassert_equal(rc, CONFIG_NRF_COMPRESS_CHUNK_SIZE, + "Expected to need chunk size bytes for LZMA data"); + + if ((pos + rc) >= sizeof(dummy_data_input)) { + rc = implementation->decompress(NULL, &dummy_data_input[pos], + (sizeof(dummy_data_input) - pos), true, + &offset, &output, &output_size); + pos += 1; + } else { + rc = implementation->decompress(NULL, &dummy_data_input[pos], rc, false, + &offset, &output, &output_size); + } + + zassert_ok(rc, "Expected data decompress to be successful"); + + total_output_size += output_size; + + if (output_size > 0) { + rc = mbedtls_sha256_update(&ctx, output, output_size); + zassert_ok(rc, "Expected hash update to be successful"); + } + + pos += offset; + } + + rc = implementation->deinit(NULL); + zassert_ok(rc, "Expected deinit to be successful"); + + zassert_equal(total_output_size, dummy_data_output_size, + "Expected decompressed data size to match"); + + rc = mbedtls_sha256_finish(&ctx, output_sha); + mbedtls_sha256_free(&ctx); + zassert_ok(rc, "Expected mbedtls sha256 finish to be successful"); + + zassert_mem_equal(output_sha, dummy_data_output_sha256, SHA256_SIZE, + "Expected hash to match"); +} + +ZTEST(nrf_compress_decompression, test_invalid_lzma1) +{ + int rc; + uint32_t pos; + uint32_t offset; + uint8_t *output; + uint32_t output_size; + struct nrf_compress_implementation *implementation; + + implementation = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + /* Random offset to make data input invalid */ + pos = 38; + + rc = implementation->init(NULL); + zassert_ok(rc, "Expected init to be successful"); + + rc = implementation->decompress_bytes_needed(NULL); + zassert_equal(rc, 2, "Expected to need 2 bytes for LZMA header"); + + rc = implementation->decompress(NULL, &dummy_data_lzma1_input[pos], rc, false, &offset, + &output, &output_size); + (void)implementation->deinit(NULL); + zassert_not_ok(rc, "Expected header decompress to be fail"); +} + +ZTEST(nrf_compress_decompression, test_too_large_malloc) +{ +#if defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_MALLOC) && !defined(CONFIG_SOC_POSIX) + int rc; + uint32_t offset; + uint8_t *output; + uint32_t output_size; + struct nrf_compress_implementation *implementation; + + /* Malloc data to reduce available heap for decompression library */ + large_malloc_object = (uint8_t *)malloc(4264); + zassert_not_null(large_malloc_object, "Expected large malloc to be successful"); + + implementation = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + + rc = implementation->init(NULL); + zassert_ok(rc, "Expected init to be successful"); + + rc = implementation->decompress_bytes_needed(NULL); + zassert_equal(rc, 2, "Expected to need 2 bytes for LZMA header"); + + rc = implementation->decompress(NULL, dummy_data_input, rc, false, &offset, &output, + &output_size); + zassert_not_ok(rc, "Expected header decompress to be fail"); + + (void)implementation->deinit(NULL); + zassert_not_ok(rc, "Expected header decompress to be fail"); + + free(large_malloc_object); + large_malloc_object = NULL; +#else + ztest_test_skip(); +#endif +} + +static void cleanup_test(void *p) +{ +#if defined(CONFIG_NRF_COMPRESS_MEMORY_TYPE_MALLOC) && !defined(CONFIG_SOC_POSIX) + if (large_malloc_object != NULL) { + free(large_malloc_object); + large_malloc_object = NULL; + } +#endif +} + +ZTEST_SUITE(nrf_compress_decompression, NULL, NULL, NULL, cleanup_test, NULL); diff --git a/tests/subsys/nrf_compress/decompression/lzma/testcase.yaml b/tests/subsys/nrf_compress/decompression/lzma/testcase.yaml new file mode 100644 index 000000000000..bf0016fd8a22 --- /dev/null +++ b/tests/subsys/nrf_compress/decompression/lzma/testcase.yaml @@ -0,0 +1,20 @@ +common: + sysbuild: true + tags: compress decompression lzma sysbuild + platform_allow: + - native_sim + - nrf52840dk/nrf52840 + - nrf5340dk/nrf5340/cpuapp + - nrf5340dk/nrf5340/cpuapp/ns + integration_platforms: + - native_sim + - nrf52840dk/nrf52840 + - nrf5340dk/nrf5340/cpuapp + - nrf5340dk/nrf5340/cpuapp/ns +tests: + nrf_compress.decompression.lzma.static: {} + nrf_compress.decompression.lzma.dynamic: + extra_configs: + - CONFIG_NRF_COMPRESS_MEMORY_TYPE_MALLOC=y + - CONFIG_COMMON_LIBC_MALLOC=y + - CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=162000 From 1084478bfb7f3867468979f57b536d6bbc2020ab Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 1 Aug 2024 07:18:43 +0100 Subject: [PATCH 35/72] doc: release: Add note on compress library Adds a note that the compress library has been added with decompression support for lzma Signed-off-by: Jamie McCrae --- .../releases_and_maturity/releases/release-notes-changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index e535837506dc..8eb0eda6e190 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -732,7 +732,7 @@ nRF RPC libraries Other libraries --------------- -|no_changes_yet_note| +* Added a compression/decompression library with support for the LZMA decompression. Security libraries ------------------ From 89219c8c11b9d4c38fe23e8eae0448e4a926ce83 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 1 Aug 2024 15:17:47 +0100 Subject: [PATCH 36/72] codeowners: Add entry for compress subsystem Adds an entry for maintainer of nRF compress subsystem Signed-off-by: Jamie McCrae --- CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CODEOWNERS b/CODEOWNERS index 642c75d71d63..47c3f183f0d1 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -109,6 +109,7 @@ Kconfig* @tejlmand /include/mpsl/ @nrfconnect/ncs-dragoon /include/net/ @rlubos /include/nfc/ @anangl @grochu +/include/nrf_compress/ @nordicjm /include/sdfw/ @anhmolt @hakonfam @jonathannilsen /include/shell/ @nordic-krch /lib/bin/ @rlubos @lemrey @@ -263,6 +264,7 @@ Kconfig* @tejlmand /subsys/bluetooth/services/wifi_prov/ @wentong-li @bama-nordic /subsys/bootloader/ @hakonfam @sigvartmh /subsys/caf/ @pdunaj +/subsys/nrf_compress/ @nordicjm /subsys/debug/ @nordic-krch @anangl /subsys/dfu/ @hakonfam @sigvartmh /subsys/dfu/dfu_multi_image/ @Damian-Nordic @@ -314,6 +316,7 @@ Kconfig* @tejlmand /tests/benchmarks/multicore/ @carlescufi /tests/bluetooth/tester/ @carlescufi @nrfconnect/ncs-paladin /tests/bluetooth/iso/ @nrfconnect/ncs-audio @Frodevan +/tests/subsys/nrf_compress/ @nordicjm /tests/crypto/ @stephen-nordic @magnev /tests/drivers/flash_patch/ @oyvindronningstad /tests/drivers/flash/flash_rpc/ @sigvartmh From cb750ce65de8685c727bc1c4d45be43eadb9c0ac Mon Sep 17 00:00:00 2001 From: Henrik Lander Date: Tue, 27 Aug 2024 08:26:32 +0200 Subject: [PATCH 37/72] Samples: Bluetooth: fix iso_time_sync sample Add temporary workaround to fix iso_time_sync sample while we are waiting for bug fix upstream. The fix upstream was merged here in https://github.com/zephyrproject-rtos/zephyr/pull/76688 Signed-off-by: Henrik Lander --- samples/bluetooth/iso_time_sync/sysbuild/hci_ipc/prj.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/bluetooth/iso_time_sync/sysbuild/hci_ipc/prj.conf b/samples/bluetooth/iso_time_sync/sysbuild/hci_ipc/prj.conf index 3f934cb7b189..3cc891ef2dfe 100644 --- a/samples/bluetooth/iso_time_sync/sysbuild/hci_ipc/prj.conf +++ b/samples/bluetooth/iso_time_sync/sysbuild/hci_ipc/prj.conf @@ -21,7 +21,7 @@ CONFIG_BT_CTLR_ADV_ISO_STREAM_COUNT=4 CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT=4 CONFIG_BT_CTLR_CONN_ISO_STREAMS=4 -CONFIG_BT_ISO_TX_MTU=5 +CONFIG_BT_ISO_TX_MTU=6 # To present the audio at the right point in time, we need the controller and # audio clock to be synchronized From 3d33b7673b66cf6b62cf72fa2ff0f290530041b4 Mon Sep 17 00:00:00 2001 From: Mateusz Kapala Date: Wed, 21 Aug 2024 13:20:09 +0200 Subject: [PATCH 38/72] samples: bluetooth: fast_pair: locator_tag: Rework ipc_radio configs Split ipc_radio image configuration for debug (prj.conf) and release (prj_release.conf). Enabled logs in debug configuration, while disabled in release one. Jira: NCSDK-28458 Signed-off-by: Mateusz Kapala --- .../releases/release-notes-changelog.rst | 4 ++ .../nrf5340dk_nrf5340_cpuapp/sysbuild.conf | 1 - .../nrf5340dk_nrf5340_cpuapp_ns/sysbuild.conf | 1 - .../thingy53_nrf5340_cpuapp/sysbuild.conf | 1 - .../thingy53_nrf5340_cpuapp_ns/sysbuild.conf | 1 - .../boards/thingy53_nrf5340_cpunet.conf | 6 +++ .../thingy53_nrf5340_cpunet_release.conf | 9 +++++ .../locator_tag/sysbuild/ipc_radio/prj.conf | 26 +++++++++---- .../sysbuild/ipc_radio/prj_release.conf | 37 +++++++++++++++++++ 9 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/boards/thingy53_nrf5340_cpunet_release.conf create mode 100644 samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/prj_release.conf diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index 8eb0eda6e190..0df691d04981 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -319,6 +319,10 @@ Bluetooth Fast Pair samples * The values for the :kconfig:option:`CONFIG_BT_ADV_PROV_TX_POWER_CORRECTION_VAL` Kconfig option in all configurations, and for the :kconfig:option:`CONFIG_BT_FAST_PAIR_FMDN_TX_POWER_CORRECTION_VAL` Kconfig option in configurations with the Find My Device Network (FMDN) extension support. The values are now aligned with the Fast Pair requirements. +* :ref:`fast_pair_locator_tag` sample: + + * Updated the :ref:`ipc_radio` image configuration by splitting it into the debug and release configurations. + Bluetooth Mesh samples ---------------------- diff --git a/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/nrf5340dk_nrf5340_cpuapp/sysbuild.conf b/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/nrf5340dk_nrf5340_cpuapp/sysbuild.conf index fadce94a9c8f..99ac6bded98b 100644 --- a/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/nrf5340dk_nrf5340_cpuapp/sysbuild.conf +++ b/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/nrf5340dk_nrf5340_cpuapp/sysbuild.conf @@ -5,7 +5,6 @@ # SB_CONFIG_NETCORE_IPC_RADIO=y -SB_CONFIG_NETCORE_IPC_RADIO_BT_HCI_IPC=y SB_CONFIG_BOOTLOADER_MCUBOOT=y SB_CONFIG_MCUBOOT_MODE_OVERWRITE_ONLY=y diff --git a/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/nrf5340dk_nrf5340_cpuapp_ns/sysbuild.conf b/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/nrf5340dk_nrf5340_cpuapp_ns/sysbuild.conf index c3a87bbc6d80..f60ca164d19f 100644 --- a/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/nrf5340dk_nrf5340_cpuapp_ns/sysbuild.conf +++ b/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/nrf5340dk_nrf5340_cpuapp_ns/sysbuild.conf @@ -5,7 +5,6 @@ # SB_CONFIG_NETCORE_IPC_RADIO=y -SB_CONFIG_NETCORE_IPC_RADIO_BT_HCI_IPC=y SB_CONFIG_BOOTLOADER_MCUBOOT=y SB_CONFIG_MCUBOOT_MODE_OVERWRITE_ONLY=y diff --git a/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/thingy53_nrf5340_cpuapp/sysbuild.conf b/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/thingy53_nrf5340_cpuapp/sysbuild.conf index b4dfe14f1d79..eb7bb83af2f4 100644 --- a/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/thingy53_nrf5340_cpuapp/sysbuild.conf +++ b/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/thingy53_nrf5340_cpuapp/sysbuild.conf @@ -5,6 +5,5 @@ # SB_CONFIG_NETCORE_IPC_RADIO=y -SB_CONFIG_NETCORE_IPC_RADIO_BT_HCI_IPC=y # Bootloader configuration is set at the Thingy:53 board level diff --git a/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/thingy53_nrf5340_cpuapp_ns/sysbuild.conf b/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/thingy53_nrf5340_cpuapp_ns/sysbuild.conf index b4dfe14f1d79..eb7bb83af2f4 100644 --- a/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/thingy53_nrf5340_cpuapp_ns/sysbuild.conf +++ b/samples/bluetooth/fast_pair/locator_tag/sysbuild/configuration/thingy53_nrf5340_cpuapp_ns/sysbuild.conf @@ -5,6 +5,5 @@ # SB_CONFIG_NETCORE_IPC_RADIO=y -SB_CONFIG_NETCORE_IPC_RADIO_BT_HCI_IPC=y # Bootloader configuration is set at the Thingy:53 board level diff --git a/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/boards/thingy53_nrf5340_cpunet.conf b/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/boards/thingy53_nrf5340_cpunet.conf index 6b240a5116ac..c74dffafd159 100644 --- a/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/boards/thingy53_nrf5340_cpunet.conf +++ b/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/boards/thingy53_nrf5340_cpunet.conf @@ -7,3 +7,9 @@ # The FEM TX gain must be changed to achieve the 0 dBm TX power on the # Bluetooth controller side. CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB=20 + +# Disable logging (only logs from cpuapp are provided using the USB CDC ACM) +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n +CONFIG_LOG_MODE_MINIMAL=n diff --git a/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/boards/thingy53_nrf5340_cpunet_release.conf b/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/boards/thingy53_nrf5340_cpunet_release.conf new file mode 100644 index 000000000000..6b240a5116ac --- /dev/null +++ b/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/boards/thingy53_nrf5340_cpunet_release.conf @@ -0,0 +1,9 @@ +# +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# The FEM TX gain must be changed to achieve the 0 dBm TX power on the +# Bluetooth controller side. +CONFIG_MPSL_FEM_NRF21540_TX_GAIN_DB=20 diff --git a/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/prj.conf b/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/prj.conf index bd05423e89bc..74712bef9cf7 100644 --- a/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/prj.conf +++ b/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/prj.conf @@ -4,16 +4,31 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # -CONFIG_IPC_SERVICE=y -CONFIG_MBOX=y - CONFIG_HEAP_MEM_POOL_SIZE=8192 - CONFIG_MAIN_STACK_SIZE=512 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512 +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_LOG=y +CONFIG_LOG_MODE_MINIMAL=y + +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y + +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + CONFIG_BT=y CONFIG_BT_HCI_RAW=y +CONFIG_BT_CTLR_ASSERT_HANDLER=y + +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y + +# Error handling configuration +CONFIG_RESET_ON_FATAL_ERROR=n # Align Bluetooth controller configuration on the Network Core # with Locator Tag sample requirements. @@ -25,6 +40,3 @@ CONFIG_BT_BUF_ACL_TX_SIZE=87 CONFIG_BT_BUF_ACL_RX_SIZE=87 CONFIG_BT_CTLR_DATA_LENGTH_MAX=87 CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y - -CONFIG_IPC_RADIO_BT=y -CONFIG_IPC_RADIO_BT_HCI_IPC=y diff --git a/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/prj_release.conf b/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/prj_release.conf new file mode 100644 index 000000000000..2ea666806521 --- /dev/null +++ b/samples/bluetooth/fast_pair/locator_tag/sysbuild/ipc_radio/prj_release.conf @@ -0,0 +1,37 @@ +# +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=512 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512 + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_CTLR_ASSERT_HANDLER=y + +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y + +# Error handling configuration +CONFIG_RESET_ON_FATAL_ERROR=y + +# Align Bluetooth controller configuration on the Network Core +# with Locator Tag sample requirements. +CONFIG_BT_CENTRAL=n +CONFIG_BT_MAX_CONN=3 +CONFIG_BT_EXT_ADV=y +CONFIG_BT_EXT_ADV_MAX_ADV_SET=2 +CONFIG_BT_BUF_ACL_TX_SIZE=87 +CONFIG_BT_BUF_ACL_RX_SIZE=87 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=87 +CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y From a8ea23813b59e40e5999636063b15d629eea373f Mon Sep 17 00:00:00 2001 From: Nordic Builder Date: Fri, 5 Jul 2024 14:20:12 +0000 Subject: [PATCH 39/72] manifest: Update sdk-find-my revision (auto-manifest PR) Automatically created by Github Action Signed-off-by: Nordic Builder --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 21ceb18967b4..55a67dcfef18 100644 --- a/west.yml +++ b/west.yml @@ -223,7 +223,7 @@ manifest: - sidewalk - name: find-my repo-path: sdk-find-my - revision: fccf8ecac55c9ee8875f4f06cd06f1e50d4897bf + revision: a764b0c41781dd682835ddc73c5ddfffa0bca833 groups: - find-my - name: azure-sdk-for-c From 3d2536083c1cba5b2540a147b2c60704ff383b54 Mon Sep 17 00:00:00 2001 From: Arkadiusz Balys Date: Mon, 26 Aug 2024 16:16:13 +0200 Subject: [PATCH 40/72] doc: known_issue: Add an entry for Openthread CLI sample Added a known issue entry for Openthread CLI sample issue regarding the USB and Partition Manager. Signed-off-by: Arkadiusz Balys --- doc/nrf/releases_and_maturity/known_issues.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/nrf/releases_and_maturity/known_issues.rst b/doc/nrf/releases_and_maturity/known_issues.rst index 06a31d042b0d..65ed9213abfc 100644 --- a/doc/nrf/releases_and_maturity/known_issues.rst +++ b/doc/nrf/releases_and_maturity/known_issues.rst @@ -831,6 +831,16 @@ Thread The issues in this section are related to the :ref:`ug_thread` protocol. +.. rst-class:: v2-7-0 + +KRKNWK-19376: OpenThread CLI sample does not work on the nRF52840 Dongle + The sample should not use Partition Manager. + To avoid a failure, the main function should have a check for whether the USB is already enabled. + + **Affected platforms:** nRF52840 Dongle + + **Workaround:** Manually cherry-pick and apply commit with fix from ``main`` (commit hash: ``f7b59d26db4cc55c6936a0a88f3daa7e0b7b2085``). + .. rst-class:: v2-7-0 v2-6-1 v2-6-0 KRKNWK-19036: High power consumption after parent loss From 3006c526de6da3bf3cfe02e350a069a403e93137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ga=C5=82da?= Date: Wed, 29 May 2024 14:30:31 +0200 Subject: [PATCH 41/72] toolchain: Python 3.12 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use Python 3.12 in Linux toolchain bundle Signed-off-by: Jan Gałda --- scripts/requirements-extra.txt | 2 +- scripts/requirements-fixed.txt | 28 +++++++++++++--------------- scripts/tools-versions-linux.yml | 2 +- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/scripts/requirements-extra.txt b/scripts/requirements-extra.txt index cceb84d9b118..7aeb60354fbb 100644 --- a/scripts/requirements-extra.txt +++ b/scripts/requirements-extra.txt @@ -1,4 +1,4 @@ -pygit2<=1.10 +pygit2>=1.15.0 Pillow>=10.3.0 # https://github.com/advisories/GHSA-44wm-f244-xhp3 editdistance>=0.5.0 PyGithub diff --git a/scripts/requirements-fixed.txt b/scripts/requirements-fixed.txt index 182fa505b9ac..b0198fa87bb8 100644 --- a/scripts/requirements-fixed.txt +++ b/scripts/requirements-fixed.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.9 +# This file is autogenerated by pip-compile with Python 3.12 # by the following command: # # pip-compile --allow-unsafe --annotation-style=line --output-file=nrf/scripts/requirements-fixed.txt --strip-extras bootloader/mcuboot/scripts/requirements.txt nrf/scripts/requirements-ci.txt nrf/scripts/requirements-extra.txt nrf/scripts/requirements.txt zephyr/scripts/requirements.txt @@ -17,7 +17,7 @@ capstone==4.0.2 # via pyocd cbor==1.0.0 # via -r zephyr/scripts/requirements-run-test.txt cbor2==5.4.6 # via -r bootloader/mcuboot/scripts/requirements.txt, -r nrf/scripts/requirements-build.txt, imgtool, zcbor certifi==2024.7.4 # via -r nrf/scripts/requirements-base.txt, requests -cffi==1.15.1 # via cmsis-pack-manager, cryptography, milksnake, pygit2, pynacl +cffi==1.16.0 # via cmsis-pack-manager, cryptography, milksnake, pygit2, pynacl chardet==5.2.0 # via -r nrf/scripts/requirements-ci.txt charset-normalizer==3.2.0 # via requests clang-format==17.0.1 # via -r nrf/scripts/requirements-build.txt, -r zephyr/scripts/requirements-extras.txt @@ -31,8 +31,7 @@ devicetree==0.0.2 # via nrf-regtool dill==0.3.7 # via pylint docopt==0.6.2 # via pykwalify ecdsa==0.18.0 # via -r nrf/scripts/requirements-build.txt -editdistance==0.6.2 # via -r nrf/scripts/requirements-extra.txt -exceptiongroup==1.1.3 # via pytest +editdistance==0.8.1 # via -r nrf/scripts/requirements-extra.txt future==0.18.3 # via junitparser gcovr==6.0 # via -r zephyr/scripts/requirements-build-test.txt gitdb==4.0.10 # via gitpython @@ -40,13 +39,13 @@ gitlint==0.18.0 # via -r nrf/scripts/requirements-ci.txt, -r zephyr/sc gitlint-core==0.18.0 # via gitlint gitpython==3.1.41 # via -r nrf/scripts/requirements-ci.txt graphviz==0.20.1 # via -r zephyr/scripts/requirements-extras.txt -grpcio==1.58.0 # via grpcio-tools -grpcio-tools==1.58.0 # via -r zephyr/scripts/requirements-extras.txt +grpcio==1.64.1 # via grpcio-tools +grpcio-tools==1.64.1 # via -r zephyr/scripts/requirements-extras.txt idna==3.7 # via -r nrf/scripts/requirements-extra.txt, requests imagesize==1.4.1 # via -r nrf/scripts/requirements-build.txt imgtool==2.0.0 # via -r zephyr/scripts/requirements-extras.txt importlib-metadata==6.8.0 # via pyocd -importlib-resources==6.1.0 # via libusb-package, pyocd +importlib-resources==6.1.0 # via pyocd iniconfig==2.0.0 # via pytest intelhex==2.3.0 # via -r bootloader/mcuboot/scripts/requirements.txt, -r nrf/scripts/requirements-build.txt, -r zephyr/scripts/requirements-base.txt, imgtool, lpc-checksum, nrf-regtool, pyocd intervaltree==3.1.0 # via pyocd @@ -58,7 +57,7 @@ junit2html==30.1.3 # via -r zephyr/scripts/requirements-extras.txt junitparser==3.1.0 # via -r zephyr/scripts/requirements-compliance.txt lark==1.1.7 # via pyocd libusb==1.0.27 # via -r nrf/scripts/requirements-extra.txt -libusb-package==1.0.26.2 # via pyocd +libusb-package==1.0.26.1 # via pyocd lpc-checksum==2.2.0 # via -r zephyr/scripts/requirements-extras.txt lxml==4.9.3 # via -r zephyr/scripts/requirements-compliance.txt, gcovr, svada markupsafe==2.1.3 # via jinja2 @@ -82,12 +81,12 @@ pluggy==1.3.0 # via pytest ply==3.11 # via -r zephyr/scripts/requirements-build-test.txt prettytable==3.9.0 # via pyocd progress==1.6 # via -r zephyr/scripts/requirements-base.txt -protobuf==4.24.3 # via -r zephyr/scripts/requirements-extras.txt, grpcio-tools +protobuf==5.27.1 # via -r zephyr/scripts/requirements-extras.txt, grpcio-tools psutil==5.9.5 # via -r zephyr/scripts/requirements-base.txt, -r zephyr/scripts/requirements-run-test.txt, pylink-square py==1.11.0 # via -r nrf/scripts/requirements-ci.txt pycparser==2.21 # via cffi pyelftools==0.30 # via -r zephyr/scripts/requirements-base.txt, pyocd -pygit2==1.10.0 # via -r nrf/scripts/requirements-extra.txt +pygit2==1.15.0 # via -r nrf/scripts/requirements-extra.txt pygithub==1.59.1 # via -r nrf/scripts/requirements-extra.txt, -r zephyr/scripts/requirements-extras.txt pygments==2.16.1 # via gcovr pyjwt==2.8.0 # via pygithub @@ -113,7 +112,6 @@ regex==2023.8.8 # via zcbor requests==2.32.0 # via -r zephyr/scripts/requirements-base.txt, pygithub rpds-py==0.10.3 # via jsonschema, referencing ruamel-yaml==0.17.32 # via pykwalify -ruamel-yaml-clib==0.2.7 # via ruamel-yaml setuptools-scm==8.0.4 # via svada sh==1.14.2 # via gitlint-core six==1.16.0 # via anytree, ecdsa, pylink-square, pyocd, python-dateutil @@ -123,10 +121,10 @@ stringcase==1.2.0 # via -r nrf/scripts/requirements-ci.txt svada==2.0.2 # via nrf-regtool tabulate==0.9.0 # via -r zephyr/scripts/requirements-run-test.txt toml==0.10.2 # via -r nrf/scripts/requirements-ci.txt -tomli==2.0.1 # via mypy, nrf-regtool, pkg-about, pylint, pytest, setuptools-scm +tomli==2.0.1 # via nrf-regtool tomlkit==0.12.1 # via pylint typed-ast==1.5.5 # via -r nrf/scripts/requirements-ci.txt -typing-extensions==4.8.0 # via astroid, mypy, pylint, pyocd, python-can, qrcode, setuptools-scm, svada +typing-extensions==4.8.0 # via mypy, pyocd, python-can, qrcode, setuptools-scm, svada urllib3==2.2.2 # via requests wcwidth==0.2.6 # via prettytable west==1.2.0 # via -r nrf/scripts/requirements-base.txt, -r zephyr/scripts/requirements-base.txt @@ -134,7 +132,7 @@ wget==3.2 # via -r nrf/scripts/requirements-ci.txt wrapt==1.15.0 # via deprecated, python-can yamllint==1.32.0 # via -r zephyr/scripts/requirements-compliance.txt zcbor==0.8.1 # via -r nrf/scripts/requirements-build.txt, -r nrf/scripts/requirements-extra.txt, -r zephyr/scripts/requirements-extras.txt -zipp==3.17.0 # via importlib-metadata, importlib-resources +zipp==3.17.0 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: -setuptools==68.2.2 # via grpcio-tools, libusb, pkg-about, python-can, setuptools-scm, west +setuptools==70.1.0 # via grpcio-tools, libusb, pkg-about, python-can, setuptools-scm, west diff --git a/scripts/tools-versions-linux.yml b/scripts/tools-versions-linux.yml index 3907c404a049..dbea6e7faf3c 100644 --- a/scripts/tools-versions-linux.yml +++ b/scripts/tools-versions-linux.yml @@ -1,5 +1,5 @@ python: - version: 3.9.18 + version: 3.12.4 git: version: 2.37.3 cmake: From 9d6898a0a2fe1b8f666687294da224255cced1d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ga=C5=82da?= Date: Mon, 26 Aug 2024 10:01:44 +0200 Subject: [PATCH 42/72] scripts: Replace deprecated pygit oid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove deprecated object.oid, use object.id https://github.com/libgit2/pygit2/blob/master/CHANGELOG.md Signed-off-by: Jan Gałda --- .github/workflows/west-commands.yml | 48 +++++++++++------------ scripts/west_commands/ncs_commands.py | 22 +++++------ scripts/west_commands/ncs_west_helpers.py | 2 +- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/.github/workflows/west-commands.yml b/.github/workflows/west-commands.yml index 0eb54f61bac5..a795e86b8b63 100644 --- a/.github/workflows/west-commands.yml +++ b/.github/workflows/west-commands.yml @@ -14,27 +14,27 @@ jobs: runs-on: ubuntu-latest name: Run Python checks for west commands on patch series (PR) steps: - - name: Checkout the code - uses: actions/checkout@v3 - with: - path: ncs/nrf - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - - name: cache-pip - uses: actions/cache@v3 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-doc-pip - - name: Install python dependencies - working-directory: ncs/nrf - run: | - pip3 install -U pip - pip3 install -U setuptools - pip3 install -U wheel - pip3 install -U mypy types-colorama types-editdistance types-PyYAML - grep -E "west" scripts/requirements-fixed.txt | xargs pip3 install -U - pip3 show -f west - - name: Run mypy - working-directory: ncs/nrf/scripts/west_commands - run: | - python3 -m mypy --config-file mypy.ini ncs_west_helpers.py pygit2_helpers.py ncs_commands.py + - name: Checkout the code + uses: actions/checkout@v3 + with: + path: ncs/nrf + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + - name: cache-pip + uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-doc-pip + - name: Install python dependencies + working-directory: ncs/nrf + run: | + pip3 install -U pip + pip3 install -U setuptools + pip3 install -U wheel + pip3 install -U mypy types-colorama types-editdistance types-PyYAML + grep -E "west==" scripts/requirements-fixed.txt | cut -f1 -d"#" | xargs pip3 install -U + pip3 show -f west + - name: Run mypy + working-directory: ncs/nrf/scripts/west_commands + run: | + python3 -m mypy --config-file mypy.ini ncs_west_helpers.py pygit2_helpers.py ncs_commands.py diff --git a/scripts/west_commands/ncs_commands.py b/scripts/west_commands/ncs_commands.py index 8297bc81515f..9c4a9afdf3f0 100644 --- a/scripts/west_commands/ncs_commands.py +++ b/scripts/west_commands/ncs_commands.py @@ -100,14 +100,14 @@ def print_likely_merged(downstream_repo: nwh.Repository, '(revert these if appropriate):', color=log.WRN_COLOR) for downstream_commit, upstream_commits in likely_merged.items(): if len(upstream_commits) == 1: - log.inf(f'- {downstream_commit.oid} {commit_title(downstream_commit)}') + log.inf(f'- {downstream_commit.id} {commit_title(downstream_commit)}') log.inf(f' Similar upstream title:\n' - f' {upstream_commits[0].oid} {commit_title(upstream_commits[0])}') + f' {upstream_commits[0].id} {commit_title(upstream_commits[0])}') else: - log.inf(f'- {downstream_commit.oid} {commit_title(downstream_commit)}\n' + log.inf(f'- {downstream_commit.id} {commit_title(downstream_commit)}\n' ' Similar upstream titles:') for i, upstream_commit in enumerate(upstream_commits, start=1): - log.inf(f' {i}. {upstream_commit.oid} {commit_title(upstream_commit)}') + log.inf(f' {i}. {upstream_commit.id} {commit_title(upstream_commit)}') else: log.dbg('no downstream patches seem to have been merged upstream') @@ -382,11 +382,11 @@ def print_loot(self, for index, commit in enumerate(loot): if self.args.files and not commit_affects_files(commit, self.args.files): - log.dbg(f"skipping {commit.oid}; it doesn't affect file filter", + log.dbg(f"skipping {commit.id}; it doesn't affect file filter", level=log.VERBOSE_VERY) continue - sha = str(commit.oid) + sha = str(commit.id) title = commit_title(commit) if self.args.sha_only: log.inf(sha) @@ -705,15 +705,15 @@ def upmerge(self, name: str, project: Project, z_project: Project) -> None: for dc, ucs in reversed(analyzer.likely_merged.items()): if len(ucs) == 1: - log.inf(f'- Reverting: {dc.oid} {commit_title(dc)}') + log.inf(f'- Reverting: {dc.id} {commit_title(dc)}') log.inf(f' Similar upstream title:\n' - f' {ucs[0].oid} {commit_title(ucs[0])}') + f' {ucs[0].id} {commit_title(ucs[0])}') else: - log.inf(f'- Reverting: {dc.oid} {commit_title(dc)}\n' + log.inf(f'- Reverting: {dc.id} {commit_title(dc)}\n' ' Similar upstream titles:') for i, uc in enumerate(ucs, start=1): - log.inf(f' {i}. {uc.oid} {commit_title(uc)}') - project.git('revert --signoff --no-edit ' + str(dc.oid)) + log.inf(f' {i}. {uc.id} {commit_title(uc)}') + project.git('revert --signoff --no-edit ' + str(dc.id)) log.inf(f'Merging: {z_rev} to project: {project.name}') msg = f"[nrf mergeup] Merge upstream automatically up to commit {z_sha}\n\nThis auto-upmerge was performed with ncs-upmerger script." project.git('merge --no-edit --no-ff --signoff -m "' + msg + '" ' + str(self.zephyr_rev)) diff --git a/scripts/west_commands/ncs_west_helpers.py b/scripts/west_commands/ncs_west_helpers.py index 13d5e2ed6ea5..7f1cf377ead6 100644 --- a/scripts/west_commands/ncs_west_helpers.py +++ b/scripts/west_commands/ncs_west_helpers.py @@ -206,7 +206,7 @@ def _downstream_outstanding_commits(self) -> list[pygit2.Commit]: # complete list of OOT patches. downstream_out: dict[str, pygit2.Commit] = {} for c in all_downstream_oot: - sha, sl = str(c.oid), commit_title(c) + sha, sl = str(c.id), commit_title(c) is_revert = title_is_revert(sl) # this is just a heuristic if len(c.parents) > 1: From 6090e453452848ae0b06815f716d6e494c0da5c1 Mon Sep 17 00:00:00 2001 From: Nordic Builder Date: Wed, 28 Aug 2024 07:41:09 +0000 Subject: [PATCH 43/72] manifest: Update sdk-zephyr revision (auto-manifest PR) Automatically created by Github Action Signed-off-by: Nordic Builder --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 55a67dcfef18..5e58b2a16b1f 100644 --- a/west.yml +++ b/west.yml @@ -72,7 +72,7 @@ manifest: # https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/modules.html - name: zephyr repo-path: sdk-zephyr - revision: 468d06db5542594fe9e6420fd2e1fe30d9209699 + revision: a415e2d702d5192ffdf7ddf67fa73f8fab70a277 import: # In addition to the zephyr repository itself, NCS also # imports the contents of zephyr/west.yml at the above From 24fc0a931dac5e6ec286d4aefc6bc34a468d0002 Mon Sep 17 00:00:00 2001 From: Torsten Robitzki Date: Wed, 27 Mar 2024 11:38:45 +0100 Subject: [PATCH 44/72] cmake: multi_image: Forward CROSS_COMPILE According to the Zephyr documentation, ZEPHYR_TOOLCHAIN_VARIANT take the value of `cross-compile`, in which case, the additional variable CROSS_COMPILE has to be set to a common path prefix. If this CROSS_COMPILE is not forwarded to the build of sub images, the build will fail. (https://docs.zephyrproject.org/latest/develop/toolchains/other_x_compilers.html) Signed-off-by: Torsten Robitzki --- cmake/multi_image.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/multi_image.cmake b/cmake/multi_image.cmake index 9ca1278653c9..8eafc3349b49 100644 --- a/cmake/multi_image.cmake +++ b/cmake/multi_image.cmake @@ -392,6 +392,7 @@ function(add_child_image_from_source) ZEPHYR_MODULES ZEPHYR_EXTRA_MODULES ZEPHYR_TOOLCHAIN_VARIANT + CROSS_COMPILE GNUARMEMB_TOOLCHAIN_PATH EXTRA_KCONFIG_TARGETS NCS_TOOLCHAIN_VERSION From 038bf007f86b65596d26577a2ea46f687731a3ad Mon Sep 17 00:00:00 2001 From: Wille Backman Date: Wed, 14 Aug 2024 13:33:41 +0300 Subject: [PATCH 45/72] doc: bluetooth: Earlier reference to QDID in Bluetooth qualification The Bluetooth qualification page mentions Bluetooth QDID in a couple of places, but the information is inside very specific sections. This adds it much earlier on the page, and gives general instructions on how to find it for Nordic devices. Signed-off-by: Wille Backman --- doc/nrf/links.txt | 1 + doc/nrf/protocols/bt/bt_qualification/index.rst | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/doc/nrf/links.txt b/doc/nrf/links.txt index 14221bbdd6ee..409ccd3656dd 100644 --- a/doc/nrf/links.txt +++ b/doc/nrf/links.txt @@ -931,6 +931,7 @@ .. _`Bluetooth Qualification Consultants`: https://www.bluetooth.com/develop-with-bluetooth/qualification-listing/qualification-consultants/ .. _`Bluetooth product types`: https://support.bluetooth.com/hc/en-us/articles/360049018712/ .. _`PRD and DPD`: https://www.bluetooth.com/download/prd_dpd_resolutions/ +.. _`Create a subset of a design`: https://qualification.support.bluetooth.com/hc/en-us/articles/27694580618637-Create-a-Subset-of-a-Design .. _`Bluetooth Mesh model specification`: .. _`Bluetooth Mesh profile specification`: https://www.bluetooth.com/specifications/specs/ diff --git a/doc/nrf/protocols/bt/bt_qualification/index.rst b/doc/nrf/protocols/bt/bt_qualification/index.rst index e62245d26284..c5e89c71fa2e 100644 --- a/doc/nrf/protocols/bt/bt_qualification/index.rst +++ b/doc/nrf/protocols/bt/bt_qualification/index.rst @@ -20,13 +20,20 @@ Pre-qualified design ******************** A *design* is a specific configuration of hardware or software implementation (or both) of adopted Bluetooth specifications, either in parts or as a whole. -If relevant, you can use an existing design that has already been qualified (called *pre-qualified design*). +If relevant, you can use an existing design that has already been qualified (called *pre-qualified design*) and has a Qualification Design ID (QDID) number. This allows you to speed up your product's qualification process by omitting a testing phase. The |NCS| contains qualified portions of various Bluetooth features (for example, :ref:`ug_ble_controller_softdevice` versions). +If your product uses a qualified Bluetooth stack provided as part of the |NCS|, you can inherit this qualification from Nordic Semiconductor, provided that you do not introduce any changes to the stack. +To find the QDID, go to the Compatibility Matrix relevant for the SoC or SiP model you use (for example, the `nRF52840 DK Compatibility Matrix`_), and open the Bluetooth QDID section. -Any qualified design offered by Nordic Semiconductor (for example, :ref:`ug_bt_mesh` versions) can be qualified independently by the customers. -However, this process may be complex and time-consuming, thus it is recommended to inherit Nordic Semiconductor's design qualifications in your End Product's listing. +Generally, the qualified designs from Nordic Semiconductor combine many features together, but when you create a product or product line, you might not need some optional features. +In this case, you can create a subset design that contains only the features you want to inherit from the qualified design. +Listing products using subsets allows your product to present its used feature list in the form of a subset and distinguish itself from other designs. +Follow the `Create a subset of a design`_ instructions to create a subset of a qualified design. + +You can independently qualify any qualified design offered by Nordic Semiconductor (for example, :ref:`ug_bt_mesh` versions). +However, this process may be complex and time-consuming, thus it is recommended that you inherit Nordic Semiconductor's design qualifications in your End Product's listing. If you want to create a Profile Subsystem that is not on the `Bluetooth Qualification Listing`_, run the relevant tests through the `Profile Tuning Suite (PTS)`_ tool and qualify the product. A full list of Bluetooth product types including their descriptions is available on the `Bluetooth product types`_ page. From b6febea0b666903bdb352b53a9c0694bb0962e40 Mon Sep 17 00:00:00 2001 From: Jan Tore Guggedal Date: Wed, 21 Aug 2024 10:44:23 +0200 Subject: [PATCH 46/72] net: nrf_cloud: Let FOTA fragment size depend on FOTA_DOWNLOAD Change the NRF_CLOUD_FOTA_DOWNLOAD_FRAGMENT_SIZE Kconfig option to depend on FOTA_DOWNLOAD so that it is available also if NRF_CLOUD_FOTA is not enabled. This way it can also be used for NRF_CLOUD_FOTA_POLL. Signed-off-by: Jan Tore Guggedal --- subsys/net/lib/nrf_cloud/Kconfig.nrf_cloud_fota | 11 ++++++----- subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c | 3 +-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/subsys/net/lib/nrf_cloud/Kconfig.nrf_cloud_fota b/subsys/net/lib/nrf_cloud/Kconfig.nrf_cloud_fota index 513744f84fc3..183bcc7a0302 100644 --- a/subsys/net/lib/nrf_cloud/Kconfig.nrf_cloud_fota +++ b/subsys/net/lib/nrf_cloud/Kconfig.nrf_cloud_fota @@ -30,11 +30,6 @@ config NRF_CLOUD_FOTA_PROGRESS_PCT_INCREMENT help 0 disables progress report. -config NRF_CLOUD_FOTA_DOWNLOAD_FRAGMENT_SIZE - int "Fragment size for FOTA downloads" - range 128 1700 - default 1700 - config NRF_CLOUD_FOTA_BLE_DEVICES bool "Enable API for FOTA of BLE devices" depends on BT @@ -45,6 +40,12 @@ source "subsys/logging/Kconfig.template.log_config" endif # NRF_CLOUD_FOTA +config NRF_CLOUD_FOTA_DOWNLOAD_FRAGMENT_SIZE + int "Fragment size for FOTA downloads" + depends on FOTA_DOWNLOAD + range 128 1900 + default 1900 + config FOTA_USE_NRF_CLOUD_SETTINGS_AREA bool "Use the same settings area as the nRF Cloud FOTA library" default y diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c index b84a91de4599..e88777419f8e 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c @@ -18,7 +18,6 @@ LOG_MODULE_REGISTER(nrf_cloud_fota_poll, CONFIG_NRF_CLOUD_FOTA_POLL_LOG_LEVEL); -#define FOTA_DL_FRAGMENT_SZ 1400 #define JOB_WAIT_S 30 /* FOTA job status strings that provide additional details for nrf_cloud_fota_status values */ @@ -375,7 +374,7 @@ static int start_download(void) .sec_tag_list = &sec_tag, .sec_tag_count = (sec_tag < 0 ? 0 : 1), .pdn_id = 0, - .frag_size_override = FOTA_DL_FRAGMENT_SZ, + .frag_size_override = CONFIG_NRF_CLOUD_FOTA_DOWNLOAD_FRAGMENT_SIZE, }, .fota = { .expected_type = img_type, From e0a3c5694c9b5d08c4de0618e0b6332f68dc3c96 Mon Sep 17 00:00:00 2001 From: Jan Tore Guggedal Date: Wed, 21 Aug 2024 14:59:04 +0200 Subject: [PATCH 47/72] net: nrf_cloud: Add non-blocking option to nrf_cloud_fota_poll Add the option to use nrf_cloud_fota_poll_process() in a non-blocking manner. The current, blocking behavior is maintained, and the async option is enabled by providing a callback function for error handling. Signed-off-by: Jan Tore Guggedal --- .../releases/release-notes-changelog.rst | 8 ++ include/net/nrf_cloud_fota_poll.h | 37 ++++++++- .../net/lib/nrf_cloud/Kconfig.nrf_cloud_fota | 2 +- .../lib/nrf_cloud/src/nrf_cloud_fota_poll.c | 80 ++++++++++++++++++- 4 files changed, 120 insertions(+), 7 deletions(-) diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index 0df691d04981..23fbad70a96e 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -719,6 +719,14 @@ Libraries for networking * Added support for dictionary logs using REST. +* :ref:`lib_nrf_cloud_fota` library: + +* Updated: + + * The :kconfig:option:`CONFIG_NRF_CLOUD_FOTA_DOWNLOAD_FRAGMENT_SIZE` Kconfig option is made available and used also when the :kconfig:option:`CONFIG_NRF_CLOUD_FOTA_POLL` Kconfig option is enabled. + The range of the option is now from 128 to 1900 bytes, and the default value is 1700 bytes. + * The function :c:func:`nrf_cloud_fota_poll_process` can now be used asynchrounously if a callback to handle errors is provided. + Libraries for NFC ----------------- diff --git a/include/net/nrf_cloud_fota_poll.h b/include/net/nrf_cloud_fota_poll.h index 29fc3c329330..066b20aba24f 100644 --- a/include/net/nrf_cloud_fota_poll.h +++ b/include/net/nrf_cloud_fota_poll.h @@ -30,18 +30,42 @@ enum nrf_cloud_fota_reboot_status { }; /** - * @brief Event handler registered with the module to handle asynchronous - * events from the module. + * @brief Reboot event handler registered with the module to handle asynchronous + * reboot events from the module. * * @param[in] status The reason for the reboot request. */ typedef void (*fota_reboot_handler_t)(enum nrf_cloud_fota_reboot_status status); +/** + * @brief Error event handler registered with the module to handle asynchronous + * error events from the module. + * + * @param[in] status The FOTA status for the error event. + * @param[in] status_details Details about the error event. + */ +typedef void (*fota_error_handler_t)(enum nrf_cloud_fota_status status, + const char *const status_details); + struct nrf_cloud_fota_poll_ctx { + /* Internal variables */ struct nrf_cloud_rest_context *rest_ctx; + struct k_work_delayable timeout_work; + bool is_nonblocking; + bool full_modem_fota_supported; const char *device_id; + + /** User-provided callback function to handle reboots */ fota_reboot_handler_t reboot_fn; - bool full_modem_fota_supported; + + /** Optional, user-provided callback function to handle errors. + * If the function is provided, @ref nrf_cloud_fota_poll_process will be non-blocking and + * the user will receive error events asynchronously. + * + * If the function is not provided, @ref nrf_cloud_fota_poll_process will be blocking and + * return an error code when an error occurs. + */ + fota_error_handler_t error_fn; }; /** @@ -75,8 +99,15 @@ int nrf_cloud_fota_poll_process_pending(struct nrf_cloud_fota_poll_ctx *ctx); * Execute FOTA job. * Save status and request reboot. * + * The function will be blocking during an update image download if the error_fn callback is + * not provided. + * If the error_fn callback is provided, the function will be non-blocking and the user + * will receive error events asynchronously. + * * @param[in] ctx Pointer to context used for FOTA polling operations. * + * @retval 0 Only applicable if in non-blocking mode. Indicates successful start of + * FOTA processing. * @retval -EINVAL Invalid ctx or module is not initialized. * @retval -ENOTRECOVERABLE Error performing FOTA action. * @retval -EBUSY A reboot was requested but not performed by the application. diff --git a/subsys/net/lib/nrf_cloud/Kconfig.nrf_cloud_fota b/subsys/net/lib/nrf_cloud/Kconfig.nrf_cloud_fota index 183bcc7a0302..88c1e9da3979 100644 --- a/subsys/net/lib/nrf_cloud/Kconfig.nrf_cloud_fota +++ b/subsys/net/lib/nrf_cloud/Kconfig.nrf_cloud_fota @@ -44,7 +44,7 @@ config NRF_CLOUD_FOTA_DOWNLOAD_FRAGMENT_SIZE int "Fragment size for FOTA downloads" depends on FOTA_DOWNLOAD range 128 1900 - default 1900 + default 1700 config FOTA_USE_NRF_CLOUD_SETTINGS_AREA bool "Use the same settings area as the nRF Cloud FOTA library" diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c index e88777419f8e..9e99e12a2960 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c @@ -33,6 +33,8 @@ const char * const FOTA_STATUS_DETAILS_MISMATCH = "FW file does not match specif static bool initialized; +static struct nrf_cloud_fota_poll_ctx *ctx_ptr; + /* Semaphore to indicate the FOTA download has arrived at a terminal state */ static K_SEM_DEFINE(fota_download_sem, 0, 1); @@ -46,6 +48,10 @@ static struct nrf_cloud_settings_fota_job pending_job = { .type = NRF_CLOUD_FOTA static enum nrf_cloud_fota_status fota_status = NRF_CLOUD_FOTA_QUEUED; static char const *fota_status_details = FOTA_STATUS_DETAILS_SUCCESS; +/* Forward-declarations */ +static void handle_download_succeeded_and_reboot(struct nrf_cloud_fota_poll_ctx *ctx); +static int update_job_status(struct nrf_cloud_fota_poll_ctx *ctx); + /****************************************************/ /* Define wrappers for transport-specific functions */ /****************************************************/ @@ -124,7 +130,12 @@ static void http_fota_dl_handler(const struct fota_download_evt *evt) nrf_cloud_download_end(); fota_status = NRF_CLOUD_FOTA_SUCCEEDED; fota_status_details = FOTA_STATUS_DETAILS_SUCCESS; - k_sem_give(&fota_download_sem); + + if (ctx_ptr->is_nonblocking) { + handle_download_succeeded_and_reboot(ctx_ptr); + } else { + k_sem_give(&fota_download_sem); + } break; case FOTA_DOWNLOAD_EVT_ERASE_PENDING: case FOTA_DOWNLOAD_EVT_ERASE_TIMEOUT: @@ -150,7 +161,32 @@ static void http_fota_dl_handler(const struct fota_download_evt *evt) } else if (evt->cause == FOTA_DOWNLOAD_ERROR_CAUSE_TYPE_MISMATCH) { fota_status_details = FOTA_STATUS_DETAILS_MISMATCH; } - k_sem_give(&fota_download_sem); + + if (ctx_ptr->is_nonblocking) { + ctx_ptr->error_fn(fota_status, fota_status_details); + + (void)update_job_status(ctx_ptr); + } else { + k_sem_give(&fota_download_sem); + } + break; + case FOTA_DOWNLOAD_EVT_CANCELLED: + /* This event only needs to be handled in the case of non-blocking operation. + * In blocking mode, the download will be cancelled by the timeout work item, so + * the fota_status and details are set accordingly. + */ + + if (ctx_ptr->is_nonblocking) { + LOG_DBG("FOTA download cancelled"); + nrf_cloud_download_end(); + + fota_status = NRF_CLOUD_FOTA_TIMED_OUT; + fota_status_details = FOTA_STATUS_DETAILS_TIMEOUT; + + ctx_ptr->error_fn(fota_status, fota_status_details); + + (void)update_job_status(ctx_ptr); + } break; case FOTA_DOWNLOAD_EVT_PROGRESS: LOG_DBG("FOTA download percent: %d%%", evt->progress); @@ -166,7 +202,14 @@ static void http_fota_dl_handler(const struct fota_download_evt *evt) nrf_cloud_download_end(); fota_status = NRF_CLOUD_FOTA_FAILED; fota_status_details = FOTA_STATUS_DETAILS_DL_ERR; - k_sem_give(&fota_download_sem); + + if (ctx_ptr->is_nonblocking) { + ctx_ptr->error_fn(fota_status, fota_status_details); + + (void)update_job_status(ctx_ptr); + } else { + k_sem_give(&fota_download_sem); + } } #endif /* CONFIG_NRF_CLOUD_COAP_DOWNLOADS */ break; @@ -197,6 +240,13 @@ static void process_pending_job(struct nrf_cloud_fota_poll_ctx *ctx) } } +static void fota_dl_timeout_work_fn(struct k_work *work) +{ + LOG_ERR("Timeout; FOTA download took longer than %d minutes", CONFIG_FOTA_DL_TIMEOUT_MIN); + + (void)fota_download_cancel(); +} + int nrf_cloud_fota_poll_init(struct nrf_cloud_fota_poll_ctx *ctx) { int err; @@ -236,6 +286,19 @@ int nrf_cloud_fota_poll_init(struct nrf_cloud_fota_poll_ctx *ctx) return err; } + /* If an error handler is provided, error messages will be sent asynchronously, + * so the timeout must be detected via a delayable work item instead of a semaphore. + * Calls to nrf_cloud_fota_poll_process() will then be nonblocking. + */ + if (ctx->error_fn) { + ctx->is_nonblocking = true; + + k_work_init_delayable(&ctx->timeout_work, fota_dl_timeout_work_fn); + } + + /* A copy of the ctx pointer is needed to use in http_fota_dl_handler */ + ctx_ptr = ctx; + initialized = true; return 0; } @@ -492,6 +555,17 @@ int nrf_cloud_fota_poll_process(struct nrf_cloud_fota_poll_ctx *ctx) return -ENOTRECOVERABLE; } + /* Set timeout and return if this call is asynchronous, ie error_fn is defined */ + if (ctx->is_nonblocking) { + k_work_schedule(&ctx->timeout_work, K_MINUTES(CONFIG_FOTA_DL_TIMEOUT_MIN)); + + return 0; + } + + /* When this point is reached, this function will block until timeout or the fota_download + * reports that the download is done. + */ + err = wait_for_download(); if (err == -ETIMEDOUT) { LOG_ERR("Timeout; FOTA download took longer than %d minutes", From 937ada24fa008667bd3a3eea0033a51274f71037 Mon Sep 17 00:00:00 2001 From: Jan Tore Guggedal Date: Thu, 22 Aug 2024 08:49:28 +0200 Subject: [PATCH 48/72] net: nrf_cloud: nrf_cloud_fota_poll: Set fragment size runtime Add the option to set HTTP fragment size at run time. This enables users to create their own logic to fine-tune the size at run time to optimize download efficiency. Signed-off-by: Jan Tore Guggedal --- include/net/nrf_cloud_fota_poll.h | 13 +++++++++++++ subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/net/nrf_cloud_fota_poll.h b/include/net/nrf_cloud_fota_poll.h index 066b20aba24f..4ba1a6ce93d0 100644 --- a/include/net/nrf_cloud_fota_poll.h +++ b/include/net/nrf_cloud_fota_poll.h @@ -55,6 +55,19 @@ struct nrf_cloud_fota_poll_ctx { bool full_modem_fota_supported; const char *device_id; + /* Public variables */ + + /** HTTP fragment size. Sets the size of the requested payload in each HTTP request when + * downloading the firmware image. Note that the header size is not included in this size. + * It is important that the total size of each fragment (HTTP headers + payload) fits in + * the buffers of the underlying network stack layers. Failing to do so, may result in + * failure to download new firmware images. + * + * If this value is set to 0, the Kconfig option + * :kconfig:option:`CONFIG_NRF_CLOUD_FOTA_DOWNLOAD_FRAGMENT_SIZE` will be used. + */ + uint32_t fragment_size; + /** User-provided callback function to handle reboots */ fota_reboot_handler_t reboot_fn; diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c index 9e99e12a2960..2a711620bf1f 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c @@ -437,7 +437,8 @@ static int start_download(void) .sec_tag_list = &sec_tag, .sec_tag_count = (sec_tag < 0 ? 0 : 1), .pdn_id = 0, - .frag_size_override = CONFIG_NRF_CLOUD_FOTA_DOWNLOAD_FRAGMENT_SIZE, + .frag_size_override = ctx_ptr->fragment_size ? ctx_ptr->fragment_size : + CONFIG_NRF_CLOUD_FOTA_DOWNLOAD_FRAGMENT_SIZE, }, .fota = { .expected_type = img_type, From 05e9f0ce9a5a82001d909d343af1f5da907b4130 Mon Sep 17 00:00:00 2001 From: Marcin Jelinski Date: Thu, 22 Aug 2024 11:43:48 +0200 Subject: [PATCH 49/72] nfc: ndef: Fix memory allocation check to prevent NULL dereference Fixes coverity issue 112949 Ref: NCSDK-27131 Signed-off-by: Marcin Jelinski --- subsys/nfc/ndef/ch_rec_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/nfc/ndef/ch_rec_parser.c b/subsys/nfc/ndef/ch_rec_parser.c index 00ce5abc31dd..2871af0dbf1c 100644 --- a/subsys/nfc/ndef/ch_rec_parser.c +++ b/subsys/nfc/ndef/ch_rec_parser.c @@ -213,7 +213,7 @@ static int ac_rec_payload_parse(struct nfc_ndef_bin_payload_desc *payload_desc, ac_rec->aux_data_ref = (struct nfc_ndef_ch_ac_rec_ref *) memory_allocate(&buf, ac_rec->aux_data_ref_cnt * sizeof(*ac_rec->aux_data_ref)); - if (ac_rec->aux_data_ref) { + if (!ac_rec->aux_data_ref) { return -ENOMEM; } From 103b894bc75517a151793a4d86af5f5b27bd595e Mon Sep 17 00:00:00 2001 From: Piotr Kosycarz Date: Wed, 28 Aug 2024 08:12:30 +0200 Subject: [PATCH 50/72] tests: benchmarks: multicore: idle: use exit-latency-us Set exit-latency-us for 1ms. Signed-off-by: Piotr Kosycarz --- .../idle/boards/nrf54h20dk_nrf54h20_cpuapp_s2ram.overlay | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/benchmarks/multicore/idle/boards/nrf54h20dk_nrf54h20_cpuapp_s2ram.overlay b/tests/benchmarks/multicore/idle/boards/nrf54h20dk_nrf54h20_cpuapp_s2ram.overlay index c9b5aee2aa93..05c0cfa2726a 100644 --- a/tests/benchmarks/multicore/idle/boards/nrf54h20dk_nrf54h20_cpuapp_s2ram.overlay +++ b/tests/benchmarks/multicore/idle/boards/nrf54h20dk_nrf54h20_cpuapp_s2ram.overlay @@ -16,6 +16,8 @@ compatible = "zephyr,power-state"; power-state-name = "suspend-to-ram"; min-residency-us = <800000>; + /* TODO: replace with a busy loop in S2RAM entering procedure; replace 1000 with real value here */ + exit-latency-us = <1000>; }; }; }; From 7380d022a94e9c28410bbca07318c4935e04499d Mon Sep 17 00:00:00 2001 From: Piotr Kosycarz Date: Wed, 28 Aug 2024 08:50:17 +0200 Subject: [PATCH 51/72] codeowners: set owners for tests/benchmarks/multicore/idle LL test. Signed-off-by: Piotr Kosycarz --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/CODEOWNERS b/CODEOWNERS index 47c3f183f0d1..878ca4fba8ff 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -314,6 +314,7 @@ Kconfig* @tejlmand /subsys/zigbee/ @milewr /tests/ @PerMac @katgiadla /tests/benchmarks/multicore/ @carlescufi +/tests/benchmarks/multicore/idle/ @adamkondraciuk @nrfconnect/ncs-low-level-test /tests/bluetooth/tester/ @carlescufi @nrfconnect/ncs-paladin /tests/bluetooth/iso/ @nrfconnect/ncs-audio @Frodevan /tests/subsys/nrf_compress/ @nordicjm From c297ea960d08bba20220f3b45bf73d8be21077ea Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Thu, 22 Aug 2024 09:53:03 +0200 Subject: [PATCH 52/72] nrf_rpc: add uint64_t serializer Commit adds uint64_t serializer Signed-off-by: Aleksandr Khromykh --- include/nrf_rpc/nrf_rpc_serialize.h | 30 +++++++++++++++++++++++++++ subsys/nrf_rpc/nrf_rpc_serialize.c | 32 +++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/include/nrf_rpc/nrf_rpc_serialize.h b/include/nrf_rpc/nrf_rpc_serialize.h index f877a1e8f141..c25829d1ce10 100644 --- a/include/nrf_rpc/nrf_rpc_serialize.h +++ b/include/nrf_rpc/nrf_rpc_serialize.h @@ -98,6 +98,20 @@ void nrf_rpc_encode_uint(struct nrf_rpc_cbor_ctx *ctx, uint32_t value); */ void nrf_rpc_encode_int(struct nrf_rpc_cbor_ctx *ctx, int32_t value); +/** @brief Encode an 64bits unsigned integer value. + * + * @param[in,out] ctx Structure used to encode CBOR stream. + * @param[in] value Encoded value. + */ +void nrf_rpc_encode_uint64(struct nrf_rpc_cbor_ctx *ctx, uint64_t value); + +/** @brief Encode an 64bits integer value. + * + * @param[in,out] ctx Structure used to encode CBOR stream. + * @param[in] value Encoded value. + */ +void nrf_rpc_encode_int64(struct nrf_rpc_cbor_ctx *ctx, int64_t value); + /** @brief Encode a string value. * * @param[in,out] ctx CBOR encoding context. @@ -189,6 +203,22 @@ uint32_t nrf_rpc_decode_uint(struct nrf_rpc_cbor_ctx *ctx); */ int32_t nrf_rpc_decode_int(struct nrf_rpc_cbor_ctx *ctx); +/** @brief Decode a 64bits unsigned integer value. + * + * @param[in,out] ctx CBOR decoding context. + * + * @retval Decoded value. + */ +uint64_t nrf_rpc_decode_uint64(struct nrf_rpc_cbor_ctx *ctx); + +/** @brief Decode a 64bits integer value. + * + * @param[in,out] ctx CBOR decoding context. + * + * @retval Decoded value. + */ +int64_t nrf_rpc_decode_int64(struct nrf_rpc_cbor_ctx *ctx); + /** @brief Decode a string value. * * @param[in,out] ctx CBOR decoding context. diff --git a/subsys/nrf_rpc/nrf_rpc_serialize.c b/subsys/nrf_rpc/nrf_rpc_serialize.c index f44b2ea807ce..f3e2e65b2422 100644 --- a/subsys/nrf_rpc/nrf_rpc_serialize.c +++ b/subsys/nrf_rpc/nrf_rpc_serialize.c @@ -73,6 +73,16 @@ void nrf_rpc_encode_int(struct nrf_rpc_cbor_ctx *ctx, int32_t value) zcbor_int32_put(ctx->zs, value); } +void nrf_rpc_encode_uint64(struct nrf_rpc_cbor_ctx *ctx, uint64_t value) +{ + zcbor_uint64_put(ctx->zs, value); +} + +void nrf_rpc_encode_int64(struct nrf_rpc_cbor_ctx *ctx, int64_t value) +{ + zcbor_int64_put(ctx->zs, value); +} + void nrf_rpc_encode_str(struct nrf_rpc_cbor_ctx *ctx, const char *value, int len) { if (!value) { @@ -186,6 +196,28 @@ int32_t nrf_rpc_decode_int(struct nrf_rpc_cbor_ctx *ctx) return 0; } +uint64_t nrf_rpc_decode_uint64(struct nrf_rpc_cbor_ctx *ctx) +{ + uint64_t result; + + if (zcbor_uint64_decode(ctx->zs, &result)) { + return result; + } + + return 0; +} + +int64_t nrf_rpc_decode_int64(struct nrf_rpc_cbor_ctx *ctx) +{ + int64_t result; + + if (zcbor_int64_decode(ctx->zs, &result)) { + return result; + } + + return 0; +} + void *nrf_rpc_decode_buffer(struct nrf_rpc_cbor_ctx *ctx, void *buffer, size_t buffer_size) { struct zcbor_string zst = {0}; From 59280dfed37e3973453441d8b2c151ee773ef85b Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Thu, 22 Aug 2024 09:54:31 +0200 Subject: [PATCH 53/72] net: openthread: rpc: extend commissioning functionality Commit adds serialization of: - otDatasetGetActive - otDatasetSetActive Signed-off-by: Aleksandr Khromykh --- .../rpc/client/ot_rpc_commissioning_client.c | 45 ++++- .../rpc/client/ot_rpc_diag_client.c | 5 - .../net/openthread/rpc/common/ot_rpc_common.c | 108 ++++++++++- .../net/openthread/rpc/common/ot_rpc_common.h | 42 +++++ subsys/net/openthread/rpc/common/ot_rpc_ids.h | 7 +- .../rpc/server/ot_rpc_commissioning_server.c | 67 ++++++- .../{server/ctrl => client}/CMakeLists.txt | 12 +- .../rpc/client/commissioning/CMakeLists.txt | 37 ---- .../rpc/client/commissioning/testcase.yaml | 7 - .../openthread/rpc/client/ctrl/CMakeLists.txt | 21 --- .../net/openthread/rpc/client/ctrl/prj.conf | 20 --- .../rpc/client/{commissioning => }/prj.conf | 0 .../src/main.c => src/cmsng_suite.c} | 117 +++++++++++- .../{ctrl/src/main.c => src/ctrl_suite.c} | 0 .../rpc/client/{ctrl => }/testcase.yaml | 2 +- .../net/openthread/rpc/common/test_rpc_env.h | 15 ++ .../server/{commissioning => }/CMakeLists.txt | 8 +- .../rpc/server/commissioning/testcase.yaml | 7 - .../net/openthread/rpc/server/ctrl/prj.conf | 19 -- .../rpc/server/{commissioning => }/prj.conf | 0 .../src/main.c => src/cmsng_suite.c} | 170 +++++++++++++++--- .../{ctrl/src/main.c => src/ctrl_suite.c} | 0 .../rpc/server/{ctrl => }/testcase.yaml | 2 +- 23 files changed, 543 insertions(+), 168 deletions(-) rename tests/subsys/net/openthread/rpc/{server/ctrl => client}/CMakeLists.txt (85%) delete mode 100644 tests/subsys/net/openthread/rpc/client/commissioning/CMakeLists.txt delete mode 100644 tests/subsys/net/openthread/rpc/client/commissioning/testcase.yaml delete mode 100644 tests/subsys/net/openthread/rpc/client/ctrl/CMakeLists.txt delete mode 100644 tests/subsys/net/openthread/rpc/client/ctrl/prj.conf rename tests/subsys/net/openthread/rpc/client/{commissioning => }/prj.conf (100%) rename tests/subsys/net/openthread/rpc/client/{commissioning/src/main.c => src/cmsng_suite.c} (55%) rename tests/subsys/net/openthread/rpc/client/{ctrl/src/main.c => src/ctrl_suite.c} (100%) rename tests/subsys/net/openthread/rpc/client/{ctrl => }/testcase.yaml (83%) rename tests/subsys/net/openthread/rpc/server/{commissioning => }/CMakeLists.txt (86%) delete mode 100644 tests/subsys/net/openthread/rpc/server/commissioning/testcase.yaml delete mode 100644 tests/subsys/net/openthread/rpc/server/ctrl/prj.conf rename tests/subsys/net/openthread/rpc/server/{commissioning => }/prj.conf (100%) rename tests/subsys/net/openthread/rpc/server/{commissioning/src/main.c => src/cmsng_suite.c} (51%) rename tests/subsys/net/openthread/rpc/server/{ctrl/src/main.c => src/ctrl_suite.c} (100%) rename tests/subsys/net/openthread/rpc/server/{ctrl => }/testcase.yaml (83%) diff --git a/subsys/net/openthread/rpc/client/ot_rpc_commissioning_client.c b/subsys/net/openthread/rpc/client/ot_rpc_commissioning_client.c index 17938fe72381..f50cca7f2193 100644 --- a/subsys/net/openthread/rpc/client/ot_rpc_commissioning_client.c +++ b/subsys/net/openthread/rpc/client/ot_rpc_commissioning_client.c @@ -118,7 +118,7 @@ otError otDatasetSetActiveTlvs(otInstance *aInstance, const otOperationalDataset nrf_rpc_encode_buffer(&ctx, aDataset->mTlvs, aDataset->mLength); - nrf_rpc_cbor_cmd_no_err(&ot_group, OT_RPC_CMD_DATA_SET_ACTIVE_TLVS, &ctx, + nrf_rpc_cbor_cmd_no_err(&ot_group, OT_RPC_CMD_DATASET_SET_ACTIVE_TLVS, &ctx, ot_rpc_decode_error, &error); return error; @@ -137,8 +137,49 @@ otError otDatasetGetActiveTlvs(otInstance *aInstance, otOperationalDatasetTlvs * NRF_RPC_CBOR_ALLOC(&ot_group, ctx, 0); - nrf_rpc_cbor_cmd_no_err(&ot_group, OT_RPC_CMD_DATA_GET_ACTIVE_TLVS, &ctx, + nrf_rpc_cbor_cmd_no_err(&ot_group, OT_RPC_CMD_DATASET_GET_ACTIVE_TLVS, &ctx, ot_rpc_decode_dataset_tlvs, &dataset); return dataset ? OT_ERROR_NONE : OT_ERROR_NOT_FOUND; } + +otError otDatasetSetActive(otInstance *aInstance, const otOperationalDataset *aDataset) +{ + struct nrf_rpc_cbor_ctx ctx; + size_t cbor_buffer_size; + otError error; + + ARG_UNUSED(aInstance); + + if (aDataset == NULL) { + return OT_ERROR_INVALID_ARGS; + } + + cbor_buffer_size = OPERATIONAL_DATASET_LENGTH(aDataset); + + NRF_RPC_CBOR_ALLOC(&ot_group, ctx, cbor_buffer_size); + ot_rpc_encode_dataset(&ctx, aDataset); + nrf_rpc_cbor_cmd_no_err(&ot_group, OT_RPC_CMD_DATASET_SET_ACTIVE, &ctx, ot_rpc_decode_error, + &error); + + return error; +} + +otError otDatasetGetActive(otInstance *aInstance, otOperationalDataset *aDataset) +{ + struct nrf_rpc_cbor_ctx ctx; + otOperationalDataset *dataset = aDataset; + + ARG_UNUSED(aInstance); + + if (aDataset == NULL) { + return OT_ERROR_NOT_FOUND; + } + + NRF_RPC_CBOR_ALLOC(&ot_group, ctx, 0); + + nrf_rpc_cbor_cmd_no_err(&ot_group, OT_RPC_CMD_DATASET_GET_ACTIVE, &ctx, + ot_rpc_decode_dataset, &dataset); + + return dataset ? OT_ERROR_NONE : OT_ERROR_NOT_FOUND; +} diff --git a/subsys/net/openthread/rpc/client/ot_rpc_diag_client.c b/subsys/net/openthread/rpc/client/ot_rpc_diag_client.c index 34e4ebef9673..a0288023d926 100644 --- a/subsys/net/openthread/rpc/client/ot_rpc_diag_client.c +++ b/subsys/net/openthread/rpc/client/ot_rpc_diag_client.c @@ -84,11 +84,6 @@ const char *otGetVersionString(void) return version; } -otError otDatasetGetActive(otInstance *aInstance, otOperationalDataset *aDataset) -{ - return 0; -} - uint8_t otLinkGetChannel(otInstance *aInstance) { uint8_t ret; diff --git a/subsys/net/openthread/rpc/common/ot_rpc_common.c b/subsys/net/openthread/rpc/common/ot_rpc_common.c index 904d086dc4cc..833f530c919a 100644 --- a/subsys/net/openthread/rpc/common/ot_rpc_common.c +++ b/subsys/net/openthread/rpc/common/ot_rpc_common.c @@ -8,8 +8,6 @@ #include -#include - void ot_rpc_decode_error(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx, void *handler_data) { @@ -39,6 +37,112 @@ void ot_rpc_decode_dataset_tlvs(const struct nrf_rpc_group *group, struct nrf_rp } } +static void ot_rpc_encode_timestamp(struct nrf_rpc_cbor_ctx *ctx, const otTimestamp *timestamp) +{ + nrf_rpc_encode_uint64(ctx, timestamp->mSeconds); + nrf_rpc_encode_uint(ctx, timestamp->mTicks); + nrf_rpc_encode_bool(ctx, timestamp->mAuthoritative); +} + +static void ot_rpc_decode_timestamp(struct nrf_rpc_cbor_ctx *ctx, otTimestamp *timestamp) +{ + timestamp->mSeconds = nrf_rpc_decode_uint64(ctx); + timestamp->mTicks = nrf_rpc_decode_uint(ctx); + timestamp->mAuthoritative = nrf_rpc_decode_bool(ctx); +} + +void ot_rpc_encode_dataset(struct nrf_rpc_cbor_ctx *ctx, const otOperationalDataset *dataset) +{ + ot_rpc_encode_timestamp(ctx, &dataset->mActiveTimestamp); + ot_rpc_encode_timestamp(ctx, &dataset->mPendingTimestamp); + nrf_rpc_encode_buffer(ctx, dataset->mNetworkKey.m8, sizeof(dataset->mNetworkKey.m8)); + nrf_rpc_encode_str(ctx, dataset->mNetworkName.m8, strlen(dataset->mNetworkName.m8)); + nrf_rpc_encode_buffer(ctx, dataset->mExtendedPanId.m8, sizeof(dataset->mExtendedPanId.m8)); + nrf_rpc_encode_buffer(ctx, dataset->mMeshLocalPrefix.m8, + sizeof(dataset->mMeshLocalPrefix.m8)); + nrf_rpc_encode_uint(ctx, dataset->mDelay); + nrf_rpc_encode_uint(ctx, dataset->mPanId); + nrf_rpc_encode_uint(ctx, dataset->mChannel); + nrf_rpc_encode_buffer(ctx, dataset->mPskc.m8, sizeof(dataset->mPskc.m8)); + + nrf_rpc_encode_uint(ctx, dataset->mSecurityPolicy.mRotationTime); + nrf_rpc_encode_bool(ctx, !!dataset->mSecurityPolicy.mObtainNetworkKeyEnabled); + nrf_rpc_encode_bool(ctx, !!dataset->mSecurityPolicy.mNativeCommissioningEnabled); + nrf_rpc_encode_bool(ctx, !!dataset->mSecurityPolicy.mRoutersEnabled); + nrf_rpc_encode_bool(ctx, !!dataset->mSecurityPolicy.mExternalCommissioningEnabled); + nrf_rpc_encode_bool(ctx, !!dataset->mSecurityPolicy.mCommercialCommissioningEnabled); + nrf_rpc_encode_bool(ctx, !!dataset->mSecurityPolicy.mAutonomousEnrollmentEnabled); + nrf_rpc_encode_bool(ctx, !!dataset->mSecurityPolicy.mNetworkKeyProvisioningEnabled); + nrf_rpc_encode_bool(ctx, !!dataset->mSecurityPolicy.mTobleLinkEnabled); + nrf_rpc_encode_bool(ctx, !!dataset->mSecurityPolicy.mNonCcmRoutersEnabled); + nrf_rpc_encode_uint(ctx, dataset->mSecurityPolicy.mVersionThresholdForRouting); + + nrf_rpc_encode_uint(ctx, dataset->mChannelMask); + + nrf_rpc_encode_bool(ctx, dataset->mComponents.mIsActiveTimestampPresent); + nrf_rpc_encode_bool(ctx, dataset->mComponents.mIsPendingTimestampPresent); + nrf_rpc_encode_bool(ctx, dataset->mComponents.mIsNetworkKeyPresent); + nrf_rpc_encode_bool(ctx, dataset->mComponents.mIsNetworkNamePresent); + nrf_rpc_encode_bool(ctx, dataset->mComponents.mIsExtendedPanIdPresent); + nrf_rpc_encode_bool(ctx, dataset->mComponents.mIsMeshLocalPrefixPresent); + nrf_rpc_encode_bool(ctx, dataset->mComponents.mIsDelayPresent); + nrf_rpc_encode_bool(ctx, dataset->mComponents.mIsPanIdPresent); + nrf_rpc_encode_bool(ctx, dataset->mComponents.mIsChannelPresent); + nrf_rpc_encode_bool(ctx, dataset->mComponents.mIsPskcPresent); + nrf_rpc_encode_bool(ctx, dataset->mComponents.mIsSecurityPolicyPresent); + nrf_rpc_encode_bool(ctx, dataset->mComponents.mIsChannelMaskPresent); +} + +void ot_rpc_decode_dataset(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx, + void *handler_data) +{ + otOperationalDataset *dataset = *(otOperationalDataset **)handler_data; + + if (zcbor_nil_expect(ctx->zs, NULL)) { + *(otOperationalDataset **)handler_data = NULL; + return; + } + + ot_rpc_decode_timestamp(ctx, &dataset->mActiveTimestamp); + ot_rpc_decode_timestamp(ctx, &dataset->mPendingTimestamp); + nrf_rpc_decode_buffer(ctx, dataset->mNetworkKey.m8, sizeof(dataset->mNetworkKey.m8)); + nrf_rpc_decode_str(ctx, dataset->mNetworkName.m8, sizeof(dataset->mNetworkName.m8)); + nrf_rpc_decode_buffer(ctx, dataset->mExtendedPanId.m8, sizeof(dataset->mExtendedPanId.m8)); + nrf_rpc_decode_buffer(ctx, dataset->mMeshLocalPrefix.m8, + sizeof(dataset->mMeshLocalPrefix.m8)); + dataset->mDelay = nrf_rpc_decode_uint(ctx); + dataset->mPanId = nrf_rpc_decode_uint(ctx); + dataset->mChannel = nrf_rpc_decode_uint(ctx); + nrf_rpc_decode_buffer(ctx, dataset->mPskc.m8, sizeof(dataset->mPskc.m8)); + + dataset->mSecurityPolicy.mRotationTime = nrf_rpc_decode_uint(ctx); + dataset->mSecurityPolicy.mObtainNetworkKeyEnabled = nrf_rpc_decode_bool(ctx) ? 1 : 0; + dataset->mSecurityPolicy.mNativeCommissioningEnabled = nrf_rpc_decode_bool(ctx) ? 1 : 0; + dataset->mSecurityPolicy.mRoutersEnabled = nrf_rpc_decode_bool(ctx) ? 1 : 0; + dataset->mSecurityPolicy.mExternalCommissioningEnabled = nrf_rpc_decode_bool(ctx) ? 1 : 0; + dataset->mSecurityPolicy.mCommercialCommissioningEnabled = nrf_rpc_decode_bool(ctx) ? 1 : 0; + dataset->mSecurityPolicy.mAutonomousEnrollmentEnabled = nrf_rpc_decode_bool(ctx) ? 1 : 0; + dataset->mSecurityPolicy.mNetworkKeyProvisioningEnabled = nrf_rpc_decode_bool(ctx) ? 1 : 0; + dataset->mSecurityPolicy.mTobleLinkEnabled = nrf_rpc_decode_bool(ctx) ? 1 : 0; + dataset->mSecurityPolicy.mNonCcmRoutersEnabled = nrf_rpc_decode_bool(ctx) ? 1 : 0; + dataset->mSecurityPolicy.mVersionThresholdForRouting = nrf_rpc_decode_uint(ctx); + + dataset->mChannelMask = nrf_rpc_decode_uint(ctx); + + dataset->mComponents.mIsActiveTimestampPresent = nrf_rpc_decode_bool(ctx); + dataset->mComponents.mIsPendingTimestampPresent = nrf_rpc_decode_bool(ctx); + dataset->mComponents.mIsNetworkKeyPresent = nrf_rpc_decode_bool(ctx); + dataset->mComponents.mIsNetworkNamePresent = nrf_rpc_decode_bool(ctx); + dataset->mComponents.mIsExtendedPanIdPresent = nrf_rpc_decode_bool(ctx); + dataset->mComponents.mIsMeshLocalPrefixPresent = nrf_rpc_decode_bool(ctx); + dataset->mComponents.mIsDelayPresent = nrf_rpc_decode_bool(ctx); + dataset->mComponents.mIsPanIdPresent = nrf_rpc_decode_bool(ctx); + dataset->mComponents.mIsChannelPresent = nrf_rpc_decode_bool(ctx); + dataset->mComponents.mIsPskcPresent = nrf_rpc_decode_bool(ctx); + dataset->mComponents.mIsSecurityPolicyPresent = nrf_rpc_decode_bool(ctx); + dataset->mComponents.mIsChannelMaskPresent = nrf_rpc_decode_bool(ctx); +} + void ot_rpc_report_decoding_error(uint8_t cmd_evt_id) { nrf_rpc_err(-EBADMSG, NRF_RPC_ERR_SRC_RECV, &ot_group, cmd_evt_id, NRF_RPC_PACKET_TYPE_CMD); diff --git a/subsys/net/openthread/rpc/common/ot_rpc_common.h b/subsys/net/openthread/rpc/common/ot_rpc_common.h index df1334efea53..980858110be8 100644 --- a/subsys/net/openthread/rpc/common/ot_rpc_common.h +++ b/subsys/net/openthread/rpc/common/ot_rpc_common.h @@ -7,8 +7,47 @@ #ifndef OT_RPC_COMMON_H_ #define OT_RPC_COMMON_H_ +#include + #include +#define OT_RPC_TIMESTAMP_LENGTH(timestamp) \ + sizeof((timestamp).mSeconds) + 1 + \ + sizeof((timestamp).mTicks) + 1 + \ + sizeof((timestamp).mAuthoritative) + +#define OT_RPC_SECURITY_POLICY_LENGTH(policy) \ + sizeof((policy).mRotationTime) + 1 + 10 + +#define OT_RPC_OPERATIONAL_COMPONENTS_LENGTH(components) \ + sizeof((components).mIsActiveTimestampPresent) + \ + sizeof((components).mIsPendingTimestampPresent) + \ + sizeof((components).mIsNetworkKeyPresent) + \ + sizeof((components).mIsNetworkNamePresent) + \ + sizeof((components).mIsExtendedPanIdPresent) + \ + sizeof((components).mIsMeshLocalPrefixPresent) + \ + sizeof((components).mIsDelayPresent) + \ + sizeof((components).mIsPanIdPresent) + \ + sizeof((components).mIsChannelPresent) + \ + sizeof((components).mIsPskcPresent) + \ + sizeof((components).mIsSecurityPolicyPresent) + \ + sizeof((components).mIsChannelMaskPresent) + +#define OPERATIONAL_DATASET_LENGTH(dataset) \ + OT_RPC_TIMESTAMP_LENGTH((dataset)->mActiveTimestamp) + \ + OT_RPC_TIMESTAMP_LENGTH((dataset)->mPendingTimestamp) + \ + sizeof((dataset)->mNetworkKey.m8) + 1 + \ + sizeof((dataset)->mNetworkName.m8) + 1 + \ + sizeof((dataset)->mExtendedPanId.m8) + 1 + \ + sizeof((dataset)->mMeshLocalPrefix.m8) + 1 + \ + sizeof((dataset)->mDelay) + 1 + \ + sizeof((dataset)->mPanId) + 1 + \ + sizeof((dataset)->mChannel) + 1 + \ + sizeof((dataset)->mPskc.m8) + 1 + \ + OT_RPC_SECURITY_POLICY_LENGTH((dataset)->mSecurityPolicy) + \ + sizeof((dataset)->mChannelMask) + 1 + \ + OT_RPC_OPERATIONAL_COMPONENTS_LENGTH((dataset)->mComponents) + NRF_RPC_GROUP_DECLARE(ot_group); void ot_rpc_decode_error(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx, @@ -17,6 +56,9 @@ void ot_rpc_decode_void(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_c void *handler_data); void ot_rpc_decode_dataset_tlvs(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx, void *handler_data); +void ot_rpc_decode_dataset(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx, + void *handler_data); +void ot_rpc_encode_dataset(struct nrf_rpc_cbor_ctx *ctx, const otOperationalDataset *dataset); /* The function reports about command decoding error (not responses). */ void ot_rpc_report_decoding_error(uint8_t cmd_evt_id); diff --git a/subsys/net/openthread/rpc/common/ot_rpc_ids.h b/subsys/net/openthread/rpc/common/ot_rpc_ids.h index 5fae2333c5e7..53e7d810fdbb 100644 --- a/subsys/net/openthread/rpc/common/ot_rpc_ids.h +++ b/subsys/net/openthread/rpc/common/ot_rpc_ids.h @@ -37,9 +37,10 @@ enum ot_rpc_cmd_server { OT_RPC_CMD_IF_EXTADDR, OT_RPC_CMD_THREAD_DISCOVER, OT_RPC_CMD_DATASET_IS_COMMISSIONED, - OT_RPC_CMD_DATA_SET_ACTIVE_TLVS, - OT_RPC_CMD_DATA_GET_ACTIVE_TLVS, - OT_RPC_CMD_DATASET_ACTIVE_GET, + OT_RPC_CMD_DATASET_SET_ACTIVE_TLVS, + OT_RPC_CMD_DATASET_GET_ACTIVE_TLVS, + OT_RPC_CMD_DATASET_SET_ACTIVE, + OT_RPC_CMD_DATASET_GET_ACTIVE, OT_RPC_CMD_GET_VERSION_STRING, OT_RPC_CMD_LINK_GET_CHANNEL, OT_RPC_CMD_LINK_GET_COUNTERS, diff --git a/subsys/net/openthread/rpc/server/ot_rpc_commissioning_server.c b/subsys/net/openthread/rpc/server/ot_rpc_commissioning_server.c index bdee7e63b42c..2f65f1838a20 100644 --- a/subsys/net/openthread/rpc/server/ot_rpc_commissioning_server.c +++ b/subsys/net/openthread/rpc/server/ot_rpc_commissioning_server.c @@ -130,7 +130,7 @@ static void ot_rpc_data_set_active_tlvs_rpc_handler(const struct nrf_rpc_group * ot_rpc_decode_dataset_tlvs(group, ctx, &data_ptr); if (!nrf_rpc_decoding_done_and_check(group, ctx)) { - ot_rpc_report_decoding_error(OT_RPC_CMD_DATA_SET_ACTIVE_TLVS); + ot_rpc_report_decoding_error(OT_RPC_CMD_DATASET_SET_ACTIVE_TLVS); return; } @@ -145,7 +145,7 @@ static void ot_rpc_data_set_active_tlvs_rpc_handler(const struct nrf_rpc_group * nrf_rpc_rsp_send_uint(group, error); } -NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_data_set_active_tlvs, OT_RPC_CMD_DATA_SET_ACTIVE_TLVS, +NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_data_set_active_tlvs, OT_RPC_CMD_DATASET_SET_ACTIVE_TLVS, ot_rpc_data_set_active_tlvs_rpc_handler, NULL); static void ot_rpc_rsp_send_dataset(otOperationalDatasetTlvs *dataset) @@ -166,7 +166,7 @@ static void ot_rpc_data_get_active_tlvs_rpc_handler(const struct nrf_rpc_group * otError error; if (!nrf_rpc_decoding_done_and_check(group, ctx)) { - ot_rpc_report_decoding_error(OT_RPC_CMD_DATA_GET_ACTIVE_TLVS); + ot_rpc_report_decoding_error(OT_RPC_CMD_DATASET_GET_ACTIVE_TLVS); return; } @@ -177,5 +177,64 @@ static void ot_rpc_data_get_active_tlvs_rpc_handler(const struct nrf_rpc_group * ot_rpc_rsp_send_dataset(error == OT_ERROR_NONE ? &dataset : NULL); } -NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_data_get_active_tlvs, OT_RPC_CMD_DATA_GET_ACTIVE_TLVS, +NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_data_get_active_tlvs, OT_RPC_CMD_DATASET_GET_ACTIVE_TLVS, ot_rpc_data_get_active_tlvs_rpc_handler, NULL); + +static void ot_rpc_dataset_set_active_rpc_handler(const struct nrf_rpc_group *group, + struct nrf_rpc_cbor_ctx *ctx, void *handler_data) +{ + otOperationalDataset dataset; + void *data_ptr = &dataset; + otError error; + + ot_rpc_decode_dataset(group, ctx, &data_ptr); + + if (!nrf_rpc_decoding_done_and_check(group, ctx)) { + ot_rpc_report_decoding_error(OT_RPC_CMD_DATASET_SET_ACTIVE); + return; + } + + if (data_ptr) { + openthread_api_mutex_lock(openthread_get_default_context()); + error = otDatasetSetActive(openthread_get_default_instance(), &dataset); + openthread_api_mutex_unlock(openthread_get_default_context()); + } else { + error = OT_ERROR_INVALID_ARGS; + } + + nrf_rpc_rsp_send_uint(group, error); +} + +NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_dataset_set_active, OT_RPC_CMD_DATASET_SET_ACTIVE, + ot_rpc_dataset_set_active_rpc_handler, NULL); + +static void ot_rpc_dataset_get_active_rpc_handler(const struct nrf_rpc_group *group, + struct nrf_rpc_cbor_ctx *ctx, void *handler_data) +{ + otOperationalDataset dataset; + struct nrf_rpc_cbor_ctx tx_ctx; + size_t cbor_buffer_size = OPERATIONAL_DATASET_LENGTH(&dataset); + otError error; + + if (!nrf_rpc_decoding_done_and_check(group, ctx)) { + ot_rpc_report_decoding_error(OT_RPC_CMD_DATASET_GET_ACTIVE); + return; + } + + openthread_api_mutex_lock(openthread_get_default_context()); + error = otDatasetGetActive(openthread_get_default_instance(), &dataset); + openthread_api_mutex_unlock(openthread_get_default_context()); + + if (error != OT_ERROR_NONE) { + NRF_RPC_CBOR_ALLOC(&ot_group, tx_ctx, 1); + nrf_rpc_encode_null(&tx_ctx); + } else { + NRF_RPC_CBOR_ALLOC(&ot_group, tx_ctx, cbor_buffer_size); + ot_rpc_encode_dataset(&tx_ctx, &dataset); + } + + nrf_rpc_cbor_rsp_no_err(&ot_group, &tx_ctx); +} + +NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_dataset_get_active, OT_RPC_CMD_DATASET_GET_ACTIVE, + ot_rpc_dataset_get_active_rpc_handler, NULL); diff --git a/tests/subsys/net/openthread/rpc/server/ctrl/CMakeLists.txt b/tests/subsys/net/openthread/rpc/client/CMakeLists.txt similarity index 85% rename from tests/subsys/net/openthread/rpc/server/ctrl/CMakeLists.txt rename to tests/subsys/net/openthread/rpc/client/CMakeLists.txt index c88dd5587e11..116955e2b317 100644 --- a/tests/subsys/net/openthread/rpc/server/ctrl/CMakeLists.txt +++ b/tests/subsys/net/openthread/rpc/client/CMakeLists.txt @@ -6,21 +6,21 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(ot_rpc_ctrl_server_test) +project(ot_rpc_client_test) FILE(GLOB app_sources src/*.c) target_include_directories(app PRIVATE # Needed to access OpenThread RPC command IDs. ${ZEPHYR_NRF_MODULE_DIR}/subsys/net/openthread/rpc/common - ../../common -) + ../common + ) target_sources(app PRIVATE ${app_sources} - ../../common/net_l2_openthread.c - ../../common/nrf_rpc_single_thread.c -) + ../common/net_l2_openthread.c + ../common/nrf_rpc_single_thread.c + ) # Fill the gaps due to not setting NET_L2_OPENTHREAD. zephyr_include_directories( diff --git a/tests/subsys/net/openthread/rpc/client/commissioning/CMakeLists.txt b/tests/subsys/net/openthread/rpc/client/commissioning/CMakeLists.txt deleted file mode 100644 index 60ef2e5c3ee9..000000000000 --- a/tests/subsys/net/openthread/rpc/client/commissioning/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (c) 2024 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# -cmake_minimum_required(VERSION 3.20.0) - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(ot_rpc_commissioning_client_test) - -FILE(GLOB app_sources src/*.c) - -target_include_directories(app PRIVATE - # Needed to access OpenThread RPC command IDs. - ${ZEPHYR_NRF_MODULE_DIR}/subsys/net/openthread/rpc/common - ../../common - ) - -target_sources(app PRIVATE - ${app_sources} - ../../common/net_l2_openthread.c - ../../common/nrf_rpc_single_thread.c - ) - -# Fill the gaps due to not setting NET_L2_OPENTHREAD. -zephyr_include_directories( - ${ZEPHYR_OPENTHREAD_MODULE_DIR}/include -) - -zephyr_compile_definitions( - CONFIG_OPENTHREAD_PKT_LIST_SIZE=1 -) - -# Enforce single-threaded nRF RPC command processing. -target_link_options(app PUBLIC - -Wl,--wrap=nrf_rpc_os_init,--wrap=nrf_rpc_os_thread_pool_send -) diff --git a/tests/subsys/net/openthread/rpc/client/commissioning/testcase.yaml b/tests/subsys/net/openthread/rpc/client/commissioning/testcase.yaml deleted file mode 100644 index 6d96261afde4..000000000000 --- a/tests/subsys/net/openthread/rpc/client/commissioning/testcase.yaml +++ /dev/null @@ -1,7 +0,0 @@ -tests: - net.openthread.rpc.client.commissioning: - sysbuild: true - platform_allow: native_sim - tags: openthread ci_build sysbuild ci_tests_subsys_net_openthread - integration_platforms: - - native_sim diff --git a/tests/subsys/net/openthread/rpc/client/ctrl/CMakeLists.txt b/tests/subsys/net/openthread/rpc/client/ctrl/CMakeLists.txt deleted file mode 100644 index 47ae6a7ef85f..000000000000 --- a/tests/subsys/net/openthread/rpc/client/ctrl/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -# -# Copyright (c) 2024 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# -cmake_minimum_required(VERSION 3.20.0) - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(ot_rpc_ctrl_client_test) - -FILE(GLOB app_sources src/*.c) - -target_include_directories(app PRIVATE - # Needed to access OpenThread RPC command IDs. - ${ZEPHYR_NRF_MODULE_DIR}/subsys/net/openthread/rpc/common - ../../common - ) - -target_sources(app PRIVATE - ${app_sources} - ) diff --git a/tests/subsys/net/openthread/rpc/client/ctrl/prj.conf b/tests/subsys/net/openthread/rpc/client/ctrl/prj.conf deleted file mode 100644 index 8de336d12499..000000000000 --- a/tests/subsys/net/openthread/rpc/client/ctrl/prj.conf +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2024 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# - -# Ztest configuration -CONFIG_ZTEST=y -CONFIG_TEST_RANDOM_GENERATOR=y - -CONFIG_OPENTHREAD_RPC=y -CONFIG_OPENTHREAD_RPC_CLIENT=y -CONFIG_NETWORKING=y -CONFIG_NRF_RPC_CBKPROXY_OUT_SLOTS=0 - -CONFIG_MOCK_NRF_RPC=y -CONFIG_MOCK_NRF_RPC_TRANSPORT=y - -CONFIG_KERNEL_MEM_POOL=y -CONFIG_HEAP_MEM_POOL_SIZE=4096 diff --git a/tests/subsys/net/openthread/rpc/client/commissioning/prj.conf b/tests/subsys/net/openthread/rpc/client/prj.conf similarity index 100% rename from tests/subsys/net/openthread/rpc/client/commissioning/prj.conf rename to tests/subsys/net/openthread/rpc/client/prj.conf diff --git a/tests/subsys/net/openthread/rpc/client/commissioning/src/main.c b/tests/subsys/net/openthread/rpc/client/src/cmsng_suite.c similarity index 55% rename from tests/subsys/net/openthread/rpc/client/commissioning/src/main.c rename to tests/subsys/net/openthread/rpc/client/src/cmsng_suite.c index 4d6223b99238..8006157d461f 100644 --- a/tests/subsys/net/openthread/rpc/client/commissioning/src/main.c +++ b/tests/subsys/net/openthread/rpc/client/src/cmsng_suite.c @@ -78,7 +78,7 @@ ZTEST(ot_rpc_commissioning_cli, test_otDatasetSetActiveTlvs) {INT_SEQUENCE(OT_OPERATIONAL_DATASET_MAX_LENGTH)}, OT_OPERATIONAL_DATASET_MAX_LENGTH}; - mock_nrf_rpc_tr_expect_add(RPC_CMD(OT_RPC_CMD_DATA_SET_ACTIVE_TLVS, TLVS), + mock_nrf_rpc_tr_expect_add(RPC_CMD(OT_RPC_CMD_DATASET_SET_ACTIVE_TLVS, TLVS), RPC_RSP(OT_ERROR_NONE)); error = otDatasetSetActiveTlvs(NULL, &dataset); mock_nrf_rpc_tr_expect_done(); @@ -106,7 +106,7 @@ ZTEST(ot_rpc_commissioning_cli, test_otDatasetGetActiveTlvs) {INT_SEQUENCE(OT_OPERATIONAL_DATASET_MAX_LENGTH)}, OT_OPERATIONAL_DATASET_MAX_LENGTH}; - mock_nrf_rpc_tr_expect_add(RPC_CMD(OT_RPC_CMD_DATA_GET_ACTIVE_TLVS), RPC_RSP(TLVS)); + mock_nrf_rpc_tr_expect_add(RPC_CMD(OT_RPC_CMD_DATASET_GET_ACTIVE_TLVS), RPC_RSP(TLVS)); error = otDatasetGetActiveTlvs(NULL, &dataset); mock_nrf_rpc_tr_expect_done(); zassert_equal(error, OT_ERROR_NONE); @@ -119,7 +119,7 @@ ZTEST(ot_rpc_commissioning_cli, test_otDatasetGetActiveTlvs_null) otError error; otOperationalDatasetTlvs dataset; - mock_nrf_rpc_tr_expect_add(RPC_CMD(OT_RPC_CMD_DATA_GET_ACTIVE_TLVS), RPC_RSP(CBOR_NULL)); + mock_nrf_rpc_tr_expect_add(RPC_CMD(OT_RPC_CMD_DATASET_GET_ACTIVE_TLVS), RPC_RSP(CBOR_NULL)); error = otDatasetGetActiveTlvs(NULL, &dataset); mock_nrf_rpc_tr_expect_done(); zassert_equal(error, OT_ERROR_NOT_FOUND); @@ -197,4 +197,115 @@ ZTEST(ot_rpc_commissioning_cli, test_discover_cb_handler_empty) zassert_true(cb_called); } +/* Test serialization of otDatasetSetActive() */ +ZTEST(ot_rpc_commissioning_cli, test_otDatasetSetActive) +{ + otError error; + + const otOperationalDataset dataset = { + {0x0123456789abcdefull, 0x1234, false}, + {0x0123456789abcdefull, 0x1234, false}, + {{INT_SEQUENCE(OT_NETWORK_KEY_SIZE)}}, + {{INT_SEQUENCE(OT_NETWORK_NAME_MAX_SIZE)}}, + {{INT_SEQUENCE(OT_EXT_PAN_ID_SIZE)}}, + {{INT_SEQUENCE(OT_IP6_PREFIX_SIZE)}}, + 0x12345678ul, + 0xabcd, + 0xef67, + {{INT_SEQUENCE(OT_PSKC_MAX_SIZE)}}, + {0x9876, 1, 0, 1, 0, 1, 0, 1, 0, 1, 7}, + 0xfedcba98, + {false, true, false, true, false, true, false, true, false, true, false, true}}; + + mock_nrf_rpc_tr_expect_add(RPC_CMD(OT_RPC_CMD_DATASET_SET_ACTIVE, DATASET), + RPC_RSP(OT_ERROR_NONE)); + error = otDatasetSetActive(NULL, &dataset); + mock_nrf_rpc_tr_expect_done(); + zassert_equal(error, OT_ERROR_NONE); +} + +/* Test incoming parameters validation of otDatasetSetActive() */ +ZTEST(ot_rpc_commissioning_cli, test_otDatasetSetActive_negative) +{ + otError error; + + error = otDatasetSetActive(NULL, NULL); + zassert_equal(error, OT_ERROR_INVALID_ARGS); +} + +/* Test serialization of otDatasetGetActive() */ +ZTEST(ot_rpc_commissioning_cli, test_otDatasetGetActive) +{ + otError error; + otOperationalDataset dataset; + uint8_t net_key[] = {INT_SEQUENCE(OT_NETWORK_KEY_SIZE)}; + uint8_t nwk_name[] = {INT_SEQUENCE(OT_NETWORK_NAME_MAX_SIZE), 0}; + uint8_t ext_pan_id[] = {INT_SEQUENCE(OT_EXT_PAN_ID_SIZE)}; + uint8_t local_prefix[] = {INT_SEQUENCE(OT_IP6_PREFIX_SIZE)}; + uint8_t pskc[] = {INT_SEQUENCE(OT_PSKC_MAX_SIZE)}; + + mock_nrf_rpc_tr_expect_add(RPC_CMD(OT_RPC_CMD_DATASET_GET_ACTIVE), RPC_RSP(DATASET)); + error = otDatasetGetActive(NULL, &dataset); + mock_nrf_rpc_tr_expect_done(); + zassert_equal(error, OT_ERROR_NONE); + zassert_equal(dataset.mActiveTimestamp.mSeconds, 0x0123456789abcdefull); + zassert_equal(dataset.mActiveTimestamp.mTicks, 0x1234); + zassert_false(dataset.mActiveTimestamp.mAuthoritative); + + zassert_equal(dataset.mPendingTimestamp.mSeconds, 0x0123456789abcdefull); + zassert_equal(dataset.mPendingTimestamp.mTicks, 0x1234); + zassert_false(dataset.mPendingTimestamp.mAuthoritative); + + zassert_mem_equal(dataset.mNetworkKey.m8, net_key, OT_NETWORK_KEY_SIZE); + zassert_mem_equal(dataset.mNetworkName.m8, nwk_name, OT_NETWORK_NAME_MAX_SIZE + 1); + zassert_mem_equal(dataset.mExtendedPanId.m8, ext_pan_id, OT_EXT_PAN_ID_SIZE); + zassert_mem_equal(dataset.mMeshLocalPrefix.m8, local_prefix, OT_IP6_PREFIX_SIZE); + zassert_equal(dataset.mDelay, 0x12345678ul); + zassert_equal(dataset.mPanId, 0xabcd); + zassert_equal(dataset.mChannel, 0xef67); + zassert_mem_equal(dataset.mPskc.m8, pskc, OT_PSKC_MAX_SIZE); + + zassert_equal(dataset.mSecurityPolicy.mRotationTime, 0x9876); + zassert_true(!!dataset.mSecurityPolicy.mObtainNetworkKeyEnabled); + zassert_false(!!dataset.mSecurityPolicy.mNativeCommissioningEnabled); + zassert_true(!!dataset.mSecurityPolicy.mRoutersEnabled); + zassert_false(!!dataset.mSecurityPolicy.mExternalCommissioningEnabled); + zassert_true(!!dataset.mSecurityPolicy.mCommercialCommissioningEnabled); + zassert_false(!!dataset.mSecurityPolicy.mAutonomousEnrollmentEnabled); + zassert_true(!!dataset.mSecurityPolicy.mNetworkKeyProvisioningEnabled); + zassert_false(!!dataset.mSecurityPolicy.mTobleLinkEnabled); + zassert_true(!!dataset.mSecurityPolicy.mNonCcmRoutersEnabled); + zassert_equal(dataset.mSecurityPolicy.mVersionThresholdForRouting, 7); + + zassert_equal(dataset.mChannelMask, 0xfedcba98ul); + + zassert_false(dataset.mComponents.mIsActiveTimestampPresent); + zassert_true(dataset.mComponents.mIsPendingTimestampPresent); + zassert_false(dataset.mComponents.mIsNetworkKeyPresent); + zassert_true(dataset.mComponents.mIsNetworkNamePresent); + zassert_false(dataset.mComponents.mIsExtendedPanIdPresent); + zassert_true(dataset.mComponents.mIsMeshLocalPrefixPresent); + zassert_false(dataset.mComponents.mIsDelayPresent); + zassert_true(dataset.mComponents.mIsPanIdPresent); + zassert_false(dataset.mComponents.mIsChannelPresent); + zassert_true(dataset.mComponents.mIsPskcPresent); + zassert_false(dataset.mComponents.mIsSecurityPolicyPresent); + zassert_true(dataset.mComponents.mIsChannelMaskPresent); +} + +/* Test NULL replay on otDatasetGetActive() and parameter validation. */ +ZTEST(ot_rpc_commissioning_cli, test_otDatasetGetActive_null) +{ + otError error; + otOperationalDataset dataset; + + mock_nrf_rpc_tr_expect_add(RPC_CMD(OT_RPC_CMD_DATASET_GET_ACTIVE), RPC_RSP(CBOR_NULL)); + error = otDatasetGetActive(NULL, &dataset); + mock_nrf_rpc_tr_expect_done(); + zassert_equal(error, OT_ERROR_NOT_FOUND); + + error = otDatasetGetActive(NULL, NULL); + zassert_equal(error, OT_ERROR_NOT_FOUND); +} + ZTEST_SUITE(ot_rpc_commissioning_cli, NULL, NULL, tc_setup, NULL, NULL); diff --git a/tests/subsys/net/openthread/rpc/client/ctrl/src/main.c b/tests/subsys/net/openthread/rpc/client/src/ctrl_suite.c similarity index 100% rename from tests/subsys/net/openthread/rpc/client/ctrl/src/main.c rename to tests/subsys/net/openthread/rpc/client/src/ctrl_suite.c diff --git a/tests/subsys/net/openthread/rpc/client/ctrl/testcase.yaml b/tests/subsys/net/openthread/rpc/client/testcase.yaml similarity index 83% rename from tests/subsys/net/openthread/rpc/client/ctrl/testcase.yaml rename to tests/subsys/net/openthread/rpc/client/testcase.yaml index 599c3604a112..2ffdfe9c0182 100644 --- a/tests/subsys/net/openthread/rpc/client/ctrl/testcase.yaml +++ b/tests/subsys/net/openthread/rpc/client/testcase.yaml @@ -1,5 +1,5 @@ tests: - net.openthread.rpc.client.ctrl: + net.openthread.rpc.client: sysbuild: true platform_allow: native_sim tags: openthread ci_build sysbuild ci_tests_subsys_net_openthread diff --git a/tests/subsys/net/openthread/rpc/common/test_rpc_env.h b/tests/subsys/net/openthread/rpc/common/test_rpc_env.h index 5a3bfd78e935..2b373e4aba2f 100644 --- a/tests/subsys/net/openthread/rpc/common/test_rpc_env.h +++ b/tests/subsys/net/openthread/rpc/common/test_rpc_env.h @@ -33,6 +33,7 @@ /* Other test data */ +#define CBOR_UINT64(value) 0x1B, BT_BYTES_LIST_LE64(BSWAP_64(value)) #define CBOR_UINT32(value) 0x1A, BT_BYTES_LIST_LE32(BSWAP_32(value)) #define CBOR_UINT16(value) 0x19, BT_BYTES_LIST_LE16(BSWAP_16(value)) /* for value bigger than 0x17 */ @@ -44,3 +45,17 @@ #define EXT_PAN_ID 0x48, INT_SEQUENCE(OT_EXT_PAN_ID_SIZE) #define STEERING_DATA 0x50, INT_SEQUENCE(OT_STEERING_DATA_MAX_LENGTH) #define TLVS 0x58, 0xFE, INT_SEQUENCE(OT_OPERATIONAL_DATASET_MAX_LENGTH) +#define NWK_KEY 0x50, INT_SEQUENCE(OT_NETWORK_KEY_SIZE) +#define LOCAL_PREFIX 0x48, INT_SEQUENCE(OT_IP6_PREFIX_SIZE) +#define PSKC 0x50, INT_SEQUENCE(OT_PSKC_MAX_SIZE) +#define TIMESTAMP CBOR_UINT64(0x0123456789abcdef), CBOR_UINT16(0x1234), CBOR_FALSE +#define SECURITY_POLICY \ + CBOR_UINT16(0x9876), CBOR_TRUE, CBOR_FALSE, CBOR_TRUE, CBOR_FALSE, CBOR_TRUE, CBOR_FALSE, \ + CBOR_TRUE, CBOR_FALSE, CBOR_TRUE, 0x07 +#define DATASET_COMPONENTS \ + CBOR_FALSE, CBOR_TRUE, CBOR_FALSE, CBOR_TRUE, CBOR_FALSE, CBOR_TRUE, CBOR_FALSE, \ + CBOR_TRUE, CBOR_FALSE, CBOR_TRUE, CBOR_FALSE, CBOR_TRUE +#define DATASET \ + TIMESTAMP, TIMESTAMP, NWK_KEY, NWK_NAME, EXT_PAN_ID, LOCAL_PREFIX, \ + CBOR_UINT32(0x12345678), CBOR_UINT16(0xabcd), CBOR_UINT16(0xef67), PSKC, \ + SECURITY_POLICY, CBOR_UINT32(0xfedcba98), DATASET_COMPONENTS diff --git a/tests/subsys/net/openthread/rpc/server/commissioning/CMakeLists.txt b/tests/subsys/net/openthread/rpc/server/CMakeLists.txt similarity index 86% rename from tests/subsys/net/openthread/rpc/server/commissioning/CMakeLists.txt rename to tests/subsys/net/openthread/rpc/server/CMakeLists.txt index ccf8f03c896f..313a0abcd31b 100644 --- a/tests/subsys/net/openthread/rpc/server/commissioning/CMakeLists.txt +++ b/tests/subsys/net/openthread/rpc/server/CMakeLists.txt @@ -6,21 +6,21 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(ot_rpc_commissioning_server_test) +project(ot_rpc_server_test) FILE(GLOB app_sources src/*.c) target_include_directories(app PRIVATE # Needed to access OpenThread RPC command IDs. ${ZEPHYR_NRF_MODULE_DIR}/subsys/net/openthread/rpc/common - ../../common + ../common ) target_sources(app PRIVATE ${app_sources} ${ZEPHYR_NRF_MODULE_DIR}/subsys/net/openthread/rpc/server/ot_rpc_commissioning_server.c - ../../common/net_l2_openthread.c - ../../common/nrf_rpc_single_thread.c + ../common/net_l2_openthread.c + ../common/nrf_rpc_single_thread.c ) # Fill the gaps due to not setting NET_L2_OPENTHREAD. diff --git a/tests/subsys/net/openthread/rpc/server/commissioning/testcase.yaml b/tests/subsys/net/openthread/rpc/server/commissioning/testcase.yaml deleted file mode 100644 index da8e77052566..000000000000 --- a/tests/subsys/net/openthread/rpc/server/commissioning/testcase.yaml +++ /dev/null @@ -1,7 +0,0 @@ -tests: - net.openthread.rpc.server.commissioning: - sysbuild: true - platform_allow: native_sim - tags: openthread ci_build sysbuild ci_tests_subsys_net_openthread - integration_platforms: - - native_sim diff --git a/tests/subsys/net/openthread/rpc/server/ctrl/prj.conf b/tests/subsys/net/openthread/rpc/server/ctrl/prj.conf deleted file mode 100644 index 507d5eb995f9..000000000000 --- a/tests/subsys/net/openthread/rpc/server/ctrl/prj.conf +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (c) 2024 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# - -# Ztest configuration -CONFIG_ZTEST=y -CONFIG_TEST_RANDOM_GENERATOR=y - -CONFIG_OPENTHREAD_RPC=y -CONFIG_OPENTHREAD_RPC_SERVER=y -CONFIG_NRF_RPC_CBKPROXY_OUT_SLOTS=0 - -CONFIG_MOCK_NRF_RPC=y -CONFIG_MOCK_NRF_RPC_TRANSPORT=y - -CONFIG_KERNEL_MEM_POOL=y -CONFIG_HEAP_MEM_POOL_SIZE=4096 diff --git a/tests/subsys/net/openthread/rpc/server/commissioning/prj.conf b/tests/subsys/net/openthread/rpc/server/prj.conf similarity index 100% rename from tests/subsys/net/openthread/rpc/server/commissioning/prj.conf rename to tests/subsys/net/openthread/rpc/server/prj.conf diff --git a/tests/subsys/net/openthread/rpc/server/commissioning/src/main.c b/tests/subsys/net/openthread/rpc/server/src/cmsng_suite.c similarity index 51% rename from tests/subsys/net/openthread/rpc/server/commissioning/src/main.c rename to tests/subsys/net/openthread/rpc/server/src/cmsng_suite.c index 26ca9349c088..beefa738bff3 100644 --- a/tests/subsys/net/openthread/rpc/server/commissioning/src/main.c +++ b/tests/subsys/net/openthread/rpc/server/src/cmsng_suite.c @@ -20,36 +20,21 @@ #include /* Fake functions */ - -DEFINE_FFF_GLOBALS; FAKE_VALUE_FUNC(otError, otThreadDiscover, otInstance *, uint32_t, uint16_t, bool, bool, otHandleActiveScanResult, void *); FAKE_VALUE_FUNC(bool, otDatasetIsCommissioned, otInstance *); FAKE_VALUE_FUNC(otError, otDatasetSetActiveTlvs, otInstance *, const otOperationalDatasetTlvs *); FAKE_VALUE_FUNC(otError, otDatasetGetActiveTlvs, otInstance *, otOperationalDatasetTlvs *); -FAKE_VOID_FUNC(otCliInit, otInstance *, otCliOutputCallback, void *); -FAKE_VOID_FUNC(otCliInputLine, char *); -FAKE_VALUE_FUNC(const otNetifAddress *, otIp6GetUnicastAddresses, otInstance *); -FAKE_VALUE_FUNC(const otNetifMulticastAddress *, otIp6GetMulticastAddresses, otInstance *); -FAKE_VALUE_FUNC(otError, otIp6SubscribeMulticastAddress, otInstance *, const otIp6Address *); -FAKE_VALUE_FUNC(otError, otIp6UnsubscribeMulticastAddress, otInstance *, const otIp6Address *); -FAKE_VALUE_FUNC(otError, otIp6SetEnabled, otInstance *, bool); -FAKE_VALUE_FUNC(bool, otIp6IsEnabled, otInstance *); -FAKE_VALUE_FUNC(otError, otThreadSetEnabled, otInstance *, bool); -FAKE_VALUE_FUNC(otDeviceRole, otThreadGetDeviceRole, otInstance *); -FAKE_VALUE_FUNC(otError, otThreadSetLinkMode, otInstance *, otLinkModeConfig); -FAKE_VALUE_FUNC(otLinkModeConfig, otThreadGetLinkMode, otInstance *); -FAKE_VALUE_FUNC(otError, otLinkSetPollPeriod, otInstance *, uint32_t); -FAKE_VALUE_FUNC(uint32_t, otLinkGetPollPeriod, otInstance *); -FAKE_VALUE_FUNC(const otExtAddress *, otLinkGetExtendedAddress, otInstance *); -FAKE_VALUE_FUNC(otError, otSetStateChangedCallback, otInstance *, otStateChangedCallback, void *); -FAKE_VOID_FUNC(otRemoveStateChangeCallback, otInstance *, otStateChangedCallback, void *); +FAKE_VALUE_FUNC(otError, otDatasetSetActive, otInstance *, const otOperationalDataset *); +FAKE_VALUE_FUNC(otError, otDatasetGetActive, otInstance *, otOperationalDataset *); #define FOREACH_FAKE(f) \ f(otThreadDiscover); \ f(otDatasetIsCommissioned); \ f(otDatasetSetActiveTlvs); \ - f(otDatasetGetActiveTlvs) + f(otDatasetGetActiveTlvs); \ + f(otDatasetSetActive); \ + f(otDatasetGetActive) extern uint64_t ot_thread_discover_cb_encoder(uint32_t callback_slot, uint32_t _rsv0, uint32_t _rsv1, uint32_t _ret, @@ -129,7 +114,7 @@ ZTEST(ot_rpc_commissioning_server, test_otDatasetSetActiveTlvs) otDatasetSetActiveTlvs_fake.return_val = OT_ERROR_NONE; mock_nrf_rpc_tr_expect_add(RPC_RSP(OT_ERROR_NONE), NO_RSP); - mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_DATA_SET_ACTIVE_TLVS, TLVS)); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_DATASET_SET_ACTIVE_TLVS, TLVS)); mock_nrf_rpc_tr_expect_done(); zassert_equal(otDatasetSetActiveTlvs_fake.call_count, 1); @@ -144,13 +129,13 @@ ZTEST(ot_rpc_commissioning_server, test_otDatasetSetActiveTlvs) ZTEST(ot_rpc_commissioning_server, test_otDatasetSetActiveTlvs_negative) { mock_nrf_rpc_tr_expect_add(RPC_RSP(OT_ERROR_INVALID_ARGS), NO_RSP); - mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_DATA_SET_ACTIVE_TLVS, CBOR_NULL)); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_DATASET_SET_ACTIVE_TLVS, CBOR_NULL)); mock_nrf_rpc_tr_expect_done(); zassert_equal(otDatasetSetActiveTlvs_fake.call_count, 0); } -static otError custom_fake(otInstance *instance, otOperationalDatasetTlvs *dataset) +static otError dataset_get_tlvs_fake(otInstance *instance, otOperationalDatasetTlvs *dataset) { otOperationalDatasetTlvs expected_dataset = { {INT_SEQUENCE(OT_OPERATIONAL_DATASET_MAX_LENGTH)}, @@ -167,10 +152,10 @@ static otError custom_fake(otInstance *instance, otOperationalDatasetTlvs *datas */ ZTEST(ot_rpc_commissioning_server, test_otDatasetGetActiveTlvs) { - otDatasetGetActiveTlvs_fake.custom_fake = custom_fake; + otDatasetGetActiveTlvs_fake.custom_fake = dataset_get_tlvs_fake; mock_nrf_rpc_tr_expect_add(RPC_RSP(TLVS), NO_RSP); - mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_DATA_GET_ACTIVE_TLVS)); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_DATASET_GET_ACTIVE_TLVS)); mock_nrf_rpc_tr_expect_done(); zassert_equal(otDatasetGetActiveTlvs_fake.call_count, 1); @@ -185,7 +170,7 @@ ZTEST(ot_rpc_commissioning_server, test_otDatasetGetActiveTlvs_null) otDatasetGetActiveTlvs_fake.return_val = OT_ERROR_NOT_FOUND; mock_nrf_rpc_tr_expect_add(RPC_RSP(CBOR_NULL), NO_RSP); - mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_DATA_GET_ACTIVE_TLVS)); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_DATASET_GET_ACTIVE_TLVS)); mock_nrf_rpc_tr_expect_done(); zassert_equal(otDatasetGetActiveTlvs_fake.call_count, 1); @@ -233,4 +218,137 @@ ZTEST(ot_rpc_commissioning_server, test_tx_discover_cb_null) mock_nrf_rpc_tr_expect_done(); } +/* + * Test reception of otDatasetSetActive command. + * Test serialization of the result: OT_ERROR_NONE. + */ +ZTEST(ot_rpc_commissioning_server, test_otDatasetSetActive) +{ + const otOperationalDataset *expected_dataset; + uint8_t net_key[] = {INT_SEQUENCE(OT_NETWORK_KEY_SIZE)}; + uint8_t nwk_name[] = {INT_SEQUENCE(OT_NETWORK_NAME_MAX_SIZE), 0}; + uint8_t ext_pan_id[] = {INT_SEQUENCE(OT_EXT_PAN_ID_SIZE)}; + uint8_t local_prefix[] = {INT_SEQUENCE(OT_IP6_PREFIX_SIZE)}; + uint8_t pskc[] = {INT_SEQUENCE(OT_PSKC_MAX_SIZE)}; + + otDatasetSetActive_fake.return_val = OT_ERROR_NONE; + + mock_nrf_rpc_tr_expect_add(RPC_RSP(OT_ERROR_NONE), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_DATASET_SET_ACTIVE, DATASET)); + mock_nrf_rpc_tr_expect_done(); + + expected_dataset = otDatasetSetActive_fake.arg1_val; + + zassert_equal(otDatasetSetActive_fake.call_count, 1); + zassert_equal(expected_dataset->mActiveTimestamp.mSeconds, 0x0123456789abcdefull); + zassert_equal(expected_dataset->mActiveTimestamp.mTicks, 0x1234); + zassert_false(expected_dataset->mActiveTimestamp.mAuthoritative); + + zassert_equal(expected_dataset->mPendingTimestamp.mSeconds, 0x0123456789abcdefull); + zassert_equal(expected_dataset->mPendingTimestamp.mTicks, 0x1234); + zassert_false(expected_dataset->mPendingTimestamp.mAuthoritative); + + zassert_mem_equal(expected_dataset->mNetworkKey.m8, net_key, OT_NETWORK_KEY_SIZE); + zassert_mem_equal(expected_dataset->mNetworkName.m8, nwk_name, + OT_NETWORK_NAME_MAX_SIZE + 1); + zassert_mem_equal(expected_dataset->mExtendedPanId.m8, ext_pan_id, OT_EXT_PAN_ID_SIZE); + zassert_mem_equal(expected_dataset->mMeshLocalPrefix.m8, local_prefix, OT_IP6_PREFIX_SIZE); + zassert_equal(expected_dataset->mDelay, 0x12345678ul); + zassert_equal(expected_dataset->mPanId, 0xabcd); + zassert_equal(expected_dataset->mChannel, 0xef67); + zassert_mem_equal(expected_dataset->mPskc.m8, pskc, OT_PSKC_MAX_SIZE); + + zassert_equal(expected_dataset->mSecurityPolicy.mRotationTime, 0x9876); + zassert_true(!!expected_dataset->mSecurityPolicy.mObtainNetworkKeyEnabled); + zassert_false(!!expected_dataset->mSecurityPolicy.mNativeCommissioningEnabled); + zassert_true(!!expected_dataset->mSecurityPolicy.mRoutersEnabled); + zassert_false(!!expected_dataset->mSecurityPolicy.mExternalCommissioningEnabled); + zassert_true(!!expected_dataset->mSecurityPolicy.mCommercialCommissioningEnabled); + zassert_false(!!expected_dataset->mSecurityPolicy.mAutonomousEnrollmentEnabled); + zassert_true(!!expected_dataset->mSecurityPolicy.mNetworkKeyProvisioningEnabled); + zassert_false(!!expected_dataset->mSecurityPolicy.mTobleLinkEnabled); + zassert_true(!!expected_dataset->mSecurityPolicy.mNonCcmRoutersEnabled); + zassert_equal(expected_dataset->mSecurityPolicy.mVersionThresholdForRouting, 7); + + zassert_equal(expected_dataset->mChannelMask, 0xfedcba98ul); + + zassert_false(expected_dataset->mComponents.mIsActiveTimestampPresent); + zassert_true(expected_dataset->mComponents.mIsPendingTimestampPresent); + zassert_false(expected_dataset->mComponents.mIsNetworkKeyPresent); + zassert_true(expected_dataset->mComponents.mIsNetworkNamePresent); + zassert_false(expected_dataset->mComponents.mIsExtendedPanIdPresent); + zassert_true(expected_dataset->mComponents.mIsMeshLocalPrefixPresent); + zassert_false(expected_dataset->mComponents.mIsDelayPresent); + zassert_true(expected_dataset->mComponents.mIsPanIdPresent); + zassert_false(expected_dataset->mComponents.mIsChannelPresent); + zassert_true(expected_dataset->mComponents.mIsPskcPresent); + zassert_false(expected_dataset->mComponents.mIsSecurityPolicyPresent); + zassert_true(expected_dataset->mComponents.mIsChannelMaskPresent); +} + +/* + * Test reception of otDatasetSetActive command with NULL pointer. + * Test serialization of the result: OT_ERROR_INVALID_ARGS. + */ +ZTEST(ot_rpc_commissioning_server, test_otDatasetSetActive_negative) +{ + mock_nrf_rpc_tr_expect_add(RPC_RSP(OT_ERROR_INVALID_ARGS), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_DATASET_SET_ACTIVE, CBOR_NULL)); + mock_nrf_rpc_tr_expect_done(); + + zassert_equal(otDatasetSetActive_fake.call_count, 0); +} + +static otError dataset_get_fake(otInstance *instance, otOperationalDataset *dataset) +{ + otOperationalDataset expected_dataset = { + {0x0123456789abcdefull, 0x1234, false}, + {0x0123456789abcdefull, 0x1234, false}, + {{INT_SEQUENCE(OT_NETWORK_KEY_SIZE)}}, + {{INT_SEQUENCE(OT_NETWORK_NAME_MAX_SIZE)}}, + {{INT_SEQUENCE(OT_EXT_PAN_ID_SIZE)}}, + {{INT_SEQUENCE(OT_IP6_PREFIX_SIZE)}}, + 0x12345678ul, + 0xabcd, + 0xef67, + {{INT_SEQUENCE(OT_PSKC_MAX_SIZE)}}, + {0x9876, 1, 0, 1, 0, 1, 0, 1, 0, 1, 7}, + 0xfedcba98, + {false, true, false, true, false, true, false, true, false, true, false, true}}; + + memcpy(dataset, &expected_dataset, sizeof(otOperationalDataset)); + + return OT_ERROR_NONE; +} + +/* + * Test reception of otDatasetGetActive command. + * Test serialization of the result: dataset. + */ +ZTEST(ot_rpc_commissioning_server, test_otDatasetGetActive) +{ + otDatasetGetActive_fake.custom_fake = dataset_get_fake; + + mock_nrf_rpc_tr_expect_add(RPC_RSP(DATASET), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_DATASET_GET_ACTIVE)); + mock_nrf_rpc_tr_expect_done(); + + zassert_equal(otDatasetGetActive_fake.call_count, 1); +} + +/* + * Test reception of otDatasetGetActive command. + * Test serialization of the result: NULL as dataset has not been found. + */ +ZTEST(ot_rpc_commissioning_server, test_otDatasetGetActive_null) +{ + otDatasetGetActive_fake.return_val = OT_ERROR_NOT_FOUND; + + mock_nrf_rpc_tr_expect_add(RPC_RSP(CBOR_NULL), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_DATASET_GET_ACTIVE)); + mock_nrf_rpc_tr_expect_done(); + + zassert_equal(otDatasetGetActive_fake.call_count, 1); +} + ZTEST_SUITE(ot_rpc_commissioning_server, NULL, NULL, tc_setup, NULL, NULL); diff --git a/tests/subsys/net/openthread/rpc/server/ctrl/src/main.c b/tests/subsys/net/openthread/rpc/server/src/ctrl_suite.c similarity index 100% rename from tests/subsys/net/openthread/rpc/server/ctrl/src/main.c rename to tests/subsys/net/openthread/rpc/server/src/ctrl_suite.c diff --git a/tests/subsys/net/openthread/rpc/server/ctrl/testcase.yaml b/tests/subsys/net/openthread/rpc/server/testcase.yaml similarity index 83% rename from tests/subsys/net/openthread/rpc/server/ctrl/testcase.yaml rename to tests/subsys/net/openthread/rpc/server/testcase.yaml index 3f2d3d7c4d2f..13603fb6e4f5 100644 --- a/tests/subsys/net/openthread/rpc/server/ctrl/testcase.yaml +++ b/tests/subsys/net/openthread/rpc/server/testcase.yaml @@ -1,5 +1,5 @@ tests: - net.openthread.rpc.server.ctrl: + net.openthread.rpc.server: sysbuild: true platform_allow: native_sim tags: openthread ci_build sysbuild ci_tests_subsys_net_openthread From 68a8352c8e4bdfd0d2cfab771763dcc6d4c898ed Mon Sep 17 00:00:00 2001 From: Tomasz Tyzenhauz Date: Mon, 26 Aug 2024 13:14:05 +0200 Subject: [PATCH 54/72] manifest: Update Sidewalk scripts: Add retry twister flags to UT pal: ble disable unused configuration pal: add crypto keys module samples: use boot banner with Sidewalk app samples: fix sidewalk_thread msgq samples: add check for mfg at platform_init Signed-off-by: Tomasz Tyzenhauz --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 5e58b2a16b1f..860f9f859c67 100644 --- a/west.yml +++ b/west.yml @@ -218,7 +218,7 @@ manifest: compare-by-default: false - name: sidewalk repo-path: sdk-sidewalk - revision: ec5b68df4398594fdb569942993cdc1b4acbee0b + revision: b9df50c4e80ba2b00cbd33b230484662dd9f1393 groups: - sidewalk - name: find-my From 029696ee287c72979facb3e3fb481e5f6f702ef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ku=C5=BAnia?= Date: Tue, 27 Aug 2024 12:32:58 +0200 Subject: [PATCH 55/72] samples: suit: Enable LTO in flash companion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable LTO to make the application fit in 32kB. Signed-off-by: Rafał Kuźnia --- samples/suit/flash_companion/prj.conf | 4 ++++ .../smp_transfer/sysbuild/nrf54h20dk_nrf54h20_memory_map.dtsi | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/samples/suit/flash_companion/prj.conf b/samples/suit/flash_companion/prj.conf index 8d5467ee0973..69145eab3c13 100644 --- a/samples/suit/flash_companion/prj.conf +++ b/samples/suit/flash_companion/prj.conf @@ -68,3 +68,7 @@ CONFIG_SUIT_ENVELOPE_OUTPUT_MPI_MERGE=n # Enable canonical zcbor encoding CONFIG_ZCBOR_CANONICAL=y + +# Enable LTO +CONFIG_LTO=y +CONFIG_ISR_TABLES_LOCAL_DECLARATION=y diff --git a/samples/suit/smp_transfer/sysbuild/nrf54h20dk_nrf54h20_memory_map.dtsi b/samples/suit/smp_transfer/sysbuild/nrf54h20dk_nrf54h20_memory_map.dtsi index 50a65dfe09d5..673187adfb0b 100644 --- a/samples/suit/smp_transfer/sysbuild/nrf54h20dk_nrf54h20_memory_map.dtsi +++ b/samples/suit/smp_transfer/sysbuild/nrf54h20dk_nrf54h20_memory_map.dtsi @@ -15,7 +15,7 @@ }; companion_partition: partition@f7000 { - reg = <0xf7000 DT_SIZE_K(36)>; + reg = <0xf7000 DT_SIZE_K(32)>; }; }; &cpurad_rx_partitions { From bd0c4b243aa1902bb7cd43f1a84c78b069b8756e Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Tue, 27 Aug 2024 08:20:32 +0200 Subject: [PATCH 56/72] applications: nrf_desktop: Disable USB remote wakeup on nRF54H20 The USB remote wakeup is not yet supported by DWC2 USB device controller driver. Disable the feature in application configuration. Jira: NCSDK-28559 Signed-off-by: Marek Pieta Signed-off-by: Anna Wojdylo --- applications/nrf_desktop/src/modules/Kconfig.usb_state | 5 +++++ .../releases/release-notes-changelog.rst | 2 ++ 2 files changed, 7 insertions(+) diff --git a/applications/nrf_desktop/src/modules/Kconfig.usb_state b/applications/nrf_desktop/src/modules/Kconfig.usb_state index dee657d9df98..286e17e71c24 100644 --- a/applications/nrf_desktop/src/modules/Kconfig.usb_state +++ b/applications/nrf_desktop/src/modules/Kconfig.usb_state @@ -16,10 +16,15 @@ config DESKTOP_USB_REMOTE_WAKEUP bool "Enable USB remote wakeup" default y depends on DESKTOP_USB_PM_ENABLE + depends on !UDC_DWC2 help Enable USB remote wakeup functionality. The USB wakeup request is triggered on wake_up_event. + The DWC2 USB device controller driver used by the nRF54H20 SoC does + not support the remote wakeup capability. Because of that, the feature + is disabled in the configuration. + config DESKTOP_USB_SUBSCRIBER_REPORT_PRIORITY int "USB HID reports subscriber priority" default 255 diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index 23fbad70a96e..9900aca8e7cb 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -244,6 +244,8 @@ nRF Desktop For details, see :ref:`nrf_desktop_usb_state_sof_synchronization`. * Local HID report buffering in :ref:`nrf_desktop_usb_state`. This ensures that the memory buffer passed to the USB next stack is valid until a HID report is sent and allows to enqueue up to two HID input reports for a USB HID instance (used only when :ref:`CONFIG_DESKTOP_USB_HID_REPORT_SENT_ON_SOF ` Kconfig option is enabled). + * Kconfig dependency that prevents enabling USB remote wakeup (:ref:`CONFIG_DESKTOP_USB_REMOTE_WAKEUP `) for the nRF54H20 SoC. + The DWC2 USB device controller driver used by the nRF54H20 SoC does not support the remote wakeup capability. * Updated: From 394983d47a9eab91609b528f0b7120d917dd0741 Mon Sep 17 00:00:00 2001 From: Bernt Johan Damslora Date: Mon, 26 Aug 2024 12:16:12 +0200 Subject: [PATCH 57/72] boards: thingy91x: Add minimal BMM350 init Adds a minimal BMM350 initialization file to the Thingy:91 X board. The OTP memory on BMM350 is disabled on boot to save power. Signed-off-by: Bernt Johan Damslora --- boards/nordic/thingy91x/CMakeLists.txt | 7 ++++ boards/nordic/thingy91x/bmm350_init_minimal.c | 42 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 boards/nordic/thingy91x/bmm350_init_minimal.c diff --git a/boards/nordic/thingy91x/CMakeLists.txt b/boards/nordic/thingy91x/CMakeLists.txt index dd914b447ec4..41ca1b773565 100644 --- a/boards/nordic/thingy91x/CMakeLists.txt +++ b/boards/nordic/thingy91x/CMakeLists.txt @@ -17,6 +17,13 @@ if(CONFIG_BOARD_THINGY91X_NRF9151_NS) set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_LIST_DIR}/thingy91x_nrf9151_pm_static.yml CACHE INTERNAL "") endif() +# If the BMM350 driver is not used, use a minimal initialization instead to save power. +# Once a driver is available in the Zephyr tree, this can be removed. +if (CONFIG_REGULATOR AND CONFIG_I2C AND NOT CONFIG_BMM350) + zephyr_library_named(bmm350_init_minimal) + zephyr_library_sources(bmm350_init_minimal.c) +endif() + if(CONFIG_BOARD_THINGY91X_NRF5340_CPUAPP OR CONFIG_BOARD_THINGY91X_NRF5340_CPUAPP_NS) if(CONFIG_BOARD_ENABLE_CPUNET) zephyr_library() diff --git a/boards/nordic/thingy91x/bmm350_init_minimal.c b/boards/nordic/thingy91x/bmm350_init_minimal.c new file mode 100644 index 000000000000..fd6779f0a4cd --- /dev/null +++ b/boards/nordic/thingy91x/bmm350_init_minimal.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA. + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(bmm350_init_minimal, CONFIG_BOARD_LOG_LEVEL); + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(ldsw_sensors), okay) && \ + DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) + +#define LDSW_SENSORS DEVICE_DT_GET(DT_NODELABEL(ldsw_sensors)) +#define BMM350_I2C_DEVICE DEVICE_DT_GET(DT_NODELABEL(i2c2)) +#define BMM350_I2C_ADDRESS 0x14 + +#define BMM350_REG_OTP_CMD_REG 0x50 +#define BMM350_OTP_CMD_PWR_OFF_OTP 0x80 +#define BMM350_START_UP_TIME_FROM_POR 3000 + +static int bmm350_init_minimal(void) +{ + if (regulator_is_enabled(LDSW_SENSORS)) { + k_sleep(K_USEC(BMM350_START_UP_TIME_FROM_POR)); + + /* Turn off the OTP memory on BMM350 to save power */ + return i2c_reg_write_byte(BMM350_I2C_DEVICE, BMM350_I2C_ADDRESS, + BMM350_REG_OTP_CMD_REG, BMM350_OTP_CMD_PWR_OFF_OTP); + } + return 0; +} + +SYS_INIT(bmm350_init_minimal, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY); + +#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(ldsw_sensors), okay) && \ + * DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) + */ From 9f92f097cb11d4565fd86e9575942f3a55fe1756 Mon Sep 17 00:00:00 2001 From: Przemyslaw Bida Date: Wed, 28 Aug 2024 12:43:12 +0200 Subject: [PATCH 58/72] nrf_rpc: openthread: Add ot message api serialization. Commit adds ot message api related functions: - otMessageAppend - otUdpNewMessage - otMessageFree - otMessageGetLength - otMessageGetOffset - otMessageRead Signed-off-by: Przemyslaw Bida --- .../client/src/ot_shell.c | 51 ++- .../net/openthread/rpc/client/CMakeLists.txt | 1 + .../rpc/client/ot_rpc_ot_message_client.c | 216 ++++++++++++ subsys/net/openthread/rpc/common/ot_rpc_ids.h | 6 + .../net/openthread/rpc/common/ot_rpc_types.h | 2 + .../net/openthread/rpc/server/CMakeLists.txt | 1 + .../rpc/server/ot_rpc_message_server.c | 312 ++++++++++++++++++ .../rpc/server/ot_rpc_message_server.h | 18 + 8 files changed, 605 insertions(+), 2 deletions(-) create mode 100644 subsys/net/openthread/rpc/client/ot_rpc_ot_message_client.c create mode 100644 subsys/net/openthread/rpc/server/ot_rpc_message_server.c create mode 100644 subsys/net/openthread/rpc/server/ot_rpc_message_server.h diff --git a/samples/nrf_rpc/protocols_serialization/client/src/ot_shell.c b/samples/nrf_rpc/protocols_serialization/client/src/ot_shell.c index 3a0f2a442d45..4b615674d699 100644 --- a/samples/nrf_rpc/protocols_serialization/client/src/ot_shell.c +++ b/samples/nrf_rpc/protocols_serialization/client/src/ot_shell.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include @@ -407,14 +409,58 @@ static int cmd_thread(const struct shell *sh, size_t argc, char *argv[]) return ot_cli_command_invoke(ot_cli_command_thread, sh, argc, argv); } +static int cmd_test_message(const struct shell *sh, size_t argc, char *argv[]) +{ + otError error = OT_ERROR_NONE; + otMessage *message = NULL; + uint16_t offset = 0; + uint16_t read = 0; + uint16_t length = 0; + static const char UDP_PAYLOAD[] = "Hello OpenThread World!"; + char buf[128] = {0}; + + message = otUdpNewMessage(NULL, NULL); + if (message == NULL) { + error = OT_ERROR_NO_BUFS; + goto exit; + }; + + offset = otMessageGetOffset(message); + + error = otMessageAppend(message, UDP_PAYLOAD, sizeof(UDP_PAYLOAD)); + if (error != OT_ERROR_NONE) { + goto exit; + } + + length = otMessageGetLength(message); + shell_print(sh, "length %d, offset %d", length, offset); + read = otMessageRead(message, offset, buf, length); + shell_print(sh, "read data: %s", buf); + + if (strcmp(UDP_PAYLOAD, buf) == 0) { + shell_print(sh, "Payload matches."); + } else { + shell_print(sh, "Payload doesn't match."); + } + + read = otMessageRead((otMessage *)2, offset, buf, length); + shell_print(sh, "read data len %d should be 0.", read); + +exit: + if (message != NULL) { + otMessageFree(message); + } + + return 0; +} + static int cmd_ot(const struct shell *sh, size_t argc, char *argv[]) { return ot_cli_command_send(sh, argc, argv); } SHELL_STATIC_SUBCMD_SET_CREATE( - ot_cmds, - SHELL_CMD_ARG(ifconfig, NULL, "Interface management", cmd_ifconfig, 1, 1), + ot_cmds, SHELL_CMD_ARG(ifconfig, NULL, "Interface management", cmd_ifconfig, 1, 1), SHELL_CMD_ARG(ipmaddr, NULL, "IPv6 multicast configuration", cmd_ipmaddr, 1, 2), SHELL_CMD_ARG(mode, NULL, "Mode configuration", cmd_mode, 1, 1), SHELL_CMD_ARG(pollperiod, NULL, "Polling configuration", cmd_pollperiod, 1, 1), @@ -422,6 +468,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_CMD_ARG(thread, NULL, "Role management", cmd_thread, 2, 0), SHELL_CMD_ARG(discover, NULL, "Thread discovery scan", cmd_discover, 1, 4), SHELL_CMD_ARG(active_tlvs, NULL, "Set active dataset", cmd_active_tlvs, 1, 1), + SHELL_CMD_ARG(test_message, NULL, "Test message API", cmd_test_message, 1, 0), SHELL_SUBCMD_SET_END); SHELL_CMD_ARG_REGISTER(ot, &ot_cmds, diff --git a/subsys/net/openthread/rpc/client/CMakeLists.txt b/subsys/net/openthread/rpc/client/CMakeLists.txt index 131014d0045d..32f8524aa883 100644 --- a/subsys/net/openthread/rpc/client/CMakeLists.txt +++ b/subsys/net/openthread/rpc/client/CMakeLists.txt @@ -12,6 +12,7 @@ zephyr_library_sources( ot_rpc_ctrl_client.c ot_rpc_commissioning_client.c ot_rpc_diag_client.c + ot_rpc_ot_message_client.c ) zephyr_library_include_directories( diff --git a/subsys/net/openthread/rpc/client/ot_rpc_ot_message_client.c b/subsys/net/openthread/rpc/client/ot_rpc_ot_message_client.c new file mode 100644 index 000000000000..d977006e185c --- /dev/null +++ b/subsys/net/openthread/rpc/client/ot_rpc_ot_message_client.c @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "nrf_rpc/nrf_rpc_serialize.h" +#include "openthread/error.h" +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include + +#include + +otError otMessageAppend(otMessage *aMessage, const void *aBuf, uint16_t aLength) +{ + struct nrf_rpc_cbor_ctx ctx; + ot_msg_key key = (ot_msg_key)aMessage; + otError error = OT_ERROR_NONE; + + if (aLength == 0 || aBuf == NULL) { + error = OT_ERROR_NONE; + goto exit; + } + + NRF_RPC_CBOR_ALLOC(&ot_group, ctx, aLength + sizeof(key) + 5); + + if (!zcbor_uint_encode(ctx.zs, &key, sizeof(key))) { + NRF_RPC_CBOR_DISCARD(&ot_group, ctx); + error = OT_ERROR_INVALID_ARGS; + goto exit; + } + + if (!zcbor_bstr_encode_ptr(ctx.zs, aBuf, aLength)) { + NRF_RPC_CBOR_DISCARD(&ot_group, ctx); + error = OT_ERROR_INVALID_ARGS; + goto exit; + } + + nrf_rpc_cbor_cmd_no_err(&ot_group, OT_RPC_CMD_MESSAGE_APPEND, &ctx, ot_rpc_decode_error, + &error); + +exit: + return error; +} + +otMessage *otUdpNewMessage(otInstance *aInstance, const otMessageSettings *aSettings) +{ + otMessage *msg = NULL; + bool decoded_ok; + struct nrf_rpc_cbor_ctx ctx; + ot_msg_key key = 0; + + ARG_UNUSED(aInstance); + + NRF_RPC_CBOR_ALLOC(&ot_group, ctx, sizeof(otMessageSettings) + 3); + + nrf_rpc_encode_buffer(&ctx, (const void *)aSettings, sizeof(otMessageSettings)); + + nrf_rpc_cbor_cmd_rsp_no_err(&ot_group, OT_RPC_CMD_UDP_NEW_MESSAGE, &ctx); + + decoded_ok = zcbor_uint_decode(ctx.zs, &key, sizeof(key)); + nrf_rpc_cbor_decoding_done(&ot_group, &ctx); + + if (!decoded_ok) { + nrf_rpc_err(-EBADMSG, NRF_RPC_ERR_SRC_RECV, &ot_group, OT_RPC_CMD_UDP_NEW_MESSAGE, + NRF_RPC_PACKET_TYPE_RSP); + } + + msg = (otMessage *)key; + return msg; +} + +void otMessageFree(otMessage *aMessage) +{ + struct nrf_rpc_cbor_ctx ctx; + ot_msg_key key = (ot_msg_key)aMessage; + + NRF_RPC_CBOR_ALLOC(&ot_group, ctx, sizeof(uint32_t) + 1); + + if (!zcbor_uint32_encode(ctx.zs, &key)) { + NRF_RPC_CBOR_DISCARD(&ot_group, ctx); + return; + } + + nrf_rpc_cbor_cmd_rsp_no_err(&ot_group, OT_RPC_CMD_MESSAGE_FREE, &ctx); + + nrf_rpc_cbor_decoding_done(&ot_group, &ctx); +} + +uint16_t otMessageGetLength(const otMessage *aMessage) +{ + struct nrf_rpc_cbor_ctx ctx; + ot_msg_key key = (ot_msg_key)aMessage; + uint16_t ret = 0; + bool decoded_ok; + + NRF_RPC_CBOR_ALLOC(&ot_group, ctx, sizeof(uint32_t) + 1); + + if (!zcbor_uint32_encode(ctx.zs, &key)) { + NRF_RPC_CBOR_DISCARD(&ot_group, ctx); + goto exit; + } + + nrf_rpc_cbor_cmd_rsp_no_err(&ot_group, OT_RPC_CMD_MESSAGE_GET_LENGTH, &ctx); + + decoded_ok = zcbor_uint_decode(ctx.zs, &ret, sizeof(ret)); + nrf_rpc_cbor_decoding_done(&ot_group, &ctx); + + if (!decoded_ok) { + nrf_rpc_err(-EBADMSG, NRF_RPC_ERR_SRC_RECV, &ot_group, + OT_RPC_CMD_MESSAGE_GET_LENGTH, NRF_RPC_PACKET_TYPE_RSP); + } + +exit: + return ret; +} + +uint16_t otMessageGetOffset(const otMessage *aMessage) +{ + struct nrf_rpc_cbor_ctx ctx; + ot_msg_key key = (ot_msg_key)aMessage; + uint16_t ret = 0; + bool decoded_ok; + + NRF_RPC_CBOR_ALLOC(&ot_group, ctx, sizeof(uint32_t) + 2); + + if (!zcbor_uint32_encode(ctx.zs, &key)) { + NRF_RPC_CBOR_DISCARD(&ot_group, ctx); + goto exit; + } + + nrf_rpc_cbor_cmd_rsp_no_err(&ot_group, OT_RPC_CMD_MESSAGE_GET_OFFSET, &ctx); + + decoded_ok = zcbor_uint_decode(ctx.zs, &ret, sizeof(ret)); + nrf_rpc_cbor_decoding_done(&ot_group, &ctx); + + if (!decoded_ok) { + nrf_rpc_err(-EBADMSG, NRF_RPC_ERR_SRC_RECV, &ot_group, + OT_RPC_CMD_MESSAGE_GET_OFFSET, NRF_RPC_PACKET_TYPE_RSP); + } + +exit: + return ret; +} + +uint16_t otMessageRead(const otMessage *aMessage, uint16_t aOffset, void *aBuf, uint16_t aLength) +{ + struct nrf_rpc_cbor_ctx ctx; + ot_msg_key key = (ot_msg_key)aMessage; + uint16_t ret = 0; + struct zcbor_string zst; + bool decoded_ok; + + if (aLength == 0 || aBuf == NULL || aMessage == NULL) { + return 0; + } + + NRF_RPC_CBOR_ALLOC(&ot_group, ctx, sizeof(key) + sizeof(aOffset) + sizeof(aLength) + 5); + + if (!zcbor_uint_encode(ctx.zs, &key, sizeof(key))) { + NRF_RPC_CBOR_DISCARD(&ot_group, ctx); + goto exit; + } + + if (!zcbor_uint_encode(ctx.zs, &aOffset, sizeof(aOffset))) { + NRF_RPC_CBOR_DISCARD(&ot_group, ctx); + goto exit; + } + + if (!zcbor_uint_encode(ctx.zs, &aLength, sizeof(aLength))) { + NRF_RPC_CBOR_DISCARD(&ot_group, ctx); + goto exit; + } + + nrf_rpc_cbor_cmd_rsp_no_err(&ot_group, OT_RPC_CMD_MESSAGE_READ, &ctx); + + if (zcbor_nil_expect(ctx.zs, NULL)) { + nrf_rpc_cbor_decoding_done(&ot_group, &ctx); + goto exit; + } + + if (ctx.zs->constant_state->error != ZCBOR_ERR_WRONG_TYPE) { + nrf_rpc_cbor_decoding_done(&ot_group, &ctx); + goto exit; + } + + zcbor_pop_error(ctx.zs); + + decoded_ok = zcbor_bstr_decode(ctx.zs, &zst); + + nrf_rpc_cbor_decoding_done(&ot_group, &ctx); + + if (!decoded_ok) { + nrf_rpc_err(-EBADMSG, NRF_RPC_ERR_SRC_RECV, &ot_group, OT_RPC_CMD_MESSAGE_READ, + NRF_RPC_PACKET_TYPE_RSP); + goto exit; + } + + ret = zst.len < aLength ? zst.len : aLength; + + memcpy(aBuf, zst.value, ret); + +exit: + return ret; +} diff --git a/subsys/net/openthread/rpc/common/ot_rpc_ids.h b/subsys/net/openthread/rpc/common/ot_rpc_ids.h index 53e7d810fdbb..98e2878d9324 100644 --- a/subsys/net/openthread/rpc/common/ot_rpc_ids.h +++ b/subsys/net/openthread/rpc/common/ot_rpc_ids.h @@ -57,4 +57,10 @@ enum ot_rpc_cmd_server { OT_RPC_CMD_THREAD_GET_NEXT_NEIGHBOR_INFO, OT_RPC_CMD_THREAD_GET_PARENT_INFO, OT_RPC_CMD_THREAD_GET_PARTITION_ID, + OT_RPC_CMD_UDP_NEW_MESSAGE, + OT_RPC_CMD_MESSAGE_FREE, + OT_RPC_CMD_MESSAGE_APPEND, + OT_RPC_CMD_MESSAGE_GET_LENGTH, + OT_RPC_CMD_MESSAGE_GET_OFFSET, + OT_RPC_CMD_MESSAGE_READ, }; diff --git a/subsys/net/openthread/rpc/common/ot_rpc_types.h b/subsys/net/openthread/rpc/common/ot_rpc_types.h index 349085671eda..d8d25e55fae5 100644 --- a/subsys/net/openthread/rpc/common/ot_rpc_types.h +++ b/subsys/net/openthread/rpc/common/ot_rpc_types.h @@ -26,3 +26,5 @@ enum ot_rpc_link_mode_offsets { OT_RPC_LINK_MODE_DEVICE_TYPE_OFFSET = 1, OT_RPC_LINK_MODE_NETWORK_DATA_OFFSET = 2, }; + +typedef uint32_t ot_msg_key; diff --git a/subsys/net/openthread/rpc/server/CMakeLists.txt b/subsys/net/openthread/rpc/server/CMakeLists.txt index 92ce545c2eb2..425f859cb181 100644 --- a/subsys/net/openthread/rpc/server/CMakeLists.txt +++ b/subsys/net/openthread/rpc/server/CMakeLists.txt @@ -15,6 +15,7 @@ zephyr_library_sources_ifdef(CONFIG_NET_L2_OPENTHREAD ot_rpc_if_server.c ot_rpc_commissioning_server.c ot_rpc_diag_server.c + ot_rpc_message_server.c ) zephyr_library_include_directories( diff --git a/subsys/net/openthread/rpc/server/ot_rpc_message_server.c b/subsys/net/openthread/rpc/server/ot_rpc_message_server.c new file mode 100644 index 000000000000..14255b0139fd --- /dev/null +++ b/subsys/net/openthread/rpc/server/ot_rpc_message_server.c @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#define OT_MESSAGES_POOL 8 + +static otMessage *ot_message_registry[OT_MESSAGES_POOL]; + +ot_msg_key ot_reg_msg_alloc(void) +{ + for (ot_msg_key i = 0; i < OT_MESSAGES_POOL; i++) { + if (ot_message_registry[i] == NULL) { + return i + 1; + } + } + return 0; +} + +void ot_msg_free(ot_msg_key key) +{ + key--; + if (key >= OT_MESSAGES_POOL) { + return; + } + + if (ot_message_registry[key] != NULL) { + ot_message_registry[key] = NULL; + } +} + +otMessage *ot_msg_get(ot_msg_key key) +{ + key--; + + if (key < OT_MESSAGES_POOL) { + return ot_message_registry[key]; + } + + return NULL; +} + +static void ot_rpc_msg_free(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx, + void *handler_data) +{ + ot_msg_key key = 0; + bool decoding_ok; + otMessage *message; + + decoding_ok = zcbor_uint_decode(ctx->zs, &key, sizeof(key)); + + nrf_rpc_cbor_decoding_done(group, ctx); + + if (!decoding_ok) { + ot_rpc_report_decoding_error(OT_RPC_CMD_MESSAGE_FREE); + goto exit; + } + + message = ot_msg_get(key); + + if (message != NULL) { + openthread_api_mutex_lock(openthread_get_default_context()); + otMessageFree(message); + openthread_api_mutex_unlock(openthread_get_default_context()); + } + + ot_msg_free(key); + +exit: + nrf_rpc_rsp_send_void(group); +} + +static void ot_rpc_msg_append(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx, + void *handler_data) +{ + otError error = OT_ERROR_NONE; + struct nrf_rpc_cbor_ctx rsp_ctx; + struct zcbor_string zst; + uint32_t key; + bool decoding_ok; + otMessage *message; + + decoding_ok = zcbor_uint_decode(ctx->zs, &key, sizeof(uint32_t)); + + if (!decoding_ok) { + nrf_rpc_cbor_decoding_done(group, ctx); + ot_rpc_report_decoding_error(OT_RPC_CMD_MESSAGE_APPEND); + error = OT_ERROR_INVALID_ARGS; + goto exit; + } + + decoding_ok = zcbor_bstr_decode(ctx->zs, &zst); + + if (!decoding_ok) { + nrf_rpc_cbor_decoding_done(group, ctx); + ot_rpc_report_decoding_error(OT_RPC_CMD_MESSAGE_APPEND); + error = OT_ERROR_INVALID_ARGS; + goto exit; + } + + message = ot_msg_get(key); + + if (message != NULL) { + openthread_api_mutex_lock(openthread_get_default_context()); + error = otMessageAppend(ot_msg_get(key), zst.value, zst.len); + openthread_api_mutex_unlock(openthread_get_default_context()); + } else { + error = OT_ERROR_INVALID_ARGS; + } + + nrf_rpc_cbor_decoding_done(group, ctx); + +exit: + NRF_RPC_CBOR_ALLOC(group, rsp_ctx, sizeof(otError) + 1); + zcbor_uint_encode(rsp_ctx.zs, &error, sizeof(otError)); + nrf_rpc_cbor_rsp_no_err(group, &rsp_ctx); +} + +static void ot_rpc_msg_udp_new(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx, + void *handler_data) +{ + uint32_t key = 0; + struct nrf_rpc_cbor_ctx rsp_ctx; + otMessageSettings settings; + otMessageSettings *pSettings; + + pSettings = nrf_rpc_decode_buffer(ctx, &settings, sizeof(otMessageSettings)); + + nrf_rpc_cbor_decoding_done(group, ctx); + + key = ot_reg_msg_alloc(); + + if (key == 0) { + goto exit; + } + + openthread_api_mutex_lock(openthread_get_default_context()); + ot_message_registry[key - 1] = + otUdpNewMessage(openthread_get_default_instance(), pSettings); + openthread_api_mutex_unlock(openthread_get_default_context()); + + if (ot_message_registry[key - 1] == NULL) { + key = 0; + } + +exit: + NRF_RPC_CBOR_ALLOC(group, rsp_ctx, sizeof(uint32_t) + 1); + zcbor_uint_encode(rsp_ctx.zs, &key, sizeof(uint32_t)); + nrf_rpc_cbor_rsp_no_err(group, &rsp_ctx); +} + +static void ot_rpc_msg_length(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx, + void *handler_data) +{ + uint32_t key; + bool decoding_ok; + struct nrf_rpc_cbor_ctx rsp_ctx; + uint16_t length = 0; + otMessage *message; + + decoding_ok = zcbor_uint_decode(ctx->zs, &key, sizeof(key)); + + nrf_rpc_cbor_decoding_done(group, ctx); + + if (!decoding_ok) { + ot_rpc_report_decoding_error(OT_RPC_CMD_MESSAGE_APPEND); + goto exit; + } + + message = ot_msg_get(key); + + if (message != NULL) { + openthread_api_mutex_lock(openthread_get_default_context()); + length = otMessageGetLength(message); + openthread_api_mutex_unlock(openthread_get_default_context()); + } + +exit: + + NRF_RPC_CBOR_ALLOC(group, rsp_ctx, sizeof(length) + 2); + zcbor_uint_encode(rsp_ctx.zs, &length, sizeof(length)); + nrf_rpc_cbor_rsp_no_err(group, &rsp_ctx); +} + +static void ot_rpc_get_offset(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx, + void *handler_data) +{ + uint32_t key; + bool decoding_ok; + struct nrf_rpc_cbor_ctx rsp_ctx; + uint16_t offset = 0; + otMessage *message; + + decoding_ok = zcbor_uint_decode(ctx->zs, &key, sizeof(key)); + + nrf_rpc_cbor_decoding_done(group, ctx); + + if (!decoding_ok) { + ot_rpc_report_decoding_error(OT_RPC_CMD_MESSAGE_APPEND); + goto exit; + } + + message = ot_msg_get(key); + + if (message != NULL) { + openthread_api_mutex_lock(openthread_get_default_context()); + offset = otMessageGetOffset(message); + openthread_api_mutex_unlock(openthread_get_default_context()); + } + +exit: + + NRF_RPC_CBOR_ALLOC(group, rsp_ctx, sizeof(offset) + 1); + zcbor_uint_encode(rsp_ctx.zs, &offset, sizeof(offset)); + nrf_rpc_cbor_rsp_no_err(group, &rsp_ctx); +} + +static void ot_rpc_msg_read(const struct nrf_rpc_group *group, struct nrf_rpc_cbor_ctx *ctx, + void *handler_data) +{ + uint16_t offset; + uint16_t length; + uint32_t key; + struct nrf_rpc_cbor_ctx rsp_ctx; + const uint16_t chunk_size = 64; + uint8_t buf[chunk_size]; + uint16_t read = 0; + otMessage *message; + + if (!zcbor_uint_decode(ctx->zs, &key, sizeof(key))) { + nrf_rpc_cbor_decoding_done(group, ctx); + ot_rpc_report_decoding_error(OT_RPC_CMD_MESSAGE_APPEND); + goto exit; + } + + if (!zcbor_uint_decode(ctx->zs, &offset, sizeof(offset))) { + nrf_rpc_cbor_decoding_done(group, ctx); + ot_rpc_report_decoding_error(OT_RPC_CMD_MESSAGE_APPEND); + goto exit; + } + + if (!zcbor_uint_decode(ctx->zs, &length, sizeof(length))) { + nrf_rpc_cbor_decoding_done(group, ctx); + ot_rpc_report_decoding_error(OT_RPC_CMD_MESSAGE_APPEND); + goto exit; + } + + nrf_rpc_cbor_decoding_done(group, ctx); + + NRF_RPC_CBOR_ALLOC(group, rsp_ctx, length + 2); + + message = ot_msg_get(key); + + if (message == NULL) { + zcbor_nil_put(rsp_ctx.zs, NULL); + goto exit; + } + + if (!zcbor_bstr_start_encode(rsp_ctx.zs)) { + goto exit; + } + + openthread_api_mutex_lock(openthread_get_default_context()); + + do { + read = otMessageRead(message, offset, buf, + (chunk_size < length) ? chunk_size : length); + memcpy(rsp_ctx.zs[0].payload_mut, buf, read); + rsp_ctx.zs->payload_mut += read; + length -= read; + offset += read; + } while (read > 0 && length > 0); + + openthread_api_mutex_unlock(openthread_get_default_context()); + + if (!zcbor_bstr_end_encode(rsp_ctx.zs, NULL)) { + goto exit; + } + +exit: + nrf_rpc_cbor_rsp_no_err(group, &rsp_ctx); +} + +NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_msg_length, OT_RPC_CMD_MESSAGE_GET_LENGTH, + ot_rpc_msg_length, NULL); + +NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_get_offset, OT_RPC_CMD_MESSAGE_GET_OFFSET, + ot_rpc_get_offset, NULL); + +NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_msg_read, OT_RPC_CMD_MESSAGE_READ, ot_rpc_msg_read, NULL); + +NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_msg_free, OT_RPC_CMD_MESSAGE_FREE, ot_rpc_msg_free, NULL); + +NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_msg_udp_new, OT_RPC_CMD_UDP_NEW_MESSAGE, + ot_rpc_msg_udp_new, NULL); + +NRF_RPC_CBOR_CMD_DECODER(ot_group, ot_rpc_msg_append, OT_RPC_CMD_MESSAGE_APPEND, ot_rpc_msg_append, + NULL); diff --git a/subsys/net/openthread/rpc/server/ot_rpc_message_server.h b/subsys/net/openthread/rpc/server/ot_rpc_message_server.h new file mode 100644 index 000000000000..12b0413f9467 --- /dev/null +++ b/subsys/net/openthread/rpc/server/ot_rpc_message_server.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef OT_RPC_OT_MESSAGE_ +#define OT_RPC_OT_MESSAGE_ + +#include +#include +#include + +ot_msg_key ot_reg_msg_alloc(void); +void ot_msg_free(ot_msg_key key); +otMessage *ot_msg_get(ot_msg_key key); + +#endif From a8ae7b4a306eb55cd83d139848196a5f026b80f7 Mon Sep 17 00:00:00 2001 From: Pete Skeggs Date: Mon, 26 Aug 2024 15:38:07 -0700 Subject: [PATCH 59/72] net: lib: nrf_cloud: Add logging of cloud info Add new Kconfig CONFIG_NRF_CLOUD_VERBOSE_DETAILS. Always log device id. If the new Kconfig is y, also log stage, protocol, sec tag, and host name. If device is connected to the cloud using MQTT, also log the tenant. Modify the nrf_cloud_multi_service sample to remove printing of device id, but instead call new nrf_cloud_print_details() function. Do the same for the nrf_cloud_rest_fota, nrf_cloud_rest_device_message, and nrf_cloud_rest_cell_location samples. Reduce heap when using CoAP to prevent build error when modem trace and CoAP provisioning are enabled. Jira: IRIS-6931 Signed-off-by: Pete Skeggs --- .../releases/release-notes-changelog.rst | 17 +- include/net/nrf_cloud.h | 59 +++++++ .../src/cloud_connection.c | 10 +- .../nrf_cloud_rest_cell_location/src/main.c | 13 +- .../nrf_cloud_rest_device_message/src/main.c | 7 +- .../cellular/nrf_cloud_rest_fota/src/main.c | 11 +- subsys/net/lib/nrf_cloud/CMakeLists.txt | 3 +- subsys/net/lib/nrf_cloud/Kconfig | 7 + subsys/net/lib/nrf_cloud/coap/src/nrfc_dtls.c | 45 +---- subsys/net/lib/nrf_cloud/src/nrf_cloud_info.c | 164 ++++++++++++++++++ 10 files changed, 270 insertions(+), 66 deletions(-) create mode 100644 subsys/net/lib/nrf_cloud/src/nrf_cloud_info.c diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index 9900aca8e7cb..78552be7847d 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -343,7 +343,10 @@ Cellular samples * :ref:`nrf_cloud_rest_fota` sample: - * Added support for setting the FOTA update check interval using the config section in the shadow. + * Added: + + * Support for setting the FOTA update check interval using the config section in the shadow. + * A call to the :c:func:`nrf_cloud_print_details` function and removed redundant logging. * :ref:`nrf_cloud_multi_service` sample: @@ -351,6 +354,7 @@ Cellular samples * The :kconfig:option:`CONFIG_TEST_COUNTER_MULTIPLIER` Kconfig option to multiply the number of test counter messages sent, for testing purposes. * A handler for new nRF Cloud event type ``NRF_CLOUD_EVT_RX_DATA_DISCON`` to stop sensors and location services. + * A call to the :c:func:`nrf_cloud_print_details` function and removed redundant logging. * Updated: @@ -361,7 +365,14 @@ Cellular samples * :ref:`nrf_cloud_rest_device_message` sample: - * Added support for dictionary logs using REST. + * Added: + + * Support for dictionary logs using REST. + * A call to the :c:func:`nrf_cloud_print_details` function and removed redundant logging. + +* :ref:`nrf_cloud_rest_cell_pos_sample` sample: + + * Added a call to the :c:func:`nrf_cloud_print_details` function and removed redundant logging. Cryptography samples -------------------- @@ -690,6 +701,8 @@ Libraries for networking * The function :c:func:`nrf_cloud_client_id_runtime_set` to set the device ID string if the :kconfig:option:`CONFIG_NRF_CLOUD_CLIENT_ID_SRC_RUNTIME` Kconfig option is enabled. * The functions :c:func:`nrf_cloud_sec_tag_set` and :c:func:`nrf_cloud_sec_tag_get` to set and get the sec tag used for nRF Cloud credentials. * A new nRF Cloud event type ``NRF_CLOUD_EVT_RX_DATA_DISCON`` which is generated when a device is deleted from nRF Cloud. + * The function :c:func:`nrf_cloud_print_details` to log common nRF Cloud connection information in a uniform way. + * The :kconfig:option:`CONFIG_NRF_CLOUD_VERBOSE_DETAILS` Kconfig option to enable the :c:func:`nrf_cloud_print_details` function to print all details instead of only the device ID. * Updated: diff --git a/include/net/nrf_cloud.h b/include/net/nrf_cloud.h index fefb3f805aa0..755bb859a517 100644 --- a/include/net/nrf_cloud.h +++ b/include/net/nrf_cloud.h @@ -701,6 +701,65 @@ int nrf_cloud_init(const struct nrf_cloud_init_param *param); */ int nrf_cloud_uninit(void); +/** + * @brief Print details about cloud connection. + * + * if @kconfig{CONFIG_NRF_CLOUD_VERBOSE_DETAILS} is not enabled, + * only print the device id. If enabled, also print the protocol, + * sec tag, host name, stage, and team id. + * + * @return A negative value indicates an error. + */ +int nrf_cloud_print_details(void); + +/** + * @brief Retrieve the IMEI. + * + * If @kconfig{CONFIG_NRF_MODEM_LIB} is not enabled, returns an error. + * + * @param[in,out] buf A pointer in which to store the IMEI string. + * @param[in] buf_sz The size of the buffer. It should be at least 22 + * to include the 15 bytes for the IMEI and 7 for AT + * command overhead. + * + * @retval 0 If successful. + * @retval -ENOTSUP If the modem library is not available. + * @return A negative value indicates an error. + */ +int nrf_cloud_get_imei(char *buf, size_t buf_sz); + +/** + * @brief Retrieve the device's UUID. + * + * If @kconfig{CONFIG_NRF_MODEM_LIB} is not enabled, returns an error. + * + * @param[in,out] buf A pointer in which to store the UUID string. + * @param[in] buf_sz The size of the buffer. It should be at least + * NRF_DEVICE_UUID_STR_LEN + 1 bytes in size. + * + * @retval 0 If successful. + * @retval -ENOTSUP If the modem library is not available. + * @retval -EINVAL buf cannot be NULL. + * @retval -ENOMEM buf_sz was too small. + * @return A negative value indicates an error. + */ +int nrf_cloud_get_uuid(char *buf, size_t buf_sz); + +/** + * @brief Retrieve the Modem firmware version. + * + * If @kconfig{CONFIG_NRF_MODEM_LIB} is not enabled, returns an error. + * + * @param[in,out] buf A pointer in which to store the mfw string. + * @param[in] buf_sz The size of the buffer. The required size could + * be up to 2048, but 32 should be sufficient. + * + * @retval 0 If successful. + * @retval -ENOTSUP If the modem library is not available. + * @return A negative value indicates an error. + */ +int nrf_cloud_get_modem_fw(char *buf, size_t buf_sz); + /** * @brief Connect to the cloud. * diff --git a/samples/cellular/nrf_cloud_multi_service/src/cloud_connection.c b/samples/cellular/nrf_cloud_multi_service/src/cloud_connection.c index 64fd2651d1a9..d01b0162b180 100644 --- a/samples/cellular/nrf_cloud_multi_service/src/cloud_connection.c +++ b/samples/cellular/nrf_cloud_multi_service/src/cloud_connection.c @@ -248,21 +248,15 @@ void cloud_transport_error_detected(void) */ static bool connect_cloud(void) { - char device_id[NRF_CLOUD_CLIENT_ID_MAX_LEN + 1]; int err; LOG_INF("Connecting to nRF Cloud"); - err = nrf_cloud_client_id_get(device_id, sizeof(device_id)); - if (!err) { - LOG_INF("Device ID: %s", device_id); - } else { - LOG_ERR("Error requesting the device id: %d", err); - } - /* Clear the disconnected flag, no longer accurate. */ k_event_clear(&cloud_events, CLOUD_DISCONNECTED); + nrf_cloud_print_details(); + #if defined(CONFIG_NRF_CLOUD_MQTT) /* Connect to nRF Cloud -- Non-blocking. State updates are handled in callbacks. */ err = nrf_cloud_connect(); diff --git a/samples/cellular/nrf_cloud_rest_cell_location/src/main.c b/samples/cellular/nrf_cloud_rest_cell_location/src/main.c index 472b9b3b686a..ea623407a532 100644 --- a/samples/cellular/nrf_cloud_rest_cell_location/src/main.c +++ b/samples/cellular/nrf_cloud_rest_cell_location/src/main.c @@ -149,8 +149,6 @@ static void check_modem_fw_version(void) return; } - LOG_INF("Modem FW version: %s", mfwv_str); - if ((sscanf(mfwv_str, "mfw_nrf9160_%u.%u.%u", &major, &minor, &rev) != 3) && (sscanf(mfwv_str, "mfw_nrf91x1_%u.%u.%u", &major, &minor, &rev) != 3)) { LOG_WRN("Unable to parse modem FW version number"); @@ -436,9 +434,6 @@ int init(void) return err; } - /* Check modem FW version */ - check_modem_fw_version(); - /* Print the nRF Cloud device ID. This device ID should match the ID used * to provision the device on nRF Cloud or to register a public JWT signing key. */ @@ -448,7 +443,13 @@ int init(void) return err; } - LOG_INF("Device ID: %s", device_id); + err = nrf_cloud_print_details(); + if (err) { + LOG_ERR("Error printing cloud information: %d", err); + } + + /* Check modem FW version */ + check_modem_fw_version(); /* Inform the app event manager that this module is ready to receive events */ module_set_state(MODULE_STATE_READY); diff --git a/samples/cellular/nrf_cloud_rest_device_message/src/main.c b/samples/cellular/nrf_cloud_rest_device_message/src/main.c index 950076faa3da..6ef960d29daf 100644 --- a/samples/cellular/nrf_cloud_rest_device_message/src/main.c +++ b/samples/cellular/nrf_cloud_rest_device_message/src/main.c @@ -454,8 +454,6 @@ static int setup_connection(void) return err; } - LOG_INF("Device ID: %s", device_id); - /* Connect to LTE */ err = connect_to_lte(); if (err) { @@ -528,6 +526,11 @@ static int init(void) return -EFAULT; } + err = nrf_cloud_print_details(); + if (err) { + LOG_ERR("Error printing cloud information: %d", err); + } + /* If provisioning library is disabled, ensure device has credentials installed * before proceeding */ diff --git a/samples/cellular/nrf_cloud_rest_fota/src/main.c b/samples/cellular/nrf_cloud_rest_fota/src/main.c index 85ea88504fb9..d8c92a1fb6fb 100644 --- a/samples/cellular/nrf_cloud_rest_fota/src/main.c +++ b/samples/cellular/nrf_cloud_rest_fota/src/main.c @@ -159,9 +159,7 @@ static void get_modem_info(void) { int err = modem_info_params_get(&mdm_param); - if (!err) { - LOG_INF("Modem FW Ver: %s", mdm_param.device.modem_fw.value_string); - } else { + if (err) { LOG_WRN("Unable to obtain modem info, error: %d", err); } } @@ -349,6 +347,11 @@ int init(void) return -EFAULT; } + err = nrf_cloud_print_details(); + if (err) { + LOG_ERR("Error printing cloud information: %d", err); + } + err = nrf_cloud_fota_poll_init(&fota_ctx); if (err) { LOG_ERR("FOTA support init failed: %d", err); @@ -383,8 +386,6 @@ int init(void) return err; } - LOG_INF("Device ID: %s", device_id); - err = dk_buttons_init(button_handler); if (err) { LOG_ERR("Failed to initialize button: error: %d", err); diff --git a/subsys/net/lib/nrf_cloud/CMakeLists.txt b/subsys/net/lib/nrf_cloud/CMakeLists.txt index 82bbf8ee7db7..45f6f0856a9b 100644 --- a/subsys/net/lib/nrf_cloud/CMakeLists.txt +++ b/subsys/net/lib/nrf_cloud/CMakeLists.txt @@ -10,7 +10,8 @@ zephyr_library_sources( src/nrf_cloud_codec.c src/nrf_cloud_mem.c src/nrf_cloud_client_id.c - src/nrf_cloud_sec_tag.c) + src/nrf_cloud_sec_tag.c + src/nrf_cloud_info.c) zephyr_library_sources_ifdef( CONFIG_NRF_CLOUD_ALERT src/nrf_cloud_alert.c) diff --git a/subsys/net/lib/nrf_cloud/Kconfig b/subsys/net/lib/nrf_cloud/Kconfig index 8086f7d3a89e..f3ea2773181b 100644 --- a/subsys/net/lib/nrf_cloud/Kconfig +++ b/subsys/net/lib/nrf_cloud/Kconfig @@ -27,6 +27,13 @@ rsource "Kconfig.nrf_cloud_coap" rsource "Kconfig.nrf_cloud_shadow_info" +config NRF_CLOUD_VERBOSE_DETAILS + bool "Log more info about cloud connection" + default y + help + Log at INF level the stage, protocol, sec tag, host name, and team ID, + in addition to device id. + config NRF_CLOUD_GATEWAY bool "nRF Cloud Gateway" help diff --git a/subsys/net/lib/nrf_cloud/coap/src/nrfc_dtls.c b/subsys/net/lib/nrf_cloud/coap/src/nrfc_dtls.c index c1575abad3cb..4adc7777e306 100644 --- a/subsys/net/lib/nrf_cloud/coap/src/nrfc_dtls.c +++ b/subsys/net/lib/nrf_cloud/coap/src/nrfc_dtls.c @@ -37,50 +37,18 @@ static bool dtls_cid_active; static bool cid_supported = true; static bool keepopen_supported; -#if defined(CONFIG_MODEM_INFO) -static struct modem_param_info mdm_param; - -static int get_modem_info(void) -{ - int err; - - err = modem_info_string_get(MODEM_INFO_IMEI, - mdm_param.device.imei.value_string, - MODEM_INFO_MAX_RESPONSE_SIZE); - if (err <= 0) { - LOG_ERR("Could not get IMEI: %d", err); - return err; - } - - err = modem_info_string_get(MODEM_INFO_FW_VERSION, - mdm_param.device.modem_fw.value_string, - MODEM_INFO_MAX_RESPONSE_SIZE); - if (err <= 0) { - LOG_ERR("Could not get mfw ver: %d", err); - return err; - } - - LOG_INF("IMEI: %s", mdm_param.device.imei.value_string); - LOG_INF("Modem FW version: %s", mdm_param.device.modem_fw.value_string); - - return 0; -} - -#endif /* CONFIG_MODEM_INFO */ - static int get_device_ip_address(uint8_t *d4_addr) { #if defined(CONFIG_MODEM_INFO) + char buf[INET_ADDRSTRLEN + sizeof(" ") + INET6_ADDRSTRLEN + 1]; int err; - err = modem_info_string_get(MODEM_INFO_IP_ADDRESS, - mdm_param.network.ip_address.value_string, - MODEM_INFO_MAX_RESPONSE_SIZE); + err = modem_info_string_get(MODEM_INFO_IP_ADDRESS, buf, sizeof(buf)); if (err <= 0) { LOG_ERR("Could not get IP addr: %d", err); return err; } - err = inet_pton(AF_INET, mdm_param.network.ip_address.value_string, d4_addr); + err = inet_pton(AF_INET, buf, d4_addr); if (err == 1) { return 0; } @@ -103,13 +71,6 @@ int nrfc_dtls_setup(int sock) /* once connected, cache the connection info */ dtls_cid_active = false; -#if defined(CONFIG_MODEM_INFO) - err = get_modem_info(); - if (err) { - LOG_INF("Modem firmware version not known"); - } -#endif - err = get_device_ip_address(d4_addr); if (!err) { LOG_DBG("Client IP address: %u.%u.%u.%u", diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_info.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_info.c new file mode 100644 index 000000000000..83f962ceb19e --- /dev/null +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_info.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +#if defined(CONFIG_MODEM_JWT) +#include +#endif +#include "nrf_cloud_transport.h" +#include "nrf_cloud_client_id.h" + +#include + +LOG_MODULE_REGISTER(nrf_cloud_info, CONFIG_NRF_CLOUD_LOG_LEVEL); + +#if defined(CONFIG_NRF_MODEM_LIB) +#include +int nrf_cloud_get_imei(char *buf, size_t buf_sz) +{ + int err; + char *eol; + + err = nrf_modem_at_cmd(buf, buf_sz, "AT+CGSN"); + if (err) { + return err; + } + + eol = strstr(buf, "\r\n"); + if (eol) { + *eol = '\0'; + } + return 0; +} + +int nrf_cloud_get_uuid(char *buf, size_t buf_sz) +{ +#if defined(CONFIG_MODEM_JWT) + struct nrf_device_uuid dev_id; + int err; + + if (buf == NULL) { + return -EINVAL; + } + if (buf_sz <= NRF_DEVICE_UUID_STR_LEN) { + return -ENOMEM; + } + + err = modem_jwt_get_uuids(&dev_id, NULL); + if (!err) { + strncpy(buf, dev_id.str, buf_sz); + } + return err; +#else + return -ENOTSUP; +#endif /* CONFIG_MODEM_JWT */ +} + +int nrf_cloud_get_modem_fw(char *buf, size_t buf_sz) +{ + int err; + char *eol; + + err = nrf_modem_at_cmd(buf, buf_sz, "AT+CGMR"); + if (err) { + return err; + } + + eol = strstr(buf, "\r\n"); + if (eol) { + *eol = '\0'; + } + return 0; +} + +#else +int nrf_cloud_get_imei(char *buf, size_t buf_sz) +{ + return -ENOTSUP; +} + +int nrf_cloud_get_uuid(char *buf, size_t buf_sz) +{ + return -ENOTSUP; +} + +int nrf_cloud_get_modem_fw(char *buf, size_t buf_sz) +{ + return -ENOTSUP; +} +#endif /* CONFIG_NRF_MODEM_LIB */ + +int nrf_cloud_print_details(void) +{ + int err; + const char *device_id; + + err = nrf_cloud_client_id_ptr_get(&device_id); + if (!err) { + LOG_INF("Device ID: %s", device_id); + } else { + LOG_ERR("Error requesting the device ID: %d", err); + } + +#if defined(CONFIG_NRF_CLOUD_VERBOSE_DETAILS) + const char *protocol = "Unknown"; + const char *host_name = "Unknown"; + char buf[100]; + + err = nrf_cloud_get_imei(buf, sizeof(buf)); + if (!err) { + LOG_INF("IMEI: %s", buf); + } else { + LOG_ERR("Error requesting the IMEI: %d", err); + } + err = nrf_cloud_get_uuid(buf, sizeof(buf)); + if (!err) { + LOG_INF("UUID: %s", buf); + } else { + LOG_ERR("Error requesting the UUID: %d", err); + } + err = nrf_cloud_get_modem_fw(buf, sizeof(buf)); + if (!err) { + LOG_INF("Modem FW: %s", buf); + } else { + LOG_ERR("Error requesting the modem fw version: %d", err); + } + +#if defined(CONFIG_NRF_CLOUD_MQTT) + protocol = "MQTT"; + host_name = CONFIG_NRF_CLOUD_HOST_NAME; +#elif defined(CONFIG_NRF_CLOUD_COAP) + protocol = "CoAP"; + host_name = CONFIG_NRF_CLOUD_COAP_SERVER_HOSTNAME; +#elif defined(CONFIG_NRF_CLOUD_REST) + protocol = "REST"; + host_name = CONFIG_NRF_CLOUD_REST_HOST_NAME; +#endif + LOG_INF("Protocol: %s", protocol); + LOG_INF("Sec tag: %d", nrf_cloud_sec_tag_get()); + LOG_INF("Host name: %s", host_name); + + /* Tenant will not be known unless device is connected to cloud with MQTT. */ +#if defined(CONFIG_NRF_CLOUD_MQTT) + char stage[NRF_CLOUD_STAGE_ID_MAX_LEN]; + char tenant[NRF_CLOUD_TENANT_ID_MAX_LEN]; + + err = nct_stage_get(stage, sizeof(stage)); + if (!err) { + LOG_INF("Stage: %s", stage); + } else { + LOG_ERR("Error determining nRF Cloud stage: %d", err); + } + err = nct_tenant_id_get(tenant, sizeof(tenant)); + if (!err) { + LOG_INF("Team ID: %s", tenant); + } else { + LOG_ERR("Error determining team ID: %d", err); + } +#endif +#endif /* CONFIG_NRF_CLOUD_VERBOSE_DETAILS */ + + return err; +} From a3f4cfc084931f79d75ec995672ff5e4d4e09a63 Mon Sep 17 00:00:00 2001 From: Pete Skeggs Date: Tue, 27 Aug 2024 10:34:42 -0700 Subject: [PATCH 60/72] net: lib: nrf_cloud_coap: binary log support Send binary (dictionary) logs over CoAP to d2c/bin. Jira: IRIS-9388 Signed-off-by: Pete Skeggs --- include/net/nrf_cloud_coap.h | 3 ++- .../coap/include/nrf_cloud_coap_transport.h | 15 +++++++++++++++ .../net/lib/nrf_cloud/coap/src/nrf_cloud_coap.c | 16 ++++++++++++++++ .../lib/nrf_cloud/src/nrf_cloud_log_backend.c | 16 ++++++---------- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/include/net/nrf_cloud_coap.h b/include/net/nrf_cloud_coap.h index 1714d23406d7..e7f7df0704da 100644 --- a/include/net/nrf_cloud_coap.h +++ b/include/net/nrf_cloud_coap.h @@ -409,7 +409,8 @@ int nrf_cloud_coap_shadow_delta_process(const struct nrf_cloud_data *in_data, struct nrf_cloud_obj *const delta_out); /** - * @brief Send raw bytes to nRF Cloud. + * @brief Send raw bytes to nRF Cloud on the /msg/d2c/raw topic. The data sent can be for any + * purpose. * * @param[in] buf buffer with binary string. * @param[in] buf_len length of buf in bytes. diff --git a/subsys/net/lib/nrf_cloud/coap/include/nrf_cloud_coap_transport.h b/subsys/net/lib/nrf_cloud/coap/include/nrf_cloud_coap_transport.h index fb0a3360e6a8..ec46ae2402ef 100644 --- a/subsys/net/lib/nrf_cloud/coap/include/nrf_cloud_coap_transport.h +++ b/subsys/net/lib/nrf_cloud/coap/include/nrf_cloud_coap_transport.h @@ -246,6 +246,21 @@ int nrf_cloud_coap_patch(const char *resource, const char *query, enum coap_content_format fmt, bool reliable, coap_client_response_cb_t cb, void *user); +/** + * @brief Send binary log data to nRF Cloud on the /msg/d2c/bin topic. The data sent should + * come from the nrf_cloud_log_backend. It will be assembled in sequential order and made + * available for download by the nRF Cloud REST API or website. + * + * @param[in] buf buffer with binary string. + * @param[in] buf_len length of buf in bytes. + * @param[in] confirmable Select whether to use a CON or NON CoAP transfer. + * @return 0 If successful, nonzero if failed. + * Negative values are device-side errors defined in errno.h. + * Positive values are cloud-side errors (CoAP result codes) + * defined in zephyr/net/coap.h. + */ +int nrf_cloud_coap_bin_log_send(const uint8_t * const buf, size_t buf_len, bool confirmable); + /** @} */ #ifdef __cplusplus diff --git a/subsys/net/lib/nrf_cloud/coap/src/nrf_cloud_coap.c b/subsys/net/lib/nrf_cloud/coap/src/nrf_cloud_coap.c index 72dac7f8d623..7697072ead43 100644 --- a/subsys/net/lib/nrf_cloud/coap/src/nrf_cloud_coap.c +++ b/subsys/net/lib/nrf_cloud/coap/src/nrf_cloud_coap.c @@ -246,6 +246,22 @@ int nrf_cloud_coap_bytes_send(uint8_t *buf, size_t buf_len, bool confirmable) return err; } +int nrf_cloud_coap_bin_log_send(const uint8_t * const buf, size_t buf_len, bool confirmable) +{ + int err = 0; + + if (!nrf_cloud_coap_is_connected()) { + return -EACCES; + } + + err = nrf_cloud_coap_post(COAP_D2C_BIN_RSC, NULL, buf, buf_len, + COAP_CONTENT_FORMAT_APP_OCTET_STREAM, confirmable, NULL, NULL); + if (err) { + LOG_ERR("Failed to send POST request: %d", err); + } + return err; +} + int nrf_cloud_coap_obj_send(struct nrf_cloud_obj *const obj, bool confirmable) { if (!nrf_cloud_coap_is_connected()) { diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_log_backend.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_log_backend.c index adf94c62f456..40ae30c85ffd 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_log_backend.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_log_backend.c @@ -136,10 +136,6 @@ BUILD_ASSERT(!((IS_ENABLED(CONFIG_LOG_BACKEND_UART_OUTPUT_TEXT) || && IS_ENABLED(CONFIG_LOG_FMT_SECTION_STRIP)), "CONFIG_LOG_FMT_SECTION_STRIP is not compatible with text logging."); -#if defined(CONFIG_NRF_CLOUD_LOG_DICTIONARY_LOGGING_ENABLED) -BUILD_ASSERT(!IS_ENABLED(CONFIG_NRF_CLOUD_COAP), - "nRF Cloud dictionary logging is only available for MQTT and REST"); -#endif LOG_BACKEND_DEFINE(log_nrf_cloud_backend, logger_api, false); /* Reduce reported log_buf size by 1 so we can null terminate */ @@ -158,11 +154,6 @@ static void logger_init(const struct log_backend *const backend) if ((backend != &log_nrf_cloud_backend) || initialized) { return; } - if ((CONFIG_LOG_BACKEND_NRF_CLOUD_OUTPUT_DEFAULT != LOG_OUTPUT_TEXT) && - IS_ENABLED(CONFIG_NRF_CLOUD_COAP)) { - LOG_ERR("Only text mode logs supported with current cloud transport"); - return; - } initialized = true; nrf_cloud_log_init(); @@ -512,7 +503,11 @@ static int send_ring_buffer(void) } } while (err == -EBUSY); } else if (IS_ENABLED(CONFIG_NRF_CLOUD_COAP)) { - err = nrf_cloud_coap_json_message_send(output_data.ptr, true, true); + if (log_format_current == LOG_OUTPUT_TEXT) { + err = nrf_cloud_coap_json_message_send(output_data.ptr, true, true); + } else { + err = nrf_cloud_coap_bin_log_send(output_data.ptr, output_data.len, true); + } } else { err = -ENODEV; } @@ -529,6 +524,7 @@ static int send_ring_buffer(void) ret = ring_buf_get_finish(&log_nrf_cloud_rb, stored); ring_buf_reset(&log_nrf_cloud_rb); num_msgs = 0; + if (ret) { LOG_ERR("Error finishing ring buffer: %d", ret); err = ret; From 1b3dd83e01c7b6196c69cd757e0cc977870b1657 Mon Sep 17 00:00:00 2001 From: Pete Skeggs Date: Fri, 2 Aug 2024 17:32:18 -0700 Subject: [PATCH 61/72] doc: Update docs for CoAP dictionary log support Add to library doc and changelog. Signed-off-by: Pete Skeggs --- doc/nrf/libraries/networking/nrf_cloud_log.rst | 4 ++-- .../releases/release-notes-changelog.rst | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/nrf/libraries/networking/nrf_cloud_log.rst b/doc/nrf/libraries/networking/nrf_cloud_log.rst index df3dde430494..5a83c0702d96 100644 --- a/doc/nrf/libraries/networking/nrf_cloud_log.rst +++ b/doc/nrf/libraries/networking/nrf_cloud_log.rst @@ -56,7 +56,7 @@ Supported backends ================== When so configured, this library includes a Zephyr logging backend that can transport log messages to nRF Cloud using REST, MQTT, or CoAP. -The logging backend can also use either JSON messages or dictionary-based compact binary messages (binary messages are only supported with MQTT and REST). +The logging backend can also use either JSON messages or dictionary-based compact binary messages. Multiple JSON log messages are sent together as a JSON array to the `d2c/bulk device message topic `_. The nRF Cloud backend splits the array into individual JSON messages for display. @@ -100,7 +100,7 @@ Configure one of the following Kconfig options to select the data transport meth Configure the message encoding: -* :kconfig:option:`CONFIG_LOG_BACKEND_NRF_CLOUD_OUTPUT_TEXT` or :kconfig:option:`CONFIG_LOG_BACKEND_NRF_CLOUD_OUTPUT_DICTIONARY` (MQTT or REST only) +* :kconfig:option:`CONFIG_LOG_BACKEND_NRF_CLOUD_OUTPUT_TEXT` or :kconfig:option:`CONFIG_LOG_BACKEND_NRF_CLOUD_OUTPUT_DICTIONARY` See `Dictionary-based Logging`_ to learn how dictionary-based logging works, how the dictionary is built, and how to decode the binary log output. Dictionary logs are compact binary log messages that require decoding using an offline script. diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index 78552be7847d..03e92d2661d1 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -733,6 +733,7 @@ Libraries for networking * :ref:`lib_nrf_cloud_log` library: * Added support for dictionary logs using REST. + * Added support for dictionary (binary) logs when connected to nRF Cloud using CoAP. * :ref:`lib_nrf_cloud_fota` library: From e56f75e6ab555b5fdc705fc6611e9101de55d104 Mon Sep 17 00:00:00 2001 From: Arkadiusz Balys Date: Wed, 28 Aug 2024 12:40:39 +0200 Subject: [PATCH 62/72] samples: matter: add error logs to key migration process. It is expected to see some error logs if the operational keys migration fails. Signed-off-by: Arkadiusz Balys --- samples/matter/common/src/migration/migration_manager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/samples/matter/common/src/migration/migration_manager.cpp b/samples/matter/common/src/migration/migration_manager.cpp index 4ce9b9bede8a..89e5eafd44b8 100644 --- a/samples/matter/common/src/migration/migration_manager.cpp +++ b/samples/matter/common/src/migration/migration_manager.cpp @@ -11,6 +11,9 @@ #include #include +#include +LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); + namespace Nrf::Matter { namespace Migration @@ -32,12 +35,14 @@ namespace Migration for (const chip::FabricInfo &fabric : chip::Server::GetInstance().GetFabricTable()) { err = keystore->MigrateOpKeypairForFabric(fabric.GetFabricIndex(), obsoleteKeystore); if (CHIP_NO_ERROR != err) { + LOG_ERR("Cannot migrate %d fabric to PSA crypto storage", fabric.GetFabricIndex()); break; } } #ifdef CONFIG_NCS_SAMPLE_MATTER_FACTORY_RESET_ON_KEY_MIGRATION_FAILURE if (CHIP_NO_ERROR != err) { + LOG_ERR("Keystore migration failure due to %s. Performing Factory reset...", err.AsString()); GroupDataProviderImpl::Instance().WillBeFactoryReset(); chip::Server::GetInstance().ScheduleFactoryReset(); /* Return a success to not block the Matter event Loop and allow to call scheduled factory From 2e9c82cc67f61bebcd5feaff24e4a807da028389 Mon Sep 17 00:00:00 2001 From: Nordic Builder Date: Tue, 27 Aug 2024 14:34:40 +0000 Subject: [PATCH 63/72] manifest: Update sdk-nrfxlib revision (auto-manifest PR) Automatically created by Github Action Signed-off-by: Nordic Builder --- west.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/west.yml b/west.yml index 860f9f859c67..8cfe0b596553 100644 --- a/west.yml +++ b/west.yml @@ -157,7 +157,7 @@ manifest: - name: nrfxlib repo-path: sdk-nrfxlib path: nrfxlib - revision: 56e62181e1d65bf7c21acf128aa15c290bfcc380 + revision: 9e4d3e4639956c332b95d66093bc641f1addd9c3 - name: trusted-firmware-m repo-path: sdk-trusted-firmware-m path: modules/tee/tf-m/trusted-firmware-m @@ -203,7 +203,7 @@ manifest: # Only for internal Nordic development repo-path: dragoon.git remote: dragoon - revision: fc68c233ae346436ae57c07a590cb40838ce53d0 + revision: 65b46548d2d4c8cf61cdc2303129da2f1ca1f9ee submodules: true groups: - dragoon From 45833767add48dd5694a2f7af7ebb30aad6468a0 Mon Sep 17 00:00:00 2001 From: Damian Krolik Date: Wed, 28 Aug 2024 15:38:03 +0200 Subject: [PATCH 64/72] samples: protocols_serialization: server: fatal error trigger Add a feature to trigger a fatal error by pressing Button 1 to test exposing the crash log to an RPC client. Also, fix a bug in the crash log functionality introduced by adding the stream log level configurability. Signed-off-by: Damian Krolik --- .../server/CMakeLists.txt | 6 ++++- .../protocols_serialization/server/Kconfig | 9 +++++++ .../protocols_serialization/server/README.rst | 12 ++++++++-- .../server/snippets/log_rpc/log_rpc.conf | 3 +++ .../server/src/fatal_error_trigger.c | 24 +++++++++++++++++++ subsys/logging/log_backend_rpc.c | 1 + 6 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 samples/nrf_rpc/protocols_serialization/server/src/fatal_error_trigger.c diff --git a/samples/nrf_rpc/protocols_serialization/server/CMakeLists.txt b/samples/nrf_rpc/protocols_serialization/server/CMakeLists.txt index fe151c53413a..48d5223050c8 100644 --- a/samples/nrf_rpc/protocols_serialization/server/CMakeLists.txt +++ b/samples/nrf_rpc/protocols_serialization/server/CMakeLists.txt @@ -11,9 +11,13 @@ project(protocols_serialization_server) # NORDIC SDK APP START target_sources(app PRIVATE src/main.c) + +if(CONFIG_NRF_PS_SERVER_FATAL_ERROR_TRIGGER) + target_sources(app PRIVATE src/fatal_error_trigger.c) +endif() # NORDIC SDK APP END # Link OpenThread CLI even though OPENTHREAD_SHELL is not selected if(CONFIG_OPENTHREAD_RPC) -zephyr_link_libraries(openthread-cli-ftd) + zephyr_link_libraries(openthread-cli-ftd) endif() diff --git a/samples/nrf_rpc/protocols_serialization/server/Kconfig b/samples/nrf_rpc/protocols_serialization/server/Kconfig index 5486ad55fa2e..7bb8255e8974 100644 --- a/samples/nrf_rpc/protocols_serialization/server/Kconfig +++ b/samples/nrf_rpc/protocols_serialization/server/Kconfig @@ -22,6 +22,15 @@ config LOG_BACKEND_RTT config LOG_BACKEND_UART default n +config NRF_PS_SERVER_FATAL_ERROR_TRIGGER + bool "Fatal error trigger" + select DK_LIBRARY + help + Enables triggering a fatal error by pressing Button 1 on the development + kit. This trigger allows for testing the feature of logging over RPC that + provides an RPC client with access to the crash log stored in the retained + RAM partition. + module = NRF_PS_SERVER module-str = nrf_ps_server source "${ZEPHYR_BASE}/subsys/logging/Kconfig.template.log_config" diff --git a/samples/nrf_rpc/protocols_serialization/server/README.rst b/samples/nrf_rpc/protocols_serialization/server/README.rst index be3016ef5f6f..17f55dc9c7f4 100644 --- a/samples/nrf_rpc/protocols_serialization/server/README.rst +++ b/samples/nrf_rpc/protocols_serialization/server/README.rst @@ -45,6 +45,14 @@ The following snippets are available: * ``log_rpc`` - Enables logging over RPC. * ``openthread`` - Enables the server part of the OpenThread RPC. +User interface +************** + +Button 1: + * When the ``log_rpc`` snippet is enabled: triggers a fatal error. + This is used for testing the crash log feature. + * Otherwise: not available. + Building and running ******************** @@ -73,7 +81,7 @@ In the protocols serialization samples, one peripheral is used for shell and log .. group-tab:: nRF52840 DK - By default, the nRF52840 DK uses the ``uart0`` peripheral for shell and logging purposes, and the ``uart1`` peripheral for sending OpenThread and Bluetooth remove procedure calls (RPCs). + By default, the nRF52840 DK uses the ``uart0`` peripheral for shell and logging purposes, and the ``uart1`` peripheral for sending OpenThread and Bluetooth remote procedure calls (RPCs). The ``uart1`` peripheral is configured to use the following pins: @@ -107,7 +115,7 @@ In the protocols serialization samples, one peripheral is used for shell and log .. group-tab:: nRF54l15 DK - By default, the nRF54L15 DK uses the ``uart20`` peripheral for shell and logging purposes, and the ``uart21`` peripheral for sending OpenThread and Bluetooth remove procedure calls (RPCs). + By default, the nRF54L15 DK uses the ``uart20`` peripheral for shell and logging purposes, and the ``uart21`` peripheral for sending OpenThread and Bluetooth remote procedure calls (RPCs). The ``uart21`` peripheral is configured to use the following pins: diff --git a/samples/nrf_rpc/protocols_serialization/server/snippets/log_rpc/log_rpc.conf b/samples/nrf_rpc/protocols_serialization/server/snippets/log_rpc/log_rpc.conf index 9acc209a1ad4..de18731088ce 100644 --- a/samples/nrf_rpc/protocols_serialization/server/snippets/log_rpc/log_rpc.conf +++ b/samples/nrf_rpc/protocols_serialization/server/snippets/log_rpc/log_rpc.conf @@ -14,3 +14,6 @@ CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=1024 # Enable OpenThread logs along with logging over RPC CONFIG_OPENTHREAD_DEBUG=y CONFIG_OPENTHREAD_LOG_LEVEL_INFO=y + +# Enable fatal error trigger for testing the crash log feature +CONFIG_NRF_PS_SERVER_FATAL_ERROR_TRIGGER=y diff --git a/samples/nrf_rpc/protocols_serialization/server/src/fatal_error_trigger.c b/samples/nrf_rpc/protocols_serialization/server/src/fatal_error_trigger.c new file mode 100644 index 000000000000..2a3241d48980 --- /dev/null +++ b/samples/nrf_rpc/protocols_serialization/server/src/fatal_error_trigger.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include + +#include +#include + +static void button_handler(uint32_t button_state, uint32_t has_changed) +{ + if (button_state & DK_BTN1_MSK) { + k_oops(); + } +} + +static int button_handler_init(void) +{ + return dk_buttons_init(button_handler); +} + +SYS_INIT(button_handler_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/subsys/logging/log_backend_rpc.c b/subsys/logging/log_backend_rpc.c index b819ef694f49..96efade20a83 100644 --- a/subsys/logging/log_backend_rpc.c +++ b/subsys/logging/log_backend_rpc.c @@ -266,6 +266,7 @@ static void process(const struct log_backend *const backend, union log_msg_gener */ if (panic_mode) { flags |= LOG_OUTPUT_FLAG_CRLF_LFONLY; + max_level = LOG_RPC_LEVEL_DBG; } else if (NRF_RPC_GROUP_STATUS(log_rpc_group)) { flags |= LOG_OUTPUT_FLAG_CRLF_NONE; } else { From dc0efd4a9d642cd1a8659c910b83d7b2106f0f5c Mon Sep 17 00:00:00 2001 From: Dominik Chat Date: Mon, 26 Aug 2024 10:41:34 +0200 Subject: [PATCH 65/72] nfc: platform: Fix NULL pointer check and potential dereference Fix potential NULL pointer dereferencing in ring_buf_get_data function. Jira: NCSDK-27132 Signed-off-by: Dominik Chat --- .../releases/release-notes-changelog.rst | 1 + subsys/nfc/lib/platform_internal_thread.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index 03e92d2661d1..ae4d9f3e9fde 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -747,6 +747,7 @@ Libraries for NFC ----------------- * Added an experimental serialization of NFC tag 2 and tag 4 APIs. +* Fixed a potential issue with handling data pointers in the function ``ring_buf_get_data`` in the :file:`platform_internal_thread` file. nRF RPC libraries ----------------- diff --git a/subsys/nfc/lib/platform_internal_thread.c b/subsys/nfc/lib/platform_internal_thread.c index d07d3a269ee5..6e9eee8d4e94 100644 --- a/subsys/nfc/lib/platform_internal_thread.c +++ b/subsys/nfc/lib/platform_internal_thread.c @@ -64,6 +64,10 @@ static int ring_buf_get_data(struct ring_buf *buf, uint8_t **data, uint32_t size uint32_t tmp; int err; + if (!buf || !data || !is_alloc) { + return -EINVAL; + } + *is_alloc = false; /* Try to access data without copying. @@ -79,7 +83,7 @@ static int ring_buf_get_data(struct ring_buf *buf, uint8_t **data, uint32_t size } *data = k_malloc(size); - if (data == NULL) { + if (*data == NULL) { LOG_DBG("Could not allocate %d bytes.", size); return -ENOMEM; } From 32b91a8fe62d6c2c86d076344c03cbb79f5e91b2 Mon Sep 17 00:00:00 2001 From: Francesco Domenico Servidio Date: Mon, 26 Aug 2024 15:18:03 +0200 Subject: [PATCH 66/72] doc: Documentation edits for 2.7.99-cs1 release Added firmware bundle compatibility table. Updated nRF54H20 GS guide. Added initial power management documentation. Added initial clock control documentation. Migration notes for |NCS| v2.7.99-cs1 and the nRF54H20 DK. Signed-off-by: Francesco Domenico Servidio --- doc/nrf/app_dev/device_guides/nrf54h.rst | 13 + .../nrf54h/ug_nrf54h20_architecture.rst | 2 + .../ug_nrf54h20_architecture_clockman.rst | 114 ++++++++ .../nrf54h/ug_nrf54h20_architecture_pm.rst | 247 ++++++++++++++++++ .../nrf54h/ug_nrf54h20_gs.rst | 74 ++---- doc/nrf/links.txt | 5 + .../migration_guide_nRF54H20_cs_to_2_7.rst | 2 +- ...ration_guide_nRF54H20_cs_to_2_7_99-cs1.rst | 61 +++++ doc/nrf/samples/other.rst | 1 + tests/benchmarks/multicore/idle/README.rst | 10 +- 10 files changed, 473 insertions(+), 56 deletions(-) create mode 100644 doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture_clockman.rst create mode 100644 doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture_pm.rst create mode 100644 doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7_99-cs1.rst diff --git a/doc/nrf/app_dev/device_guides/nrf54h.rst b/doc/nrf/app_dev/device_guides/nrf54h.rst index 23c78aa84dcd..d4c00818ed9f 100644 --- a/doc/nrf/app_dev/device_guides/nrf54h.rst +++ b/doc/nrf/app_dev/device_guides/nrf54h.rst @@ -21,6 +21,19 @@ Zephyr and the |NCS| provide support and contain board definitions for developin | ``nrf54h20dk_nrf54h20_cpurad`` | ``nrf54h20dk_nrf54h20_cpuppr`` +The following table indicates the compatibility between nRF54H20 firmware bundle versions and |NCS| versions: + +.. list-table:: + :header-rows: 1 + + * - |NCS| version + - nRF54H20 firmware bundle version + * - v2.7 + - v0.5.0 + * - v2.7.99-cs1 + - v0.6.2 + + .. toctree:: :maxdepth: 2 :caption: Subpages: diff --git a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture.rst b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture.rst index c6f9eb2b191c..c1579082e492 100644 --- a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture.rst +++ b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture.rst @@ -21,3 +21,5 @@ The following pages briefly describe topics like the responsibilities of the cor ug_nrf54h20_architecture_ipc ug_nrf54h20_architecture_boot ug_nrf54h20_architecture_lifecycle + ug_nrf54h20_architecture_pm + ug_nrf54h20_architecture_clockman diff --git a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture_clockman.rst b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture_clockman.rst new file mode 100644 index 000000000000..4509e7fe059c --- /dev/null +++ b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture_clockman.rst @@ -0,0 +1,114 @@ +.. _ug_nrf54h20_architecture_clockman: + +nRF54H20 clock management +######################### + +.. contents:: + :local: + :depth: 2 + +The nRF54H20 SoC consists of multiple asynchronous clock domains and requires clock sources for correct operation. +Each of the clock sources needs proper management for the following reasons: + +* To start and stop the clock at the appropriate time. +* To select the proper clock source. +* To calibrate or synchronize the clock to a more accurate source. + +Some clock management operations are performed solely by hardware circuits, while others require software intervention. +Most clocks can be locked to more accurate ones to improve their accuracy. + + +Clock domains +************* + +The nRF54H20 SoC consists of the following clock domains: + +* Low frequency clock (LFCLK) +* High-frequency oscillator (HFXO) +* FLL16M +* Application Core HSFLL +* Radio Core HSFLL +* Secure Domain HSFLL +* Global HSFLL + +Each clock domain is enabled independently of others, and it is automatically enabled when at least one sink is active. +The firmware can choose to keep each clock domains enabled even when all its sinks are inactive. + +Clock domain sources are selected by ``clock_control`` drivers based on the clock parameter requirements reported by the software modules using the ``clock_control`` functions. +These requirements can include clock frequency, accuracy, or precision. +Some clock domains are configured by ``clock_control`` drivers using ``LRCCONF`` peripherals, while others are configured with the assistance of the System Controller Firmware. + +The application-facing APIs expose only the domain that directly clocks the component used by the application. +The management of the clocks on which this domain depends is handled internally by the associated clock driver. + +For example, a firmware module might request better timing accuracy for a fast UART instance. +In this case, the firmware module requests the accuracy from the global HSFLL device driver, which directly clocks the UART. +The dependencies, such as FLL16M and LFXO, are managed internally by the global HSFLL driver, not directly by the firmware module. + +LFCLK +===== + +The Low-Frequency Clock domain is responsible for generating a 32768 Hz clock signal for ultra-low-power peripherals like ``GRTC`` or ``RTC``. + +HFXO +==== + +The high-frequency crystal oscillator domain is responsible for clocking peripherals requiring high accuracy and MHz range frequency. +The drawback of this clock source is relatively high power consumption so it is enabled only when needed. + +Hardware capabilities +--------------------- + +The HFXO, like any other clock domain, can be connected in hardware to one of the available sources. +Additionally, it provides the clock signal to all of its sinks. + +FLL16M +====== + +The FLL16M clock domain clocks most of the peripherals in the system (*slow*, 16 MHz). +Its accuracy results in the timing accuracy of slow ``UART``, ``SPI``, ``TWI``, ``PWM``, ``SAADC``, among others. + +Local HSFLLs +============ + +Local HSFLLs are clocking CPUs in local domains, fast peripherals around them, and local RAM. + +Global HSFLL +============ + +Global HSFLL clocks *fast* peripherals, FLPR, RAM, and MRAM blocks. + +Zephyr clock control API +************************ + +Zephyr RTOS contains a ``clock_control`` device driver class for managing clocks. +The ``clock_control`` API is designed to support multiple requestors. +Moreover, the ``clock_control`` API supports blocking or asynchronous operations based on notifications when the requested clock settings are applied. + +The ``clock_control`` subsystem exposes portable parameters in its functions, which include: + +* Accuracy requests in ppm values for all the clock domains. +* Precision requests in enumerated high- and low-precision modes. +* Frequency requests (clock rate) for the Application core HSFLL (all the other clock domains have fixed frequencies). + +When multiple modules request conflicting parameters from the same clock, the system prioritizes selecting the mode with minimal power consumption that satisfies all requests. +For example, if a UART driver requests 100 ppm accuracy and a SPI driver requests 200 ppm accuracy, the system will choose a mode with 100 ppm accuracy or better, as it meets both requirements (100 ppm accuracy is better than 200 ppm) while optimizing power usage. +This policy applies to all clock parameters, including frequency and precision, following these criteria: + +* The applied precision is at least as good as requested. +* The applied frequency is at least as fast as requested. +* All parameters are optimized for power consumption. + +For more details, see the following links: + +* :ref:`zephyr:clock_control_api`. +* The following calls in the `Zephyr's nRF clock control API extensions`_ (:file:`include/zephyr/drivers/clock_control/nrf_clock_control.h`): + + * ``nrf_clock_control_request()``: Requests a reservation to use a given clock with specified attributes. + * ``nrf_clock_control_release()``: Releases a reserved use of a clock. + * ``nrf_clock_control_cancel_or_release()``: Safely cancels a reservation request. + +* The following calls in the `clocks devicetree macro API`_ (:file:`include/zephyr/devicetree/clocks.h`): + + * ``DT_CLOCKS_CTLR_BY_IDX()``: Gets the node identifier for the controller phandle from a *clocks* phandle-array property at an index. + * ``DT_CLOCKS_CTLR()``: It is equivalent to ``DT_CLOCKS_CTLR_BY_IDX()`` with index (idx) set to 0. diff --git a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture_pm.rst b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture_pm.rst new file mode 100644 index 000000000000..d1dc886440c3 --- /dev/null +++ b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture_pm.rst @@ -0,0 +1,247 @@ +.. _ug_nrf54h20_architecture_pm: + +nRF54H20 Power Management +######################### + +.. contents:: + :local: + :depth: 2 + +The nRF54H20 SoC is a distributed system where each domain tries to achieve minimal power consumption for itself. +When all CPUs are ready to fully minimize power consumption by entering the System Off hardware state, the System Controller prepares the system and triggers the entrance in this state. + +Power states +************ + +The nRF54H20 ARM Cortex CPUs currently support the following software power states: + +* Active +* Idle +* Local suspend to Ram + +Overview +******** + +Each CPU in the nRF54H20 SoC tries to preserve as much power as possible, independently from other CPUs. +The power management subsystem, operating independently within each CPU, continuously selects the most optimal power state based on the current conditions of the CPU. + +Power states details +******************** + +The following sections describes the details of each of the software power states available on the nRF54H20 SoC. + +Active +====== + +*Active* is the power state in which the CPU is actively processing. + +.. list-table:: + :widths: auto + + * - CPU + - Powered on and clocked. + + * - RAM + - Banks used by the executed code are enabled. + Other banks may be in any state. + + * - System state + - *System ON* + + * - Peripherals + - All can be active. + The state of all inactive peripherals is retained in the hardware flip-flops. + + * - Coprocessors + - All can be active. + The state of inactive coprocessors is retained according to their selected sleep state. + + * - System timer (based on GRTC) + - Active + +This is the power state with the highest power consumption. +The software execution latency is minimal. +The primary source of latency is the wake-up of the ``MRAMC``. +The maximum latency depends on the MRAM power state configured by the System Controller. + +Idle +==== + +*Idle* is the lightest sleep power state available in the system where the cache content is retained. + +.. list-table:: + :widths: auto + + * - CPU + - Powered on but suspended (not clocked). + + * - RAM + - Banks used by the executed code are enabled. + Other banks may be in any state. + + * - System state + - *System ON* + + * - Peripherals + - All can be active. + The local peripherals are powered and preserve their state. + The state of inactive peripherals in other domains is retained in the hardware flip-flops. + + * - Coprocessors + - All can be active. + The state of inactive coprocessors is retained according to their selected sleep state. + + * - System timer (based on GRTC) + - Active + +The power consumption in this state is lower than in *Active*, but higher than in other power states. +The wake-up latency is higher than in *Active*, but lower than in the other power states. +The primary sources of wake-up latency are the wake-up of the ``MRAMC`` and the startup of clock sources. +The maximum latency depends on the MRAM power state configured by the System Controller. + +Local Suspend to RAM +******************** + +*Local Suspend to RAM* is a sleep state that balances between power consumption and wake-up latency. + +This state is available only for DVFS-capable domains. +Other domains, such as Radio, cannot retain the CPU and local peripherals in the *System ON (All) Idle* state. + +In this state, the entire local Active Power Domain, including the CPU, is unpowered. +The state of the CPU and the peripherals powered by the local Active Power Domain is not retained by hardware flip-flops. +Instead, their state is retained by software in RAM. + +.. list-table:: + :widths: auto + + * - CPU + - Unpowered. + Its state is retained in RAM. + + * - RAM + - Enabled or retained depending on the hardware state. + + * - System state + - * *System ON* if at least one other CPU or a peripheral clocked greater than 32 kHz is active. + * *System ON Idle* if all CPUs are disabled and the only active peripherals are clocked with 32 kHz (real-time part of ``GRTC``, ``RTC``, ``WDT``) or System Off wake-up sources. + * *System ON All Idle* if all other CPUs and all peripherals except System Off wake-up sources are disabled. + + The hardware automatically selects one of these states based on the activity of other CPUs and peripherals. + + * - Peripherals + - * Powered by the local Active Power Domain must be disabled. + * Powered by any other power domain can be active. + + The state of the inactive peripherals located in other power domains is retained in the hardware flip-flops. + + It is recommended to use only 32 kHz clocked peripherals in this state to allow entering *System ON Idle*. + One example could be using GPIO as CSN to wake up the system and enable an SPIS peripheral only after the system is woken up. + + * - Coprocessors + - Global can be active. + There are no local coprocessors in the domains supporting this sleep state. + The state of inactive coprocessors is retained according to their selected sleep state. + + * - System timer (based on GRTC) + - Active + +The power consumption in this state depends on the overall System state but is lower than in any of the *Idle* states. +The wake-up latency is higher than in any of the *Idle* states due to the CPU state restoration procedure. + +Selecting the optimal power state +********************************* + +In the nRF54H20 SoC, each local domain is responsible for selecting the power state that results in minimal power consumption while maintaining an acceptable level of performance. + +Entering a deeper sleep state leads to power savings when the system is idle, but it requires increased power consumption to enter and exit the sleep state. +There is a minimum sleep duration that justifies the energy spent on entering and exiting a sleep state, and this duration varies for each sleep state. + +In the SoC, a local domain has full control over entering and exiting local sleep states, allowing it to assess whether entering these sleep states is optimal at any given moment. +However, entering sleep states associated with system-off requires cooperation between local domains and the System Controller. +Local domains have limited control over the time and energy required to enter or exit system-off, as well as the power consumption during system-off. + +Latency management +****************** + +The sources of wake-up latency in the nRF54H20 SoC can be categorized into two types: local and global. +Each CPU is responsible for managing its latency sources, with local sources handled by local domains and global sources managed by the System Controller. + +Local cores are responsible for handling latencies caused by restoring the system from suspend-to-RAM states. +Local cores schedule their wake-up in advance of expected events. +The timing of expected events is reported to the power management subsystem in the RTOS by the software modules anticipating these events. +The power management subsystem sets a ``GRTC`` channel in advance of the next expected event to compensate for local wake-up latency. + +The System Controller is responsible for handling latencies caused by restoring the system from the system-off state (the warm boot procedure latency). +The System Controller schedules the system wake-up from the system-off state in advance of the next ``GRTC`` event to compensate for the warm-boot latency of the system. + +Because the warm-boot latency is compensated by the System Controller, from a local CPU's perspective, the latency when restoring from the local-off state and the system-off state is expected to be the same. + +Latency in local domains +======================== + +Any local software module (like a device driver) can anticipate events like ISRs. +Some of these events have predictable timing, while others have unpredictable timing. +Handling the latency of events with unpredictable timing is the same in both simple and complex systems. + +If handling an event with predictable timing requires restoring the state of the software module or the peripherals used by this module before the event is processed, the software module is responsible for scheduling a timer event in advance. +This scheduled event is used to restore the state of the software module or peripherals. + +The Power Management subsystem in a local domain is responsible for scheduling a wake-up in advance to compensate for the domain's core state restoration latency from the local power state. +The wake-up time scheduled in advance by the power management subsystem is combined with the advance time added by the software module. +This approach ensures that the local domain and the software modules anticipating an event have sufficient time to fully restore before the event occurs, allowing the event to be handled without latency. + +Unretained hardware classification +********************************** + +Some power states in the nRF54H20 SoC result in powering off certain peripherals. +The state of these peripherals is not retained by hardware and must be restored by software before the peripheral is activated. + +See the following sections for the lists of peripheral groups and the related software modules responsible for restoring the peripheral's state for each group. + +Peripherals in local domains +============================ + +All local domains include a common set of hardware modules. +In addition to these, most local domains also contain domain-specific peripherals. + +Common peripherals for all local domains +---------------------------------------- + +Each local domain contains a set of peripherals that are classified consistently across all local domains. +The following table summarizes the active peripherals that need handling when exiting the *Local Suspend to RAM* state. + ++---------------+--------------------+--------------------+--------------------+--------------------------+ +|Type | List of the | Source of data to | Time of restoration| Software module | +| | peripherals | restore | | responsible for restoring| ++===============+====================+====================+====================+==========================+ +|Active | * ``MVDMA`` | Device driver's | Decided by the | The device driver | +|peripherals | | code and data | driver | | ++---------------+--------------------+--------------------+--------------------+--------------------------+ + +Peripherals specific to the Application Domain +---------------------------------------------- + +There are no peripherals specific to the Application Domain. + +Peripherals specific to the Secure Domain +----------------------------------------- + +The Secure Domain contains additional peripherals that require handling in the *Local Suspend to RAM* state. + ++---------------+--------------------+--------------------+--------------------+--------------------------+ +|Type | List of the | Source of data to | Time of restoration| Software module | +| | peripherals | restore | | responsible for restoring| ++===============+====================+====================+====================+==========================+ +|Active | * ``CRACEN`` | Device driver's | Decided by the | The device driver | +|peripherals | | code and data | driver | | ++---------------+--------------------+--------------------+--------------------+--------------------------+ + +Peripherals specific to the Radio Domain +---------------------------------------- + +The Radio Domain does not implement the *Local Suspend to RAM* state. + +Power management benchmark +************************** + +To benchmark the power consumption in *Idle* state, see :ref:`multicore_idle_test`. diff --git a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_gs.rst b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_gs.rst index cad878626bae..9bc622f0a023 100644 --- a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_gs.rst +++ b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_gs.rst @@ -20,9 +20,9 @@ Make sure you have all the required hardware and that your computer has one of t Hardware ======== -* nRF54H20 DK version PCA10175 v0.7.2 (ES3) or PCA10175 v0.8.0 (ES3.3, ES4). - These are the only versions of the nRF54H20 DK compatible with the |NCS| v2.7.0. - Check the version number on your DK's sticker to verify its compatibility with the |NCS| version v2.7.0. +* nRF54H20 DK, version PCA10175 v0.8.0 (ES4) or later revisions. + This is the only version of the nRF54H20 DK compatible with the |NCS| v2.7.99-cs1. + Check the version number on your DK's sticker to verify its compatibility with the |NCS| version v2.7.99-cs1. * USB-C cable. Software @@ -81,10 +81,10 @@ To work with the nRF54H20 DK, follow the instructions in the next sections to in .. _ug_nrf54h20_install_toolchain: -Installing the |NCS| v2.7.0 and its toolchain -********************************************* +Installing the |NCS| v2.7.99-cs1 and its toolchain +************************************************** -You can install the |NCS| v2.7.0 and its toolchain by using Toolchain Manager. +You can install the |NCS| v2.7.99-cs1 and its toolchain by using Toolchain Manager. Toolchain Manager is a tool available from `nRF Connect for Desktop`_, a cross-platform tool that provides different applications that simplify installing the |NCS|. Both the tool and the application are available for Windows, Linux, and MacOS. @@ -109,9 +109,9 @@ To install the toolchain and the SDK using the Toolchain Manager app, complete t The Toolchain Manager window #. Click :guilabel:`SETTINGS` in the navigation bar to specify where you want to install the |NCS|. - #. In :guilabel:`SDK ENVIRONMENTS`, click the :guilabel:`Install` button next to the |NCS| version 2.7.0. + #. In :guilabel:`SDK ENVIRONMENTS`, click the :guilabel:`Install` button next to the |NCS| version 2.7.99-cs1. - The |NCS| version 2.7.0 is installed on your machine. + The |NCS| version 2.7.99-cs1 is installed on your machine. The :guilabel:`Install` button changes to :guilabel:`Open VS Code`. #. Set up the preferred building method: @@ -157,10 +157,10 @@ Both of these terminal emulators start the required :ref:`toolchain environment Installing nRF Util and its commands ************************************ -Using the nRF54H20 DK with the |NCS| v2.7.0 requires the following: +Using the nRF54H20 DK with the |NCS| v2.7.99-cs1 requires the following: * nRF Util version 7.11.1 or above -* nRF Util ``device`` version 2.4.0 +* nRF Util ``device`` version 2.4.6 1. Download the nrfutil executable file from the `nRF Util development tool`_ product page. #. Add nRF Util to the system path on Linux and MacOS, or environment variables on Windows, to run it from anywhere on the system. @@ -180,9 +180,9 @@ Using the nRF54H20 DK with the |NCS| v2.7.0 requires the following: nrfutil self-upgrade -#. Install the nRF Util ``device`` command to version 2.4.0 as follows:: +#. Install the nRF Util ``device`` command version 2.4.6 as follows:: - nrfutil install device=2.4.0 --force + nrfutil install device=2.4.6 --force For more information, consult the `nRF Util`_ documentation. @@ -199,9 +199,9 @@ Programming the BICR ==================== The Board Information Configuration Registers (BICR) are non-volatile memory (NVM) registers that contain information on how the nRF54H20 SoC must interact with other board elements, including the information about the power and clock delivery to the SoC. -To prepare the nRF54H20 DK for first use, you must manually program the values of the BICR using a precompiled BICR binary file (:file:`bicr_ext_loadcap.hex`). +To prepare the nRF54H20 DK for first use, you must manually program the values of the BICR using a precompiled BICR binary file (:file:`bicr.hex`). -1. Download the `BICR binary file`_ . +1. Download the `BICR new binary file`_. #. Connect the nRF54H20 DK to your computer using the **DEBUGGER** port on the DK. .. note:: @@ -214,17 +214,17 @@ To prepare the nRF54H20 DK for first use, you must manually program the values o #. Move the BICR HEX file to a folder of your choice, then program the BICR by running nRF Util from that folder using the following command:: - nrfutil device program --options chip_erase_mode=ERASE_NONE --firmware bicr_ext_loadcap.hex --core Secure --serial-number + nrfutil device program --options chip_erase_mode=ERASE_NONE --firmware build/zephyr/bicr.hex --core Application --serial-number .. rst-class:: numbered-step Programming the SDFW and SCFW ============================= -After programming the BICR, the nRF54H20 SoC requires the provisioning of a bundle ( :file:`nrf54h20_soc_binaries_v0.5.0.zip`) containing the precompiled firmware for the Secure Domain and System Controller. +After programming the BICR, the nRF54H20 SoC requires the provisioning of a bundle ( :file:`nrf54h20_soc_binaries_v0.6.2.zip`) containing the precompiled firmware for the Secure Domain and System Controller. To program the Secure Domain Firmware (SDFW, also known as ``urot``) and the System Controller Firmware (SCFW) from the firmware bundle to the nRF54H20 DK, do the following: -1. Download the `nRF54H20 firmware bundle v0.5.0`_. +1. Download the `nRF54H20 firmware bundle v0.6.2`_. .. note:: On MacOS, ensure that the ZIP file is not unpacked automatically upon download. @@ -235,32 +235,6 @@ To program the Secure Domain Firmware (SDFW, also known as ``urot``) and the Sys .. rst-class:: numbered-step -Updating the FICR -================= - -.. caution:: - This step is required only if your nRF54H20 DK is version PCA10175 v0.7.2 or v0.8.0 ES3.3. - Jump to the next step if your DK is version ES4, meaning v0.8.0 with no ES markings. - -After programming the SDFW and SCFW from the firmware bundle, you must update the Factory Information Configuration Registers (FICR) to correctly configure some trims of the nRF54H20 SoC. -To update the FICR, you must run a J-Link script: - -1. Get the Jlink script that updates the FICR:: - - curl -LO https://files.nordicsemi.com/artifactory/swtools/external/scripts/nrf54h20es_trim_adjust.jlink - -#. Run the script: - - * Linux and Mac OS:: - - JLinkExe -CommanderScript nrf54h20es_trim_adjust.jlink - - * Windows:: - - jlink.exe -CommanderScript nrf54h20es_trim_adjust.jlink - -.. rst-class:: numbered-step - Transitioning the nRF54H20 SoC to RoT ===================================== @@ -332,8 +306,8 @@ To transition the LCS to ``RoT``, do the following: .. _ug_nrf54h20_gs_sample: -Programming the sample -********************** +Building and programming the sample +*********************************** The :zephyr:code-sample:`sysbuild_hello_world` sample is a multicore sample running on both the application core (``cpuapp``) and the Peripheral Processor (PPR, ``cpuppr``). It uses the ``nrf54h20dk/nrf54h20/cpuapp`` board target. @@ -341,18 +315,18 @@ It uses the ``nrf54h20dk/nrf54h20/cpuapp`` board target. To build and program the sample to the nRF54H20 DK, complete the following steps: 1. Connect the nRF54H20 DK to your computer using the **DEBUGGER** port on the DK. -#. Open nRF Connect for Desktop, navigate to the Toolchain Manager, select the v2.7.0 toolchain, and click the :guilabel:`Open terminal` button. +#. Open nRF Connect for Desktop, navigate to the Toolchain Manager, select the v2.7.99-cs1 toolchain, and click the :guilabel:`Open terminal` button. #. In the terminal window, navigate to the :file:`zephyr/samples/sysbuild/hello_world` folder containing the sample. #. Build the sample for application and radio cores by running the following command:: west build -p -b nrf54h20dk/nrf54h20/cpuapp -T sample.sysbuild.hello_world.nrf54h20dk_cpuapp_cpurad . -#. Program the sample. - If you have multiple Nordic Semiconductor devices, make sure that only the nRF54H20 DK you want to program is connected. +You can now program the sample. +If you have multiple Nordic Semiconductor devices, make sure that only the nRF54H20 DK you want to program is connected. - .. code-block:: console +.. code-block:: console - west flash + west flash The sample will be automatically built and programmed on both the application core and the Peripheral Processor (PPR) of the nRF54H20. diff --git a/doc/nrf/links.txt b/doc/nrf/links.txt index 409ccd3656dd..fecac55087b3 100644 --- a/doc/nrf/links.txt +++ b/doc/nrf/links.txt @@ -1652,9 +1652,14 @@ .. _`nRF54H20 firmware bundle`: https://files.nordicsemi.com/artifactory/SDSC/external/nrf54h20_soc_binaries_v0.5.0.zip .. _`nRF54H20 firmware bundle v0.3.3`: https://files.nordicsemi.com/artifactory/SDSC/external/nrf54h20_soc_binaries_v0.3.3.zip .. _`nRF54H20 firmware bundle v0.5.0`: https://files.nordicsemi.com/artifactory/SDSC/external/nrf54h20_soc_binaries_v0.5.0.zip +.. _`nRF54H20 firmware bundle v0.6.2`: https://files.nordicsemi.com/artifactory/SDSC/external/nrf54h20_soc_binaries_v0.6.2.zip .. _`BICR binary file`: https://files.nordicsemi.com/artifactory/SDSC/external/bicr_ext_loadcap.hex +.. _`BICR new binary file`: https://files.nordicsemi.com/artifactory/SDSC/external/bicr/bicr.hex .. _`J-Link version 7.94e`: https://www.segger.com/downloads/jlink/ .. _`J-Link version 7.88j`: https://www.segger.com/downloads/jlink/ + +.. _`Zephyr's nRF clock control API extensions`: https://github.com/nrfconnect/sdk-zephyr/blob/main/include/zephyr/drivers/clock_control/nrf_clock_control.h +.. _`clocks devicetree macro API`: https://github.com/nrfconnect/sdk-zephyr/blob/main/include/zephyr/devicetree/clocks.h diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7.rst index 09d812d75a3d..76b759273996 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7.rst @@ -1,4 +1,4 @@ -.. _migration_nrf4h20_to_2.7: +.. _migration_nrf54h20_to_2.7: Migration notes for |NCS| v2.7.0 and the nRF54H20 DK #################################################### diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7_99-cs1.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7_99-cs1.rst new file mode 100644 index 000000000000..7d8894f6136e --- /dev/null +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7_99-cs1.rst @@ -0,0 +1,61 @@ +.. _migration_nrf54h20_to_2.7.99-cs1: + +Migration notes for |NCS| v2.7.99-cs1 and the nRF54H20 DK +######################################################### + +This document describes what existing users of the |NCS| v2.7.0 must consider when migrating their environment to the |NCS| v2.7.99-cs1: + +nRF54H20 DK compatibility + The |NCS| v2.7.99-cs1 is compatible only with the nRF54H20 DK, version PCA10175 v0.8.0 (ES4) or later revisions. + +|NCS| v2.7.99-cs1 + You can update your |NCS| v2.7.0 installation and toolchain to v2.7.99-cs1 by using the Toolchain Manager: + + 1. Open `nRF Connect for Desktop`_. + #. Open the Toolchain Manager application in nRF Connect for Desktop. + #. Click the button with the arrow pointing down next to the installed |NCS| version (v2.7.0) to expand the drop-down menu with options. + #. In the drop-down menu, click :guilabel:`Update toolchain`. + #. In the same drop-down menu, click :guilabel:`Update SDK`. + +nrfutil device + ``nrfutil device`` has been updated to version 2.4.6. + + Install the nRF Util ``device`` command version 2.4.6 as follows:: + + nrfutil install device=2.4.6 --force + + For more information, consult the `nRF Util`_ documentation. + +SDFW and SCFW firmwares + The *nRF54H20 firmware bundle* has been updated to version 0.6.2. + + To update the firmware bundle of your development kit while in Root of Trust, do the following: + + 1. Download the `nRF54H20 firmware bundle v0.6.2`_. + + .. note:: + On MacOS, ensure that the ZIP file is not unpacked automatically upon download. + + #. Move the :file:`.zip` bundle to a folder of your choice, then run nRF Util to program the binaries using the following command:: + + nrfutil device x-suit-dfu --firmware --serial-number + +nRF54H20 BICR + The nRF54H20 BICR has been updated. + + To update the BICR of your development kit while in Root of Trust, do the following: + + 1. Download the `BICR new binary file`_. + #. Connect the nRF54H20 DK to your computer using the **DEBUGGER** port on the DK. + + .. note:: + On MacOS, connecting the DK might cause a popup containing the message ``Disk Not Ejected Properly`` to repeatedly appear on screen. + To disable this, run ``JLinkExe``, then run ``MSDDisable`` in the J-Link Commander interface. + + #. List all the connected development kits to see their serial number (matching the one on the DK's sticker):: + + nrfutil device list + + #. Move the BICR HEX file to a folder of your choice, then program the BICR by running nRF Util from that folder using the following command:: + + nrfutil device program --options chip_erase_mode=ERASE_NONE --firmware --core Secure --serial-number diff --git a/doc/nrf/samples/other.rst b/doc/nrf/samples/other.rst index 37baab622fd4..d7e4ba380729 100644 --- a/doc/nrf/samples/other.rst +++ b/doc/nrf/samples/other.rst @@ -12,3 +12,4 @@ Other samples ../../../samples/ipc/*/README ../../../samples/mpsl/*/README ../../../samples/benchmarks/*/README + ../../../tests/benchmarks/multicore/*/README diff --git a/tests/benchmarks/multicore/idle/README.rst b/tests/benchmarks/multicore/idle/README.rst index c1e1b19c954f..d9586335209d 100644 --- a/tests/benchmarks/multicore/idle/README.rst +++ b/tests/benchmarks/multicore/idle/README.rst @@ -1,5 +1,3 @@ -:orphan: - .. _multicore_idle_test: Multicore idle test @@ -24,6 +22,7 @@ Overview ******** The test demonstrates how to build a multicore idle application with :ref:`configuration_system_overview_sysbuild`. + When building with sysbuild, the build system adds child images based on the options selected in the project's additional configuration and build files. This test shows how to inform the build system about dedicated sources for additional images. The test comes with the following additional files: @@ -41,8 +40,9 @@ Building and running .. include:: /includes/build_and_run_test.txt -The remote board needs to be specified using ``SB_CONFIG_REMOTE_BOARD``. -As shown below, it is recommended to use configuration setups from :file:`testcase.yaml` using the ``-T`` option to build the test. +The remote board must be specified using ``SB_CONFIG_REMOTE_BOARD``. +To build the test, use configuration setups from :file:`testcase.yaml` using the ``-T`` option. +See the following examples: nRF5340 DK You can build the test for application and network cores as follows: @@ -70,7 +70,7 @@ nRF54H20 DK An additional configuration setup is provided to execute code directly from the non-volatile memory (MRAM) on the PPR core. This configuration uses :ref:`zephyr:nordic-ppr-xip` and enables :kconfig:option:`CONFIG_XIP` on the PPR core. - It can be built as follows: + You can build the sample as follows: .. code-block:: console From 896857e2b0961ec4ad39e88521e5e8c1dbaf596b Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 26 Aug 2024 16:55:36 +0200 Subject: [PATCH 67/72] drivers: mpsl: Add !SOC_SERIES_NRF54HX dep to CLOCK_CONTROL_MPSL The MPSL clock control driver does not support the SOC_SERIES_NRF54HX which uses the new nrf2 clock control API, which is selected by default if CLOCK_CONTROL is selected on the SOC level. Signed-off-by: Bjarki Arge Andreasen --- drivers/mpsl/clock_control/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mpsl/clock_control/Kconfig b/drivers/mpsl/clock_control/Kconfig index fa3c4e1e3cbf..099c191e3ed3 100644 --- a/drivers/mpsl/clock_control/Kconfig +++ b/drivers/mpsl/clock_control/Kconfig @@ -8,5 +8,6 @@ config CLOCK_CONTROL_MPSL bool depends on MPSL depends on CLOCK_CONTROL + depends on !SOC_SERIES_NRF54HX default y select CLOCK_CONTROL_NRF_FORCE_ALT From 6945f557299cfe0f20bc299e009368c6aa328818 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 27 Aug 2024 12:40:28 +0200 Subject: [PATCH 68/72] manifest: sdk-zephyr: update to 28b6861211d2d9f54411ff60357a42d84a253600 Update zephyr to revision 28b6861211d2d9f54411ff60357a42d84a253600 Signed-off-by: Bjarki Arge Andreasen --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 8cfe0b596553..7e0819d1fa11 100644 --- a/west.yml +++ b/west.yml @@ -72,7 +72,7 @@ manifest: # https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/modules.html - name: zephyr repo-path: sdk-zephyr - revision: a415e2d702d5192ffdf7ddf67fa73f8fab70a277 + revision: 28b6861211d2d9f54411ff60357a42d84a253600 import: # In addition to the zephyr repository itself, NCS also # imports the contents of zephyr/west.yml at the above From dae7979fdc0065f8a71d6ba74aaebee27af5800e Mon Sep 17 00:00:00 2001 From: Bartosz Gentkowski Date: Fri, 5 Jul 2024 14:24:05 +0200 Subject: [PATCH 69/72] doc: update documentation for 2.7.99-cs1 Customer sampling release doc updates. Signed-off-by: Bartosz Gentkowski --- .../nrf54h/ug_nrf54h20_architecture_pm.rst | 2 +- doc/nrf/conf.py | 2 +- .../adding_code.rst | 4 +- doc/nrf/links.txt | 4 +- doc/nrf/releases_and_maturity.rst | 1 - .../releases_and_maturity/known_issues.rst | 2 + .../migration/migration_guide_1.x_to_2.x.rst | 2 + ...gration_guide_2.4.99-cs3_to_2.6.99-cs2.rst | 2 + .../migration/migration_guide_2.5.rst | 2 + .../migration/migration_guide_2.6.rst | 2 + .../migration/migration_guide_2.7.rst | 2 + .../migration/migration_guide_2.8.rst | 2 + .../migration_guide_nRF54H20_cs_to_2_7.rst | 2 + ...ration_guide_nRF54H20_cs_to_2_7_99-cs1.rst | 4 +- .../migration/migration_hwmv2.rst | 2 + .../migration/migration_sysbuild.rst | 2 + .../migration_guides.rst | 17 ++- .../releases_and_maturity/release_notes.rst | 5 +- .../releases/release-notes-2.7.99-cs1.rst | 109 ++++++++++++++++++ .../releases/release-notes-changelog.rst | 2 + doc/nrf/shortcuts.txt | 6 +- doc/versions.json | 2 +- 22 files changed, 158 insertions(+), 20 deletions(-) create mode 100644 doc/nrf/releases_and_maturity/releases/release-notes-2.7.99-cs1.rst diff --git a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture_pm.rst b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture_pm.rst index d1dc886440c3..89d1f93aa9a9 100644 --- a/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture_pm.rst +++ b/doc/nrf/app_dev/device_guides/working_with_nrf/nrf54h/ug_nrf54h20_architecture_pm.rst @@ -105,7 +105,7 @@ Local Suspend to RAM *Local Suspend to RAM* is a sleep state that balances between power consumption and wake-up latency. This state is available only for DVFS-capable domains. -Other domains, such as Radio, cannot retain the CPU and local peripherals in the *System ON (All) Idle* state. +Other domains, such as Radio, can retain the CPU and local peripherals in hardware flip-flops in the *System ON (All) Idle* state. In this state, the entire local Active Power Domain, including the CPU, is unpowered. The state of the CPU and the peripherals powered by the local Active Power Domain is not retained by hardware flip-flops. diff --git a/doc/nrf/conf.py b/doc/nrf/conf.py index 439529833686..2c0bc5844e66 100644 --- a/doc/nrf/conf.py +++ b/doc/nrf/conf.py @@ -28,7 +28,7 @@ project = "nRF Connect SDK" copyright = "2019-2024, Nordic Semiconductor" author = "Nordic Semiconductor" -version = release = "2.7.99" +version = release = "2.7.99-cs1" sys.path.insert(0, str(ZEPHYR_BASE / "doc" / "_extensions")) sys.path.insert(0, str(NRF_BASE / "doc" / "_extensions")) diff --git a/doc/nrf/dev_model_and_contributions/adding_code.rst b/doc/nrf/dev_model_and_contributions/adding_code.rst index 0c0d61fc966f..f621fd5c237b 100644 --- a/doc/nrf/dev_model_and_contributions/adding_code.rst +++ b/doc/nrf/dev_model_and_contributions/adding_code.rst @@ -162,7 +162,7 @@ This is demonstrated by the following code, that would be placed somewhere in yo - name: nrf repo-path: sdk-nrf remote: ncs - revision: 2.7.0 + revision: 2.7.99-cs1 import: true self: path: application @@ -189,7 +189,7 @@ For example: projects: - name: nrf remote: ncs - revision: 2.7.0 + revision: 2.7.99-cs1 import: true # Example for how to override a repository in the nRF Connect SDK with your own: - name: mcuboot diff --git a/doc/nrf/links.txt b/doc/nrf/links.txt index fecac55087b3..c418ab749ad7 100644 --- a/doc/nrf/links.txt +++ b/doc/nrf/links.txt @@ -327,8 +327,9 @@ .. _`nRF socket options`: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrfxlib/nrf_modem/doc/sockets.html -.. _`Repositories and revisions for v2.6.99-cs1`: https://docs.nordicsemi.com/bundle/ncs-2.6.99-cs1/page/nrf/releases_and_maturity/repository_revisions.html +.. _`Repositories and revisions for v2.7.99-cs1`: https://docs.nordicsemi.com/bundle/ncs-2.7.99-cs1/page/nrf/releases_and_maturity/repository_revisions.html .. _`Repositories and revisions for v2.7.0`: https://docs.nordicsemi.com/bundle/ncs-2.7.0/page/nrf/releases_and_maturity/repository_revisions.html +.. _`Repositories and revisions for v2.6.99-cs1`: https://docs.nordicsemi.com/bundle/ncs-2.6.99-cs1/page/nrf/releases_and_maturity/repository_revisions.html .. _`Repositories and revisions for v2.6.1`: https://docs.nordicsemi.com/bundle/ncs-2.6.1/page/nrf/releases_and_maturity/repository_revisions.html .. _`Repositories and revisions for v2.6.0`: https://docs.nordicsemi.com/bundle/ncs-2.6.0/page/nrf/releases_and_maturity/repository_revisions.html .. _`Repositories and revisions for v2.5.3`: https://docs.nordicsemi.com/bundle/ncs-2.5.3/page/nrf/releases_and_maturity/repository_revisions.html @@ -415,6 +416,7 @@ .. _`Migrating to the current hardware model`: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/releases_and_maturity/migration/migration_hwmv2.html +.. _`Migration notes for nRF Connect SDK v2.7.99-cs1 and the nRF54H20 DK`: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7_99-cs1.html .. _`Migration notes for nRF Connect SDK v2.7.0 for nRF54H20 DK users`: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7.html .. _`Transition your development environment to nRF Connect SDK v2.7.0 for v2.4.99-cs3 users`: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/releases_and_maturity/migration/nRF54H20_migration_2.7/transition_guide_2.4.99-cs3_to_2.7_environment.html .. _`Update your development environment for nRF Connect SDK v2.7.0 for v2.6.99-cs2 users`: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/releases_and_maturity/migration/nRF54H20_migration_2.7/migration_guide_2.6.99-cs2_to_2_7_environment.html diff --git a/doc/nrf/releases_and_maturity.rst b/doc/nrf/releases_and_maturity.rst index 7c82c5e294d9..a87b7522a2b5 100644 --- a/doc/nrf/releases_and_maturity.rst +++ b/doc/nrf/releases_and_maturity.rst @@ -27,4 +27,3 @@ If an issue is found in a release after it has taken place, those issues are lis releases_and_maturity/migration_guides releases_and_maturity/repository_revisions releases_and_maturity/software_maturity - releases_and_maturity/known_issues diff --git a/doc/nrf/releases_and_maturity/known_issues.rst b/doc/nrf/releases_and_maturity/known_issues.rst index 65ed9213abfc..611bbdd63af5 100644 --- a/doc/nrf/releases_and_maturity/known_issues.rst +++ b/doc/nrf/releases_and_maturity/known_issues.rst @@ -1,3 +1,5 @@ +:orphan: + .. _known_issues: Known issues diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_1.x_to_2.x.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_1.x_to_2.x.rst index d58b1e5db81a..a70e4ccbabe4 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_1.x_to_2.x.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_1.x_to_2.x.rst @@ -1,3 +1,5 @@ +:orphan: + .. _ncs_2.0.0_migration: Migration notes for |NCS| v2.0.0 diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_2.4.99-cs3_to_2.6.99-cs2.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_2.4.99-cs3_to_2.6.99-cs2.rst index a5791574fac8..2fb0f6413515 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_2.4.99-cs3_to_2.6.99-cs2.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_2.4.99-cs3_to_2.6.99-cs2.rst @@ -1,3 +1,5 @@ +:orphan: + .. _migration_cs3_to_2_6_99_cs2: Migration notes for |NCS| v2.6.99_cs2 for v2.4.99-cs3 users diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_2.5.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_2.5.rst index b7f4539c88be..b2cac995fd0b 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_2.5.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_2.5.rst @@ -1,3 +1,5 @@ +:orphan: + .. _migration_2.5: Migration guide for |NCS| v2.5.0 diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_2.6.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_2.6.rst index 86f04155e708..a74ee2b8c93f 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_2.6.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_2.6.rst @@ -1,3 +1,5 @@ +:orphan: + .. _migration_2.6: Migration guide for |NCS| v2.6.0 diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_2.7.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_2.7.rst index 287aeb9ea1e9..01cf5d4a7a02 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_2.7.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_2.7.rst @@ -1,3 +1,5 @@ +:orphan: + .. _migration_2.7: Migration guide for |NCS| v2.7.0 diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_2.8.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_2.8.rst index 5db420d6db7a..dc9721f9fd8b 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_2.8.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_2.8.rst @@ -1,3 +1,5 @@ +:orphan: + .. _migration_2.8: Migration guide for |NCS| v2.8.0 (Working draft) diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7.rst index 76b759273996..0ddae2621f5f 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7.rst @@ -1,3 +1,5 @@ +:orphan: + .. _migration_nrf54h20_to_2.7: Migration notes for |NCS| v2.7.0 and the nRF54H20 DK diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7_99-cs1.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7_99-cs1.rst index 7d8894f6136e..bbd96111bb18 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7_99-cs1.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7_99-cs1.rst @@ -1,3 +1,5 @@ +:orphan: + .. _migration_nrf54h20_to_2.7.99-cs1: Migration notes for |NCS| v2.7.99-cs1 and the nRF54H20 DK @@ -58,4 +60,4 @@ nRF54H20 BICR #. Move the BICR HEX file to a folder of your choice, then program the BICR by running nRF Util from that folder using the following command:: - nrfutil device program --options chip_erase_mode=ERASE_NONE --firmware --core Secure --serial-number + nrfutil device program --options chip_erase_mode=ERASE_NONE --firmware --core Application --serial-number diff --git a/doc/nrf/releases_and_maturity/migration/migration_hwmv2.rst b/doc/nrf/releases_and_maturity/migration/migration_hwmv2.rst index c8721e98a065..a0e50e87b666 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_hwmv2.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_hwmv2.rst @@ -1,3 +1,5 @@ +:orphan: + .. _hwmv1_to_v2_migration: Migrating to the current hardware model diff --git a/doc/nrf/releases_and_maturity/migration/migration_sysbuild.rst b/doc/nrf/releases_and_maturity/migration/migration_sysbuild.rst index 9784975f1bf3..48f5de4e7158 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_sysbuild.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_sysbuild.rst @@ -1,3 +1,5 @@ +:orphan: + .. _child_parent_to_sysbuild_migration: Migrating from multi-image builds to sysbuild diff --git a/doc/nrf/releases_and_maturity/migration_guides.rst b/doc/nrf/releases_and_maturity/migration_guides.rst index d169e313c883..afb55f6f89ab 100644 --- a/doc/nrf/releases_and_maturity/migration_guides.rst +++ b/doc/nrf/releases_and_maturity/migration_guides.rst @@ -9,10 +9,15 @@ Migration guides are also provided for major functionality updates. .. note:: |migration_contact_devzone| -.. toctree:: - :maxdepth: 1 - :glob: - :reversed: - :caption: Subpages: +* `Migrating from multi-image builds to sysbuild`_ +* `Migrating to the current hardware model`_ +* `Migration guide for nRF Connect SDK v2.7.0`_ +* `Migration guide for nRF Connect SDK v2.6.0`_ +* `Migration guide for nRF Connect SDK v2.5.0`_ +* `Migration guide for nRF Connect SDK v2.0.0`_ - migration/* +For nRF54H20 customer sampling participants: + +* `Migration notes for nRF Connect SDK v2.7.99-cs1 and the nRF54H20 DK`_ +* `Migration notes for nRF Connect SDK v2.7.0 for nRF54H20 DK users`_ +* `Migration guide for nRF Connect SDK v2.6.99_cs2 for v2.4.99-cs3 users`_ diff --git a/doc/nrf/releases_and_maturity/release_notes.rst b/doc/nrf/releases_and_maturity/release_notes.rst index b4bee91f41d5..ee6028c73fc3 100644 --- a/doc/nrf/releases_and_maturity/release_notes.rst +++ b/doc/nrf/releases_and_maturity/release_notes.rst @@ -10,9 +10,8 @@ This page is included only in the latest documentation, because it might contain .. note:: A "99" at the end of the version number of this documentation indicates continuous updates on the main branch since the previous major.minor release. - When looking at this latest documentation, be aware of the following aspects: + When looking at this latest documentation, be aware of the following aspect: - * Changes between releases are tracked on the :ref:`ncs_release_notes_changelog` page, but the main branch might contain additional changes that are not listed on that page. * The release note pages that are available in the latest documentation might differ slightly from the release notes that were included in the respective |NCS| release at its release date. Therefore, to see the official version of the release notes for a specific |NCS| release, switch to the documentation for the corresponding |NCS| version using the selector in the upper left corner. @@ -20,7 +19,7 @@ This page is included only in the latest documentation, because it might contain :maxdepth: 1 :caption: Subpages: - releases/release-notes-changelog + releases/release-notes-2.7.99-cs1 releases/release-notes-2.7.0 releases/release-notes-2.6.99-cs2 releases/release-notes-2.6.99-cs1 diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-2.7.99-cs1.rst b/doc/nrf/releases_and_maturity/releases/release-notes-2.7.99-cs1.rst new file mode 100644 index 000000000000..d633c2cc7191 --- /dev/null +++ b/doc/nrf/releases_and_maturity/releases/release-notes-2.7.99-cs1.rst @@ -0,0 +1,109 @@ +.. _ncs_release_notes_2799_cs1: + +|NCS| v2.7.99-cs1 Release Notes +############################### + +.. contents:: + :local: + :depth: 3 + +|NCS| v2.7.99-cs1 is a **customer sampling** release, tailored exclusively for participants in the nRF54H20 SoC customer sampling program. +Do not use this release of |NCS| if you are not participating in the program. + +The release is not part of the regular release cycle and is specifically designed to support early adopters working with the nRF54H20 SoC. +It is intended to provide early access to the latest developments for nRF54H20 SoC, enabling participants to experiment with new features and provide feedback. + +The scope of this release is intentionally narrow, concentrating solely on the nRF54H20 DK. +You can use the latest stable release of |NCS| to work with other boards. + +All functionality related to nRF54H20 SoC is considered experimental. + +Highlights +********** + +Added the following features as experimental: + +* Power management with support for System On All Idle power state. +* Clock control API. +* New peripheral driver SAADC. + +Release tag +*********** + +The release tag for the |NCS| manifest repository (|ncs_repo|) is **v2.7.99-cs1**. +Check the :file:`west.yml` file for the corresponding tags in the project repositories. + +To use this release, check out the tag in the manifest repository and run ``west update``. +See :ref:`cloning_the_repositories` and :ref:`gs_updating_repos_examples` for more information. + +For information on the included repositories and revisions, see `Repositories and revisions for v2.7.99-cs1`_. + +IDE and tool support +******************** + +`nRF Connect extension for Visual Studio Code `_ is the recommended IDE for |NCS| v2.7.99-cs1. +See the :ref:`installation` section for more information about supported operating systems and toolchain. + +.. note:: + + Because of the significant, potentially breaking changes introduced in the |NCS| v2.7.0, the support for v2.7.99-cs1 in the |nRFVSC| is experimental in the following areas: + + * sysbuild - During the extension stabilization period, manually edit and verify Kconfig option values instead of using the nRF Kconfig GUI. + * Hardware Model v2 - During the extension stabilization period, edit devicetree files manually instead of using the Devicetree Visual Editor. + Moreover, custom boards added in the extension will follow the Zephyr's Hardware Model v1. + + The extension users that need v2.7.99-cs1 should `switch to the pre-release version of the extension`_. + +Migration notes +*************** + +See the `Migration notes for nRF Connect SDK v2.7.99-cs1 and the nRF54H20 DK`_ for the changes required or recommended when migrating your environment to the |NCS| v2.7.99-cs1. + +Changelog +********* + +The following sections provide detailed lists of changes by component. + +Zephyr +====== + +.. NOTE TO MAINTAINERS: All the Zephyr commits in the below git commands must be handled specially after each upmerge and each nRF Connect SDK release. + +The Zephyr fork in |NCS| (``sdk-zephyr``) contains all commits from the upstream Zephyr repository up to and including ``28b6861211d2d9f54411ff60357a42d84a253600``, with some |NCS| specific additions. + +* Added: + + * Experimental support for Power management with support for System On All Idle power state. + * Experimental support for a new peripheral driver SAADC. + See the :zephyr:code-sample:`adc_sequence` and :zephyr:code-sample:`adc_dt` sample documentation for more details. + * Experimental support for the clock control API. + See the :file:`include/zephyr/drivers/clock_control/nrf_clock_control.h` file for more details. + +For the list of upstream Zephyr commits (not including cherry-picked commits) incorporated into nRF Connect SDK since the most recent release, run the following command from the :file:`ncs/zephyr` repository (after running ``west update``): + +.. code-block:: none + + git log --oneline 28b6861211 ^25e90e7bb0 + +For the list of |NCS| specific commits, including commits cherry-picked from upstream, run: + +.. code-block:: none + + git log --oneline manifest-rev ^28b6861211 + +The current |NCS| main branch is based on revision ``28b6861211`` of Zephyr. + +.. note:: + For possible breaking changes and changes between the latest Zephyr release and the current Zephyr version, refer to the :ref:`Zephyr release notes `. + +Documentation +============= + +* Added: + + * A page about :ref:`ug_nrf54h20_architecture_clockman`. + * A page about :ref:`ug_nrf54h20_architecture_pm`. + * Documentation for :ref:`multicore_idle_test`. + * :ref:`migration_nrf54h20_to_2.7.99-cs1`. + +* Updated :ref:`ug_nrf54h` and :ref:`ug_nrf54h20_gs` guides with information about the |NCS| v2.7.99-cs1. diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index ae4d9f3e9fde..df0085072dbe 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -1,3 +1,5 @@ +:orphan: + .. _ncs_release_notes_changelog: Changelog for |NCS| v2.7.99 diff --git a/doc/nrf/shortcuts.txt b/doc/nrf/shortcuts.txt index 71eeaffd67e6..421cdb15b1fc 100644 --- a/doc/nrf/shortcuts.txt +++ b/doc/nrf/shortcuts.txt @@ -1,8 +1,8 @@ .. |NCS| replace:: nRF Connect SDK -.. |release| replace:: v2.7.0 -.. |release_tt| replace:: ``v2.7.0`` -.. |release_number_tt| replace:: ``2.7.0`` +.. |release| replace:: v2.7.99-cs1 +.. |release_tt| replace:: ``v2.7.99-cs1`` +.. |release_number_tt| replace:: ``2.7.99-cs1`` .. ### Config shortcuts diff --git a/doc/versions.json b/doc/versions.json index 5d284142941d..263abf8df581 100644 --- a/doc/versions.json +++ b/doc/versions.json @@ -1,5 +1,5 @@ [ - "2.7.99", + "2.7.99-cs1", "2.7.0", "2.6.99-cs2", "2.6.99-cs1", From 34c9071a44048d2aa466894d351cc8b6a8f4ce6e Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 29 Aug 2024 17:10:24 +0200 Subject: [PATCH 70/72] samples: suit: smp_transfer: flash_companion: disable CLOCK_CONTROL CLOCK_CONTROL is now enabled by default for the nRF54H20 cpuapp. Disable it for the flash_companion to save flash. Signed-off-by: Bjarki Arge Andreasen --- samples/suit/flash_companion/prj.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/samples/suit/flash_companion/prj.conf b/samples/suit/flash_companion/prj.conf index 69145eab3c13..668587cdc696 100644 --- a/samples/suit/flash_companion/prj.conf +++ b/samples/suit/flash_companion/prj.conf @@ -72,3 +72,6 @@ CONFIG_ZCBOR_CANONICAL=y # Enable LTO CONFIG_LTO=y CONFIG_ISR_TABLES_LOCAL_DECLARATION=y + +# Minimize flash usage +CONFIG_CLOCK_CONTROL=n From 23a9baf2aed6ba331ea4e470df95b1430882e123 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 29 Aug 2024 09:25:16 +0200 Subject: [PATCH 71/72] version: update VERSION to 2.7.99-cs1 VERSION 2.7.99-cs1 Signed-off-by: Gerard Marull-Paretas --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1de7f517c3f4..84183430af00 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.7.99 +2.7.99-cs1 From f3d4818cfc535fbe50863652ee0aa655477cfdb7 Mon Sep 17 00:00:00 2001 From: divya pillai Date: Thu, 29 Aug 2024 17:17:31 +0200 Subject: [PATCH 72/72] doc: post-release doc update after 2.7.99-cs1 post-release doc update after 2.7.99-cs1 Signed-off-by: divya pillai --- doc/nrf/conf.py | 2 +- .../dev_model_and_contributions/adding_code.rst | 4 ++-- doc/nrf/releases_and_maturity.rst | 1 + doc/nrf/releases_and_maturity/known_issues.rst | 2 -- .../migration/migration_guide_1.x_to_2.x.rst | 2 -- ...migration_guide_2.4.99-cs3_to_2.6.99-cs2.rst | 2 -- .../migration/migration_guide_2.5.rst | 2 -- .../migration/migration_guide_2.6.rst | 2 -- .../migration/migration_guide_2.7.rst | 2 -- .../migration/migration_guide_2.8.rst | 2 -- .../migration_guide_nRF54H20_cs_to_2_7.rst | 2 -- ...igration_guide_nRF54H20_cs_to_2_7_99-cs1.rst | 2 -- .../migration/migration_hwmv2.rst | 2 -- .../migration/migration_sysbuild.rst | 2 -- .../releases_and_maturity/migration_guides.rst | 17 ++++++----------- doc/nrf/releases_and_maturity/release_notes.rst | 4 +++- .../releases/release-notes-changelog.rst | 2 -- doc/nrf/shortcuts.txt | 6 +++--- doc/versions.json | 1 + 19 files changed, 17 insertions(+), 42 deletions(-) diff --git a/doc/nrf/conf.py b/doc/nrf/conf.py index 2c0bc5844e66..439529833686 100644 --- a/doc/nrf/conf.py +++ b/doc/nrf/conf.py @@ -28,7 +28,7 @@ project = "nRF Connect SDK" copyright = "2019-2024, Nordic Semiconductor" author = "Nordic Semiconductor" -version = release = "2.7.99-cs1" +version = release = "2.7.99" sys.path.insert(0, str(ZEPHYR_BASE / "doc" / "_extensions")) sys.path.insert(0, str(NRF_BASE / "doc" / "_extensions")) diff --git a/doc/nrf/dev_model_and_contributions/adding_code.rst b/doc/nrf/dev_model_and_contributions/adding_code.rst index f621fd5c237b..0c0d61fc966f 100644 --- a/doc/nrf/dev_model_and_contributions/adding_code.rst +++ b/doc/nrf/dev_model_and_contributions/adding_code.rst @@ -162,7 +162,7 @@ This is demonstrated by the following code, that would be placed somewhere in yo - name: nrf repo-path: sdk-nrf remote: ncs - revision: 2.7.99-cs1 + revision: 2.7.0 import: true self: path: application @@ -189,7 +189,7 @@ For example: projects: - name: nrf remote: ncs - revision: 2.7.99-cs1 + revision: 2.7.0 import: true # Example for how to override a repository in the nRF Connect SDK with your own: - name: mcuboot diff --git a/doc/nrf/releases_and_maturity.rst b/doc/nrf/releases_and_maturity.rst index a87b7522a2b5..7c82c5e294d9 100644 --- a/doc/nrf/releases_and_maturity.rst +++ b/doc/nrf/releases_and_maturity.rst @@ -27,3 +27,4 @@ If an issue is found in a release after it has taken place, those issues are lis releases_and_maturity/migration_guides releases_and_maturity/repository_revisions releases_and_maturity/software_maturity + releases_and_maturity/known_issues diff --git a/doc/nrf/releases_and_maturity/known_issues.rst b/doc/nrf/releases_and_maturity/known_issues.rst index 611bbdd63af5..65ed9213abfc 100644 --- a/doc/nrf/releases_and_maturity/known_issues.rst +++ b/doc/nrf/releases_and_maturity/known_issues.rst @@ -1,5 +1,3 @@ -:orphan: - .. _known_issues: Known issues diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_1.x_to_2.x.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_1.x_to_2.x.rst index a70e4ccbabe4..d58b1e5db81a 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_1.x_to_2.x.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_1.x_to_2.x.rst @@ -1,5 +1,3 @@ -:orphan: - .. _ncs_2.0.0_migration: Migration notes for |NCS| v2.0.0 diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_2.4.99-cs3_to_2.6.99-cs2.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_2.4.99-cs3_to_2.6.99-cs2.rst index 2fb0f6413515..a5791574fac8 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_2.4.99-cs3_to_2.6.99-cs2.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_2.4.99-cs3_to_2.6.99-cs2.rst @@ -1,5 +1,3 @@ -:orphan: - .. _migration_cs3_to_2_6_99_cs2: Migration notes for |NCS| v2.6.99_cs2 for v2.4.99-cs3 users diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_2.5.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_2.5.rst index b2cac995fd0b..b7f4539c88be 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_2.5.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_2.5.rst @@ -1,5 +1,3 @@ -:orphan: - .. _migration_2.5: Migration guide for |NCS| v2.5.0 diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_2.6.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_2.6.rst index a74ee2b8c93f..86f04155e708 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_2.6.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_2.6.rst @@ -1,5 +1,3 @@ -:orphan: - .. _migration_2.6: Migration guide for |NCS| v2.6.0 diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_2.7.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_2.7.rst index 01cf5d4a7a02..287aeb9ea1e9 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_2.7.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_2.7.rst @@ -1,5 +1,3 @@ -:orphan: - .. _migration_2.7: Migration guide for |NCS| v2.7.0 diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_2.8.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_2.8.rst index dc9721f9fd8b..5db420d6db7a 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_2.8.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_2.8.rst @@ -1,5 +1,3 @@ -:orphan: - .. _migration_2.8: Migration guide for |NCS| v2.8.0 (Working draft) diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7.rst index 0ddae2621f5f..76b759273996 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7.rst @@ -1,5 +1,3 @@ -:orphan: - .. _migration_nrf54h20_to_2.7: Migration notes for |NCS| v2.7.0 and the nRF54H20 DK diff --git a/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7_99-cs1.rst b/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7_99-cs1.rst index bbd96111bb18..83e88a275546 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7_99-cs1.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_guide_nRF54H20_cs_to_2_7_99-cs1.rst @@ -1,5 +1,3 @@ -:orphan: - .. _migration_nrf54h20_to_2.7.99-cs1: Migration notes for |NCS| v2.7.99-cs1 and the nRF54H20 DK diff --git a/doc/nrf/releases_and_maturity/migration/migration_hwmv2.rst b/doc/nrf/releases_and_maturity/migration/migration_hwmv2.rst index a0e50e87b666..c8721e98a065 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_hwmv2.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_hwmv2.rst @@ -1,5 +1,3 @@ -:orphan: - .. _hwmv1_to_v2_migration: Migrating to the current hardware model diff --git a/doc/nrf/releases_and_maturity/migration/migration_sysbuild.rst b/doc/nrf/releases_and_maturity/migration/migration_sysbuild.rst index 48f5de4e7158..9784975f1bf3 100644 --- a/doc/nrf/releases_and_maturity/migration/migration_sysbuild.rst +++ b/doc/nrf/releases_and_maturity/migration/migration_sysbuild.rst @@ -1,5 +1,3 @@ -:orphan: - .. _child_parent_to_sysbuild_migration: Migrating from multi-image builds to sysbuild diff --git a/doc/nrf/releases_and_maturity/migration_guides.rst b/doc/nrf/releases_and_maturity/migration_guides.rst index afb55f6f89ab..d169e313c883 100644 --- a/doc/nrf/releases_and_maturity/migration_guides.rst +++ b/doc/nrf/releases_and_maturity/migration_guides.rst @@ -9,15 +9,10 @@ Migration guides are also provided for major functionality updates. .. note:: |migration_contact_devzone| -* `Migrating from multi-image builds to sysbuild`_ -* `Migrating to the current hardware model`_ -* `Migration guide for nRF Connect SDK v2.7.0`_ -* `Migration guide for nRF Connect SDK v2.6.0`_ -* `Migration guide for nRF Connect SDK v2.5.0`_ -* `Migration guide for nRF Connect SDK v2.0.0`_ +.. toctree:: + :maxdepth: 1 + :glob: + :reversed: + :caption: Subpages: -For nRF54H20 customer sampling participants: - -* `Migration notes for nRF Connect SDK v2.7.99-cs1 and the nRF54H20 DK`_ -* `Migration notes for nRF Connect SDK v2.7.0 for nRF54H20 DK users`_ -* `Migration guide for nRF Connect SDK v2.6.99_cs2 for v2.4.99-cs3 users`_ + migration/* diff --git a/doc/nrf/releases_and_maturity/release_notes.rst b/doc/nrf/releases_and_maturity/release_notes.rst index ee6028c73fc3..e712cb126e44 100644 --- a/doc/nrf/releases_and_maturity/release_notes.rst +++ b/doc/nrf/releases_and_maturity/release_notes.rst @@ -10,8 +10,9 @@ This page is included only in the latest documentation, because it might contain .. note:: A "99" at the end of the version number of this documentation indicates continuous updates on the main branch since the previous major.minor release. - When looking at this latest documentation, be aware of the following aspect: + When looking at this latest documentation, be aware of the following aspects: + * Changes between releases are tracked on the :ref:`ncs_release_notes_changelog` page, but the main branch might contain additional changes that are not listed on that page. * The release note pages that are available in the latest documentation might differ slightly from the release notes that were included in the respective |NCS| release at its release date. Therefore, to see the official version of the release notes for a specific |NCS| release, switch to the documentation for the corresponding |NCS| version using the selector in the upper left corner. @@ -19,6 +20,7 @@ This page is included only in the latest documentation, because it might contain :maxdepth: 1 :caption: Subpages: + releases/release-notes-changelog releases/release-notes-2.7.99-cs1 releases/release-notes-2.7.0 releases/release-notes-2.6.99-cs2 diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index df0085072dbe..ae4d9f3e9fde 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -1,5 +1,3 @@ -:orphan: - .. _ncs_release_notes_changelog: Changelog for |NCS| v2.7.99 diff --git a/doc/nrf/shortcuts.txt b/doc/nrf/shortcuts.txt index 421cdb15b1fc..71eeaffd67e6 100644 --- a/doc/nrf/shortcuts.txt +++ b/doc/nrf/shortcuts.txt @@ -1,8 +1,8 @@ .. |NCS| replace:: nRF Connect SDK -.. |release| replace:: v2.7.99-cs1 -.. |release_tt| replace:: ``v2.7.99-cs1`` -.. |release_number_tt| replace:: ``2.7.99-cs1`` +.. |release| replace:: v2.7.0 +.. |release_tt| replace:: ``v2.7.0`` +.. |release_number_tt| replace:: ``2.7.0`` .. ### Config shortcuts diff --git a/doc/versions.json b/doc/versions.json index 263abf8df581..3c60b5b2fc9a 100644 --- a/doc/versions.json +++ b/doc/versions.json @@ -1,4 +1,5 @@ [ + "2.7.99", "2.7.99-cs1", "2.7.0", "2.6.99-cs2",