Back to Tock

IEEE 802.15.4

doc/syscalls/30001_ieee802154.md

latest14.4 KB
Original Source

IEEE 802.15.4

Overview

Tock exposes two userland interfaces that share driver number 0x30001to support two different implementations of an IEEE 802.15.4 stack in the kernel: The standard (MAC) interface and the physical (raw) interface. The standard interface implements packet framing and a MAC layer, virtualizes the 15.4 interface, and provides a multi-programmable userspace interface. It is appropriate for applications that want to send payloads while relying on the kernel for 802.15.4 framing/security. The second interface, the physical interface, provides userspace with the ability to send/receive raw 802.15.4 frames as well as directly control the radio, and is appropriate for processes that need raw 802.15.4 communication and direct radio control.

Standard (MAC) interface

The Standard (MAC) interface (capsules/extra/src/ieee802154/driver.rs) has the following properties:

  • Uses the in-kernel 802.15.4 stack to build headers, handle security, and multiplex access across multiple processes.
  • Userland provides payloads plus metadata; the kernel prepares frames and handles encryption/MIC when requested.
  • Supports neighbor and key management for link-layer security.

The stack is:

text
┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ Syscall Interface
┌──────────────────────┐
│     RadioDriver      │
└──────────────────────┘
┄┄ ieee802154::device::MacDevice ┄┄
┌──────────────────────┐
│      VirtualMac      │
└──────────────────────┘
┄┄ ieee802154::device::MacDevice ┄┄
┌──────────────────────┐
│        Framer        │
└──────────────────────┘
┄┄ ieee802154::mac::Mac ┄┄
┌──────────────────────┐
│  MAC (ex: AwakeMac)  │
└──────────────────────┘
┄┄ hil::radio::Radio ┄┄
┌──────────────────────┐
│    802.15.4 Radio    │
└──────────────────────┘

PHY (raw) interface

  1. PHY (raw) interface (capsules/extra/src/ieee802154/phy_driver.rs)
    • Exposes the radio directly with minimal framing support.
    • Userland provides full 802.15.4 MAC frames without the FCS/CRC bytes as defined in Figure 7-1 of the IEEE 802.15.4-2020 specification.
    • Intended for single-process access or custom stacks that want complete control over framing and radio parameters.

The stack is:

text
┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ Syscall Interface
┌─────────────────────────┐
│ phy_driver::RadioDriver │
└─────────────────────────┘
┄┄ hil::radio::Radio ┄┄
┌─────────────────────────┐
│     802.15.4 Radio      │
└─────────────────────────┘

Selecting MAC vs PHY at build time (board main.rs)

Both the Standard (MAC) interface and the PHY (raw) interface intentionally share the same driver number (0x30001). This means userspace does not choose which implementation it is talking to at runtime. Instead, the choice is locked in when the kernel is built by the board configuration.

Concretely:

  • The board constructs either the MAC capsule (capsules/extra/src/ieee802154/driver.rs) or the raw PHY capsule (capsules/extra/src/ieee802154/phy_driver.rs) in its main.rs.
  • The board then exposes that capsule by returning it from SyscallDriverLookup::with_driver() when driver_num == capsules_extra::ieee802154::DRIVER_NUM.

General guidance for board authors:

  • To expose the PHY (raw) interface, use components::ieee802154::Ieee802154RawComponent (which instantiates capsules_extra::ieee802154::phy_driver::RadioDriver).
  • To expose the Standard (MAC) interface, use components::ieee802154::Ieee802154Component (which instantiates capsules_extra::ieee802154::RadioDriver) and provide an AES-CCM mux (the MAC interface uses link-layer security/framing support).

Notes:

  • Only one implementation should be mapped to driver number 0x30001 in a given kernel image. If a userspace app uses commands that are not supported by the compiled-in implementation, the kernel will return NOSUPPORT.

Allow

