Merged in antmerlino/nuttx/xbee-stability-improvements (pull request #1000)

Xbee stability improvements

Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
Anthony Merlino
2019-08-16 22:30:52 +00:00
committed by Gregory Nutt
4 changed files with 381 additions and 96 deletions
+14
View File
@@ -29,4 +29,18 @@ config XBEE_NETDEV_RECVRPRIO
the MAC character driver (which should always be lowest priority since
it is a "catch-all" type receiver).
config XBEE_LOCKUP_WORKAROUND
bool "Enable workaround to counteract XBee lockup"
default y
---help---
When receiving large amounts of data over the XBee, there is some probability
that the XBee will lockup and stop sending us data over SPI. In most cases,
querying the XBee will get it out of this state and communication will resume.
In some cases however, the XBee will freeze completely and won't ever respond
to our queries.
This workaround periodically queries the XBee if there hasn't been any
recent interaction. Additionally, if any query does not get a response
after 10 attempts, the XBee is reset.
endif # IEEE802154_XBEE
File diff suppressed because it is too large Load Diff
+18 -1
View File
@@ -167,6 +167,7 @@ struct xbee_priv_s
* callback to registered receivers */
WDOG_ID assocwd; /* Association watchdog */
struct work_s assocwork; /* For polling for association status */
bool associating; /* Are we currently associating */
sem_t atquery_sem; /* Only allow one AT query at a time */
sem_t atresp_sem; /* For signaling pending AT response received */
char querycmd[2]; /* Stores the pending AT Query command */
@@ -177,6 +178,11 @@ struct xbee_priv_s
sem_t tx_sem; /* Support a single pending transmit */
sem_t txdone_sem; /* For signalling tx is completed */
bool txdone;
#ifdef CONFIG_XBEE_LOCKUP_WORKAROUND
WDOG_ID lockup_wd; /* Watchdog to protect for XBee lockup */
struct work_s lockupwork; /* For deferring lockup query check to LPWORK queue*/
struct work_s backupwork; /* For deferring backing up parameters to LPWORK queue*/
#endif
/******************* Fields related to Xbee radio ***************************/
@@ -382,7 +388,18 @@ void xbee_send_atquery(FAR struct xbee_priv_s *priv, FAR const char *atcommand);
*
****************************************************************************/
#define xbee_query_assoc(priv) xbee_atquery(priv "AI")
#define xbee_query_assoc(priv) xbee_atquery(priv, "AI")
/****************************************************************************
* Name: xbee_save_params
*
* Description:
* Sends API frame with AT command request to write current parameters to
* non-volatile memory so that they are used after next reset.
*
****************************************************************************/
#define xbee_save_params(priv) xbee_atquery(priv, "WR")
/****************************************************************************
* Name: xbee_set_panid
+36 -2
View File
@@ -58,6 +58,10 @@
#define XBEE_RESPONSE_TIMEOUT MSEC2TICK(200)
#ifdef CONFIG_XBEE_LOCKUP_WORKAROUND
#define XBEE_LOCKUP_SENDATTEMPTS 20
#endif
/****************************************************************************
* Private Types
****************************************************************************/
@@ -146,9 +150,12 @@ static void xbee_assocworker(FAR void *arg)
{
FAR struct xbee_priv_s *priv = (FAR struct xbee_priv_s *)arg;
xbee_send_atquery(priv, "AI");
if (priv->associating)
{
xbee_send_atquery(priv, "AI");
(void)wd_start(priv->assocwd, XBEE_ASSOC_POLLDELAY, xbee_assoctimer, 1, (wdparm_t)arg);
(void)wd_start(priv->assocwd, XBEE_ASSOC_POLLDELAY, xbee_assoctimer, 1, (wdparm_t)arg);
}
}
/****************************************************************************
@@ -303,6 +310,9 @@ int xbee_req_data(XBEEHANDLE xbee,
#ifdef CONFIG_DEBUG_ASSERTIONS
int prevoffs = frame->io_offset;
#endif
#ifdef CONFIG_XBEE_LOCKUP_WORKAROUND
int retries = XBEE_LOCKUP_SENDATTEMPTS;
#endif
/* Support one pending transmit at a time */
@@ -380,6 +390,28 @@ int xbee_req_data(XBEEHANDLE xbee,
/* Wait for a transmit status to be received. Does not necessarily mean success */
while (nxsem_wait(&priv->txdone_sem) < 0);
/* If the transmit timeout has occured, and there are no IOBs available,
* we may be blocking the context needed to free the IOBs. We cannot receive
* the Tx status because it requires an IOB. Therefore, if we have hit the
* timeout, and there are no IOBs, let's move on assuming the transmit was
* a success
*/
if (!priv->txdone && iob_navail(false) <= 0)
{
wlwarn("Couldn't confirm TX. No IOBs\n");
break;
}
#ifdef CONFIG_XBEE_LOCKUP_WORKAROUND
if (--retries == 0 && !priv->txdone)
{
wlerr("XBee not responding. Resetting.\n");
priv->lower->reset(priv->lower);
retries = XBEE_LOCKUP_SENDATTEMPTS;
}
#endif
}
while (!priv->txdone);
@@ -646,6 +678,8 @@ int xbee_req_associate(XBEEHANDLE xbee, FAR struct ieee802154_assoc_req_s *req)
xbee_set_epassocflags(priv, XBEE_EPASSOCFLAGS_AUTOASSOC);
priv->associating = true;
/* In order to track the association status, we must poll the device for
* an update.
*/