Expand description
X-MAC protocol layer for low power 802.15.4 reception, intended primarily to manage an Atmel RF233 radio.
Original X-MAC paper, on which this implementation is heavily based: http://www.cs.cmu.edu/~andersoe/papers/xmac-sensys.pdf
Nodes using this layer place their radios to sleep for the vast majority of
the time, thereby reducing power consumption. Transmitters wake and send a
stream of small, strobed preamble
packets to the desired recipient. If a
receiver wakes and ACKS a relevant preamble, the receiver waits for a data
packet before returning to sleep. See comments below for implementation
details.
Additional notes:
- Since much of a node’s time is spent sleeping, transmission latency is much higher than using a radio that is always powered on.
- Err(ErrorCode::NOACK)s may be generated when transmitting, if the destination node cannot acknowledge within the maximum retry interval.
- Since X-MAC relies on proper sleep/wake behavior for all nodes, any node with this implementation will not be able to communicate correctly with non-XMAC-wrapped radios.
§Usage
This capsule implements the capsules::ieee802154::mac::Mac
interface while
wrapping an actual kernel::hil::radio::Radio' with a similar interface, and can be used as the backend for a
capsules::ieee802154::device::MacDevice`,
which should fully encode frames before passing it to this layer.
In general, given a radio driver RF233Device
,
a kernel::hil::time::Alarm
, and a kernel::hil::rng::Rng
device, the
necessary modifications to the board configuration are shown below for imix
s:
// main.rs
use capsules::ieee802154::mac::Mac;
use capsules::ieee802154::xmac;
type XMacDevice = capsules::ieee802154::xmac::XMac<'static, RF233Device, Alarm>;
// ...
// XMac needs one buffer in addition to those provided to the RF233 driver.
// 1. stores actual packet contents to free the SPI buffers used by the
// radio for transmitting preamble packets
static mut MAC_BUF: [u8; radio::MAX_BUF_SIZE] = [0x00; radio::MAX_BUF_SIZE];
// ...
let xmac: &XMacDevice = static_init!(XMacDevice, xmac::XMac::new(rf233, alarm, rng, &mut MAC_BUF));
rng.set_client(xmac);
alarm.set_client(xmac);
// Hook up the radio to the XMAC implementation.
rf233.set_transmit_client(xmac);
rf233.set_receive_client(xmac, &mut RF233_RX_BUF);
rf233.set_power_client(xmac);
xmac.initialize();
// We can now use the XMac driver to instantiate a MacDevice like a Framer
let mac_device = static_init!(
capsules::ieee802154::framer::Framer<'static, XMacDevice>,
capsules::ieee802154::framer::Framer::new(xmac));
xmac.set_transmit_client(mac_device);
xmac.set_receive_client(mac_device);
xmac.set_config_client(mac_device);