1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

Merge pull request #14120 from akshaim/Kconfig_lwmac

gnrc/lwmac : Expose configurations to Kconfig
This commit is contained in:
Leandro Lanzieri 2020-07-08 19:32:50 +02:00 committed by GitHub
commit ffee93deed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 327 additions and 150 deletions

View File

@ -47,7 +47,7 @@
* ## Simple retransmission scheme
* LWMAC adopts a simple retransmission scheme to enhance link reliability. The data
* packet will only be dropped in case the retransmission counter gets larger than
* @ref GNRC_LWMAC_MAX_DATA_TX_RETRIES.
* @ref CONFIG_GNRC_LWMAC_MAX_DATA_TX_RETRIES.
*
* ## Automatic phase backoff scheme
* LWMAC adopts an automatic phase backoff scheme to reduce WR (preamble) collision
@ -93,18 +93,20 @@ extern "C" {
* time is divided into repeated cycles (or, superframes), and in each
* cycle, a node only wakes up for a period of time for receiving potential
* incoming packets for itself. This macro defines the wake-up interval, or,
* in other words, defines the cycle duration used in LWMAC. If the wake-up interval
* is short, nodes will wake up more frequently, which also increases
* in other words, defines the cycle duration used in LWMAC. If the wake-up
* interval is short, nodes will wake up more frequently, which also increases
* the chances for receiving packets from neighbors (i.e., leads to higher
* throughput), but also results in higher power consumption.
* In LWMAC, by default, we regard the wake-up period as the beginning of a cycle.
* In LWMAC, by default, we regard the wake-up period as the beginning of a
* cycle.
*/
#ifndef GNRC_LWMAC_WAKEUP_INTERVAL_US
#define GNRC_LWMAC_WAKEUP_INTERVAL_US (200LU *US_PER_MS)
#ifndef CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US
#define CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US (200LU *US_PER_MS)
#endif
/**
* @brief The Maximum WR (preamble packet @ref gnrc_lwmac_frame_wr_t) duration time.
* @brief The Maximum WR (preamble packet @ref gnrc_lwmac_frame_wr_t) duration
* time.
*
* Since LWMAC adopts duty-cycle scheme, a node only wakes up for a short
* period in each cycle. Thus, to probe where is the wake-up period of the
@ -112,87 +114,95 @@ extern "C" {
* communication. To ensure that the receiver will catch at least one WR
* packet in one cycle, the sender repeatedly broadcasts a stream of WR packets
* with the broadcast duration (preamble duration) slightly longer period than
* @ref GNRC_LWMAC_WAKEUP_INTERVAL_US.
* @ref CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US.
*/
#ifndef GNRC_LWMAC_PREAMBLE_DURATION_US
#define GNRC_LWMAC_PREAMBLE_DURATION_US ((13LU *GNRC_LWMAC_WAKEUP_INTERVAL_US) / 10)
#define GNRC_LWMAC_PREAMBLE_DURATION_US ((13LU * CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US) / 10)
#endif
/**
* @brief Timeout to send the next WR in case no WA has been received during that
* time.
* @brief Timeout to send the next WR in case no WA has been received during
* that time.
*
* In LWMAC, when a sender initiates a transmission to a receiver, it starts with
* sending a stream of repeated WR packets with @ref GNRC_LWMAC_TIME_BETWEEN_WR_US interval
* between two consecutive WRs. After sending one WR (preamble) packet, the sender turns
* to the listen mode to receive the potential incoming WA (preamble-ACK) packet with
* a timeout of @ref GNRC_LWMAC_TIME_BETWEEN_WR_US. If no WA is received during
* @ref GNRC_LWMAC_TIME_BETWEEN_WR_US, the sender starts sending the next WR.
* It is referenced to the beginning of both WRs, but due to internal
* overhead, the exact spacing is slightly higher.
* The minimum possible value depends on the time it takes to completely
* send a WR with the given hardware (including processor) and data rate.
* In LWMAC, when a sender initiates a transmission to a receiver, it starts
* with sending a stream of repeated WR packets with
* @ref CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US interval between two consecutive
* WRs. After sending one WR (preamble) packet, the sender turns to the listen
* mode to receive the potential incoming WA (preamble-ACK) packet with a
* timeout of @ref CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US. If no WA is received
* during @ref CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US, the sender starts sending
* the next WR. It is referenced to the beginning of both WRs, but due to
* internal overhead, the exact spacing is slightly higher. The minimum
* possible value depends on the time it takes to completely send a WR with the
* given hardware (including processor) and data rate.
*/
#ifndef GNRC_LWMAC_TIME_BETWEEN_WR_US
#define GNRC_LWMAC_TIME_BETWEEN_WR_US (5U *US_PER_MS)
#ifndef CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US
#define CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US (5U *US_PER_MS)
#endif
/**
* @brief How long a node in LWMAC should keep awake and listen on the channel in one cycle.
* @brief How long a node in LWMAC should keep awake and listen on the channel
* in one cycle.
*
* LWMAC adopts the duty-cycle scheme that a node only wakes up for a short
* period of @ref GNRC_LWMAC_WAKEUP_DURATION_US in each cycle. In the rest of the cycle, the node
* turns off the radio to conserve power. @ref GNRC_LWMAC_WAKEUP_DURATION_US is set to twice the
* duration of @ref GNRC_LWMAC_TIME_BETWEEN_WR_US, to guarantee that the wake-up period is long
* enough that receiver will not miss the WR (preamble) packet.
* Receiver needs to support @ref NETDEV_EVENT_RX_STARTED event in order to use time-between-WR
* as a sensible default here. Otherwise the duration of WRs as well as longest
* possible data broadcasts need to be taken into account.
* period of @ref GNRC_LWMAC_WAKEUP_DURATION_US in each cycle. In the rest of
* the cycle, the node turns off the radio to conserve power.
* @ref GNRC_LWMAC_WAKEUP_DURATION_US is set to twice the duration of
* @ref CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US, to guarantee that the wake-up
* period is long enough that receiver will not miss the WR (preamble) packet.
* Receiver needs to support @ref NETDEV_EVENT_RX_STARTED event in order to use
* time-between-WR as a sensible default here. Otherwise the duration of WRs as
* well as longest possible data broadcasts need to be taken into account.
*/
#ifndef GNRC_LWMAC_WAKEUP_DURATION_US
#define GNRC_LWMAC_WAKEUP_DURATION_US (GNRC_LWMAC_TIME_BETWEEN_WR_US * 2)
#define GNRC_LWMAC_WAKEUP_DURATION_US (CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US * 2)
#endif
/**
* @brief How long broadcast packets @ref gnrc_lwmac_frame_broadcast_t will be sent to make sure
* every participant has received at least one copy.
* @brief How long broadcast packets @ref gnrc_lwmac_frame_broadcast_t will be
* sent to make sure every participant has received at least one copy.
*
* Since LWMAC adopts duty-cycle scheme, a node only wakes up for a short period in
* each cycle. Thus, when a node wants to broadcast a packet, it repeatedly broadcasts the
* packet for one @ref GNRC_LWMAC_BROADCAST_DURATION_US duration which is slightly longer
* than @ref GNRC_LWMAC_WAKEUP_INTERVAL_US. This is to ensure that all neighbors will not miss
* the broadcast procedure of the sender and catch at least one copy of the broadcast packet.
* Since LWMAC adopts duty-cycle scheme, a node only wakes up for a short
* period in each cycle. Thus, when a node wants to broadcast a packet, it
* repeatedly broadcasts the packet for one
* @ref GNRC_LWMAC_BROADCAST_DURATION_US duration which is slightly longer
* than @ref CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US. This is to ensure that all
* neighbors will not miss the broadcast procedure of the sender and catch at
* least one copy of the broadcast packet.
*/
#ifndef GNRC_LWMAC_BROADCAST_DURATION_US
#define GNRC_LWMAC_BROADCAST_DURATION_US ((GNRC_LWMAC_WAKEUP_INTERVAL_US * 11) / 10)
#define GNRC_LWMAC_BROADCAST_DURATION_US ((CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US * 11) / 10)
#endif
/**
* @brief Time to idle between two successive broadcast packets, referenced to the
* start of the packet.
* @brief Time to idle between two successive broadcast packets, referenced to
* the start of the packet.
*
* The same limitation as for @ref GNRC_LWMAC_TIME_BETWEEN_WR_US apply here.
* In LWMAC, when a sender initiates a broadcast, it starts with sending a stream of
* repeated broadcast packets with @ref GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US interval
* between two consecutive broadcast packets. After sending one broadcast packet, the sender
* turns to the listen mode with a timeout of @ref GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US. When this
* timeout expires, the sender sends the next broadcast packet until reaching the maximum
* broadcast duration of @ref GNRC_LWMAC_BROADCAST_DURATION_US.
* The same limitation as for @ref CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US apply
* here. In LWMAC, when a sender initiates a broadcast, it starts with sending
* a stream ofrepeated broadcast packets with
* @ref GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US interval between two consecutive
* broadcast packets. After sending one broadcast packet, the sender turns to
* the listen mode with a timeout of
* @ref GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US. When this timeout expires, the
* sender sends the next broadcast packet until reaching the maximum broadcast
* duration of @ref GNRC_LWMAC_BROADCAST_DURATION_US.
*/
#ifndef GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US
#define GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US (GNRC_LWMAC_TIME_BETWEEN_WR_US)
#define GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US (CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US)
#endif
/**
* @brief WR preparation overhead before it can be sent (higher with debugging output).
* @brief WR preparation overhead before it can be sent (higher with debugging
* output).
*
* In LWMAC, when a sender wants to send a data packet to the receiver, it starts
* sending the WR stream a little bit earlier (advance) to the beginning edge
* of destination's wake-up phase over time. The idea is not to miss the wake-up
* period of the receiver, otherwise will lead to a long WR procedure.
* In LWMAC, when a sender wants to send a data packet to the receiver, it
* starts sending the WR stream a little bit earlier (advance) to the beginning
* edge of destination's wake-up phase over time. The idea is not to miss the
* wake-up period of the receiver, otherwise will lead to a long WR procedure.
*/
#ifndef GNRC_LWMAC_WR_PREPARATION_US
#define GNRC_LWMAC_WR_PREPARATION_US ((3U *US_PER_MS))
#ifndef CONFIG_GNRC_LWMAC_WR_PREPARATION_US
#define CONFIG_GNRC_LWMAC_WR_PREPARATION_US ((3U *US_PER_MS))
#endif
/**
@ -200,95 +210,109 @@ extern "C" {
*
* When a node in LWMAC gets a WR during its wake-up period, it immediately
* replies a WA packet to the sender for acknowledging the sender's transmission
* request. After sending the WA, the receiver waits for the data packet from the
* sender, with a timeout of @ref GNRC_LWMAC_DATA_DELAY_US duration. In case no data will be
* received in this period, the receiver regards reception failed and go back to
* normal listen mode. However, in case the receiver receives other unintended packets,
* like WR/WA packets from other neighbor communication pairs, the receiver resets
* this timeout and continues to wait for the data packet, with the consideration that
* the sender's data transmission might be delayed due to other ongoing transmissions
* (the data packet is transmitted with CSMA/CA).
* This data timeout is long enough to catch the beginning of the packet if the transceiver
* supports @ref NETDEV_EVENT_RX_STARTED event (this can be important for big packets).
* request. After sending the WA, the receiver waits for the data packet from
* the sender, with a timeout of @ref CONFIG_GNRC_LWMAC_DATA_DELAY_US duration.
* In case no data will be received in this period, the receiver regards
* reception failed and go back to normal listen mode. However, in case the
* receiver receives other unintended packets, like WR/WA packets from other
* neighbor communication pairs, the receiver resets this timeout and continues
* to wait for the data packet, with the consideration that the sender's data
* transmission might be delayed due to other ongoing transmissions (the data
* packet is transmitted with CSMA/CA). This data timeout is long enough to
* catch the beginning of the packet if the transceiver supports
* @ref NETDEV_EVENT_RX_STARTED event (this can be important for big packets).
*/
#ifndef GNRC_LWMAC_DATA_DELAY_US
#define GNRC_LWMAC_DATA_DELAY_US (10U *US_PER_MS)
#ifndef CONFIG_GNRC_LWMAC_DATA_DELAY_US
#define CONFIG_GNRC_LWMAC_DATA_DELAY_US (10U *US_PER_MS)
#endif
/**
* @brief CSMA retries for DATA packet after WR->WA was successful.
*
* After receiving the WA packet @ref gnrc_lwmac_frame_wa_t from the receiver, the sender
* starts sending the data packet using CSMA/CA. This macro defines how many CSMA retries
* a sender will be allowed to execute for sending its data, before the data is successfully
* sent (gets data ACK from the receiver).
* After receiving the WA packet @ref gnrc_lwmac_frame_wa_t from the receiver,
* the sender starts sending the data packet using CSMA/CA. This macro defines
* how many CSMA retries a sender will be allowed to execute for sending its
* data, before the data is successfully sent (gets data ACK from the receiver).
*/
#ifndef GNRC_LWMAC_DATA_CSMA_RETRIES
#define GNRC_LWMAC_DATA_CSMA_RETRIES (3U)
#ifndef CONFIG_GNRC_LWMAC_DATA_CSMA_RETRIES
#define CONFIG_GNRC_LWMAC_DATA_CSMA_RETRIES (3U)
#endif
/**
* @brief Maximum TX transmission retries for DATA packet in case of no response from the receiver.
* @brief Maximum TX transmission retries for DATA packet in case of no
* response from the receiver.
*
* When a data packet is scheduled for transmission, i.e., pushed into TX for sending,
* LWMAC defines a maximum of @ref GNRC_LWMAC_MAX_DATA_TX_RETRIES retries for transmission of the
* packet. That is, in case of transmission failure in TX due to no WA from the receiver,
* the sender will not drop the packet, but keeps it and retries to send the data packet
* in the following cycles, until the sender reaches the maximum retries limit defined here.
* Then, the packet will be dropped.
* When a data packet is scheduled for transmission, i.e., pushed into TX for
* sending, LWMAC defines a maximum of
* @ref CONFIG_GNRC_LWMAC_MAX_DATA_TX_RETRIES retries for transmission of the
* packet. That is, in case of transmission failure in TX due to no WA from the
* receiver, the sender will not drop the packet, but keeps it and retries to
* send the data packet in the following cycles, until the sender reaches the
* maximum retries limit defined here. Then, the packet will be dropped.
*/
#ifndef GNRC_LWMAC_MAX_DATA_TX_RETRIES
#define GNRC_LWMAC_MAX_DATA_TX_RETRIES (3U)
#ifndef CONFIG_GNRC_LWMAC_MAX_DATA_TX_RETRIES
#define CONFIG_GNRC_LWMAC_MAX_DATA_TX_RETRIES (3U)
#endif
/**
* @brief MAX burst transmission packet number in one shot.
*
* LWMAC supports burst transmission based on the pending-bit technique, and this macro
* here defines the largest number of packets allowed to be sent in one consecutive
* sequence. In case a sender has multi packets for one receiver,the burst transmission
* procedure is as follow:
* 1. The sender first uses WR stream to locate the receiver's wake-up period (if the
* sender has already phase-locked the receiver's phase, normally the sender only cost
* one WR to get the first WA from the receiver) and then sends its first data.
* 2. After the transmission of the first data, the sender immediately sends a WR to
* the receiver for starting the second round of transmission of the second data. The
* receiver should also immediately reply WA for continue receiving data packets. In
* case the sender doesn't receive WA during @ref GNRC_LWMAC_TIME_BETWEEN_WR_US, it regards the
* consecutive (burst) transmission failed and quits TX procedure (the data will be queued
* back to the transmission queue for normal transmission attempt in following cycles).
* 3. In case the second transmission succeeds, the sender repeats step (2) to send all the
* following pending packets.
* In short, in burst transmission mode, the sender doesn't tolerate no-WA event. ALl the
* pending data packets should be sent with only one WR cost for leading the transmission.
* LWMAC supports burst transmission based on the pending-bit technique, and
* this macro here defines the largest number of packets allowed to be sent in
* one consecutive sequence. In case a sender has multi packets for one
* receiver,the burst transmission procedure is as follows:
*
* 1. The sender first uses WR stream to locate the receiver's wake-up period
* (if the sender has already phase-locked the receiver's phase, normally
* the sender only cost one WR to get the first WA from the receiver) and
* then sends its first data.
* 2. After the transmission of the first data, the sender immediately sends a
* WR to the receiver for starting the second round of transmission of the
* second data. The receiver should also immediately reply WA for continue
* receiving data packets. In case the sender doesn't receive WA during
* @ref CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US, it regards the consecutive
* (burst) transmission failed and quits TX procedure (the data will be
* queued back to the transmission queue for normal transmission attempt in
* following cycles).
* 3. In case the second transmission succeeds, the sender repeats step (2) to
* send all the following pending packets.
*
* In short, in burst transmission mode, the sender doesn't tolerate no-WA
* event. All the pending data packets should be sent with only one WR cost for
* leading the transmission.
*/
#ifndef GNRC_LWMAC_MAX_TX_BURST_PKT_NUM
#define GNRC_LWMAC_MAX_TX_BURST_PKT_NUM (GNRC_LWMAC_WAKEUP_INTERVAL_US / GNRC_LWMAC_WAKEUP_DURATION_US)
#define GNRC_LWMAC_MAX_TX_BURST_PKT_NUM \
(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US / GNRC_LWMAC_WAKEUP_DURATION_US)
#endif
/**
* @brief MAX bad Listen period extensions a node can tolerate.
*
* In LWMAC, to allow burst transmissions, when in the wake-up period and by default, a node
* will extend its wake-up period to another @ref GNRC_LWMAC_WAKEUP_DURATION_US after each packet
* reception (except for broadcast packet). However, in some cases, a receiver may
* overhear other unintended packets, e.g., WR or WA packets for other nodes, these are
* called bad extensions for the receiver. If a receiver reaches the maximum bad listen
* extension limit defined here, it goes to sleep mode with the consideration that the
* channel is currently unavailable/busy.
* In LWMAC, to allow burst transmissions, when in the wake-up period and by
* default, a node will extend its wake-up period to another
* @ref GNRC_LWMAC_WAKEUP_DURATION_US after each packet reception (except for
* broadcast packet). However, in some cases, a receiver may overhear other
* unintended packets, e.g., WR or WA packets for other nodes, these are called
* bad extensions for the receiver. If a receiver reaches the maximum bad listen
* extension limit defined here, it goes to sleep mode with the consideration
* that the channel is currently unavailable/busy.
*/
#ifndef GNRC_LWMAC_MAX_RX_EXTENSION_NUM
#define GNRC_LWMAC_MAX_RX_EXTENSION_NUM (3U)
#ifndef CONFIG_GNRC_LWMAC_MAX_RX_EXTENSION_NUM
#define CONFIG_GNRC_LWMAC_MAX_RX_EXTENSION_NUM (3U)
#endif
/**
* @brief CSMA retries for broadcast packet.
*
* Currently, each broadcast packet is sent with CSMA/CA for collision avoidance.
* Too many CSMA retries may lead to running out of destinations wake-up period.
* Currently, each broadcast packet is sent with CSMA/CA for collision
* avoidance.
*
* @note Too many CSMA retries may lead to running out of destinations
* wake-up period.
*/
#ifndef GNRC_LWMAC_BROADCAST_CSMA_RETRIES
#define GNRC_LWMAC_BROADCAST_CSMA_RETRIES (3U)
#ifndef CONFIG_GNRC_LWMAC_BROADCAST_CSMA_RETRIES
#define CONFIG_GNRC_LWMAC_BROADCAST_CSMA_RETRIES (3U)
#endif
/** @} */

View File

@ -90,12 +90,17 @@ extern "C" {
*/
#define GNRC_LWMAC_RADIO_IS_ON (0x04)
/**
* @ingroup net_gnrc_lwmac_conf
* @{
*/
/**
* @brief The default largest number of parallel timeouts in LWMAC
*/
#ifndef GNRC_LWMAC_TIMEOUT_COUNT
#define GNRC_LWMAC_TIMEOUT_COUNT (3U)
#ifndef CONFIG_GNRC_LWMAC_TIMEOUT_COUNT
#define CONFIG_GNRC_LWMAC_TIMEOUT_COUNT (3U)
#endif
/** @} */
/**
* @brief Internal states of LWMAC
@ -194,7 +199,7 @@ typedef struct lwmac {
gnrc_lwmac_state_t state; /**< Internal state of MAC layer */
uint32_t last_wakeup; /**< Used to calculate wakeup times */
uint8_t lwmac_info; /**< LWMAC's internal information (flags) */
gnrc_lwmac_timeout_t timeouts[GNRC_LWMAC_TIMEOUT_COUNT]; /**< Store timeouts used for protocol */
gnrc_lwmac_timeout_t timeouts[CONFIG_GNRC_LWMAC_TIMEOUT_COUNT]; /**< Store timeouts used for protocol */
#if (GNRC_MAC_ENABLE_DUTYCYCLE_RECORD == 1)
/* Parameters for recording duty-cycle */

View File

@ -10,6 +10,7 @@ menu "GNRC Network stack"
rsource "application_layer/dhcpv6/Kconfig"
rsource "link_layer/gomach/Kconfig"
rsource "link_layer/lorawan/Kconfig"
rsource "link_layer/lwmac/Kconfig"
rsource "link_layer/mac/Kconfig"
rsource "netif/Kconfig"
rsource "network_layer/ipv6/Kconfig"

View File

@ -0,0 +1,142 @@
# Copyright (c) 2020 Freie Universitaet Berlin
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
#
menuconfig KCONFIG_MODULE_GNRC_LWMAC
bool "Configure GNRC LWMAC"
depends on MODULE_GNRC_LWMAC
help
Configure the GNRC LWMAC using Kconfig.
if KCONFIG_MODULE_GNRC_LWMAC
config GNRC_LWMAC_WAKEUP_INTERVAL_US
int "Time between consecutive wake-ups in microseconds"
default 200000
help
Configure 'CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US', time between
consecutive wake-ups in microseconds. This configuration governs power
consumption, latency and throughput! In LWMAC, devices adopt duty-cycle
scheme to conserve power. That is, time is divided into repeated cycles
(or, superframes), and in each cycle, a node only wakes up for a period
of time for receiving potential incoming packets for itself. This
configuration defines the wake-up interval, or, in other words, defines
the cycle duration used in LWMAC. If the wake-up interval is short,
nodes will wake up more frequently, which also increases the chances
for receiving packets from neighbors (i.e., leads to higher throughput,
but also results in higher power consumption. In LWMAC, by default, we
regard the wake-up period as the beginning of a cycle.
config GNRC_LWMAC_TIME_BETWEEN_WR_US
int "Timeout to send the next WR in microseconds"
default 5000
help
Configure 'CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US', timeout to send the
next WR in case no WA has been received during that time in
microseconds.In LWMAC, when a sender initiates a transmission to a
receiver, it starts with sending a stream of repeated WR packets with
'CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US' interval between two
consecutive WRs. After sending one WR (preamble) packet, the sender
turns to the listen mode to receive the potential incoming WA
(preamble-ACK) packet with a timeout of
'CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US'. If no WA is received during
'CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US', the sender starts sending
the next WR. It is referenced to the beginning of both WRs, but due to
internal overhead, the exact spacing is slightly higher. The minimum
possible value depends on the time it takes to completely send a WR
with the given hardware (including processor) and data rate.
config GNRC_LWMAC_WR_PREPARATION_US
int "WR preparation overhead time in microseconds"
default 3000
help
Configure 'CONFIG_GNRC_LWMAC_WR_PREPARATION_US', WR preparation overhead
before it can be sent (higher with debugging output).In LWMAC, when a
sender wants to send a data packet to the receiver, it starts sending
the WR stream a little bit earlier (advance) to the beginning edge of
destination's wake-up phase over time. The idea is not to miss the
wake-up period of the receiver, otherwise will lead to a long WR
procedure.
config GNRC_LWMAC_DATA_DELAY_US
int "Time to wait after a WA in microseconds"
default 10000
help
Configure 'CONFIG_GNRC_LWMAC_DATA_DELAY_US', time to wait after a WA
for data to arrive in microseconds. When a node in LWMAC gets a WR
during its wake-up period, it immediately replies a WA packet to the
sender for acknowledging the sender's transmission request. After
sending the WA, the receiver waits for the data packet from the sender,
with a timeout of 'CONFIG_GNRC_LWMAC_DATA_DELAY_US' duration. In case
no data will be received in this period, the receiver regards
reception failed and go back to normal listen mode. However, in case the
receiver receives other unintended packets, like WR/WA packets from
other neighbor communication pairs, the receiver resets this timeout
and continues to wait for the data packet, with the consideration that
the sender's data transmission might be delayed due to other ongoing
transmissions (the data packet is transmitted with CSMA/CA). This data
timeout is long enough to catch the beginning of the packet if the
transceiver supports 'NETDEV_EVENT_RX_STARTED' event (this can be
important for big packets).
config GNRC_LWMAC_DATA_CSMA_RETRIES
int "Number of CSMA retries for DATA packet after WR->WA success"
default 3
help
Configure 'CONFIG_GNRC_LWMAC_DATA_CSMA_RETRIES', number of CSMA retries
for DATA packet after WR->WA was successful. After receiving the WA
packet 'gnrc_lwmac_frame_wa_t' from the receiver, the sender starts
sending the data packet using CSMA/CA. This configuration defines how
many CSMA retries a sender will be allowed to execute for sending its
data, before the data is successfully sent (gets data ACK from the
receiver).
config GNRC_LWMAC_MAX_DATA_TX_RETRIES
int "MAX number of TX retries for DATA packet"
default 3
help
Configure 'CONFIG_GNRC_LWMAC_MAX_DATA_TX_RETRIES', the maximum number
of TX transmission retries for DATA packet in case of no response from
the receiver. When a data packet is scheduled for transmission, i.e.,
pushed into TX for sending, LWMAC defines a maximum of
'CONFIG_GNRC_LWMAC_MAX_DATA_TX_RETRIES' retries for transmission of the
packet. That is, in case of transmission failure in TX due to no WA
from the receiver, the sender will not drop the packet, but keeps it
and retries to send the data packet in the following cycles, until the
sender reaches the maximum retries limit defined here. Then, the packet
will be dropped.
config GNRC_LWMAC_MAX_RX_EXTENSION_NUM
int "MAX number of bad listen period extensions"
default 3
help
Configure 'CONFIG_GNRC_LWMAC_MAX_RX_EXTENSION_NUM', the maximum
number of bad listen period extensions a node can tolerate. In LWMAC,
to allow burst transmissions, when in the wake-up period and by
default, a node will extend its wake-up period to another
'GNRC_LWMAC_WAKEUP_DURATION_US' after each packet reception (except for
broadcast packet). However, in some cases, a receiver may overhear other
unintended packets, e.g., WR or WA packets for other nodes, these are
called bad extensions for the receiver. If a receiver reaches the
maximum bad listen extension limit defined here, it goes to sleep mode
with the consideration that the channel is currently unavailable/busy.
config GNRC_LWMAC_BROADCAST_CSMA_RETRIES
int "Number of CSMA retries for broadcast packet"
default 3
help
Configure 'CONFIG_GNRC_LWMAC_BROADCAST_CSMA_RETRIES',the number of CSMA
retries for broadcast packet. Currently, each broadcast packet is sent
with CSMA/CA for collision avoidance. **Too many CSMA retries may lead
to running out of destinations wake-up period**.
config GNRC_LWMAC_TIMEOUT_COUNT
int "MAX number of number of parallel timeouts"
default 3
help
Configure 'CONFIG_GNRC_LWMAC_TIMEOUT_COUNT', the default value for the
maximum number of parallel timeouts in LWMAC.
endif # KCONFIG_MODULE_GNRC_LWMAC

View File

@ -340,9 +340,9 @@ void _gnrc_lwmac_set_netdev_state(gnrc_netif_t *netif, netopt_state_t devstate);
*/
static inline uint32_t _gnrc_lwmac_ticks_to_phase(uint32_t ticks)
{
assert(GNRC_LWMAC_WAKEUP_INTERVAL_US != 0);
assert(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US != 0);
return (ticks % RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US));
return (ticks % RTT_US_TO_TICKS(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US));
}
/**
@ -368,7 +368,7 @@ static inline uint32_t _gnrc_lwmac_ticks_until_phase(uint32_t phase)
if (tmp < 0) {
/* Phase in next interval */
tmp += RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US);
tmp += RTT_US_TO_TICKS(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US);
}
return (uint32_t)tmp;

