mirror of
https://github.com/apache/nuttx.git
synced 2026-05-21 21:34:07 +08:00
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:
@@ -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
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user