doc/memos/rdm0004.md
This memo describes a Hardware Abstraction Layer (HAL) for radios compliant with the IEEE802.15.4 standard. The work follows a technology-specific approach to provide well defined hardware access that allows to implement agnostic IEEE802.15.4 PHY and MAC layers on top. Additionally, the new HAL enables integration of network stacks that require direct access to the radio.
This document is currently under open discussions. The content of this document is licensed with a Creative Commons CC-BY-SA license.
This memo uses the RFC2119 terminology and the following acronyms and definitions:
This document is a product of the Uniform Network Stack Integration and aims to describe the architecture of a Hardware Abstraction Layer for IEEE802.15.4 compliant radios.
The IEEE802.15.4 Radio HAL abstracts common functionalities of IEEE802.15.4 compliant radios such as loading packets, transmitting, configuring PHY parameters, etc. This abstraction is required for upper layers that require hardware-independent access to drive IEEE802.15.4 radio devices (802.15.4 MAC, network stacks, test applications, etc).
In the current RIOT lower network stack architecture, all network interfaces
are driven by the netdev interface. The work presented in this document
addresses deficits of using netdev as a Hardware Abstraction Layer:
netdev is too generic to be used as a HAL to cover the wide range of
different technologies in RIOT (IEEE802.15.4, BLE, Ethernet, WiFi,
Proprietary devices, ...). The semantics of a standardized radio are
technology specific and in most cases well defined. In the case of
IEEE802.15.4 devices, they are defined by the IEEE.netdev includes PHY and MAC components that are not in the scope of a
hardware abstraction layer. The netdev interface is implemented as a device
driver but it additionally includes technology-dependent components for every
single device. For the case of IEEE802.15.4, this includes components of the
802.15.4 MAC/PHY such as transmission of Physical Service Data Units (PSDU),
or retransmissions with CSMA-CA and ACK handling. As a consequence,
code is duplicated, feature sets of similar devices heavily depend on the
specific implementation, and integration of new devices is more complex than
need be. Furthermore, duplication and unspecified device access complicate
code maintenance.netdev hardcodes MAC layer functionalities, which is likely the consequence
of hardware MAC acceleration on certain devices. These capabilities are
currently only available if the hardware provides integrated support. An
indication mechanism which MAC features are provided within a netdev
implementation is missing. A full MAC layer that is situated on top of the HAL
requires a defined access to specific radio functionalities in order to meet
timing constraints or energy requirements. That means, varying properties
between implementations and partly implemented MAC features within the device
driver interfere with the concept of transparent hardware access by one MAC
layer implementation.Other components of the 802.15.4 MAC are present in the GNRC Netif
implementation for the 802.15.4 Link Layer (gnrc_netif_ieee802154). These
components prepare and parse 802.15.4 frames in order to send and receive data.
However, mandatory 802.15.4 MAC features are missing (commissioning, security,
channel scanning, etc). One major drawback of this approach is the fact that
802.15.4 MAC components of gnrc_netif_ieee802154 are GNRC specific and
cannot be reused in other network stacks that require a 802.15.4 MAC.
As a solution, the lower layer should be separated into three main components:
The 802.15.4 MAC and netif are not part of this document, but they are affected by this work, thus, they are mentioned to give an outlook for upcoming efforts on the lower network stack.
The following picture compares the current RIOT lower network stack
architecture (left) with the approach described in this document (right). As
can be seen, the new approach adds IEEE802.15.4 specific APIs and layers
between the lower layer network stack interface (GNRC Netif) and the hardware
dependent device driver. In contrast, the netdev based solution misses a
specific Radio HAL which prevents to run a hardware-agnostic MAC on top.
OLD | NEW
=== | ===
|
+---------------------+ | +---------------------+ +---------------------+
| | | | | | |
| GNRC Network Stack | | | GNRC Network Stack | | |
| | | | | | |
+---------------------+ | +---------------------+ | |
^ | ^ | |
| | | | |
gnrc_netapi | gnrc_netapi | OpenThread, OpenWSN |
| | | | |
v | v | |
+---------------------+ | +---------------------+ | |
| | | | | | |
| GNRC Netif | | | GNRC Netif | | |
| | | | | | |
+---------------------+ | +---------------------+ +---------------------+
^ | ^ ^
| | | |
gnrc_netif_ops_t | gnrc_netif_ops_t |
| | | |
v | v |
+---------------------+ | +---------------------+ |
| | | | | |
|gnrc_netif_ieee802154| | |gnrc_netif_ieee802154| |
| | | | | |
+---------------------+ | +---------------------+ |
^ | ^ |
| | | |
| | 802.15.4 MAC API Radio HAL API
| | | |
| | v |
| | +---------------------+ |
| | | | |
netdev_driver_t | | 802.15.4 MAC | |
| | | | |
| | +---------------------+ |
| | ^ |
| | | |
| | Radio HAL API ----------------+
| | | |
v | v v
+---------------------+ | +---------------------+-------------------------+
| | | | | | |
| netdev | Device | | | 802.15.4 Radio HAL | |
| | Driver | | | | Device Driver |
|----------+ | | +---------------------+ |
| | | | |
+---------------------+ | +-----------------------------------------------+
+-----------------------------------------------------------------------------+
| |
| Upper layer |
| |
+-----------------------------------------------------------------------------+
| ^
| |
| |
| |
Radio Ops Event Notification +----------------------------+
| | IRQ Handler | |
| | +----------------------| Bottom-Half processor |
| | | | |
| | | +----------------------------+
| | | ^
| | | |
v | v IRQ
+-----------------------------+ |
| 802.15.4 Radio HAL | HW independent |
|-----------------------------|-------------------------------|----------------
| | HW dependent |
| | |
| Device Driver | |
| |-------------------------------+
| |
+-----------------------------+
As shown in the above figure, the IEEE802.15.4 Radio HAL is a central component that provides any upper layer a technology-dependent and unified access to the device driver, by implementing the Radio HAL API.
The HAL uses an Event Notification mechanism to inform the upper layer about
radio events (IEEE802154_RADIO_CONFIRM_TX_DONE,
IEEE802154_RADIO_INDICATION_RX_DONE, IEEE802154_RADIO_CONFIRM_CCA, etc).
This mechanism can either run in interrupt context or thread context, if the
device is not able to resolve events during ISR (e.g SPI devices). For the
latter, the radio HAL requires an upper layer to take over the Bottom-Half
processing which means, offloading the ISR to thread context.
Upper layers are users that requires direct access to the primitive operations of a radio and its hardware acceleration features, if available.
Examples for Upper Layers:
The upper layer accesses the radio using the Radio HAL API. Events that are triggered by the device (packet received, transmission finished) are indicated by the event notification mechanism, described below.
The Bottom-Half (BH) processor is a component to offload the IRQ processing to thread context. The component is required for radios that cannot resolve radio events during ISR (SPI devices).
The component registers an IRQ handler during initialization which is executed when the device triggers and interrupt. This handler uses internal mechanisms to call the Radio API IRQ handler from a safe context. The IRQ handler may run on a higher priority context. Although the API implementation SHOULD NOT implement reentrancy, it MUST handle concurrent calls between the IRQ handler and API functions.
The BH processor can be implemented dependent or independent of the network stack. A network stack independent solution is preferred in order to reuse functionality between different network stacks.
The term "Bottom Half" was originally introduced by the Linux kernel. See Top and Bottom Halves
The Radio HAL is defined by the Radio HAL API which consists of three main components: Radio Operations, Event Notification, and the Device Specific IEEE802.15.4 HAL implementation.
The Radio HAL Implementation provides a set of functionalities to control the operation of the device, to process the IRQ handler and to receive event notifications from the device.
The Radio Operations (radio_ops) interface exposes operations that are common
to control 802.15.4 devices and to request their hardware capabilities
information (i.e., MAC acceleration hardware)
The interface defines a collection of mandatory functions:
The interface provides a collection of optional functions that may or may not be implemented, dependent on the hardware acceleration features of a device. These functions include:
All radio_ops functions are non-blocking and some of them follow a
Request/Confirm scheme which means, the end of a request is indicated by a
confirmation function. The confirmation function may be polled. In such case,
the function uses standard error codes to indicate the status (success, error
or request has not finished).
The full list of functions can be found in the Interface Definition section.
The Radio HAL provides an Event Notification mechanism to inform the upper layer about an event (a packet was received, a transmission finished, etc).
The upper layer can subscribe to these events to perform different actions. As an example, a MAC layer would subscribe to the RX done event to allocate the received packet. The TX done event is commonly used to release resources or update statistics.
As described before, the Event Notification mechanism can be called during ISR
or thread context (BH processor). Thus, this must be taken into consideration
for the implementation of the Event Notification callback (e.g the
IEEE802154_RADIO_INDICATION_RX_DONE event might post an event to an event
queue in order to fetch the packet).
The full list of events and implications are defined in the Interface Definition section.
The Device Driver implements the hardware-dependent part of the IEEE802.15.4
Radio HAL by wrapping the radio_ops interface around the device specific
code, which grants access to all device operations.
The Device Driver additionally provides a mechanism to expose the ISR of radios that require the Bottom-Half processor.
The function set of the Device Driver can include device specific features that are not exposed by the Radio HAL API (e.g., Smart Listening with AT86RF2xx radios).
In order to implement the 802.15.4 abstraction on top of a device driver, it is required an initialization procedure that performs the following tasks:
The radio_ops interface provides an "on" function that turns on the device
and enables interrupts. It is expected that the upper layer will call this
function to enable the radio device, if the initialization procedure succeeded.
The Radio HAL defines an Abstract State Machine. In order to ensure a uniform behavior in all devices, all Radio HAL device drivers should be implemented against this. Transient states (e.g pending requests) are not included in this diagram. However, the upper layer MUST NOT trigger another request if there is already a pending one.
+---------+
| |
| OFF |<------ Any state
| | OFF
+---------+
|
ON |
|
v
+---------+
+--------| |--------+
| | TRX_OFF |<----+ |
| +----->| | | |
| | +---------+ | |
SET_TRX_STATE | | | | SET_TRX_STATE
| | | |
v | | v
+---------+ +---------+
| |------------->| |
| IDLE | | RX |
| |<-------------| |
+---------+ +---------+
SET_TRX_STATE
A specification for each state is described in the following items.
OFF: If radio initialization succeeds, the Abstract State Machine begins in
OFF state. During this state the device consumes the least power and all
hardware components (transceiver, crypto acceleration) are disabled.
TRX OFF: During this state the device is on but the transceiver is off (PLL
not locked). The power consumption is higher than the OFF state but the
device is able to operate the transceiver and other hardware components (e.g
crypto accelerator).
IDLE: This state is device specific and represents a state where the device is ready to transmit, fetch a received frame, change the Physical Information Base or perform Stand-Alone CCA.
RX ON: During RX ON state the radio is able to detect Start Frame Delimiter (SFD) and thus, receive frames.
The Radio HAL doesn't define an explicit send function. Unlike the netdev
approach, it bases on separation of the send procedure into frame loading
and triggering the transmissions start.
Although it is possible to load and start using the netdev interface with the
NETOPT_PRELOADING option, the Radio HAL approach is easier and more
lightweight to implement since it doesn't require internal state variables.
Separated load and start is required for MAC layers with timing constraints (E.g. TSCH mode of 802.15.4 MAC).
In the rare case a radio device doesn't support loading the frame buffer without triggering a transmission, it is still possible to implement the load and transmit pattern using an internal buffer. However, this case is very unlikely because such a device could not meet 802.15.4 timing requirements.
It is expected that a higher layer "send" function is defined for convenience which handles both loading and frame sending. Typically, this would be a 802.15.4 MAC implementation which preloads the devices buffer once accessible, and triggers a send operation at a scheduled time slot. Alternatively, this could be a helper function for non MAC users.
Sometimes upper layers require information associated to the transmission or reception of a packet. The TSCH mode of the 802.15.4 MAC may require LQI and RSSI data from a received packet to schedule new cells. The 802.15.4 MAC may also require the information associated to the frame retransmission component (frame pending bit, number of retransmission, status) if the hardware provides support for hardware retransmissions.
The 802.15.4 Radio HAL API provides functions to retrieve this data. Note that retrieving this information is optional in cases where the RX information is not needed or when the device doesn't support frame retransmissions.
The Radio Ops interface is implemented using function pointers.
These functions should be implemented with device specific validations only. Parameters that are not device specific (valid channel settings, address lengths, etc) should be checked by higher layers in order to avoids redundancy.
Note that the Radio Ops interface only implements a few get functions. The reason behind this is the fact most members of the PHY and MAC Information Base (such as address, TX power, channel number) are already stored in RAM.
The full documentation of Radio Ops functions is available in net/ieee802154/radio.h.
The following table summarizes the Radio Ops and the state in which the Ops can
be invoked (marked with X).
- Send/Receive
+---------------------------------+
|`OFF` | `TRX_OFF` | `IDLE` | `RX`|
+------------------------------------------------------------+
| `write` | _ | X | X | _ |
| `len` | _ | X | X | _ |
| `read` | _ | X | X | _ |
| `*_op(*_TRANSMIT)` | _ | _ | X | _ |
+------------------------------------------------------------+
- CCA related
+---------------------------------+
|`OFF` | `TRX_OFF` | `IDLE` | `RX`|
+------------------------------------------------------------+
| `set_cca_threshold` | [ ] | [X] | [X] | [X]|
| `set_cca_mode` | [ ] | [X] | [X] | [X]|
| `*_op(*_CCA)` | [ ] | [ ] | [X] | [ ]|
+------------------------------------------------------------+
- PIB/MIB related
+---------------------------------+
|`OFF` | `TRX_OFF` | `IDLE` | `RX`|
+------------------------------------------------------------+
| `config_phy` | [ ] | [X] | [X] | [ ]|
| `set_frame_retrans` | [ ] | [X] | [X] | [X]|
| `set_csma_params` | [ ] | [X] | [X] | [X]|
| `set_frame_filter_mode` | [ ] | [X] | [X] | [X]|
| `config_addr_filter` | [ ] | [X] | [X] | [X]|
| `config_src_addr_match` | [ ] | [X] | [X] | [X]|
+------------------------------------------------------------+
- Device State Management
+---------------------------------+
|`OFF` | `TRX_OFF` | `IDLE` | `RX`|
+------------------------------------------------------------+
| `*_op(*_SET_{IDLE,RX})` | [ ] | [X] | [X] | [X]|
| `*_on` | [X] | [ ] | [ ] | [ ]|
| `off` | [X] | [X] | [X] | [X]|
+------------------------------------------------------------+
The Event Notification mechanism is implemented with a function callback. The callback function is supposed to be implemented by the upper layer.
The events follow the naming convention of the IEEE Services Access Points (SAP). This means, events that are a triggered as a result of a Request are prefixed with "CONFIRM". All the other events are prefixed with "INDICATION".
The callback signature, the events and their expected behavior are documented
in net/ieee802154/radio.h.
MAC specific events such as TX done with frame pending, CSMA-CA medium busy or exceeded number of retransmissions are not explicitly reported because they can be extracted after the TX done event using the Radio HAL API.
Some radio devices support events such as ACK Timeout, CSMA Backoff timeout or PLL lock. Such events are out of the scope of this document. However, these may be added and implemented at any time if required by upper layers.
The following table summarizes the events, whether an event is mandatory, the states which may generate the event notification and special handling. Although mandatory events may be ignored or disabled by the upper layer, all Radio HAL implementations must generate at least the mandatory events. The presence of optional events MUST be indicated using Radio Caps (see Section 6.3).
Event | Mandatory | Trig. state |
+-------------------------------------------+-----------+-------------+
| IEEE802154_RADIO_INDICATION_RX_START | [ ] | RX |
| IEEE802154_RADIO_INDICATION_RX_DONE [1] | [X] | RX |
| IEEE802154_RADIO_INDICATION_CRC_ERROR [2] | [ ] | RX |
| IEEE802154_RADIO_INDICATION_TX_START | [ ] | IDLE |
| IEEE802154_RADIO_CONFIRM_TX_DONE [3] | [X] | IDLE |
| IEEE802154_RADIO_CONFIRM_CCA [4] | [ ] | IDLE |
+-------------------------------------------+-----------+-------------+
[1]: The upper layer MUST set the Abstract State Machine state to `IDLE` or
`TRX_OFF` before calling `read` or `len`.
[2]: Should be treated as the `IEEE802154_RADIO_INDICATION_RX_DONE` event. Use
the `read` function to drop the frame.
[3]: On occurrence, the upper layer MUST call
`confirm_op(IEEE802154_RADIO_CONFIRM_TX_DONE)` to finish the transmission. The
Abstract State Machine stays in IDLE.
[4]: On occurrence, the upper layer MUST call
`confirm_op(IEEE802154_RADIO_CONFIRM_CCA` to finish the CCA procedure and fetch
the channel state. The Abstract State Machine stays in IDLE, ready to transmit
the next frame.
The Radio HAL implementation exposes a set of capabilities (Caps) in order to
indicate the presence of a specific hardware feature. The Caps are encoded
using bit flags. The Radio HAL header defines a set of ieee802154_radio_has_*
functions that check whether the radio supports a capability.
See net/ieee802154/radio.h for a full list of capabilities.
A Radio HAL implementation MUST indicate all capabilities supported by the device and driver implementation.
The Radio HAL is designed to be agnostic to different versions of the IEEE802.15.4 standard. A single radio device typically implements hardware acceleration for only one standard, whereas different standards are not always compatible. As an example, IEEE802.15.4--2006 devices do not support Enhanced Acknowledgement packets which are required by the TSCH layer of IEEE802.15.4--2012. For compatibility, a software MAC can provide such functionality. The Radio HAL adapts considerations to enable different versions of the IEEE802.15.4 MAC on top of the abstraction layer.
The Radio HAL interface defines three transmission modes to allow sending frames using (i) CSMA-CA, (ii) CCA, or (iii) directly without any contention mechanism. In that way, a MAC layer can easily send data frames benefiting from hardware accelerated CSMA-CA or Beacons that have to meet timing constraints and thus, require a direct send function.
A HAL implementation can provide several transmit modes, but it MUST implement at least one. It is recommended that the implementation provides modes that exploit the internal devices capabilities. Implementing a direct mode is desired for software MAC layers on top.
PHY definitions are specific to a IEEE802.15.4 version. As an example, older
standards define PHY channels with a channel number. In modern standards,
channels are represented using a (channel number, channel page, channel modulation) tuple. The config_phy function is called with a pointer to a
ieee802154_phy_conf_t structure which describes the PHY configuration. In
order to support newer versions, this structure can be extended without changing
the Radio HAL API.
The Radio Operations interface radio_ops can be extended to support
functionalities of newer standards. As an example, most SubGHz radios support a
Listen Before Talk feature that can be implemented as a new and optional
operation.
Thanks to Peter Kietzmann, Benjamin Valentin, Marian Buschsieweke, Leandro Lanzieri and Martine Lenders for their reviews, comments and suggestions.
The author of this memo can be contacted via email at [email protected]