View File

@ -293,14 +293,15 @@ void lwmac_set_state(gnrc_netif_t *netif, gnrc_lwmac_state_t newstate)
uint32_t alarm;
rtt_clear_alarm();
alarm = random_uint32_range(RTT_US_TO_TICKS((3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2)),
RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US -
(3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2)));
alarm = random_uint32_range(
RTT_US_TO_TICKS((3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2)),
RTT_US_TO_TICKS(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US -
(3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2)));
LOG_WARNING("WARNING: [LWMAC] phase backoffed: %lu us\n",
(unsigned long)RTT_TICKS_TO_US(alarm));
netif->mac.prot.lwmac.last_wakeup = netif->mac.prot.lwmac.last_wakeup + alarm;
alarm = _next_inphase_event(netif->mac.prot.lwmac.last_wakeup,
RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US));
RTT_US_TO_TICKS(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US));
rtt_set_alarm(alarm, rtt_cb, (void *) GNRC_LWMAC_EVENT_RTT_WAKEUP_PENDING);
}
@ -374,7 +375,7 @@ static void _sleep_management(gnrc_netif_t *netif)
if (neighbour != NULL) {
/* if phase is unknown, send immediately. */
if (neighbour->phase > RTT_TICKS_TO_US(GNRC_LWMAC_WAKEUP_INTERVAL_US)) {
if (neighbour->phase > RTT_TICKS_TO_US(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US)) {
netif->mac.tx.current_neighbor = neighbour;
gnrc_lwmac_set_tx_continue(netif, false);
netif->mac.tx.tx_burst_count = 0;
@ -388,16 +389,16 @@ static void _sleep_management(gnrc_netif_t *netif)
/* If there's not enough time to prepare a WR to catch the phase
* postpone to next interval */
if (time_until_tx < GNRC_LWMAC_WR_PREPARATION_US) {
time_until_tx += GNRC_LWMAC_WAKEUP_INTERVAL_US;
if (time_until_tx < CONFIG_GNRC_LWMAC_WR_PREPARATION_US) {
time_until_tx += CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US;
}
time_until_tx -= GNRC_LWMAC_WR_PREPARATION_US;
time_until_tx -= CONFIG_GNRC_LWMAC_WR_PREPARATION_US;
/* add a random time before goto TX, for avoiding one node for
* always holding the medium (if the receiver's phase is recorded earlier in this
* particular node) */
uint32_t random_backoff;
random_backoff = random_uint32_range(0, GNRC_LWMAC_TIME_BETWEEN_WR_US);
random_backoff = random_uint32_range(0, CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US);
time_until_tx = time_until_tx + random_backoff;
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_WAIT_DEST_WAKEUP, time_until_tx);
@ -427,7 +428,7 @@ static void _rx_management_failed(gnrc_netif_t *netif)
LOG_DEBUG("[LWMAC] Reception was NOT successful\n");
gnrc_lwmac_rx_stop(netif);
if (netif->mac.rx.rx_bad_exten_count >= GNRC_LWMAC_MAX_RX_EXTENSION_NUM) {
if (netif->mac.rx.rx_bad_exten_count >= CONFIG_GNRC_LWMAC_MAX_RX_EXTENSION_NUM) {
gnrc_lwmac_set_quit_rx(netif, true);
}
@ -442,7 +443,7 @@ static void _rx_management_failed(gnrc_netif_t *netif)
phase = phase - netif->mac.prot.lwmac.last_wakeup;
}
/* If the relative phase is beyond 4/5 cycle time, go to sleep. */
if (phase > (4 * RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US) / 5)) {
if (phase > (4 * RTT_US_TO_TICKS(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US) / 5)) {
gnrc_lwmac_set_quit_rx(netif, true);
}
@ -473,7 +474,7 @@ static void _rx_management_success(gnrc_netif_t *netif)
phase = phase - netif->mac.prot.lwmac.last_wakeup;
}
/* If the relative phase is beyond 4/5 cycle time, go to sleep. */
if (phase > (4 * RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US) / 5)) {
if (phase > (4 * RTT_US_TO_TICKS(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US) / 5)) {
gnrc_lwmac_set_quit_rx(netif, true);
}
@ -705,7 +706,7 @@ void rtt_handler(uint32_t event, gnrc_netif_t *netif)
case GNRC_LWMAC_EVENT_RTT_SLEEP_PENDING: {
/* Set next wake-up timing. */
alarm = _next_inphase_event(netif->mac.prot.lwmac.last_wakeup,
RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US));
RTT_US_TO_TICKS(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US));
rtt_set_alarm(alarm, rtt_cb, (void *) GNRC_LWMAC_EVENT_RTT_WAKEUP_PENDING);
lwmac_set_state(netif, GNRC_LWMAC_SLEEPING);
break;
@ -730,7 +731,7 @@ void rtt_handler(uint32_t event, gnrc_netif_t *netif)
LOG_DEBUG("[LWMAC] RTT: Resume duty cycling\n");
rtt_clear_alarm();
alarm = _next_inphase_event(netif->mac.prot.lwmac.last_wakeup,
RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US));
RTT_US_TO_TICKS(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US));
rtt_set_alarm(alarm, rtt_cb, (void *) GNRC_LWMAC_EVENT_RTT_WAKEUP_PENDING);
gnrc_lwmac_set_dutycycle_active(netif, true);
break;