Standard (MAC) interface

  • Description: allow() is used to share buffers with the kernel.

  • Read-Only Allow Number: 0

    Description: Write buffer containing the payload to transmit. The kernel appends the payload to the constructed 802.15.4 frame.

    Argument 1: Slice containing the payload.

    Returns: Ok(()).

  • Read-Write Allow Number: 0

    Description: Read ring buffer for received frames. The ring buffer format is:

    text
    | read index | write index | user_frame 0 | user_frame 1 | ... | user_frame n |
    

    Each user_frame stores three metadata bytes followed by the 802.15.4 frame:

    text
    | header_len | payload_len | mic_len | 15.4 frame |
    

    Argument 1: Slice for the ring buffer (must be sized as 2 + n * (3 + MAX_FRAME_SIZE)).

    Returns: Ok(()).

  • Read-Write Allow Number: 1

    Description: Config buffer used by specific commands to pass additional parameters or return data. The required size depends on the command.

    Argument 1: Slice for command-specific configuration data.

    Returns: Ok(()).

PHY (raw) interface

  • Description: allow() is used to share buffers with the kernel.

  • Read-Only Allow Number: 0

    Description: Write buffer containing the raw 802.15.4 MAC frame without the FCS/CRC. The buffer length must match the MAC frame length minus the length of the FCS/SRC.

    Argument 1: Slice containing the frame bytes.

    Returns: Ok(()).

  • Read-Write Allow Number: 0

    Description: Read ring buffer for received frames, with the same format as the standard interface. The PHY driver sets header_len and mic_len to 0 because it does not parse or secure frames.

    Argument 1: Slice for the ring buffer.

    Returns: Ok(()).

Subscribe

Both interfaces use the same subscribe numbers:

  • Subscribe Number: 0

    Description: Callback when a frame is received.

    Argument 1: LQI (link quality indicator).

    Argument 2: Unused.

    Argument 3: Unused.

    Returns: Ok(()).

  • Subscribe Number: 1

    Description: Callback when a frame transmission completes.

    Argument 1: Status code (success or error).

    Argument 2: acked flag (0/1) indicating whether the frame was acked.

    Argument 3: Unused.

    Returns: Ok(()).

Command

Many commands need more data than fits in the two integer arguments provided to the kernel command() syscall. In Tock, a driver’s kernel entrypoint receives only command_num, arg1, and arg2 (plus the calling process identity). When a command needs additional input or needs to return structured output, the process must first share an allow() buffer with the driver.

In this document, we refer to that extra shared buffer as “Argument 3” (for historical TRD-style terminology). For the IEEE 802.15.4 standard (MAC) interface, “Argument 3: app_cfg” means the driver will read/write the config buffer at RW allow number 1 (CFG). For example, command 3 (“set long address”) reads 8 bytes from that CFG buffer and uses them as the long MAC address.

