From 9490fb3d9a01d2287348b0809a11487b41d23291 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Fri, 3 Oct 2025 14:47:06 +0200 Subject: [PATCH 01/16] doc: add an entry for sdh Add a placeholder entry for sdh to be able to reference it in the changelog. Signed-off-by: Emanuele Di Santo --- doc/nrf-bm/libraries/nrf_sdh.rst | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 doc/nrf-bm/libraries/nrf_sdh.rst diff --git a/doc/nrf-bm/libraries/nrf_sdh.rst b/doc/nrf-bm/libraries/nrf_sdh.rst new file mode 100644 index 0000000000..3aa273be64 --- /dev/null +++ b/doc/nrf-bm/libraries/nrf_sdh.rst @@ -0,0 +1,6 @@ +.. _lib_nrf_sdh: + +SoftDevice handler +################## + +The SoftDevice handler is a library that handles SoftDevice initialization tasks, and pulls and dispatches the SoftDevice events to registered components. From 0d31f5978091d1aab55c9df2707e05e8835eb650 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Thu, 18 Sep 2025 14:36:57 +0200 Subject: [PATCH 02/16] sdh: soc: split seeding SoftDevice random in a separate file It is more correct to use an SoC observer to do this, rather than doing it directly in nrf_sdh_soc (the stack observer). Make the feature optional, and leave it enabled by default. Signed-off-by: Emanuele Di Santo --- .../release_notes/release_notes_changelog.rst | 7 ++- subsys/softdevice_handler/CMakeLists.txt | 2 + subsys/softdevice_handler/Kconfig | 12 +++-- subsys/softdevice_handler/nrf_sdh_soc.c | 29 +----------- subsys/softdevice_handler/rand_seed.c | 45 +++++++++++++++++++ 5 files changed, 62 insertions(+), 33 deletions(-) create mode 100644 subsys/softdevice_handler/rand_seed.c diff --git a/doc/nrf-bm/release_notes/release_notes_changelog.rst b/doc/nrf-bm/release_notes/release_notes_changelog.rst index 814432de9a..12345419e5 100644 --- a/doc/nrf-bm/release_notes/release_notes_changelog.rst +++ b/doc/nrf-bm/release_notes/release_notes_changelog.rst @@ -32,8 +32,11 @@ S145 SoftDevice SoftDevice Handler ================== -* Added the :kconfig:option:`NRF_SDH_CLOCK_HFINT_CALIBRATION_INTERVAL` Kconfig option to control the HFINT calibration interval. -* Added the :kconfig:option:`NRF_SDH_CLOCK_HFCLK_LATENCY` Kconfig option to inform the SoftDevice about the ramp-up time of the high-frequency crystal oscillator. +* Added: + + * The :kconfig:option:`NRF_SDH_CLOCK_HFINT_CALIBRATION_INTERVAL` Kconfig option to control the HFINT calibration interval. + * The :kconfig:option:`NRF_SDH_CLOCK_HFCLK_LATENCY` Kconfig option to inform the SoftDevice about the ramp-up time of the high-frequency crystal oscillator. + * The :kconfig:option:`CONFIG_NRF_SDH_SOC_RAND_SEED` Kconfig option to control whether to automatically respond to SoftDevice random seed requests. Boards ====== diff --git a/subsys/softdevice_handler/CMakeLists.txt b/subsys/softdevice_handler/CMakeLists.txt index 9aefee3546..5ff9249c96 100644 --- a/subsys/softdevice_handler/CMakeLists.txt +++ b/subsys/softdevice_handler/CMakeLists.txt @@ -11,6 +11,8 @@ zephyr_library_sources( irq_connect.c ) +zephyr_library_sources_ifdef(CONFIG_NRF_SDH_SOC_RAND_SEED rand_seed.c) + if(CONFIG_SOFTDEVICE_S115 OR CONFIG_SOFTDEVICE_S145) zephyr_library_sources(irq_forward.s) # Suppress the swap_helper.S file so that z_arm_svc can be defined manually diff --git a/subsys/softdevice_handler/Kconfig b/subsys/softdevice_handler/Kconfig index 429e0febaf..c9c0b0a91f 100644 --- a/subsys/softdevice_handler/Kconfig +++ b/subsys/softdevice_handler/Kconfig @@ -6,9 +6,6 @@ menuconfig NRF_SDH bool "Softdevice handler" depends on SOFTDEVICE - depends on NRF_SECURITY - depends on MBEDTLS_PSA_CRYPTO_C - depends on PSA_WANT_GENERATE_RANDOM if NRF_SDH @@ -123,6 +120,15 @@ config NRF_SDH_BLE_SERVICE_CHANGED endif # NRF_SDH_BLE +config NRF_SDH_SOC_RAND_SEED + bool "Automatically respond to SoftDevice random seeds requests" + depends on NRF_SECURITY + depends on MBEDTLS_PSA_CRYPTO_C + default y + help + Automatically seed SoftDevice upon NRF_EVT_RAND_SEED_REQUEST events, + using CRACEN to generate the random seed. + config NRF_SDH_STR_TABLES bool "Build string tables for SoftDevice handler events" default y diff --git a/subsys/softdevice_handler/nrf_sdh_soc.c b/subsys/softdevice_handler/nrf_sdh_soc.c index e95ad87db5..3ba59b64ae 100644 --- a/subsys/softdevice_handler/nrf_sdh_soc.c +++ b/subsys/softdevice_handler/nrf_sdh_soc.c @@ -6,11 +6,9 @@ #include #include +#include #include #include -#include -#include -#include #include LOG_MODULE_DECLARE(nrf_sdh, CONFIG_NRF_SDH_LOG_LEVEL); @@ -43,27 +41,6 @@ static const char *tostr(uint32_t evt) } } -static void softdevice_rng_seed(void) -{ - uint32_t err = NRF_ERROR_INVALID_DATA; - psa_status_t status; - uint8_t seed[SD_RAND_SEED_SIZE]; - - status = cracen_get_trng(seed, sizeof(seed)); - if (status == PSA_SUCCESS) { - err = sd_rand_seed_set(seed); - memset(seed, 0, sizeof(seed)); - if (err == NRF_SUCCESS) { - LOG_DBG("SoftDevice RNG seeded"); - return; - } - } else { - LOG_ERR("Generate random failed, psa status %d", status); - } - - LOG_ERR("Failed to seed SoftDevice RNG, nrf_error %#x", err); -} - static void soc_evt_poll(void *context) { uint32_t err; @@ -81,10 +58,6 @@ static void soc_evt_poll(void *context) LOG_DBG("SoC event: 0x%x", evt_id); } - if (evt_id == NRF_EVT_RAND_SEED_REQUEST) { - softdevice_rng_seed(); - } - /* Forward the event to SoC observers. */ TYPE_SECTION_FOREACH( struct nrf_sdh_soc_evt_observer, nrf_sdh_soc_evt_observers, obs) { diff --git a/subsys/softdevice_handler/rand_seed.c b/subsys/softdevice_handler/rand_seed.c new file mode 100644 index 0000000000..33ee206243 --- /dev/null +++ b/subsys/softdevice_handler/rand_seed.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(nrf_sdh, CONFIG_NRF_SDH_LOG_LEVEL); + +static void on_rand_seed_evt(uint32_t evt, void *ctx) +{ + uint32_t nrf_err; + psa_status_t status; + uint8_t seed[SD_RAND_SEED_SIZE]; + + if (evt != NRF_EVT_RAND_SEED_REQUEST) { + /* Not our business */ + return; + } + + status = cracen_get_trng(seed, sizeof(seed)); + if (status != PSA_SUCCESS) { + LOG_ERR("Failed to generate true random number, psa_status %d", status); + return; + } + + nrf_err = sd_rand_seed_set(seed); + + /* Discard seed immediately */ + memset(seed, 0, sizeof(seed)); + + if (nrf_err != NRF_SUCCESS) { + LOG_ERR("Failed to seed SoftDevice RNG, nrf_error %#x", nrf_err); + return; + } + + LOG_DBG("SoftDevice RNG seeded"); +} + +NRF_SDH_SOC_OBSERVER(rand_seed, on_rand_seed_evt, NULL, 0); From d3cbb66a7aa3bfde6370177c0932381e1eadcb76 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Thu, 18 Sep 2025 17:11:36 +0200 Subject: [PATCH 03/16] sdh: introduce observer priorities (high, lowest, etc.) Introduce an allowed set of priorities for observers, with validity checks. These are: HIGHEST, HIGH, USER, USER_LOW, LOWEST. These could be extended ala SYS_INIT to include a priority within a level, but it seemed a bit overkill for now. Each library or piece of code in the SDK shall have an hardcoded priority, because just changing the priority of one component would break the others. In general, a component's observer must have a lower priority than the observers in its dependencies. Signed-off-by: Emanuele Di Santo --- .../firmware_loader/ble_mcumgr/src/main.c | 2 +- .../libraries/bluetooth/services/ble_cgms.rst | 1 - .../release_notes/release_notes_changelog.rst | 1 + include/bm/bluetooth/ble_adv.h | 8 +-- include/bm/bluetooth/ble_gq.h | 2 +- include/bm/bluetooth/ble_qwr.h | 2 +- include/bm/bluetooth/services/ble_bas.h | 2 +- include/bm/bluetooth/services/ble_cgms.h | 10 +-- include/bm/bluetooth/services/ble_hids.h | 2 +- include/bm/bluetooth/services/ble_hrs.h | 2 +- include/bm/bluetooth/services/ble_lbs.h | 4 +- include/bm/bluetooth/services/ble_nus.h | 2 +- include/bm/softdevice_handler/nrf_sdh.h | 68 +++++++++++++++++-- include/bm/softdevice_handler/nrf_sdh_ble.h | 6 +- include/bm/softdevice_handler/nrf_sdh_soc.h | 6 +- lib/bluetooth/ble_conn_params/att_mtu.c | 2 +- lib/bluetooth/ble_conn_params/conn_param.c | 4 +- lib/bluetooth/ble_conn_params/data_length.c | 2 +- lib/bluetooth/ble_conn_params/phy_mode.c | 2 +- lib/bluetooth/ble_conn_state/Kconfig | 4 -- lib/bluetooth/ble_conn_state/ble_conn_state.c | 2 +- lib/bluetooth/ble_gq/Kconfig | 4 -- lib/bluetooth/ble_qwr/Kconfig | 4 -- lib/bluetooth/peer_manager/Kconfig | 6 -- lib/bluetooth/peer_manager/peer_manager.c | 2 +- samples/bluetooth/ble_cgms/src/main.c | 2 +- .../bluetooth/ble_hids_keyboard/src/main.c | 2 +- samples/bluetooth/ble_hids_mouse/src/main.c | 2 +- samples/bluetooth/ble_hrs/src/main.c | 2 +- samples/bluetooth/ble_lbs/src/main.c | 2 +- samples/bluetooth/ble_nus/src/main.c | 2 +- .../bluetooth/ble_pwr_profiling/src/main.c | 2 +- samples/bluetooth/hello_softdevice/src/main.c | 6 +- .../boot/mcuboot_recovery_entry/src/main.c | 2 +- subsys/bluetooth/services/ble_cgms/Kconfig | 4 -- subsys/bluetooth/services/ble_mcumgr/mcumgr.c | 2 +- subsys/softdevice_handler/nrf_sdh_ble.c | 2 +- subsys/softdevice_handler/nrf_sdh_soc.c | 2 +- subsys/softdevice_handler/rand_seed.c | 2 +- subsys/storage/bm_storage/sd/bm_storage_sd.c | 6 +- .../services/ble_nus/src/unity_test.c | 3 +- 41 files changed, 108 insertions(+), 85 deletions(-) diff --git a/applications/firmware_loader/ble_mcumgr/src/main.c b/applications/firmware_loader/ble_mcumgr/src/main.c index b6f7b9df8f..959377fa9f 100644 --- a/applications/firmware_loader/ble_mcumgr/src/main.c +++ b/applications/firmware_loader/ble_mcumgr/src/main.c @@ -126,7 +126,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) }; } -NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, USER_LOW); /** * @brief BLE advertising event handler diff --git a/doc/nrf-bm/libraries/bluetooth/services/ble_cgms.rst b/doc/nrf-bm/libraries/bluetooth/services/ble_cgms.rst index eafad4201b..136c66d7c6 100644 --- a/doc/nrf-bm/libraries/bluetooth/services/ble_cgms.rst +++ b/doc/nrf-bm/libraries/bluetooth/services/ble_cgms.rst @@ -25,7 +25,6 @@ Set the :kconfig:option:`CONFIG_BLE_CGMS` Kconfig option to enable the service. The CGMS service can be configured by using the following Kconfig options: -* :kconfig:option:`CONFIG_BLE_CGMS_BLE_OBSERVER_PRIO` - Sets the observer priority of the CGMS instance. * :kconfig:option:`CONFIG_BLE_CGMS_DB_RECORDS_MAX` - Sets the maximum number of records that can be stored in the database. Initialization diff --git a/doc/nrf-bm/release_notes/release_notes_changelog.rst b/doc/nrf-bm/release_notes/release_notes_changelog.rst index 12345419e5..49c55e0a26 100644 --- a/doc/nrf-bm/release_notes/release_notes_changelog.rst +++ b/doc/nrf-bm/release_notes/release_notes_changelog.rst @@ -37,6 +37,7 @@ SoftDevice Handler * The :kconfig:option:`NRF_SDH_CLOCK_HFINT_CALIBRATION_INTERVAL` Kconfig option to control the HFINT calibration interval. * The :kconfig:option:`NRF_SDH_CLOCK_HFCLK_LATENCY` Kconfig option to inform the SoftDevice about the ramp-up time of the high-frequency crystal oscillator. * The :kconfig:option:`CONFIG_NRF_SDH_SOC_RAND_SEED` Kconfig option to control whether to automatically respond to SoftDevice random seed requests. + * Priority levels for SoftDevice event observers: HIGHEST, HIGH, USER, USER_LOW, LOWEST. Boards ====== diff --git a/include/bm/bluetooth/ble_adv.h b/include/bm/bluetooth/ble_adv.h index 899102079b..54e3936535 100644 --- a/include/bm/bluetooth/ble_adv.h +++ b/include/bm/bluetooth/ble_adv.h @@ -27,18 +27,12 @@ extern "C" { #endif -/** - * @brief Advertising module BLE event observer priority. - */ -#define BLE_ADV_BLE_OBSERVER_PRIO 0 - /** * @brief Declare an instance of a BLE advertising library. */ #define BLE_ADV_DEF(instance) \ static struct ble_adv instance; \ - NRF_SDH_BLE_OBSERVER(ble_adv_##instance, ble_adv_on_ble_evt, &instance, \ - BLE_ADV_BLE_OBSERVER_PRIO) + NRF_SDH_BLE_OBSERVER(ble_adv_##instance, ble_adv_on_ble_evt, &instance, HIGH) /** * @brief Advertising modes. diff --git a/include/bm/bluetooth/ble_gq.h b/include/bm/bluetooth/ble_gq.h index cf8b908fea..5a54dd3a94 100644 --- a/include/bm/bluetooth/ble_gq.h +++ b/include/bm/bluetooth/ble_gq.h @@ -75,7 +75,7 @@ extern "C" { .data_pool = &CONCAT(_name, _heap), \ }; \ NRF_SDH_BLE_OBSERVER(CONCAT(_name, _obs), ble_gq_on_ble_evt, (void *)&_name, \ - CONFIG_BLE_GQ_OBSERVER_PRIO) + HIGH) /** * @brief Helper macro for initializing connection handle array. Used in @ref BLE_GQ_CUSTOM_DEF. diff --git a/include/bm/bluetooth/ble_qwr.h b/include/bm/bluetooth/ble_qwr.h index 78067d9372..f42fc5bab4 100644 --- a/include/bm/bluetooth/ble_qwr.h +++ b/include/bm/bluetooth/ble_qwr.h @@ -41,7 +41,7 @@ extern "C" { NRF_SDH_BLE_OBSERVER(_name ## _obs, \ ble_qwr_on_ble_evt, \ &_name, \ - CONFIG_BLE_QWR_BLE_OBSERVER_PRIO) + HIGH) /* Error code used by the module to reject prepare write requests on non-registered attributes. */ #define BLE_QWR_REJ_REQUEST_ERR_CODE BLE_GATT_STATUS_ATTERR_APP_BEGIN + 0 diff --git a/include/bm/bluetooth/services/ble_bas.h b/include/bm/bluetooth/services/ble_bas.h index 6bc5764c5c..36693fb401 100644 --- a/include/bm/bluetooth/services/ble_bas.h +++ b/include/bm/bluetooth/services/ble_bas.h @@ -29,7 +29,7 @@ extern "C" { #define BLE_BAS_DEF(_name) \ static struct ble_bas _name; \ extern void ble_bas_on_ble_evt(const ble_evt_t *ble_evt, void *ctx); \ - NRF_SDH_BLE_OBSERVER(_name##_obs, ble_bas_on_ble_evt, &_name, 0) + NRF_SDH_BLE_OBSERVER(_name##_obs, ble_bas_on_ble_evt, &_name, HIGH) /** * @brief Battery service event types. diff --git a/include/bm/bluetooth/services/ble_cgms.h b/include/bm/bluetooth/services/ble_cgms.h index 0853532cdf..a7b017bd1d 100644 --- a/include/bm/bluetooth/services/ble_cgms.h +++ b/include/bm/bluetooth/services/ble_cgms.h @@ -17,14 +17,6 @@ * of the sensor. Session Run Time and Session Start Time can be used to convey timing * information between the sensor and the collector. The Specific Ops Control Point * is used to stop and start monitoring sessions, among other things. - * - * @note The application must register this module as BLE event observer using the - * NRF_SDH_BLE_OBSERVER macro. Example: - * @code - * struct ble_cgms instance; - * NRF_SDH_BLE_OBSERVER(anything, BLE_CGMS_BLE_OBSERVER_PRIO, - * ble_cgms_on_ble_evt, &instance); - * @endcode */ #ifndef BLE_CGMS_H__ @@ -51,7 +43,7 @@ extern "C" { static struct ble_cgms _name; \ NRF_SDH_BLE_OBSERVER(_name ## _obs, \ ble_cgms_on_ble_evt, &_name, \ - CONFIG_BLE_CGMS_BLE_OBSERVER_PRIO) + HIGH) #define OPCODE_LENGTH 1 #define HANDLE_LENGTH 2 diff --git a/include/bm/bluetooth/services/ble_hids.h b/include/bm/bluetooth/services/ble_hids.h index 4dca7b634f..70a978fd0d 100644 --- a/include/bm/bluetooth/services/ble_hids.h +++ b/include/bm/bluetooth/services/ble_hids.h @@ -41,7 +41,7 @@ extern "C" { sizeof(uint32_t) * BYTES_TO_WORDS(BLE_HIDS_LINK_CTX_SIZE), \ }, \ }; \ - NRF_SDH_BLE_OBSERVER(_name##_obs, ble_hids_on_ble_evt, &_name, 0) + NRF_SDH_BLE_OBSERVER(_name##_obs, ble_hids_on_ble_evt, &_name, HIGH) /** * @brief HID boot keyboard input report maximum size, in bytes. diff --git a/include/bm/bluetooth/services/ble_hrs.h b/include/bm/bluetooth/services/ble_hrs.h index 99d28e74f9..58943ceb4c 100644 --- a/include/bm/bluetooth/services/ble_hrs.h +++ b/include/bm/bluetooth/services/ble_hrs.h @@ -30,7 +30,7 @@ extern "C" { #define BLE_HRS_DEF(_name) \ static struct ble_hrs _name; \ extern void ble_hrs_on_ble_evt(const ble_evt_t *ble_evt, void *ctx); \ - NRF_SDH_BLE_OBSERVER(_name##_obs, ble_hrs_on_ble_evt, &_name, 0) + NRF_SDH_BLE_OBSERVER(_name##_obs, ble_hrs_on_ble_evt, &_name, HIGH) /** * @defgroup BLE_HRS_BODY_SENSOR_LOCATION HRS Body sensor location diff --git a/include/bm/bluetooth/services/ble_lbs.h b/include/bm/bluetooth/services/ble_lbs.h index 6b2ce77db7..6094d2bee4 100644 --- a/include/bm/bluetooth/services/ble_lbs.h +++ b/include/bm/bluetooth/services/ble_lbs.h @@ -20,8 +20,6 @@ extern "C" { #endif -#define BLE_LBS_BLE_OBSERVER_PRIO 2 - #define BLE_UUID_LBS_BASE { 0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, \ 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00 } #define BLE_UUID_LBS_SERVICE 0x1523 @@ -39,7 +37,7 @@ struct ble_lbs; #define BLE_LBS_DEF(_name) \ static struct ble_lbs _name; \ extern void ble_lbs_on_ble_evt(const ble_evt_t *ble_evt, void *lbs_instance); \ - NRF_SDH_BLE_OBSERVER(_name ## _obs, ble_lbs_on_ble_evt, &_name, BLE_LBS_BLE_OBSERVER_PRIO) + NRF_SDH_BLE_OBSERVER(_name ## _obs, ble_lbs_on_ble_evt, &_name, HIGH) enum ble_lbs_evt_type { BLE_LBS_EVT_LED_WRITE, diff --git a/include/bm/bluetooth/services/ble_nus.h b/include/bm/bluetooth/services/ble_nus.h index 663c2435bf..5cef2159dd 100644 --- a/include/bm/bluetooth/services/ble_nus.h +++ b/include/bm/bluetooth/services/ble_nus.h @@ -48,7 +48,7 @@ void ble_nus_on_ble_evt(ble_evt_t const *ble_evt, void *context); NRF_SDH_BLE_OBSERVER(_name ## _obs, \ ble_nus_on_ble_evt, \ &_name, \ - 0) + HIGH) #define OPCODE_LENGTH 1 #define HANDLE_LENGTH 2 diff --git a/include/bm/softdevice_handler/nrf_sdh.h b/include/bm/softdevice_handler/nrf_sdh.h index 9a73809971..498fccbef4 100644 --- a/include/bm/softdevice_handler/nrf_sdh.h +++ b/include/bm/softdevice_handler/nrf_sdh.h @@ -15,12 +15,65 @@ #define NRF_SDH_H__ #include +#include +#include #include #ifdef __cplusplus extern "C" { #endif +/** + * @defgroup softdevice_observer_prio SoftDevice event observer priority levels + * + * A SoftDevice observer has a defined priority, which determines the order with + * which the observer receives relevant events compared to other observers. + * + * Five priority levels are defined: highest, high, user, user low, lowest. + * These can be selected using the tokens HIGHEST, HIGH, USER, USER_LOW, and LOWEST respectively. + * + * In general, an observer priority must be defined in such a way that an observer + * has a lower priority than that of other observers (libraries, etc.) it depends on. + * + * @{ + */ + +/* Helper macros to check for equality */ + +#define H_NRF_SDH_OBSERVER_PRIO_HIGHEST_HIGHEST 1 +#define H_NRF_SDH_OBSERVER_PRIO_HIGH_HIGH 1 +#define H_NRF_SDH_OBSERVER_PRIO_USER_USER 1 +#define H_NRF_SDH_OBSERVER_PRIO_USER_LOW_USER_LOW 1 +#define H_NRF_SDH_OBSERVER_PRIO_LOWEST_LOWEST 1 + +/** + * @brief Utility macro to check for observer priority validity. + * @internal + */ +#define PRIO_LEVEL_IS_VALID(level) \ + COND_CODE_1(H_NRF_SDH_OBSERVER_PRIO_HIGHEST_##level, (), \ + (COND_CODE_1(H_NRF_SDH_OBSERVER_PRIO_HIGH_##level, (), \ + (COND_CODE_1(H_NRF_SDH_OBSERVER_PRIO_USER_##level, (), \ + (COND_CODE_1(H_NRF_SDH_OBSERVER_PRIO_USER_LOW_##level, (), \ + (COND_CODE_1(H_NRF_SDH_OBSERVER_PRIO_LOWEST_##level, (), \ + (BUILD_ASSERT(0, "Invalid priority level"))))))))))) + +/** + * @brief Utility macro to convert a priority token to its numerical value + * @internal + */ +#define PRIO_LEVEL_ORD(level) \ + COND_CODE_1(H_NRF_SDH_OBSERVER_PRIO_HIGHEST_##level, (0), \ + (COND_CODE_1(H_NRF_SDH_OBSERVER_PRIO_HIGH_##level, (1), \ + (COND_CODE_1(H_NRF_SDH_OBSERVER_PRIO_USER_##level, (2), \ + (COND_CODE_1(H_NRF_SDH_OBSERVER_PRIO_USER_LOW_##level, (3), \ + (COND_CODE_1(H_NRF_SDH_OBSERVER_PRIO_LOWEST_##level, (4), \ + (BUILD_ASSERT(0, "Invalid priority level"))))))))))) + +/** + * @} + */ + /** * @brief SoftDevice Handler state requests. */ @@ -73,12 +126,13 @@ struct nrf_sdh_state_req_observer { * @param _handler State request handler. * @param _ctx A context passed to the state request handler. * @param _prio Priority of the observer's event handler. - * The lower the number, the higher the priority. + * Allowed input: `HIGHEST`, `HIGH`, `USER`, `USER_LOW`, `LOWEST`. */ #define NRF_SDH_STATE_REQ_OBSERVER(_observer, _handler, _ctx, _prio) \ + PRIO_LEVEL_IS_VALID(_prio); \ static bool _handler(enum nrf_sdh_state_req, void *); \ const TYPE_SECTION_ITERABLE(struct nrf_sdh_state_req_observer, _observer, \ - nrf_sdh_state_req_observers, _prio) = { \ + nrf_sdh_state_req_observers, PRIO_LEVEL_ORD(_prio)) = { \ .handler = _handler, \ .context = _ctx, \ }; @@ -140,12 +194,13 @@ struct nrf_sdh_state_evt_observer { * @param _handler State request handler. * @param _ctx A context passed to the state request handler. * @param _prio Priority of the observer's event handler. - * The lower the number, the higher the priority. + * Allowed input: `HIGHEST`, `HIGH`, `USER`, `USER_LOW`, `LOWEST`. */ #define NRF_SDH_STATE_EVT_OBSERVER(_observer, _handler, _ctx, _prio) \ + PRIO_LEVEL_IS_VALID(_prio); \ static void _handler(enum nrf_sdh_state_evt, void *); \ const TYPE_SECTION_ITERABLE(struct nrf_sdh_state_evt_observer, _observer, \ - nrf_sdh_state_evt_observers, _prio) = { \ + nrf_sdh_state_evt_observers, PRIO_LEVEL_ORD(_prio)) = { \ .handler = _handler, \ .context = _ctx, \ }; @@ -180,12 +235,13 @@ struct nrf_sdh_stack_evt_observer { * @param _handler Stack event handler. * @param _ctx A context passed to the state request handler. * @param _prio Priority of the observer's event handler. - * The lower the number, the higher the priority. + * Allowed input: `HIGHEST`, `HIGH`, `USER`, `USER_LOW`, `LOWEST`. */ #define NRF_SDH_STACK_EVT_OBSERVER(_observer, _handler, _ctx, _prio) \ + PRIO_LEVEL_IS_VALID(_prio); \ static void _handler(void *); \ const TYPE_SECTION_ITERABLE(struct nrf_sdh_stack_evt_observer, _observer, \ - nrf_sdh_stack_evt_observers, _prio) = { \ + nrf_sdh_stack_evt_observers, PRIO_LEVEL_ORD(_prio)) = { \ .handler = _handler, \ .context = _ctx, \ }; diff --git a/include/bm/softdevice_handler/nrf_sdh_ble.h b/include/bm/softdevice_handler/nrf_sdh_ble.h index 119f7cdab3..33485ee718 100644 --- a/include/bm/softdevice_handler/nrf_sdh_ble.h +++ b/include/bm/softdevice_handler/nrf_sdh_ble.h @@ -17,6 +17,7 @@ #include #include +#include #include #ifdef __cplusplus @@ -54,11 +55,12 @@ struct nrf_sdh_ble_evt_observer { * @param _handler State request handler. * @param _ctx A context passed to the state request handler. * @param _prio Priority of the observer's event handler. - * The lower the number, the higher the priority. + * Allowed input: `HIGHEST`, `HIGH`, `USER`, `USER_LOW`, `LOWEST`. */ #define NRF_SDH_BLE_OBSERVER(_observer, _handler, _ctx, _prio) \ + PRIO_LEVEL_IS_VALID(_prio); \ static const TYPE_SECTION_ITERABLE(struct nrf_sdh_ble_evt_observer, _observer, \ - nrf_sdh_ble_evt_observers, _prio) = { \ + nrf_sdh_ble_evt_observers, PRIO_LEVEL_ORD(_prio)) = { \ .handler = _handler, \ .context = _ctx, \ }; diff --git a/include/bm/softdevice_handler/nrf_sdh_soc.h b/include/bm/softdevice_handler/nrf_sdh_soc.h index 875b460a12..046272ddd3 100644 --- a/include/bm/softdevice_handler/nrf_sdh_soc.h +++ b/include/bm/softdevice_handler/nrf_sdh_soc.h @@ -16,6 +16,7 @@ #define NRF_SDH_SOC_H__ #include +#include #include #ifdef __cplusplus @@ -48,11 +49,12 @@ struct nrf_sdh_soc_evt_observer { * @param _handler State request handler. * @param _ctx A context passed to the state request handler. * @param _prio Priority of the observer's event handler. - * The lower the number, the higher the priority. + * Allowed input: `HIGHEST`, `HIGH`, `USER`, `USER_LOW`, `LOWEST`. */ #define NRF_SDH_SOC_OBSERVER(_observer, _handler, _ctx, _prio) \ + PRIO_LEVEL_IS_VALID(_prio); \ const TYPE_SECTION_ITERABLE(struct nrf_sdh_soc_evt_observer, _observer, \ - nrf_sdh_soc_evt_observers, _prio) = { \ + nrf_sdh_soc_evt_observers, PRIO_LEVEL_ORD(_prio)) = { \ .handler = _handler, \ .context = _ctx, \ }; diff --git a/lib/bluetooth/ble_conn_params/att_mtu.c b/lib/bluetooth/ble_conn_params/att_mtu.c index 6f72c020fa..e187af0c25 100644 --- a/lib/bluetooth/ble_conn_params/att_mtu.c +++ b/lib/bluetooth/ble_conn_params/att_mtu.c @@ -159,7 +159,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) mtu_exchange_request(conn_handle, idx); } } -NRF_SDH_BLE_OBSERVER(ble_observer, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(ble_observer, on_ble_evt, NULL, HIGH); int ble_conn_params_att_mtu_set(uint16_t conn_handle, uint16_t att_mtu) { diff --git a/lib/bluetooth/ble_conn_params/conn_param.c b/lib/bluetooth/ble_conn_params/conn_param.c index 5094e299f0..a3985f322b 100644 --- a/lib/bluetooth/ble_conn_params/conn_param.c +++ b/lib/bluetooth/ble_conn_params/conn_param.c @@ -167,7 +167,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) break; } } -NRF_SDH_BLE_OBSERVER(ble_observer, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(ble_observer, on_ble_evt, NULL, HIGH); static void on_state_evt(enum nrf_sdh_state_evt evt, void *ctx) { @@ -188,7 +188,7 @@ static void on_state_evt(enum nrf_sdh_state_evt evt, void *ctx) ppcp.slave_latency, ppcp.conn_sup_timeout); } -NRF_SDH_STATE_EVT_OBSERVER(ble_conn_params_sdh_state_observer, on_state_evt, NULL, 0); +NRF_SDH_STATE_EVT_OBSERVER(ble_conn_params_sdh_state_observer, on_state_evt, NULL, HIGH); int ble_conn_params_override(uint16_t conn_handle, const ble_gap_conn_params_t *conn_params) { diff --git a/lib/bluetooth/ble_conn_params/data_length.c b/lib/bluetooth/ble_conn_params/data_length.c index cb28618f81..767ef9c787 100644 --- a/lib/bluetooth/ble_conn_params/data_length.c +++ b/lib/bluetooth/ble_conn_params/data_length.c @@ -185,7 +185,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) data_length_update(conn_handle, idx); } } -NRF_SDH_BLE_OBSERVER(ble_observer, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(ble_observer, on_ble_evt, NULL, HIGH); int ble_conn_params_data_length_set(uint16_t conn_handle, struct ble_conn_params_data_length dl) { diff --git a/lib/bluetooth/ble_conn_params/phy_mode.c b/lib/bluetooth/ble_conn_params/phy_mode.c index 0b305be86e..9cbb386f2c 100644 --- a/lib/bluetooth/ble_conn_params/phy_mode.c +++ b/lib/bluetooth/ble_conn_params/phy_mode.c @@ -156,7 +156,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) radio_phy_mode_update(conn_handle, idx); } } -NRF_SDH_BLE_OBSERVER(ble_observer, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(ble_observer, on_ble_evt, NULL, HIGH); int ble_conn_params_phy_radio_mode_set(uint16_t conn_handle, ble_gap_phys_t phy_pref) { diff --git a/lib/bluetooth/ble_conn_state/Kconfig b/lib/bluetooth/ble_conn_state/Kconfig index 80b949960f..ca2489ecec 100644 --- a/lib/bluetooth/ble_conn_state/Kconfig +++ b/lib/bluetooth/ble_conn_state/Kconfig @@ -18,10 +18,6 @@ config BLE_CONN_STATE_USER_FLAG_COUNT help The number of available user flags. -config BLE_CONN_STATE_BLE_OBSERVER_PRIO - int "BLE observer priority" - default 0 - module=BLE_CONN_STATE module-str=BLE Connection state source "${ZEPHYR_BASE}/subsys/logging/Kconfig.template.log_config" diff --git a/lib/bluetooth/ble_conn_state/ble_conn_state.c b/lib/bluetooth/ble_conn_state/ble_conn_state.c index 0f00376f6c..38bc6ca4bf 100644 --- a/lib/bluetooth/ble_conn_state/ble_conn_state.c +++ b/lib/bluetooth/ble_conn_state/ble_conn_state.c @@ -423,4 +423,4 @@ static void ble_evt_handler(ble_evt_t const *ble_evt, void *ctx) } NRF_SDH_BLE_OBSERVER(ble_evt_observer, ble_evt_handler, NULL, - CONFIG_BLE_CONN_STATE_BLE_OBSERVER_PRIO); + HIGHEST); diff --git a/lib/bluetooth/ble_gq/Kconfig b/lib/bluetooth/ble_gq/Kconfig index 4584a12248..4f7d64a96d 100644 --- a/lib/bluetooth/ble_gq/Kconfig +++ b/lib/bluetooth/ble_gq/Kconfig @@ -30,10 +30,6 @@ config BLE_GQ_HEAP_SIZE Default value used for GATT queue instances defined using BLE_GQ_DEF. Sets the heap size for storing additional data that can be of variable size. -config BLE_GQ_OBSERVER_PRIO - int "SoftDevice event observer priority" - default 0 - module=BLE_GQ module-str=BLE GATT Queue source "$(ZEPHYR_BASE)/subsys/logging/Kconfig.template.log_config" diff --git a/lib/bluetooth/ble_qwr/Kconfig b/lib/bluetooth/ble_qwr/Kconfig index c65997e7a9..8c943ff30d 100644 --- a/lib/bluetooth/ble_qwr/Kconfig +++ b/lib/bluetooth/ble_qwr/Kconfig @@ -14,10 +14,6 @@ config BLE_QWR_MAX_ATTR help Maximum queued writes attributes -config BLE_QWR_BLE_OBSERVER_PRIO - int "BLE observer priority" - default 2 - module=BLE_QWR module-str=BLE QWR source "$(ZEPHYR_BASE)/subsys/logging/Kconfig.template.log_config" diff --git a/lib/bluetooth/peer_manager/Kconfig b/lib/bluetooth/peer_manager/Kconfig index a068928d32..dd09f517fa 100644 --- a/lib/bluetooth/peer_manager/Kconfig +++ b/lib/bluetooth/peer_manager/Kconfig @@ -21,12 +21,6 @@ config PM_BM_ZMS_SECTOR_SIZE int "BM_ZMS sector size" default 1024 -config PM_BLE_OBSERVER_PRIO - int "BLE events priority" - default 1 - help - Priority with which BLE events are dispatched to the Peer Manager module. - config PM_MAX_REGISTRANTS int "Maximum number of event handlers that can be registered" default 3 diff --git a/lib/bluetooth/peer_manager/peer_manager.c b/lib/bluetooth/peer_manager/peer_manager.c index e734b3ca4e..acbe7128cd 100644 --- a/lib/bluetooth/peer_manager/peer_manager.c +++ b/lib/bluetooth/peer_manager/peer_manager.c @@ -310,7 +310,7 @@ static void ble_evt_handler(const ble_evt_t *ble_evt, void *context) gcm_ble_evt_handler(ble_evt); } -NRF_SDH_BLE_OBSERVER(ble_evt_observer, ble_evt_handler, NULL, CONFIG_PM_BLE_OBSERVER_PRIO); +NRF_SDH_BLE_OBSERVER(ble_evt_observer, ble_evt_handler, NULL, HIGH); /** @brief Function for resetting the internal state of this module. */ static void internal_state_reset(void) diff --git a/samples/bluetooth/ble_cgms/src/main.c b/samples/bluetooth/ble_cgms/src/main.c index 68e08a1829..9ce84ce187 100644 --- a/samples/bluetooth/ble_cgms/src/main.c +++ b/samples/bluetooth/ble_cgms/src/main.c @@ -508,7 +508,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) } } -NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, USER_LOW); /** * @brief Function for handling advertising events. diff --git a/samples/bluetooth/ble_hids_keyboard/src/main.c b/samples/bluetooth/ble_hids_keyboard/src/main.c index c1bc881125..df8c4eec3e 100644 --- a/samples/bluetooth/ble_hids_keyboard/src/main.c +++ b/samples/bluetooth/ble_hids_keyboard/src/main.c @@ -242,7 +242,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) break; } } -NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, USER_LOW); static void ble_adv_evt_handler(struct ble_adv *ble_adv, const struct ble_adv_evt *evt) { diff --git a/samples/bluetooth/ble_hids_mouse/src/main.c b/samples/bluetooth/ble_hids_mouse/src/main.c index 9fe623c0c6..594a81281c 100644 --- a/samples/bluetooth/ble_hids_mouse/src/main.c +++ b/samples/bluetooth/ble_hids_mouse/src/main.c @@ -167,7 +167,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) break; } } -NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, USER_LOW); static void ble_adv_evt_handler(struct ble_adv *ble_adv, const struct ble_adv_evt *evt) { diff --git a/samples/bluetooth/ble_hrs/src/main.c b/samples/bluetooth/ble_hrs/src/main.c index 7b31f2320d..2294ae1ea4 100644 --- a/samples/bluetooth/ble_hrs/src/main.c +++ b/samples/bluetooth/ble_hrs/src/main.c @@ -252,7 +252,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) break; } } -NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, USER_LOW); void on_conn_params_evt(const struct ble_conn_params_evt *evt) { diff --git a/samples/bluetooth/ble_lbs/src/main.c b/samples/bluetooth/ble_lbs/src/main.c index 9cb19d8c57..68730fa532 100644 --- a/samples/bluetooth/ble_lbs/src/main.c +++ b/samples/bluetooth/ble_lbs/src/main.c @@ -72,7 +72,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) break; } } -NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, USER_LOW); static void ble_adv_evt_handler(struct ble_adv *adv, const struct ble_adv_evt *adv_evt) { diff --git a/samples/bluetooth/ble_nus/src/main.c b/samples/bluetooth/ble_nus/src/main.c index b4109e67d5..400f899334 100644 --- a/samples/bluetooth/ble_nus/src/main.c +++ b/samples/bluetooth/ble_nus/src/main.c @@ -238,7 +238,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) break; } } -NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, USER_LOW); /** * @brief Connection parameters event handler diff --git a/samples/bluetooth/ble_pwr_profiling/src/main.c b/samples/bluetooth/ble_pwr_profiling/src/main.c index 8c608f6fe2..150ff0b585 100644 --- a/samples/bluetooth/ble_pwr_profiling/src/main.c +++ b/samples/bluetooth/ble_pwr_profiling/src/main.c @@ -356,7 +356,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) break; } } -NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, USER_LOW); static void on_conn_params_evt(const struct ble_conn_params_evt *evt) { diff --git a/samples/bluetooth/hello_softdevice/src/main.c b/samples/bluetooth/hello_softdevice/src/main.c index a2be32e03a..023012dcea 100644 --- a/samples/bluetooth/hello_softdevice/src/main.c +++ b/samples/bluetooth/hello_softdevice/src/main.c @@ -18,19 +18,19 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) { LOG_INF("BLE event %d", evt->header.evt_id); } -NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, USER_LOW); static void on_soc_evt(uint32_t evt, void *ctx) { LOG_INF("SoC event"); } -NRF_SDH_SOC_OBSERVER(sdh_soc, on_soc_evt, NULL, 0); +NRF_SDH_SOC_OBSERVER(sdh_soc, on_soc_evt, NULL, USER_LOW); static void on_state_change(enum nrf_sdh_state_evt state, void *ctx) { LOG_INF("SoftDevice state has changed to %d", state); } -NRF_SDH_STATE_EVT_OBSERVER(sdh_state, on_state_change, NULL, 0); +NRF_SDH_STATE_EVT_OBSERVER(sdh_state, on_state_change, NULL, USER_LOW); int main(void) { diff --git a/samples/boot/mcuboot_recovery_entry/src/main.c b/samples/boot/mcuboot_recovery_entry/src/main.c index 41beec99ac..120c392c4e 100644 --- a/samples/boot/mcuboot_recovery_entry/src/main.c +++ b/samples/boot/mcuboot_recovery_entry/src/main.c @@ -119,7 +119,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) }; } -NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, 0); +NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, NULL, USER_LOW); static void ble_adv_evt_handler(struct ble_adv *adv, const struct ble_adv_evt *adv_evt) { diff --git a/subsys/bluetooth/services/ble_cgms/Kconfig b/subsys/bluetooth/services/ble_cgms/Kconfig index 8dabff42c4..d687dafdc8 100644 --- a/subsys/bluetooth/services/ble_cgms/Kconfig +++ b/subsys/bluetooth/services/ble_cgms/Kconfig @@ -9,10 +9,6 @@ menuconfig BLE_CGMS if BLE_CGMS -config BLE_CGMS_BLE_OBSERVER_PRIO - int "SoftDevice event observer priority" - default 0 - config BLE_CGMS_DB_RECORDS_MAX int "Number of records that can be stored in the database" default 100 diff --git a/subsys/bluetooth/services/ble_mcumgr/mcumgr.c b/subsys/bluetooth/services/ble_mcumgr/mcumgr.c index 31f313ac86..a9d7a7c90c 100644 --- a/subsys/bluetooth/services/ble_mcumgr/mcumgr.c +++ b/subsys/bluetooth/services/ble_mcumgr/mcumgr.c @@ -372,7 +372,7 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) }; } -NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, &ble_mcumgr, 0); +NRF_SDH_BLE_OBSERVER(sdh_ble, on_ble_evt, &ble_mcumgr, HIGH); int ble_mcumgr_init(void) { diff --git a/subsys/softdevice_handler/nrf_sdh_ble.c b/subsys/softdevice_handler/nrf_sdh_ble.c index cb097cffd2..28655eed3b 100644 --- a/subsys/softdevice_handler/nrf_sdh_ble.c +++ b/subsys/softdevice_handler/nrf_sdh_ble.c @@ -330,4 +330,4 @@ static void ble_evt_poll(void *context) } /* Listen to SoftDevice events */ -NRF_SDH_STACK_EVT_OBSERVER(ble_evt_obs, ble_evt_poll, NULL, 0); +NRF_SDH_STACK_EVT_OBSERVER(ble_evt_obs, ble_evt_poll, NULL, HIGH); diff --git a/subsys/softdevice_handler/nrf_sdh_soc.c b/subsys/softdevice_handler/nrf_sdh_soc.c index 3ba59b64ae..e7c267c14a 100644 --- a/subsys/softdevice_handler/nrf_sdh_soc.c +++ b/subsys/softdevice_handler/nrf_sdh_soc.c @@ -70,4 +70,4 @@ static void soc_evt_poll(void *context) } /* Listen to SoftDevice events */ -NRF_SDH_STACK_EVT_OBSERVER(soc_evt_obs, soc_evt_poll, NULL, 0); +NRF_SDH_STACK_EVT_OBSERVER(soc_evt_obs, soc_evt_poll, NULL, HIGHEST); diff --git a/subsys/softdevice_handler/rand_seed.c b/subsys/softdevice_handler/rand_seed.c index 33ee206243..52a78b7f31 100644 --- a/subsys/softdevice_handler/rand_seed.c +++ b/subsys/softdevice_handler/rand_seed.c @@ -42,4 +42,4 @@ static void on_rand_seed_evt(uint32_t evt, void *ctx) LOG_DBG("SoftDevice RNG seeded"); } -NRF_SDH_SOC_OBSERVER(rand_seed, on_rand_seed_evt, NULL, 0); +NRF_SDH_SOC_OBSERVER(rand_seed, on_rand_seed_evt, NULL, HIGH); diff --git a/subsys/storage/bm_storage/sd/bm_storage_sd.c b/subsys/storage/bm_storage/sd/bm_storage_sd.c index b3170708b2..c28400b0a8 100644 --- a/subsys/storage/bm_storage/sd/bm_storage_sd.c +++ b/subsys/storage/bm_storage/sd/bm_storage_sd.c @@ -70,9 +70,9 @@ static void on_state_evt_change(enum nrf_sdh_state_evt evt, void *ctx); RING_BUF_DECLARE(sd_fifo, CONFIG_BM_STORAGE_BACKEND_SD_QUEUE_SIZE * sizeof(struct bm_storage_sd_op)); -NRF_SDH_SOC_OBSERVER(sdh_soc, on_soc_evt, NULL, 0); -NRF_SDH_STATE_REQ_OBSERVER(sdh_state_req, on_state_req_change, NULL, 0); -NRF_SDH_STATE_EVT_OBSERVER(sdh_state_evt, on_state_evt_change, NULL, 0); +NRF_SDH_SOC_OBSERVER(sdh_soc, on_soc_evt, NULL, HIGH); +NRF_SDH_STATE_REQ_OBSERVER(sdh_state_req, on_state_req_change, NULL, HIGH); +NRF_SDH_STATE_EVT_OBSERVER(sdh_state_evt, on_state_evt_change, NULL, HIGH); static inline bool is_aligned32(uint32_t addr) { diff --git a/tests/subsys/bluetooth/services/ble_nus/src/unity_test.c b/tests/subsys/bluetooth/services/ble_nus/src/unity_test.c index 19cfdc04a7..18b98c4f7e 100644 --- a/tests/subsys/bluetooth/services/ble_nus/src/unity_test.c +++ b/tests/subsys/bluetooth/services/ble_nus/src/unity_test.c @@ -16,7 +16,8 @@ #include "cmock_ble.h" #include "cmock_nrf_sdh_ble.h" -BLE_NUS_DEF(ble_nus); +static struct ble_nus ble_nus; + uint16_t test_case_conn_handle = 0x1000; bool evt_handler_called; struct ble_nus_client_context *last_link_ctx; From 39021b3e77306e5a1827968571d799a27c699e4d Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Mon, 22 Sep 2025 16:19:15 +0200 Subject: [PATCH 04/16] sdh: ble: add GATTS and GATTC event strings to the table Add GATTS and GATTC event strings to the table. Renamed gap_evt_tostr() to ble_evt_tostr() to reflect that it now can print all BLE events. Signed-off-by: Emanuele Di Santo --- subsys/softdevice_handler/nrf_sdh_ble.c | 52 ++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/subsys/softdevice_handler/nrf_sdh_ble.c b/subsys/softdevice_handler/nrf_sdh_ble.c index 28655eed3b..0df8530cc4 100644 --- a/subsys/softdevice_handler/nrf_sdh_ble.c +++ b/subsys/softdevice_handler/nrf_sdh_ble.c @@ -15,9 +15,10 @@ LOG_MODULE_DECLARE(nrf_sdh, CONFIG_NRF_SDH_LOG_LEVEL); -const char *gap_evt_tostr(int evt) +const char *ble_evt_tostr(int evt) { switch (evt) { + /* GAP */ case BLE_GAP_EVT_CONNECTED: return "BLE_GAP_EVT_CONNECTED"; case BLE_GAP_EVT_DISCONNECTED: @@ -70,6 +71,53 @@ const char *gap_evt_tostr(int evt) #endif case BLE_GAP_EVT_ADV_SET_TERMINATED: return "BLE_GAP_EVT_ADV_SET_TERMINATED"; + + /* GATTS */ + case BLE_GATTS_EVT_WRITE: + return "BLE_GATTS_EVT_WRITE"; + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + return "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST"; + case BLE_GATTS_EVT_SYS_ATTR_MISSING: + return "BLE_GATTS_EVT_SYS_ATTR_MISSING"; + case BLE_GATTS_EVT_HVC: + return "BLE_GATTS_EVT_HVC"; + case BLE_GATTS_EVT_SC_CONFIRM: + return "BLE_GATTS_EVT_SC_CONFIRM"; + case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: + return "BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST"; + case BLE_GATTS_EVT_TIMEOUT: + return "BLE_GATTS_EVT_TIMEOUT"; + case BLE_GATTS_EVT_HVN_TX_COMPLETE: + return "BLE_GATTS_EVT_HVN_TX_COMPLETE"; + + /* GATTC */ + case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: + return "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP"; + case BLE_GATTC_EVT_REL_DISC_RSP: + return "BLE_GATTC_EVT_REL_DISC_RSP"; + case BLE_GATTC_EVT_CHAR_DISC_RSP: + return "BLE_GATTC_EVT_CHAR_DISC_RSP"; + case BLE_GATTC_EVT_DESC_DISC_RSP: + return "BLE_GATTC_EVT_DESC_DISC_RSP"; + case BLE_GATTC_EVT_ATTR_INFO_DISC_RSP: + return "BLE_GATTC_EVT_ATTR_INFO_DISC_RSP"; + case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP: + return "BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP"; + case BLE_GATTC_EVT_READ_RSP: + return "BLE_GATTC_EVT_READ_RSP"; + case BLE_GATTC_EVT_CHAR_VALS_READ_RSP: + return "BLE_GATTC_EVT_CHAR_VALS_READ_RSP"; + case BLE_GATTC_EVT_WRITE_RSP: + return "BLE_GATTC_EVT_WRITE_RSP"; + case BLE_GATTC_EVT_HVX: + return "BLE_GATTC_EVT_HVX"; + case BLE_GATTC_EVT_EXCHANGE_MTU_RSP: + return "BLE_GATTC_EVT_EXCHANGE_MTU_RSP"; + case BLE_GATTC_EVT_TIMEOUT: + return "BLE_GATTC_EVT_TIMEOUT"; + case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE: + return "BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE"; + default: return "unknown"; } @@ -304,7 +352,7 @@ static void ble_evt_poll(void *context) } if (IS_ENABLED(CONFIG_NRF_SDH_STR_TABLES)) { - LOG_DBG("BLE event: %s", gap_evt_tostr(ble_evt->header.evt_id)); + LOG_DBG("BLE event: %s", ble_evt_tostr(ble_evt->header.evt_id)); } else { LOG_DBG("BLE event: %#x", ble_evt->header.evt_id); } From 55eec9e9deaf0c84fc289f958d408b2635fe7ab7 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Mon, 22 Sep 2025 16:35:10 +0200 Subject: [PATCH 05/16] sdh: add a menu for clock configuration Add a Kconfig menu for clock configuration, to make the menu nicer. Signed-off-by: Emanuele Di Santo --- subsys/softdevice_handler/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/softdevice_handler/Kconfig b/subsys/softdevice_handler/Kconfig index c9c0b0a91f..400feada30 100644 --- a/subsys/softdevice_handler/Kconfig +++ b/subsys/softdevice_handler/Kconfig @@ -43,6 +43,8 @@ config NRF_SDH_DISPATCH_MODEL default 1 if NRF_SDH_DISPATCH_MODEL_SCHED default 2 if NRF_SDH_DISPATCH_MODEL_POLL +menu "Clock configuration" + config NRF_SDH_CLOCK_LF_SRC int "LF Clock" default 1 @@ -69,6 +71,8 @@ config NRF_SDH_CLOCK_HFCLK_LATENCY range 0 $(UINT16_MAX) default 1500 +endmenu + if NRF_SDH_BLE config NRF_SDH_BLE_CONN_TAG From 1580c2ef17768fe6cd2b113d825cb3ed3bbd1121 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Mon, 22 Sep 2025 16:35:25 +0200 Subject: [PATCH 06/16] sdh: add a menu for BLE configuration Add a Kconfig menu for BLE configuration, to make the menu nicer. Signed-off-by: Emanuele Di Santo --- subsys/softdevice_handler/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/softdevice_handler/Kconfig b/subsys/softdevice_handler/Kconfig index 400feada30..5ee2b74ac1 100644 --- a/subsys/softdevice_handler/Kconfig +++ b/subsys/softdevice_handler/Kconfig @@ -75,6 +75,8 @@ endmenu if NRF_SDH_BLE +menu "Default BLE configuration" + config NRF_SDH_BLE_CONN_TAG int "Connection tag" range 1 255 @@ -122,6 +124,8 @@ config NRF_SDH_BLE_VS_UUID_COUNT config NRF_SDH_BLE_SERVICE_CHANGED bool "Include the Service Changed characteristic in the Attribute Table" +endmenu + endif # NRF_SDH_BLE config NRF_SDH_SOC_RAND_SEED From b1bf6724a33f9296d45a39f3b7cf354b1b5047f7 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Mon, 22 Sep 2025 17:25:28 +0200 Subject: [PATCH 07/16] sdh: ble: export nrf_sdh_ble_evt_tostr() and nrf_sdh_soc_evt_tostr() Rework the functions in nrf_sdh_ble and nrf_sdh_soc that mapped BLE and SOC events to their stringified version to make them public and align their names. Instead of printing "unknown" if the event is not known, default to printing its numerical value in hexadecimal. That is also the default behavior if CONFIG_NRF_SDH_STR_TABLES is unset, and the table is not compiled. This is better than toggling the availability of the whole function, because we avoid conditional compilation around it. Signed-off-by: Emanuele Di Santo --- .../release_notes/release_notes_changelog.rst | 2 + include/bm/softdevice_handler/nrf_sdh_ble.h | 11 +++++ include/bm/softdevice_handler/nrf_sdh_soc.h | 11 +++++ subsys/softdevice_handler/Kconfig | 6 +-- subsys/softdevice_handler/nrf_sdh_ble.c | 23 ++++++----- subsys/softdevice_handler/nrf_sdh_soc.c | 40 +++++++++++-------- 6 files changed, 64 insertions(+), 29 deletions(-) diff --git a/doc/nrf-bm/release_notes/release_notes_changelog.rst b/doc/nrf-bm/release_notes/release_notes_changelog.rst index 49c55e0a26..868326caa9 100644 --- a/doc/nrf-bm/release_notes/release_notes_changelog.rst +++ b/doc/nrf-bm/release_notes/release_notes_changelog.rst @@ -38,6 +38,8 @@ SoftDevice Handler * The :kconfig:option:`NRF_SDH_CLOCK_HFCLK_LATENCY` Kconfig option to inform the SoftDevice about the ramp-up time of the high-frequency crystal oscillator. * The :kconfig:option:`CONFIG_NRF_SDH_SOC_RAND_SEED` Kconfig option to control whether to automatically respond to SoftDevice random seed requests. * Priority levels for SoftDevice event observers: HIGHEST, HIGH, USER, USER_LOW, LOWEST. + * The :c:func:`nrf_sdh_ble_evt_to_str` function to stringify a BLE event. + * The :c:func:`nrf_sdh_soc_evt_to_str` function to stringify a SoC event. Boards ====== diff --git a/include/bm/softdevice_handler/nrf_sdh_ble.h b/include/bm/softdevice_handler/nrf_sdh_ble.h index 33485ee718..92073d37d4 100644 --- a/include/bm/softdevice_handler/nrf_sdh_ble.h +++ b/include/bm/softdevice_handler/nrf_sdh_ble.h @@ -84,6 +84,17 @@ int nrf_sdh_ble_app_ram_start_get(uint32_t *app_ram_start); */ int nrf_sdh_ble_enable(uint8_t conn_cfg_tag); +/** + * @brief Stringify a SoftDevice BLE event. + * + * If :option:`CONFIG_NRF_SDH_STR_TABLES` is enabled, returns the event name. + * Otherwise, returns the supplied integer as a string. + * + * @param evt A @ref BLE_GAP_EVTS, @ref BLE_GATTS_EVTS, or @ref BLE_GATTC_EVTS enumeration value. + * @returns A statically allocated string containing the event name or numerical value. + */ +const char *nrf_sdh_ble_evt_to_str(uint32_t evt); + /** * @brief Get the assigned index for a connection handle. * diff --git a/include/bm/softdevice_handler/nrf_sdh_soc.h b/include/bm/softdevice_handler/nrf_sdh_soc.h index 046272ddd3..e542874ea0 100644 --- a/include/bm/softdevice_handler/nrf_sdh_soc.h +++ b/include/bm/softdevice_handler/nrf_sdh_soc.h @@ -59,6 +59,17 @@ struct nrf_sdh_soc_evt_observer { .context = _ctx, \ }; +/** + * @brief Stringify a SoftDevice SoC event. + * + * If :option:`CONFIG_NRF_SDH_STR_TABLES` is enabled, returns the event name. + * Otherwise, returns the supplied integer as a string. + * + * @param evt An @ref NRF_SOC_SVCS enumeration value. + * @return A statically allocated string containing the event name or numerical value. + */ +const char *nrf_sdh_soc_evt_to_str(uint32_t evt); + #ifdef __cplusplus } #endif diff --git a/subsys/softdevice_handler/Kconfig b/subsys/softdevice_handler/Kconfig index 5ee2b74ac1..1c69080d4d 100644 --- a/subsys/softdevice_handler/Kconfig +++ b/subsys/softdevice_handler/Kconfig @@ -138,11 +138,11 @@ config NRF_SDH_SOC_RAND_SEED using CRACEN to generate the random seed. config NRF_SDH_STR_TABLES - bool "Build string tables for SoftDevice handler events" + bool "Build string tables for SoftDevice events" default y help - Make prints nicer by printing the stringified version of certain enumerations. - Disable to save non-volatile memory. + Compile a table of stringified SoftDevice events for nrf_sdh_ble_evt_to_str() and + nrf_sdh_soc_evt_to_str(). Disable to save non-volatile memory. module=NRF_SDH module-str= SoftDevice handler log level diff --git a/subsys/softdevice_handler/nrf_sdh_ble.c b/subsys/softdevice_handler/nrf_sdh_ble.c index 0df8530cc4..2f5a68bcc8 100644 --- a/subsys/softdevice_handler/nrf_sdh_ble.c +++ b/subsys/softdevice_handler/nrf_sdh_ble.c @@ -6,18 +6,23 @@ #include #include +#include +#include #include #include -#include #include #define APP_RAM_START DT_REG_ADDR(DT_CHOSEN(zephyr_sram)) LOG_MODULE_DECLARE(nrf_sdh, CONFIG_NRF_SDH_LOG_LEVEL); -const char *ble_evt_tostr(int evt) +const char *nrf_sdh_ble_evt_to_str(uint32_t evt) { + int err; + static char buf[sizeof("BLE event: 0xFFFFFFFF")]; + switch (evt) { +#if defined(CONFIG_NRF_SDH_STR_TABLES) /* GAP */ case BLE_GAP_EVT_CONNECTED: return "BLE_GAP_EVT_CONNECTED"; @@ -117,9 +122,13 @@ const char *ble_evt_tostr(int evt) return "BLE_GATTC_EVT_TIMEOUT"; case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE: return "BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE"; - +#endif default: - return "unknown"; + err = snprintf(buf, sizeof(buf), "BLE event: %#x", evt); + __ASSERT(err > 0, "Encode error"); + __ASSERT(err < sizeof(buf), "Buffer too small"); + (void)err; + return buf; } } @@ -351,11 +360,7 @@ static void ble_evt_poll(void *context) break; } - if (IS_ENABLED(CONFIG_NRF_SDH_STR_TABLES)) { - LOG_DBG("BLE event: %s", ble_evt_tostr(ble_evt->header.evt_id)); - } else { - LOG_DBG("BLE event: %#x", ble_evt->header.evt_id); - } + LOG_DBG("%s", nrf_sdh_ble_evt_to_str(ble_evt->header.evt_id)); if (ble_evt->header.evt_id == BLE_GAP_EVT_CONNECTED) { idx_assign(ble_evt->evt.gap_evt.conn_handle); diff --git a/subsys/softdevice_handler/nrf_sdh_soc.c b/subsys/softdevice_handler/nrf_sdh_soc.c index e7c267c14a..77b8672718 100644 --- a/subsys/softdevice_handler/nrf_sdh_soc.c +++ b/subsys/softdevice_handler/nrf_sdh_soc.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -13,31 +14,40 @@ LOG_MODULE_DECLARE(nrf_sdh, CONFIG_NRF_SDH_LOG_LEVEL); -static const char *tostr(uint32_t evt) +const char *nrf_sdh_soc_evt_to_str(uint32_t evt) { + int err; + static char buf[sizeof("SoC event: 0xFFFFFFFF")]; + switch (evt) { +#if defined(CONFIG_NRF_SDH_STR_TABLES) case NRF_EVT_HFCLKSTARTED: - return "The HFCLK has started"; + return "NRF_EVT_HFCLKSTARTED"; case NRF_EVT_POWER_FAILURE_WARNING: - return "A power failure warning has occurred"; + return "NRF_EVT_POWER_FAILURE_WARNING"; case NRF_EVT_FLASH_OPERATION_SUCCESS: - return "Flash operation has completed successfully"; + return "NRF_EVT_FLASH_OPERATION_SUCCESS"; case NRF_EVT_FLASH_OPERATION_ERROR: - return "Flash operation has timed out with an error"; + return "NRF_EVT_FLASH_OPERATION_ERROR"; case NRF_EVT_RADIO_BLOCKED: - return "A radio timeslot was blocked"; + return "NRF_EVT_RADIO_BLOCKED"; case NRF_EVT_RADIO_CANCELED: - return "A radio timeslot was canceled by SoftDevice"; + return "NRF_EVT_RADIO_CANCELED"; case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN: - return "A radio timeslot signal callback handler return was invalid"; + return "NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN"; case NRF_EVT_RADIO_SESSION_IDLE: - return "A radio timeslot session is idle"; + return "NRF_EVT_RADIO_SESSION_IDLE"; case NRF_EVT_RADIO_SESSION_CLOSED: - return "A radio timeslot session is closed"; + return "NRF_EVT_RADIO_SESSION_CLOSED"; case NRF_EVT_RAND_SEED_REQUEST: - return "SoftDevice RNG needs to be seeded"; + return "NRF_EVT_RAND_SEED_REQUEST"; +#endif default: - return "Unknown"; + err = snprintf(buf, sizeof(buf), "SoC event: %#x", evt); + __ASSERT(err > 0, "Encode error"); + __ASSERT(err < sizeof(buf), "Buffer too small"); + (void)err; + return buf; } } @@ -52,11 +62,7 @@ static void soc_evt_poll(void *context) break; } - if (IS_ENABLED(CONFIG_NRF_SDH_STR_TABLES)) { - LOG_DBG("SoC event: %s", tostr(evt_id)); - } else { - LOG_DBG("SoC event: 0x%x", evt_id); - } + LOG_DBG("%s", nrf_sdh_soc_evt_to_str(evt_id)); /* Forward the event to SoC observers. */ TYPE_SECTION_FOREACH( From a352cbe70fbe6b0479941b94952f99f2f2cf2129 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Tue, 23 Sep 2025 09:33:16 +0200 Subject: [PATCH 08/16] sdh: update the assert message in the polling loop Update the assert message at the end of the polling loops to print which kind of event we failed to pull, e.g. SoC or BLE. Signed-off-by: Emanuele Di Santo --- subsys/softdevice_handler/nrf_sdh_ble.c | 2 +- subsys/softdevice_handler/nrf_sdh_soc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/softdevice_handler/nrf_sdh_ble.c b/subsys/softdevice_handler/nrf_sdh_ble.c index 2f5a68bcc8..143473b07b 100644 --- a/subsys/softdevice_handler/nrf_sdh_ble.c +++ b/subsys/softdevice_handler/nrf_sdh_ble.c @@ -379,7 +379,7 @@ static void ble_evt_poll(void *context) /* An SoC event may have triggered this round of polling, and BLE may not be enabled */ __ASSERT((err == NRF_ERROR_NOT_FOUND) || (err == BLE_ERROR_NOT_ENABLED), - "Failed to receive SoftDevice event, nrf_error %#x", err); + "Failed to receive SoftDevice BLE event, nrf_error %#x", err); } /* Listen to SoftDevice events */ diff --git a/subsys/softdevice_handler/nrf_sdh_soc.c b/subsys/softdevice_handler/nrf_sdh_soc.c index 77b8672718..f598d6479b 100644 --- a/subsys/softdevice_handler/nrf_sdh_soc.c +++ b/subsys/softdevice_handler/nrf_sdh_soc.c @@ -72,7 +72,7 @@ static void soc_evt_poll(void *context) } __ASSERT(err == NRF_ERROR_NOT_FOUND, - "Failed to receive SoftDevice event, nrf_error %#x", err); + "Failed to receive SoftDevice SoC event, nrf_error %#x", err); } /* Listen to SoftDevice events */ From e04fff63c5b8c1cbcb681de79b7fac66407bba74 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Tue, 23 Sep 2025 11:00:06 +0200 Subject: [PATCH 09/16] sdh: merge request/state observers There was a distinction between observers that could stop the SoftDevice state changes, and those that didn't. The former were called "request observers" and the latter "state observers". Since both observers are interested in the SoftDevice state, this commit merges the two, keeping only "state observers", for the purpose of simplifying things a bit. Now, state observers can return non-zero to these events: - NRF_SDH_STATE_EVT_ENABLE_PREPARE and - NRF_SDH_STATE_EVT_DISABLE_PREPARE to halt the state change. The return value from the observer is ignored for other events. Signed-off-by: Emanuele Di Santo --- .../release_notes/release_notes_changelog.rst | 10 ++ include/bm/softdevice_handler/nrf_sdh.h | 101 ++++-------------- lib/bluetooth/ble_conn_params/conn_param.c | 8 +- samples/bluetooth/hello_softdevice/src/main.c | 6 +- subsys/softdevice_handler/nrf_sdh.c | 79 +++++--------- subsys/softdevice_handler/nrf_sdh_ble.c | 6 +- subsys/softdevice_handler/sdh.ld | 1 - subsys/storage/bm_storage/sd/bm_storage_sd.c | 32 +++--- 8 files changed, 89 insertions(+), 154 deletions(-) diff --git a/doc/nrf-bm/release_notes/release_notes_changelog.rst b/doc/nrf-bm/release_notes/release_notes_changelog.rst index 868326caa9..911650beff 100644 --- a/doc/nrf-bm/release_notes/release_notes_changelog.rst +++ b/doc/nrf-bm/release_notes/release_notes_changelog.rst @@ -41,6 +41,16 @@ SoftDevice Handler * The :c:func:`nrf_sdh_ble_evt_to_str` function to stringify a BLE event. * The :c:func:`nrf_sdh_soc_evt_to_str` function to stringify a SoC event. +* Changed: + + * The return type of the :c:type:`nrf_sdh_state_evt_handler_t` event handler to ``int``. + +* Removed: + + * The ``NRF_SDH_STATE_REQ_OBSERVER`` macro and relative data types. + Register a state event observer and return non-zero to :c:enum:`NRF_SDH_STATE_EVT_ENABLE_PREPARE` + or :c:enum:`NRF_SDH_STATE_EVT_DISABLE_PREPARE` to abort state changes instead. + Boards ====== diff --git a/include/bm/softdevice_handler/nrf_sdh.h b/include/bm/softdevice_handler/nrf_sdh.h index 498fccbef4..053e561df7 100644 --- a/include/bm/softdevice_handler/nrf_sdh.h +++ b/include/bm/softdevice_handler/nrf_sdh.h @@ -74,75 +74,14 @@ extern "C" { * @} */ -/** - * @brief SoftDevice Handler state requests. - */ -enum nrf_sdh_state_req { - /** - * @brief Request to disable the SoftDevice. - */ - NRF_SDH_STATE_REQ_DISABLE, - /** - * @brief Request to enable the SoftDevice. - */ - NRF_SDH_STATE_REQ_ENABLE, -}; - -/** - * @brief SoftDevice Handler state request handler. - * - * @retval true If ready for the SoftDevice to change state. - * @retval false If not ready for the SoftDevice to change state. - * If false is returned, the state change is aborted. - */ -typedef bool (*nrf_sdh_state_req_handler_t)(enum nrf_sdh_state_req request, void *context); - -/** - * @brief SoftDevice Handler state request observer. - */ -struct nrf_sdh_state_req_observer { - /** - * @brief State request handler. - */ - nrf_sdh_state_req_handler_t handler; - /** - * @brief A context parameter for the handler function. - */ - void *context; -}; - -/** - * @brief Register a SoftDevice state request observer. - * - * An observer of SoftDevice state requests receives requests to change the state of the - * SoftDevice from enabled to disabled and vice versa. These requests may or may not be - * acknowledged by the observer, depending on the value returned by its request handler function. - * Thus, a request observer has the capability to defer the change of state of the SoftDevice. - * If it does so, it has the responsibility to call @ref nrf_sdh_request_continue when it is ready - * to let the SoftDevice change its state. If such capability is not necessary and you only need - * to be informed about changes of SoftDevice state, use @ref NRF_SDH_STATE_EVT_OBSERVER instead. - * - * @param _observer Name of the observer. - * @param _handler State request handler. - * @param _ctx A context passed to the state request handler. - * @param _prio Priority of the observer's event handler. - * Allowed input: `HIGHEST`, `HIGH`, `USER`, `USER_LOW`, `LOWEST`. - */ -#define NRF_SDH_STATE_REQ_OBSERVER(_observer, _handler, _ctx, _prio) \ - PRIO_LEVEL_IS_VALID(_prio); \ - static bool _handler(enum nrf_sdh_state_req, void *); \ - const TYPE_SECTION_ITERABLE(struct nrf_sdh_state_req_observer, _observer, \ - nrf_sdh_state_req_observers, PRIO_LEVEL_ORD(_prio)) = { \ - .handler = _handler, \ - .context = _ctx, \ - }; - /** * @brief SoftDevice Handler state events. */ enum nrf_sdh_state_evt { /** * @brief SoftDevice is going to be enabled. + * + * The state change can be halted by returning non-zero when receiving this event. */ NRF_SDH_STATE_EVT_ENABLE_PREPARE, /** @@ -155,6 +94,8 @@ enum nrf_sdh_state_evt { NRF_SDH_STATE_EVT_BLE_ENABLED, /** * @brief SoftDevice is going to be disabled. + * + * The state change can be halted by returning non-zero when receiving this event. */ NRF_SDH_STATE_EVT_DISABLE_PREPARE, /** @@ -165,8 +106,11 @@ enum nrf_sdh_state_evt { /** * @brief SoftDevice Handler state event handler. + * + * @retval 0 If ready for the SoftDevice to change state. + * @retval 1 If not ready for the SoftDevice to change state (state change is halted). */ -typedef void (*nrf_sdh_state_evt_handler_t)(enum nrf_sdh_state_evt state, void *context); +typedef int (*nrf_sdh_state_evt_handler_t)(enum nrf_sdh_state_evt state, void *context); /** * @brief SoftDevice Handler state observer. @@ -185,10 +129,11 @@ struct nrf_sdh_state_evt_observer { /** * @brief Register a SoftDevice state observer. * - * A SoftDevice state observer receives events when the SoftDevice state has changed or is - * about to change. These events are only meant to inform the state observer, which, contrary - * to a state request observer, does not have the capability to defer the change of state. - * If such capability is required, use @ref NRF_SDH_STATE_REQ_OBSERVER instead. + * A SoftDevice state observer receives events when the SoftDevice state has changed + * or is about to change. An observer may return non-zero when receiving + * @ref NRF_SDH_STATE_EVT_ENABLE_PREPARE or @ref NRF_SDH_STATE_EVT_DISABLE_PREPARE + * to halt the state change. A state change halted this way can be resumed + * by calling @ref nrf_sdh_request_continue(). * * @param _observer Name of the observer. * @param _handler State request handler. @@ -198,7 +143,7 @@ struct nrf_sdh_state_evt_observer { */ #define NRF_SDH_STATE_EVT_OBSERVER(_observer, _handler, _ctx, _prio) \ PRIO_LEVEL_IS_VALID(_prio); \ - static void _handler(enum nrf_sdh_state_evt, void *); \ + static int _handler(enum nrf_sdh_state_evt, void *); \ const TYPE_SECTION_ITERABLE(struct nrf_sdh_state_evt_observer, _observer, \ nrf_sdh_state_evt_observers, PRIO_LEVEL_ORD(_prio)) = { \ .handler = _handler, \ @@ -249,12 +194,9 @@ struct nrf_sdh_stack_evt_observer { /** * @brief Enable the SoftDevice. * - * This function issues a @ref NRF_SDH_STATE_REQ_ENABLE request to all observers that - * were registered using the @ref NRF_SDH_STATE_REQ_OBSERVER macro. The observers may or - * may not acknowledge the request. If all observers acknowledge the request, the - * SoftDevice is enabled. Otherwise, the process is stopped and the observers - * that did not acknowledge have the responsibility to restart it by calling - * @ref nrf_sdh_request_continue when they are ready for the SoftDevice to change state. + * Enable the SoftDevice and send state events to registered observers. + * An observer may halt the SoftDevice state change by returning non-zero when receiving + * @ref NRF_SDH_STATE_EVT_ENABLE_PREPARE. * * @retval 0 On success. * @retval -EALREADY The SoftDevice is already enabled. @@ -264,12 +206,9 @@ int nrf_sdh_enable_request(void); /** * @brief Disable the SoftDevice. * - * This function issues a @ref NRF_SDH_STATE_REQ_DISABLE request to all observers that - * were registered using the @ref NRF_SDH_STATE_REQ_OBSERVER macro. The observers may or - * may not acknowledge the request. If all observers acknowledge the request, the - * SoftDevice is disabled. Otherwise, the process is stopped and the observers - * that did not acknowledge have the responsibility to restart it by calling - * @ref nrf_sdh_request_continue when they are ready for the SoftDevice to change state. + * Disable the SoftDevice and send state events to registered observers. + * An observer may halt the SoftDevice state change by returning non-zero when receiving + * @ref NRF_SDH_STATE_EVT_DISABLE_PREPARE. * * @retval 0 On success. * @retval -EALREADY The SoftDevice is already disabled. diff --git a/lib/bluetooth/ble_conn_params/conn_param.c b/lib/bluetooth/ble_conn_params/conn_param.c index a3985f322b..6a68b71c10 100644 --- a/lib/bluetooth/ble_conn_params/conn_param.c +++ b/lib/bluetooth/ble_conn_params/conn_param.c @@ -169,24 +169,26 @@ static void on_ble_evt(const ble_evt_t *evt, void *ctx) } NRF_SDH_BLE_OBSERVER(ble_observer, on_ble_evt, NULL, HIGH); -static void on_state_evt(enum nrf_sdh_state_evt evt, void *ctx) +static int on_state_evt(enum nrf_sdh_state_evt evt, void *ctx) { int err; if (evt != NRF_SDH_STATE_EVT_BLE_ENABLED) { - return; + return 0; } err = sd_ble_gap_ppcp_set(&ppcp); if (err) { LOG_ERR("Failed to set preferred conn params, nrf_error %#x", err); - return; + return 0; } LOG_DBG("conn. interval min %u max %u, peripheral latency %u, sup. timeout %u", ppcp.min_conn_interval, ppcp.max_conn_interval, ppcp.slave_latency, ppcp.conn_sup_timeout); + + return 0; } NRF_SDH_STATE_EVT_OBSERVER(ble_conn_params_sdh_state_observer, on_state_evt, NULL, HIGH); diff --git a/samples/bluetooth/hello_softdevice/src/main.c b/samples/bluetooth/hello_softdevice/src/main.c index 023012dcea..3b7e385244 100644 --- a/samples/bluetooth/hello_softdevice/src/main.c +++ b/samples/bluetooth/hello_softdevice/src/main.c @@ -26,9 +26,11 @@ static void on_soc_evt(uint32_t evt, void *ctx) } NRF_SDH_SOC_OBSERVER(sdh_soc, on_soc_evt, NULL, USER_LOW); -static void on_state_change(enum nrf_sdh_state_evt state, void *ctx) +static int on_state_change(enum nrf_sdh_state_evt state, void *ctx) { - LOG_INF("SoftDevice state has changed to %d", state); + LOG_INF("SoftDevice state %d", state); + + return 0; } NRF_SDH_STATE_EVT_OBSERVER(sdh_state, on_state_change, NULL, USER_LOW); diff --git a/subsys/softdevice_handler/nrf_sdh.c b/subsys/softdevice_handler/nrf_sdh.c index e252d1ea14..1ae841ca8f 100644 --- a/subsys/softdevice_handler/nrf_sdh.c +++ b/subsys/softdevice_handler/nrf_sdh.c @@ -23,18 +23,7 @@ static atomic_t sdh_enabled; /* Whether the SoftDevice is enabled. */ static atomic_t sdh_suspended; /* Whether this module is suspended. */ static atomic_t sdh_transition; /* Whether enable/disable process was started. */ -static char *req_tostr(enum nrf_sdh_state_req r) -{ - switch (r) { - case NRF_SDH_STATE_REQ_ENABLE: - return "enable"; - case NRF_SDH_STATE_REQ_DISABLE: - return "disable"; - default: - return "unknown"; - }; -} -static char *state_tostr(enum nrf_sdh_state_evt s) +static char *state_to_str(enum nrf_sdh_state_evt s) { switch (s) { case NRF_SDH_STATE_EVT_ENABLE_PREPARE: @@ -50,38 +39,37 @@ static char *state_tostr(enum nrf_sdh_state_evt s) }; } -static int sdh_state_req_observer_notify(enum nrf_sdh_state_req req) +/* Used in nrf_sdh_ble.c */ +int sdh_state_evt_observer_notify(enum nrf_sdh_state_evt state) { - if (IS_ENABLED(CONFIG_NRF_SDH_STR_TABLES)) { - LOG_INF("State change request: %s", req_tostr(req)); - } else { - LOG_INF("State change request: %#x", req); - } - - TYPE_SECTION_FOREACH(struct nrf_sdh_state_req_observer, nrf_sdh_state_req_observers, obs) { - if (obs->handler(req, obs->context)) { - LOG_DBG("Notify observer %p => ready", obs); - } else { - /* Do not let SoftDevice change state now */ - LOG_DBG("Notify observer %p => busy", obs); - return -EBUSY; - } - } - - return 0; -} + int busy; + bool busy_is_allowed; -static void sdh_state_evt_observer_notify(enum nrf_sdh_state_evt state) -{ if (IS_ENABLED(CONFIG_NRF_SDH_STR_TABLES)) { - LOG_DBG("State change: %s", state_tostr(state)); + LOG_DBG("State change: %s", state_to_str(state)); } else { LOG_DBG("State change: %#x", state); } + busy_is_allowed = (state == NRF_SDH_STATE_EVT_ENABLE_PREPARE) || + (state == NRF_SDH_STATE_EVT_DISABLE_PREPARE); + TYPE_SECTION_FOREACH(struct nrf_sdh_state_evt_observer, nrf_sdh_state_evt_observers, obs) { - obs->handler(state, obs->context); + busy = obs->handler(state, obs->context); + if (!busy) { + continue; + } + if (!busy_is_allowed) { + __ASSERT(busy_is_allowed, + "Returning non-zero from these events is ignored"); + continue; + } + /* Do not let SoftDevice change state now */ + LOG_DBG("Notify observer %p => busy", obs); + return -EBUSY; } + + return 0; } __weak void softdevice_fault_handler(uint32_t id, uint32_t pc, uint32_t info) @@ -123,21 +111,17 @@ int nrf_sdh_enable_request(void) return -EALREADY; } + /* Notify observers about starting SoftDevice enable process. */ atomic_set(&sdh_transition, true); - err = sdh_state_req_observer_notify(NRF_SDH_STATE_REQ_ENABLE); + err = sdh_state_evt_observer_notify(NRF_SDH_STATE_EVT_ENABLE_PREPARE); if (err) { - /** TODO: should this be Success instead? */ /* Leave sdh_transition to 1, so process can be continued */ - __ASSERT(err == -EBUSY, "Unknown return value %d from sdh req observer", err); return -EBUSY; } atomic_set(&sdh_transition, false); - /* Notify observers about starting SoftDevice enable process. */ - sdh_state_evt_observer_notify(NRF_SDH_STATE_EVT_ENABLE_PREPARE); - err = sd_softdevice_enable(&clock_lf_cfg, softdevice_fault_handler); if (err) { LOG_ERR("Failed to enable SoftDevice, nrf_error %#x", err); @@ -151,7 +135,7 @@ int nrf_sdh_enable_request(void) NVIC_EnableIRQ((IRQn_Type)SD_EVT_IRQn); /* Notify observers about a finished SoftDevice enable process. */ - sdh_state_evt_observer_notify(NRF_SDH_STATE_EVT_ENABLED); + (void)sdh_state_evt_observer_notify(NRF_SDH_STATE_EVT_ENABLED); return 0; } @@ -166,20 +150,15 @@ int nrf_sdh_disable_request(void) atomic_set(&sdh_transition, true); - /* Notify observers about SoftDevice disable request. */ - err = sdh_state_req_observer_notify(NRF_SDH_STATE_REQ_DISABLE); + /* Notify observers about starting SoftDevice disable process. */ + err = sdh_state_evt_observer_notify(NRF_SDH_STATE_EVT_DISABLE_PREPARE); if (err) { - /** TODO: should this be Success instead? */ /* Leave sdh_transition to 1, so process can be continued */ - __ASSERT(err == -EBUSY, "Unknown return value %d from sdh req observer", err); return -EBUSY; } atomic_set(&sdh_transition, false); - /* Notify observers about starting SoftDevice disable process. */ - sdh_state_evt_observer_notify(NRF_SDH_STATE_EVT_DISABLE_PREPARE); - err = sd_softdevice_disable(); if (err) { LOG_ERR("Failed to disable SoftDevice, nrf_error %#x", err); @@ -191,7 +170,7 @@ int nrf_sdh_disable_request(void) NVIC_DisableIRQ((IRQn_Type)SD_EVT_IRQn); /* Notify observers about a finished SoftDevice enable process. */ - sdh_state_evt_observer_notify(NRF_SDH_STATE_EVT_DISABLED); + (void)sdh_state_evt_observer_notify(NRF_SDH_STATE_EVT_DISABLED); return 0; } diff --git a/subsys/softdevice_handler/nrf_sdh_ble.c b/subsys/softdevice_handler/nrf_sdh_ble.c index 143473b07b..f19353f39a 100644 --- a/subsys/softdevice_handler/nrf_sdh_ble.c +++ b/subsys/softdevice_handler/nrf_sdh_ble.c @@ -16,6 +16,8 @@ LOG_MODULE_DECLARE(nrf_sdh, CONFIG_NRF_SDH_LOG_LEVEL); +extern int sdh_state_evt_observer_notify(enum nrf_sdh_state_evt state); + const char *nrf_sdh_ble_evt_to_str(uint32_t evt) { int err; @@ -259,9 +261,7 @@ int nrf_sdh_ble_enable(uint8_t conn_cfg_tag) LOG_DBG("SoftDevice BLE enabled"); - TYPE_SECTION_FOREACH(struct nrf_sdh_state_evt_observer, nrf_sdh_state_evt_observers, obs) { - obs->handler(NRF_SDH_STATE_EVT_BLE_ENABLED, obs->context); - } + (void)sdh_state_evt_observer_notify(NRF_SDH_STATE_EVT_BLE_ENABLED); return 0; } diff --git a/subsys/softdevice_handler/sdh.ld b/subsys/softdevice_handler/sdh.ld index 72e1f6de28..d3a0c9d10a 100644 --- a/subsys/softdevice_handler/sdh.ld +++ b/subsys/softdevice_handler/sdh.ld @@ -1,4 +1,3 @@ -ITERABLE_SECTION_ROM(nrf_sdh_state_req_observers, 4) ITERABLE_SECTION_ROM(nrf_sdh_state_evt_observers, 4) ITERABLE_SECTION_ROM(nrf_sdh_stack_evt_observers, 4) ITERABLE_SECTION_ROM(nrf_sdh_soc_evt_observers, 4) diff --git a/subsys/storage/bm_storage/sd/bm_storage_sd.c b/subsys/storage/bm_storage/sd/bm_storage_sd.c index c28400b0a8..03da75addd 100644 --- a/subsys/storage/bm_storage/sd/bm_storage_sd.c +++ b/subsys/storage/bm_storage/sd/bm_storage_sd.c @@ -64,14 +64,12 @@ struct bm_storage_sd_state { static struct bm_storage_sd_state state; static void on_soc_evt(uint32_t evt, void *ctx); -static bool on_state_req_change(enum nrf_sdh_state_req req, void *ctx); -static void on_state_evt_change(enum nrf_sdh_state_evt evt, void *ctx); +static int on_state_evt_change(enum nrf_sdh_state_evt evt, void *ctx); RING_BUF_DECLARE(sd_fifo, CONFIG_BM_STORAGE_BACKEND_SD_QUEUE_SIZE * sizeof(struct bm_storage_sd_op)); NRF_SDH_SOC_OBSERVER(sdh_soc, on_soc_evt, NULL, HIGH); -NRF_SDH_STATE_REQ_OBSERVER(sdh_state_req, on_state_req_change, NULL, HIGH); NRF_SDH_STATE_EVT_OBSERVER(sdh_state_evt, on_state_evt_change, NULL, HIGH); static inline bool is_aligned32(uint32_t addr) @@ -346,22 +344,28 @@ static void on_soc_evt(uint32_t evt, void *ctx) } } -static void on_state_evt_change(enum nrf_sdh_state_evt evt, void *ctx) +static int on_state_evt_change(enum nrf_sdh_state_evt evt, void *ctx) { - if ((evt == NRF_SDH_STATE_EVT_ENABLED) || (evt == NRF_SDH_STATE_EVT_DISABLED)) { + switch (evt) { + case NRF_SDH_STATE_EVT_ENABLE_PREPARE: + case NRF_SDH_STATE_EVT_DISABLE_PREPARE: + /* Only allow changing state when idle */ + state.paused = true; + return (state.type != BM_STORAGE_SD_STATE_IDLE); + + case NRF_SDH_STATE_EVT_ENABLED: + case NRF_SDH_STATE_EVT_DISABLED: + /* Continue executing any operation still in the queue */ state.paused = false; state.sd_enabled = (evt == NRF_SDH_STATE_EVT_ENABLED); - - /* Execute any operation still in the queue. */ queue_process(); - } -} + return 0; -static bool on_state_req_change(enum nrf_sdh_state_req req, void *ctx) -{ - state.paused = true; - - return (state.type == BM_STORAGE_SD_STATE_IDLE); + case NRF_SDH_STATE_EVT_BLE_ENABLED: + default: + /* Not interesting */ + return 0; + } } const struct bm_storage_info bm_storage_info = { From 971dbd8146a32dbfe759afb4a3d166e122825e16 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Tue, 23 Sep 2025 12:27:25 +0200 Subject: [PATCH 10/16] sdh: update the doxygen for _enable_request() and _disable_request() These can return -EBUSY, which was missing. Signed-off-by: Emanuele Di Santo --- include/bm/softdevice_handler/nrf_sdh.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/bm/softdevice_handler/nrf_sdh.h b/include/bm/softdevice_handler/nrf_sdh.h index 053e561df7..404a888f28 100644 --- a/include/bm/softdevice_handler/nrf_sdh.h +++ b/include/bm/softdevice_handler/nrf_sdh.h @@ -200,6 +200,7 @@ struct nrf_sdh_stack_evt_observer { * * @retval 0 On success. * @retval -EALREADY The SoftDevice is already enabled. + * @retval -EBUSY An observer was busy, retry later. */ int nrf_sdh_enable_request(void); @@ -212,6 +213,7 @@ int nrf_sdh_enable_request(void); * * @retval 0 On success. * @retval -EALREADY The SoftDevice is already disabled. + * @retval -EBUSY An observer was busy, retry later. */ int nrf_sdh_disable_request(void); From 93d2b317306e82824e71d4deabf903e6247da952 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Mon, 22 Sep 2025 16:10:49 +0200 Subject: [PATCH 11/16] sdh: remove nrf_sdh_ble_app_ram_start_get() There is no reason for this API to be in this library. It could be added to a dedicated library later to avoid having to rely on DT macros to retrieve this information. Signed-off-by: Emanuele Di Santo --- doc/nrf-bm/release_notes/release_notes_changelog.rst | 1 + include/bm/softdevice_handler/nrf_sdh_ble.h | 10 ---------- subsys/softdevice_handler/nrf_sdh_ble.c | 11 ----------- 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/doc/nrf-bm/release_notes/release_notes_changelog.rst b/doc/nrf-bm/release_notes/release_notes_changelog.rst index 911650beff..9ac5ab980c 100644 --- a/doc/nrf-bm/release_notes/release_notes_changelog.rst +++ b/doc/nrf-bm/release_notes/release_notes_changelog.rst @@ -50,6 +50,7 @@ SoftDevice Handler * The ``NRF_SDH_STATE_REQ_OBSERVER`` macro and relative data types. Register a state event observer and return non-zero to :c:enum:`NRF_SDH_STATE_EVT_ENABLE_PREPARE` or :c:enum:`NRF_SDH_STATE_EVT_DISABLE_PREPARE` to abort state changes instead. + * The ``nrf_sdh_ble_app_ram_start_get`` function, use ``DT_REG_ADDR(DT_CHOSEN(zephyr_sram))`` instead. Boards ====== diff --git a/include/bm/softdevice_handler/nrf_sdh_ble.h b/include/bm/softdevice_handler/nrf_sdh_ble.h index 92073d37d4..c181135d10 100644 --- a/include/bm/softdevice_handler/nrf_sdh_ble.h +++ b/include/bm/softdevice_handler/nrf_sdh_ble.h @@ -65,16 +65,6 @@ struct nrf_sdh_ble_evt_observer { .context = _ctx, \ }; -/** - * @brief Retrieve the starting address of the application's RAM. - * - * @param[out] app_ram_start The starting address of the application's RAM. - * - * @retval 0 On success. - * @retval -EFAULT @p app_ram_start is @c NULL. - */ -int nrf_sdh_ble_app_ram_start_get(uint32_t *app_ram_start); - /** * @brief Enable the SoftDevice Bluetooth stack. * diff --git a/subsys/softdevice_handler/nrf_sdh_ble.c b/subsys/softdevice_handler/nrf_sdh_ble.c index f19353f39a..9b5c029270 100644 --- a/subsys/softdevice_handler/nrf_sdh_ble.c +++ b/subsys/softdevice_handler/nrf_sdh_ble.c @@ -134,17 +134,6 @@ const char *nrf_sdh_ble_evt_to_str(uint32_t evt) } } -int nrf_sdh_ble_app_ram_start_get(uint32_t *app_ram_start) -{ - if (!app_ram_start) { - return -EFAULT; - } - - *app_ram_start = APP_RAM_START; - - return 0; -} - static int default_cfg_set(void) { int err; From 316dda8d26c567f6a60bb1295c38b2802f051122 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Tue, 23 Sep 2025 12:38:53 +0200 Subject: [PATCH 12/16] sdh: remove nrf_sdh_request_continue() This function shifts the responsibility of changing the state of the SoftDevice to the observer that halted its state change. This means that potentially all observers that halt the state change not only become responsible of the process (which may not be ideal) but also have to maintain some state and logic to restart that process. Instead, let the component who requested the state change in the first place retry the operation. Signed-off-by: Emanuele Di Santo --- .../release_notes/release_notes_changelog.rst | 1 + include/bm/softdevice_handler/nrf_sdh.h | 15 +---------- subsys/softdevice_handler/nrf_sdh.c | 25 ------------------- subsys/storage/bm_storage/sd/bm_storage_sd.c | 2 -- 4 files changed, 2 insertions(+), 41 deletions(-) diff --git a/doc/nrf-bm/release_notes/release_notes_changelog.rst b/doc/nrf-bm/release_notes/release_notes_changelog.rst index 9ac5ab980c..c465ad90d0 100644 --- a/doc/nrf-bm/release_notes/release_notes_changelog.rst +++ b/doc/nrf-bm/release_notes/release_notes_changelog.rst @@ -51,6 +51,7 @@ SoftDevice Handler Register a state event observer and return non-zero to :c:enum:`NRF_SDH_STATE_EVT_ENABLE_PREPARE` or :c:enum:`NRF_SDH_STATE_EVT_DISABLE_PREPARE` to abort state changes instead. * The ``nrf_sdh_ble_app_ram_start_get`` function, use ``DT_REG_ADDR(DT_CHOSEN(zephyr_sram))`` instead. + * The ``nrf_sdh_request_continue`` function. Boards ====== diff --git a/include/bm/softdevice_handler/nrf_sdh.h b/include/bm/softdevice_handler/nrf_sdh.h index 404a888f28..9954b297f8 100644 --- a/include/bm/softdevice_handler/nrf_sdh.h +++ b/include/bm/softdevice_handler/nrf_sdh.h @@ -132,8 +132,7 @@ struct nrf_sdh_state_evt_observer { * A SoftDevice state observer receives events when the SoftDevice state has changed * or is about to change. An observer may return non-zero when receiving * @ref NRF_SDH_STATE_EVT_ENABLE_PREPARE or @ref NRF_SDH_STATE_EVT_DISABLE_PREPARE - * to halt the state change. A state change halted this way can be resumed - * by calling @ref nrf_sdh_request_continue(). + * to halt the state change. * * @param _observer Name of the observer. * @param _handler State request handler. @@ -217,18 +216,6 @@ int nrf_sdh_enable_request(void); */ int nrf_sdh_disable_request(void); -/** - * @brief Function for restarting the SoftDevice Enable/Disable process. - * - * Modules which did not acknowledge a @ref NRF_SDH_STATE_REQ_ENABLE or - * @ref NRF_SDH_STATE_REQ_DISABLE request must call this function to restart the - * SoftDevice state change process. - * - * @retval 0 On success. - * @retval -EINVAL No state change request was pending. - */ -int nrf_sdh_request_continue(void); - /** * @brief Retrieve the SoftDevice state. * diff --git a/subsys/softdevice_handler/nrf_sdh.c b/subsys/softdevice_handler/nrf_sdh.c index 1ae841ca8f..ab3c50bb7c 100644 --- a/subsys/softdevice_handler/nrf_sdh.c +++ b/subsys/softdevice_handler/nrf_sdh.c @@ -21,7 +21,6 @@ LOG_MODULE_REGISTER(nrf_sdh, CONFIG_NRF_SDH_LOG_LEVEL); static atomic_t sdh_enabled; /* Whether the SoftDevice is enabled. */ static atomic_t sdh_suspended; /* Whether this module is suspended. */ -static atomic_t sdh_transition; /* Whether enable/disable process was started. */ static char *state_to_str(enum nrf_sdh_state_evt s) { @@ -111,17 +110,11 @@ int nrf_sdh_enable_request(void) return -EALREADY; } - /* Notify observers about starting SoftDevice enable process. */ - atomic_set(&sdh_transition, true); - err = sdh_state_evt_observer_notify(NRF_SDH_STATE_EVT_ENABLE_PREPARE); if (err) { - /* Leave sdh_transition to 1, so process can be continued */ return -EBUSY; } - atomic_set(&sdh_transition, false); - err = sd_softdevice_enable(&clock_lf_cfg, softdevice_fault_handler); if (err) { LOG_ERR("Failed to enable SoftDevice, nrf_error %#x", err); @@ -148,17 +141,12 @@ int nrf_sdh_disable_request(void) return -EALREADY; } - atomic_set(&sdh_transition, true); - /* Notify observers about starting SoftDevice disable process. */ err = sdh_state_evt_observer_notify(NRF_SDH_STATE_EVT_DISABLE_PREPARE); if (err) { - /* Leave sdh_transition to 1, so process can be continued */ return -EBUSY; } - atomic_set(&sdh_transition, false); - err = sd_softdevice_disable(); if (err) { LOG_ERR("Failed to disable SoftDevice, nrf_error %#x", err); @@ -175,19 +163,6 @@ int nrf_sdh_disable_request(void) return 0; } -int nrf_sdh_request_continue(void) -{ - if (!sdh_transition) { - return -EINVAL; - } - - if (sdh_enabled) { - return nrf_sdh_disable_request(); - } else { - return nrf_sdh_enable_request(); - } -} - bool nrf_sdh_is_enabled(void) { return sdh_enabled; diff --git a/subsys/storage/bm_storage/sd/bm_storage_sd.c b/subsys/storage/bm_storage/sd/bm_storage_sd.c index 03da75addd..bab3e6eb89 100644 --- a/subsys/storage/bm_storage/sd/bm_storage_sd.c +++ b/subsys/storage/bm_storage/sd/bm_storage_sd.c @@ -339,8 +339,6 @@ static void on_soc_evt(uint32_t evt, void *ctx) if (!state.paused) { queue_process(); - } else { - nrf_sdh_request_continue(); } } From 369d6ed9e9e7d1bf1d81b3abfc86d817303cd713 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Tue, 23 Sep 2025 13:17:53 +0200 Subject: [PATCH 13/16] sdh: remove nrf_sdh_is_enabled() Use the native SoftDevice function sd_softdevice_is_enabled() instead. Signed-off-by: Emanuele Di Santo --- .../release_notes/release_notes_changelog.rst | 1 + include/bm/softdevice_handler/nrf_sdh.h | 8 ---- subsys/softdevice_handler/nrf_sdh.c | 47 +++++++++++++------ subsys/storage/bm_storage/sd/bm_storage_sd.c | 11 +++-- 4 files changed, 39 insertions(+), 28 deletions(-) diff --git a/doc/nrf-bm/release_notes/release_notes_changelog.rst b/doc/nrf-bm/release_notes/release_notes_changelog.rst index c465ad90d0..b12a9b5a03 100644 --- a/doc/nrf-bm/release_notes/release_notes_changelog.rst +++ b/doc/nrf-bm/release_notes/release_notes_changelog.rst @@ -52,6 +52,7 @@ SoftDevice Handler or :c:enum:`NRF_SDH_STATE_EVT_DISABLE_PREPARE` to abort state changes instead. * The ``nrf_sdh_ble_app_ram_start_get`` function, use ``DT_REG_ADDR(DT_CHOSEN(zephyr_sram))`` instead. * The ``nrf_sdh_request_continue`` function. + * The ``nrf_sdh_is_enabled`` function, use the SoftDevice native function :c:func:`sd_softdevice_is_enabled` instead. Boards ====== diff --git a/include/bm/softdevice_handler/nrf_sdh.h b/include/bm/softdevice_handler/nrf_sdh.h index 9954b297f8..ebd48bab4d 100644 --- a/include/bm/softdevice_handler/nrf_sdh.h +++ b/include/bm/softdevice_handler/nrf_sdh.h @@ -216,14 +216,6 @@ int nrf_sdh_enable_request(void); */ int nrf_sdh_disable_request(void); -/** - * @brief Retrieve the SoftDevice state. - * - * @retval true If the SoftDevice is enabled. - * @retval false If the SoftDevice is disabled. - */ -bool nrf_sdh_is_enabled(void); - /** * @brief Stop processing SoftDevice events. * diff --git a/subsys/softdevice_handler/nrf_sdh.c b/subsys/softdevice_handler/nrf_sdh.c index ab3c50bb7c..71d5a233d1 100644 --- a/subsys/softdevice_handler/nrf_sdh.c +++ b/subsys/softdevice_handler/nrf_sdh.c @@ -19,8 +19,7 @@ LOG_MODULE_REGISTER(nrf_sdh, CONFIG_NRF_SDH_LOG_LEVEL); #warning Please select NRF_CLOCK_LF_ACCURACY_500_PPM when using NRF_CLOCK_LF_SRC_RC #endif -static atomic_t sdh_enabled; /* Whether the SoftDevice is enabled. */ -static atomic_t sdh_suspended; /* Whether this module is suspended. */ +static atomic_t sdh_suspended; /* Whether this module is pulling SoftDevice events or not. */ static char *state_to_str(enum nrf_sdh_state_evt s) { @@ -97,6 +96,7 @@ __weak void softdevice_fault_handler(uint32_t id, uint32_t pc, uint32_t info) int nrf_sdh_enable_request(void) { int err; + uint8_t sd_is_enabled; const nrf_clock_lf_cfg_t clock_lf_cfg = { .source = CONFIG_NRF_SDH_CLOCK_LF_SRC, .rc_ctiv = CONFIG_NRF_SDH_CLOCK_LF_RC_CTIV, @@ -106,7 +106,8 @@ int nrf_sdh_enable_request(void) .hfint_ctiv = CONFIG_NRF_SDH_CLOCK_HFINT_CALIBRATION_INTERVAL, }; - if (sdh_enabled) { + (void)sd_softdevice_is_enabled(&sd_is_enabled); + if (sd_is_enabled) { return -EALREADY; } @@ -121,7 +122,6 @@ int nrf_sdh_enable_request(void) return -EINVAL; } - atomic_set(&sdh_enabled, true); atomic_set(&sdh_suspended, false); /* Enable event interrupt, the priority has already been set by the stack. */ @@ -136,8 +136,10 @@ int nrf_sdh_enable_request(void) int nrf_sdh_disable_request(void) { int err; + uint8_t sd_is_enabled; - if (!sdh_enabled) { + (void)sd_softdevice_is_enabled(&sd_is_enabled); + if (!sd_is_enabled) { return -EALREADY; } @@ -153,8 +155,6 @@ int nrf_sdh_disable_request(void) return -EINVAL; } - atomic_set(&sdh_enabled, false); - NVIC_DisableIRQ((IRQn_Type)SD_EVT_IRQn); /* Notify observers about a finished SoftDevice enable process. */ @@ -163,14 +163,18 @@ int nrf_sdh_disable_request(void) return 0; } -bool nrf_sdh_is_enabled(void) -{ - return sdh_enabled; -} - void nrf_sdh_suspend(void) { - if (!sdh_enabled || sdh_suspended) { + uint8_t sd_is_enabled; + + (void)sd_softdevice_is_enabled(&sd_is_enabled); + + if (!sd_is_enabled) { + LOG_WRN("Tried to suspend, but SoftDevice is disabled"); + return; + } + if (sdh_suspended) { + LOG_WRN("Tried to suspend, but already is suspended"); return; } @@ -181,7 +185,16 @@ void nrf_sdh_suspend(void) void nrf_sdh_resume(void) { - if ((!sdh_suspended) || (!sdh_enabled)) { + uint8_t sd_is_enabled; + + (void)sd_softdevice_is_enabled(&sd_is_enabled); + + if (!sd_is_enabled) { + LOG_WRN("Tried to resume, but SoftDevice is disabled"); + return; + } + if (!sdh_suspended) { + LOG_WRN("Tried to resume, but not suspended"); return; } @@ -194,7 +207,11 @@ void nrf_sdh_resume(void) bool nrf_sdh_is_suspended(void) { - return (!sdh_enabled) || (sdh_suspended); + uint8_t sd_is_enabled; + + (void) sd_softdevice_is_enabled(&sd_is_enabled); + + return (!sd_is_enabled || sdh_suspended); } void nrf_sdh_evts_poll(void) diff --git a/subsys/storage/bm_storage/sd/bm_storage_sd.c b/subsys/storage/bm_storage/sd/bm_storage_sd.c index bab3e6eb89..d0b8c7476c 100644 --- a/subsys/storage/bm_storage/sd/bm_storage_sd.c +++ b/subsys/storage/bm_storage/sd/bm_storage_sd.c @@ -4,16 +4,17 @@ * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ -#include #include -#include -#include -#include #include +#include +#include +#include #include #include #include #include +#include +#include /* 128-bit word line. This is the optimal size to fully utilize RRAM 128-bit word line with ECC * (error correction code) and minimize ECC updates overhead, due to these updates happening @@ -226,7 +227,7 @@ uint32_t bm_storage_backend_init(struct bm_storage *storage) return NRF_ERROR_BUSY; } - state.sd_enabled = nrf_sdh_is_enabled(); + sd_softdevice_is_enabled((uint8_t *)&state.sd_enabled); state.type = BM_STORAGE_SD_STATE_IDLE; From ebf6e44565a0a24de303b2fc763fb4b3d993dbc9 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Tue, 23 Sep 2025 13:19:31 +0200 Subject: [PATCH 14/16] sdh: let nrf_sdh_is_suspended() only check for sdh state Only check if the SoftDevice handler is suspended, not if the SoftDevice is enabled. Signed-off-by: Emanuele Di Santo --- subsys/softdevice_handler/nrf_sdh.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/subsys/softdevice_handler/nrf_sdh.c b/subsys/softdevice_handler/nrf_sdh.c index 71d5a233d1..7daa346b59 100644 --- a/subsys/softdevice_handler/nrf_sdh.c +++ b/subsys/softdevice_handler/nrf_sdh.c @@ -207,11 +207,7 @@ void nrf_sdh_resume(void) bool nrf_sdh_is_suspended(void) { - uint8_t sd_is_enabled; - - (void) sd_softdevice_is_enabled(&sd_is_enabled); - - return (!sd_is_enabled || sdh_suspended); + return sdh_suspended; } void nrf_sdh_evts_poll(void) From fd7f0908dbfad27c058af0f6b1b1f641a930476f Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Tue, 23 Sep 2025 13:22:14 +0200 Subject: [PATCH 15/16] sdh: rename variable Rename an internal variable. Signed-off-by: Emanuele Di Santo --- subsys/softdevice_handler/nrf_sdh.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/subsys/softdevice_handler/nrf_sdh.c b/subsys/softdevice_handler/nrf_sdh.c index 7daa346b59..4ea619bcba 100644 --- a/subsys/softdevice_handler/nrf_sdh.c +++ b/subsys/softdevice_handler/nrf_sdh.c @@ -19,7 +19,8 @@ LOG_MODULE_REGISTER(nrf_sdh, CONFIG_NRF_SDH_LOG_LEVEL); #warning Please select NRF_CLOCK_LF_ACCURACY_500_PPM when using NRF_CLOCK_LF_SRC_RC #endif -static atomic_t sdh_suspended; /* Whether this module is pulling SoftDevice events or not. */ +/* Whether this module is pulling SoftDevice events or not. */ +static atomic_t sdh_is_suspended; static char *state_to_str(enum nrf_sdh_state_evt s) { @@ -122,7 +123,7 @@ int nrf_sdh_enable_request(void) return -EINVAL; } - atomic_set(&sdh_suspended, false); + atomic_set(&sdh_is_suspended, false); /* Enable event interrupt, the priority has already been set by the stack. */ NVIC_EnableIRQ((IRQn_Type)SD_EVT_IRQn); @@ -173,14 +174,14 @@ void nrf_sdh_suspend(void) LOG_WRN("Tried to suspend, but SoftDevice is disabled"); return; } - if (sdh_suspended) { + if (sdh_is_suspended) { LOG_WRN("Tried to suspend, but already is suspended"); return; } NVIC_DisableIRQ((IRQn_Type)SD_EVT_IRQn); - atomic_set(&sdh_suspended, true); + atomic_set(&sdh_is_suspended, true); } void nrf_sdh_resume(void) @@ -193,7 +194,7 @@ void nrf_sdh_resume(void) LOG_WRN("Tried to resume, but SoftDevice is disabled"); return; } - if (!sdh_suspended) { + if (!sdh_is_suspended) { LOG_WRN("Tried to resume, but not suspended"); return; } @@ -202,12 +203,12 @@ void nrf_sdh_resume(void) NVIC_SetPendingIRQ((IRQn_Type)SD_EVT_IRQn); NVIC_EnableIRQ((IRQn_Type)SD_EVT_IRQn); - atomic_set(&sdh_suspended, false); + atomic_set(&sdh_is_suspended, false); } bool nrf_sdh_is_suspended(void) { - return sdh_suspended; + return sdh_is_suspended; } void nrf_sdh_evts_poll(void) From ce8ccb03b22c96bed24853975503177fb6cd4367 Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Fri, 3 Oct 2025 12:36:28 +0200 Subject: [PATCH 16/16] sdh: remove semicolons at the end of observer macros Remove these, and force users to put a semicolon themselves. Signed-off-by: Emanuele Di Santo --- include/bm/softdevice_handler/nrf_sdh.h | 4 ++-- include/bm/softdevice_handler/nrf_sdh_ble.h | 2 +- include/bm/softdevice_handler/nrf_sdh_soc.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/bm/softdevice_handler/nrf_sdh.h b/include/bm/softdevice_handler/nrf_sdh.h index ebd48bab4d..c9788e5f24 100644 --- a/include/bm/softdevice_handler/nrf_sdh.h +++ b/include/bm/softdevice_handler/nrf_sdh.h @@ -147,7 +147,7 @@ struct nrf_sdh_state_evt_observer { nrf_sdh_state_evt_observers, PRIO_LEVEL_ORD(_prio)) = { \ .handler = _handler, \ .context = _ctx, \ - }; + } /** * @brief SoftDevice stack event handler. @@ -188,7 +188,7 @@ struct nrf_sdh_stack_evt_observer { nrf_sdh_stack_evt_observers, PRIO_LEVEL_ORD(_prio)) = { \ .handler = _handler, \ .context = _ctx, \ - }; + } /** * @brief Enable the SoftDevice. diff --git a/include/bm/softdevice_handler/nrf_sdh_ble.h b/include/bm/softdevice_handler/nrf_sdh_ble.h index c181135d10..34bf22c494 100644 --- a/include/bm/softdevice_handler/nrf_sdh_ble.h +++ b/include/bm/softdevice_handler/nrf_sdh_ble.h @@ -63,7 +63,7 @@ struct nrf_sdh_ble_evt_observer { nrf_sdh_ble_evt_observers, PRIO_LEVEL_ORD(_prio)) = { \ .handler = _handler, \ .context = _ctx, \ - }; + } /** * @brief Enable the SoftDevice Bluetooth stack. diff --git a/include/bm/softdevice_handler/nrf_sdh_soc.h b/include/bm/softdevice_handler/nrf_sdh_soc.h index e542874ea0..ebe9884a84 100644 --- a/include/bm/softdevice_handler/nrf_sdh_soc.h +++ b/include/bm/softdevice_handler/nrf_sdh_soc.h @@ -57,7 +57,7 @@ struct nrf_sdh_soc_evt_observer { nrf_sdh_soc_evt_observers, PRIO_LEVEL_ORD(_prio)) = { \ .handler = _handler, \ .context = _ctx, \ - }; + } /** * @brief Stringify a SoftDevice SoC event.