View File

@ -143,8 +143,9 @@ static bool _send_wa(gnrc_netif_t *netif)
_gnrc_lwmac_ticks_to_phase(netif->mac.prot.lwmac.last_wakeup));
}
else {
lwmac_hdr.current_phase = (phase_now + RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US)) -
_gnrc_lwmac_ticks_to_phase(netif->mac.prot.lwmac.last_wakeup);
lwmac_hdr.current_phase = (phase_now +
RTT_US_TO_TICKS(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US)) -
_gnrc_lwmac_ticks_to_phase(netif->mac.prot.lwmac.last_wakeup);
}
pkt = gnrc_pktbuf_add(NULL, &lwmac_hdr, sizeof(lwmac_hdr), GNRC_NETTYPE_LWMAC);
@ -231,7 +232,7 @@ static uint8_t _packet_process_in_wait_for_data(gnrc_netif_t *netif)
gnrc_pktbuf_release(pkt);
/* Reset timeout to wait for the data packet */
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, CONFIG_GNRC_LWMAC_DATA_DELAY_US);
continue;
}
@ -241,7 +242,7 @@ static uint8_t _packet_process_in_wait_for_data(gnrc_netif_t *netif)
gnrc_pktbuf_release(pkt);
/* Reset timeout to wait for the data packet */
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, CONFIG_GNRC_LWMAC_DATA_DELAY_US);
continue;
}
@ -368,7 +369,7 @@ static bool _lwmac_rx_update(gnrc_netif_t *netif)
}
/* When reach here, WA has been sent, set timeout for expected data arrival */
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, CONFIG_GNRC_LWMAC_DATA_DELAY_US);
_gnrc_lwmac_set_netdev_state(netif, NETOPT_STATE_IDLE);
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA;
@ -403,7 +404,8 @@ static bool _lwmac_rx_update(gnrc_netif_t *netif)
}
else {
/* If radio is receiving packet, reset wait data timeout */
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA,
CONFIG_GNRC_LWMAC_DATA_DELAY_US);
}
break;
}

