lwmac: add re-initialize radio support.

This commit is contained in:
zhuoshuguo 2017-10-01 15:50:38 +02:00 committed by 原冶
parent 651b506fd4
commit d3c87d7bb9
5 changed files with 67 additions and 0 deletions

View File

@ -316,6 +316,19 @@ extern "C" {
#endif #endif
/** @} */ /** @} */
/**
* @brief Maximum preamble attempts before re-initialize radio in LWMAC.
*
* After a long period of run time, a radio may be in wrong condition which needs to be
* re-calibrated. This is indicated by having a series of continuous preamble failure (no WA)
* in LWMAC. In case we have @ref CONFIG_GNRC_LWMAC_RADIO_REINIT_THRESHOLD number of preamble
* failure, then we re-initialize the radio, trying to re-calibrate the radio for bringing it
* back to normal condition.
*/
#ifndef CONFIG_GNRC_LWMAC_RADIO_REINIT_THRESHOLD
#define CONFIG_GNRC_LWMAC_RADIO_REINIT_THRESHOLD (10U)
#endif
/** /**
* @brief Creates an IEEE 802.15.4 LWMAC network interface * @brief Creates an IEEE 802.15.4 LWMAC network interface
* *

View File

@ -197,6 +197,7 @@ typedef struct {
uint8_t bcast_seqnr; /**< Sequence number for broadcast data to filter at receiver */ uint8_t bcast_seqnr; /**< Sequence number for broadcast data to filter at receiver */
uint8_t tx_burst_count; /**< Count how many consecutive packets have been transmitted */ uint8_t tx_burst_count; /**< Count how many consecutive packets have been transmitted */
uint8_t tx_retry_count; /**< Count how many Tx-retrials have been executed before packet drop */ uint8_t tx_retry_count; /**< Count how many Tx-retrials have been executed before packet drop */
uint8_t preamble_fail_counts; /**< Preamble trial failure count. */
#endif #endif
#ifdef MODULE_GNRC_GOMACH #ifdef MODULE_GNRC_GOMACH

View File

@ -138,5 +138,16 @@ config GNRC_LWMAC_TIMEOUT_COUNT
help help
Configure 'CONFIG_GNRC_LWMAC_TIMEOUT_COUNT', the default value for the Configure 'CONFIG_GNRC_LWMAC_TIMEOUT_COUNT', the default value for the
maximum number of parallel timeouts in LWMAC. maximum number of parallel timeouts in LWMAC.
config GNRC_LWMAC_RADIO_REINIT_THRESHOLD
int "Maximum preamble attempts before re-initialize radio"
default 10
help
Configure 'CONFIG_GNRC_LWMAC_RADIO_REINIT_THRESHOLD', the maximum preamble
attempts before re-initialize radio. After a long period of run time, a radio
may be in wrong condition which needs to be re-calibrated. This is indicated
by having a series of continuous preamble failure (no WA) in LWMAC. In case
we have @ref GNRC_LWMAC_RADIO_REINI_THRESHOLD number of preamble failure,
then we re-initialize the radio, trying to re-calibrate the radio for bringing
it back to normal condition.
endif # KCONFIG_MODULE_GNRC_LWMAC endif # KCONFIG_MODULE_GNRC_LWMAC

View File

@ -83,6 +83,38 @@ int gnrc_netif_lwmac_create(gnrc_netif_t *netif, char *stack, int stacksize,
&lwmac_ops); &lwmac_ops);
} }
static void lwmac_reinit_radio(gnrc_netif_t *netif)
{
/* Initialize low-level driver. */
netif->dev->driver->init(netif->dev);
/* Set MAC address length. */
uint16_t src_len = netif->l2addr_len;
netif->dev->driver->set(netif->dev, NETOPT_SRC_LEN, &src_len, sizeof(src_len));
/* Set the MAC address of the device. */
if (netif->l2addr_len == IEEE802154_LONG_ADDRESS_LEN) {
netif->dev->driver->set(netif->dev,
NETOPT_ADDRESS_LONG,
netif->l2addr,
sizeof(netif->l2addr));
}
else {
netif->dev->driver->set(netif->dev,
NETOPT_ADDR_LEN,
netif->l2addr,
sizeof(netif->l2addr));
}
/* Enable RX-start and TX-started and TX-END interrupts. */
netopt_enable_t enable = NETOPT_ENABLE;
netif->dev->driver->set(netif->dev, NETOPT_RX_START_IRQ, &enable, sizeof(enable));
netif->dev->driver->set(netif->dev, NETOPT_RX_END_IRQ, &enable, sizeof(enable));
netif->dev->driver->set(netif->dev, NETOPT_TX_START_IRQ, &enable, sizeof(enable));
netif->dev->driver->set(netif->dev, NETOPT_TX_END_IRQ, &enable, sizeof(enable));
}
static gnrc_pktsnip_t *_make_netif_hdr(uint8_t *mhr) static gnrc_pktsnip_t *_make_netif_hdr(uint8_t *mhr)
{ {
gnrc_pktsnip_t *snip; gnrc_pktsnip_t *snip;
@ -328,6 +360,7 @@ void lwmac_set_state(gnrc_netif_t *netif, gnrc_lwmac_state_t newstate)
case GNRC_LWMAC_START: { case GNRC_LWMAC_START: {
rtt_handler(GNRC_LWMAC_EVENT_RTT_START, netif); rtt_handler(GNRC_LWMAC_EVENT_RTT_START, netif);
lwmac_set_state(netif, GNRC_LWMAC_LISTENING); lwmac_set_state(netif, GNRC_LWMAC_LISTENING);
netif->mac.tx.preamble_fail_counts = 0;
break; break;
} }
case GNRC_LWMAC_STOP: { case GNRC_LWMAC_STOP: {
@ -576,6 +609,13 @@ static void _tx_management(gnrc_netif_t *netif)
gnrc_lwmac_set_tx_continue(netif, false); gnrc_lwmac_set_tx_continue(netif, false);
gnrc_lwmac_set_quit_tx(netif, true); gnrc_lwmac_set_quit_tx(netif, true);
/* TX packet will be dropped, no automatic resending here. */ /* TX packet will be dropped, no automatic resending here. */
/* Re-initialize the radio when needed. */
if (netif->mac.tx.preamble_fail_counts >= CONFIG_GNRC_LWMAC_RADIO_REINIT_THRESHOLD) {
netif->mac.tx.preamble_fail_counts = 0;
LOG_INFO("[LWMAC] Re-initialize radio.");
lwmac_reinit_radio(netif);
}
/* Intentionally falls through */ /* Intentionally falls through */
case GNRC_LWMAC_TX_STATE_SUCCESSFUL: case GNRC_LWMAC_TX_STATE_SUCCESSFUL:

View File

@ -685,6 +685,7 @@ static bool _lwmac_tx_update(gnrc_netif_t *netif)
LOG_WARNING("WARNING: [LWMAC-tx] No response from destination\n"); LOG_WARNING("WARNING: [LWMAC-tx] No response from destination\n");
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED; netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true; reschedule = true;
netif->mac.tx.preamble_fail_counts++;
break; break;
} }
@ -735,6 +736,7 @@ static bool _lwmac_tx_update(gnrc_netif_t *netif)
if (tx_info & GNRC_LWMAC_TX_SUCCESS) { if (tx_info & GNRC_LWMAC_TX_SUCCESS) {
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_DATA; netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_DATA;
reschedule = true; reschedule = true;
netif->mac.tx.preamble_fail_counts = 0;
break; break;
} }
else { else {