Introduction of SDH and SDK v15.0 software architecture

The SDK software architecture has been hugely changed since SDK v13.0. With adding SDH to SDK, it provides SDH API to 

  • Enabling the SoftDevice and its event interrupt.
  • Disabling the SoftDevice.
  • Receiving stack events from the SoftDevice and forwarding them to the parts of application that have registered themselves as observers.
  • Sending SoftDevice state events to applications and drivers.
  • Sending SoftDevice state requests which can be accepted or rejected by an observer.
  • This module works with SoftDevices that have BLE, ANT, or BLE and ANT functionalities.

Therefore, SDH changes the registration of callbacks to BLE stack or specifically changes the application programming model with observers. So the old style ble_evt_dispatch() function as a root to receive all events and dispatch to different event handler was gone; instead, a user need to register its event callback as an observer to observe and react on different event coming from SoftDevice with SWI2. And, the handling to SoC events also follow SDH implementation.

SDH Library components

The core of SoftDevice Handler library is

  • nrf_sdh component in nrf_sdh.c

Handles requests for enabling or disabling the SoftDevice. Notifies about SoftDevice state changes. Therefore, applications or drivers can register a state observer in sdh_state_observers section and listen to these events and then perform any necessary operations based on these notifications. Before an observer is listening to events, an application/driver can register a request handling observer in sdh_req_observers section to handle the sent request to enable/disable SD. A typical usage is to enable/disable SoftDevice while application is still accessing flash through NVMC.

nrf_sdh propagates stack events to sub-modules. All nrf_sdh_* components register with the core nrf_sdh as observers in linker script defined sdh_stack_observers sections, and nrf_sdh fetches stack events and dispatches them to the correct nrf_sdh_* components.

  • nrf_sdh_soc
  • nrf_sdh_ant
  • nrf_sdh_ble

The nrf_sdh_x components are implemented in nrf_sdh_soc.c, nrf_sdh_ble.c and nrf_sdh_ant.c receive SoC/BLE.ANT type events from nrf_sdh. The received events will be dispatch to handlers registered to nrf_sdh_soc/nrf_sdh_ble/nrf_sdh_ant components in sdh_soc_observerssdh_ble_observers and sdh_ble_observers sections. So, one change from SDK v13.0 is the event handler like ble_evt_dispatch() now registered to nrf_sdh_ble component, but the handler can still be implemented in application or a lib with SDH macro API NRF_SDH_BLE_OBSERVER.

Register with the nrf_sdh_* components

The propagation part between nrf_sdh and nrf_sdh_* are fixed implemented as part of SDK architecture; while the handlers as reaction to events are application interfaced to users in nrf_sdh_* components.

Each part of an application or driver that wants to receive events from the different components of the SDH library must register itself at compile time and use the following macros specified in the Library components section sdh_*_observers where the macro is wrapped up from the macro of Section Variables.

What is an Observer?

A registered part of an application becomes an observer listening to events or requests, and also a handler function with context and priority. See the following example registering to sdh_ble_observers section and works as an BLE observer. As its name indicated, a BLE observer will listen to BLE related events or requests, so it uses the SDH BLE macro NRF_SDH_BLE_OBSERVER

Observers’ Priorities

A number that specifies the order in which it receives events from the same component with respect to other handlers. The same priority is possible but depends on the order in which the linker encounters the handlers during the linking process. Care must be taken when set priority for observers with dependency.

Linker Script

As current SDK since v13 has been implemented with SDH, it can be found various pre-defined SDH section for each component in .ld file with section name and some SDH symbols. SDK uses these section names and symbols to identify a corresponding registered callback handler.

Section Variables

Another library Section Variable in SDK also works in almost the same way as SDH. It allow registrants which usually software modules to register its variables and callbacks to registrar created section which can be found in linker script or source code. These software method creates a more modulized SDK.

Registrants create sections by macro NRF_SECTION_DEF(section_name, data_type) with defined section_name and symbols in linker script. An example of fs module is shown.


Registrants register their variables and callbacks to a created section by NRF_SECTION_ITEM_REGISTER(section_name, data_type_t var_name) = {var_value};

To make application more readable, the section registration macro of a module is usually re-defined to a module name macro.