View File

@ -48,7 +48,7 @@ static int _lwmac_find_timeout(gnrc_lwmac_t *lwmac, gnrc_lwmac_timeout_type_t ty
{
assert(lwmac);
for (unsigned i = 0; i < GNRC_LWMAC_TIMEOUT_COUNT; i++) {
for (unsigned i = 0; i < CONFIG_GNRC_LWMAC_TIMEOUT_COUNT; i++) {
if (lwmac->timeouts[i].type == type) {
return i;
}
@ -86,7 +86,7 @@ gnrc_lwmac_timeout_t *_lwmac_acquire_timeout(gnrc_netif_t *netif,
return NULL;
}
for (unsigned i = 0; i < GNRC_LWMAC_TIMEOUT_COUNT; i++) {
for (unsigned i = 0; i < CONFIG_GNRC_LWMAC_TIMEOUT_COUNT; i++) {
if (netif->mac.prot.lwmac.timeouts[i].type == GNRC_LWMAC_TIMEOUT_DISABLED) {
netif->mac.prot.lwmac.timeouts[i].type = type;
return &netif->mac.prot.lwmac.timeouts[i];
@ -138,7 +138,7 @@ void gnrc_lwmac_reset_timeouts(gnrc_netif_t *netif)
{
assert(netif);
for (unsigned i = 0; i < GNRC_LWMAC_TIMEOUT_COUNT; i++) {
for (unsigned i = 0; i < CONFIG_GNRC_LWMAC_TIMEOUT_COUNT; i++) {
if (netif->mac.prot.lwmac.timeouts[i].type != GNRC_LWMAC_TIMEOUT_DISABLED) {
_lwmac_clear_timeout(&netif->mac.prot.lwmac.timeouts[i]);
}

View File

@ -309,7 +309,8 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netif_t *netif)
wa_hdr->current_phase;
}
else {
netif->mac.tx.timestamp += RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US);
netif->mac.tx.timestamp +=
RTT_US_TO_TICKS(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US);
netif->mac.tx.timestamp -= wa_hdr->current_phase;
}
@ -324,7 +325,7 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netif_t *netif)
}
if ((own_phase < RTT_US_TO_TICKS((3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2))) ||
(own_phase > RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US -
(own_phase > RTT_US_TO_TICKS(CONFIG_GNRC_LWMAC_WAKEUP_INTERVAL_US -
(3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2)))) {
gnrc_lwmac_set_phase_backoff(netif, true);
LOG_WARNING("WARNING: [LWMAC-tx] phase close\n");
@ -384,7 +385,7 @@ static bool _send_data(gnrc_netif_t *netif)
/* It's okay to retry sending DATA. Timing doesn't matter anymore and
* destination is waiting for a certain amount of time. */
uint8_t csma_retries = GNRC_LWMAC_DATA_CSMA_RETRIES;
uint8_t csma_retries = CONFIG_GNRC_LWMAC_DATA_CSMA_RETRIES;
netif->dev->driver->set(netif->dev, NETOPT_CSMA_RETRIES,
&csma_retries, sizeof(csma_retries));
@ -507,7 +508,7 @@ void gnrc_lwmac_tx_stop(gnrc_netif_t *netif)
/* Release packet in case of failure */
if (netif->mac.tx.packet) {
if (netif->mac.tx.tx_retry_count >= GNRC_LWMAC_MAX_DATA_TX_RETRIES) {
if (netif->mac.tx.tx_retry_count >= CONFIG_GNRC_LWMAC_MAX_DATA_TX_RETRIES) {
netif->mac.tx.tx_retry_count = 0;
gnrc_pktbuf_release(netif->mac.tx.packet);
netif->mac.tx.packet = NULL;
@ -556,7 +557,7 @@ static bool _lwmac_tx_update(gnrc_netif_t *netif)
if (gnrc_netif_hdr_get_flag(netif->mac.tx.packet) &
(GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) {
/* Set CSMA retries as configured and enable */
uint8_t csma_retries = GNRC_LWMAC_BROADCAST_CSMA_RETRIES;
uint8_t csma_retries = CONFIG_GNRC_LWMAC_BROADCAST_CSMA_RETRIES;
netif->dev->driver->set(netif->dev, NETOPT_CSMA_RETRIES,
&csma_retries, sizeof(csma_retries));
netif->mac.mac_info |= GNRC_NETIF_MAC_INFO_CSMA_ENABLED;
@ -662,7 +663,8 @@ static bool _lwmac_tx_update(gnrc_netif_t *netif)
netif->mac.tx.wr_sent++;
/* Set timeout for next WR in case no WA will be received */
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_WR, GNRC_LWMAC_TIME_BETWEEN_WR_US);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_WR,
CONFIG_GNRC_LWMAC_TIME_BETWEEN_WR_US);
/* Debug WR timing */
LOG_DEBUG("[LWMAC-tx] Destination phase was: %" PRIu32 "\n",