Standard (MAC) interface commands

  • Command Number: 0

    Description: Existence check.

    Returns: Ok(()).

  • Command Number: 1

    Description: Return radio status (Ok(()) if on, OFF if off).

  • Command Number: 2

    Description: Set short address.

    Argument 1: Short address.

  • Command Number: 3

    Description: Set long address.

    Argument 1: Unused.

    Argument 2: Unused.

    Argument 3: app_cfg must be 8 bytes containing the long address.

  • Command Number: 4

    Description: Set PAN ID.

    Argument 1: PAN ID.

  • Command Number: 5

    Description: Set channel (not supported; returns NOSUPPORT).

  • Command Number: 6

    Description: Set transmission power (not supported; returns NOSUPPORT).

  • Command Number: 7

    Description: Commit configuration changes.

  • Command Number: 8

    Description: Get short address.

    Returns: SuccessWithValue (address + 1).

  • Command Number: 9

    Description: Get long address.

    Argument 3: app_cfg must be 8 bytes to receive the long address.

  • Command Number: 10

    Description: Get PAN ID.

    Returns: SuccessWithValue (PAN + 1).

  • Command Number: 11

    Description: Get channel (not supported; returns NOSUPPORT).

  • Command Number: 12

    Description: Get transmission power (not supported; returns NOSUPPORT).

  • Command Number: 13

    Description: Get maximum number of neighbors.

    Returns: SuccessWithValue (max + 1).

  • Command Number: 14

    Description: Get current number of neighbors.

    Returns: SuccessWithValue (count + 1).

  • Command Number: 15

    Description: Get short address of neighbor at index.

    Argument 1: Neighbor index.

    Returns: SuccessWithValue (short address + 1).

  • Command Number: 16

    Description: Get long address of neighbor at index.

    Argument 1: Neighbor index.

    Argument 3: app_cfg must be 8 bytes to receive the long address.

  • Command Number: 17

    Description: Add neighbor.

    Argument 1: Short address.

    Argument 3: app_cfg must be 8 bytes containing the long address.

    Returns: SuccessWithValue (neighbor index + 1).

  • Command Number: 18

    Description: Remove neighbor.

    Argument 1: Neighbor index.

  • Command Number: 19

    Description: Get maximum number of keys.

    Returns: SuccessWithValue (max + 1).

  • Command Number: 20

    Description: Get current number of keys.

    Returns: SuccessWithValue (count + 1).

  • Command Number: 21

    Description: Get security level of key at index.

    Argument 1: Key index.

    Returns: SuccessWithValue (security level + 1).

  • Command Number: 22

    Description: Get key ID of key at index.

    Argument 1: Key index.

    Argument 3: app_cfg must be 10 bytes; returns key ID mode + key ID.

  • Command Number: 23

    Description: Get key material at index.

    Argument 1: Key index.

    Argument 3: app_cfg must be 16 bytes to receive the key.

  • Command Number: 24

    Description: Add key.

    Argument 3: app_cfg must be 27 bytes:

    • 1 byte security level
    • 1 byte key ID mode
    • up to 9 bytes key ID (depending on mode)
    • 16 bytes key material

    Returns: SuccessWithValue (key index + 1).

  • Command Number: 25

    Description: Remove key.

    Argument 1: Key index.

  • Command Number: 26

    Description: Transmit a frame using the in-kernel parser/framer.

    Argument 1: Destination short address.

    Argument 3: app_cfg must be 11 bytes:

    • 1 byte security level
    • 10 bytes key ID encoding (mode + key ID)

    Returns: Ok(()) if queued or immediate success; errors include BUSY if a transmission is already pending or INVAL for bad buffers/parameters.

  • Command Number: 28

    Description: Set long address using two 32-bit words.

    Argument 1: Lower 32 bits.

    Argument 2: Upper 32 bits.

  • Command Number: 29

    Description: Get long address as a 64-bit value.

    Returns: SuccessWithValue64.

  • Command Number: 30

    Description: Turn the radio on.

PHY (raw) interface commands

  • Command Number: 0

    Description: Existence check.

  • Command Number: 1

    Description: Return radio status (Ok(()) if on, OFF if off).

  • Command Number: 2

    Description: Set short address.

    Argument 1: Short address.

  • Command Number: 4

    Description: Set PAN ID.

    Argument 1: PAN ID.

  • Command Number: 5

    Description: Set channel.

    Argument 1: Channel number.

  • Command Number: 6

    Description: Set transmission power.

    Argument 1: Signed power value.

  • Command Number: 7

    Description: Commit configuration changes.

  • Command Number: 8

    Description: Get short address.

    Returns: SuccessWithValue (address + 1).

  • Command Number: 10

    Description: Get PAN ID.

    Returns: SuccessWithValue (PAN + 1).

  • Command Number: 11

    Description: Get channel.

    Returns: SuccessWithValue (channel number).

  • Command Number: 12

    Description: Get transmission power.

    Returns: SuccessWithValue (power value).

  • Command Number: 27

    Description: Transmit a raw frame. The write buffer must contain the MAC frame without the FCS/CRC bytes.

  • Command Number: 28

    Description: Set long address using two 32-bit words.

    Argument 1: Lower 32 bits.

    Argument 2: Upper 32 bits.

  • Command Number: 29

    Description: Get long address as a 64-bit value.

    Returns: SuccessWithValue64.

  • Command Number: 30

    Description: Turn the radio on.

  • Command Number: 31

    Description: Turn the radio off.