Merged in antmerlino/nuttx/xbee_timeout (pull request #629)

Xbee: Adds a timeout to send logic to handle case where XBee module fails to respond to a Transmit request with a Transmit Status

Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
Anthony Merlino
2018-04-19 04:08:13 +00:00
committed by Gregory Nutt
parent 8a648e8fa9
commit 7061d02f0f
3 changed files with 57 additions and 4 deletions
+3
View File
@@ -643,8 +643,10 @@ static void xbee_process_apiframes(FAR struct xbee_priv_s *priv,
break;
case XBEE_APIFRAME_TXSTATUS:
{
wd_cancel(priv->reqdata_wd);
xbee_process_txstatus(priv, frame->io_data[frame->io_offset],
frame->io_data[frame->io_offset + 1]);
priv->txdone = true;
nxsem_post(&priv->txdone_sem);
}
break;
@@ -1027,6 +1029,7 @@ XBEEHANDLE xbee_init(FAR struct spi_dev_s *spi,
priv->assocwd = wd_create();
priv->atquery_wd = wd_create();
priv->reqdata_wd = wd_create();
priv->frameid = 0; /* Frame ID should never be 0, but it is incremented
* in xbee_next_frameid before being used so it will be 1 */
+2
View File
@@ -172,9 +172,11 @@ struct xbee_priv_s
char querycmd[2]; /* Stores the pending AT Query command */
bool querydone; /* Used to tell waiting thread query is done*/
WDOG_ID atquery_wd; /* Support AT Query timeout and retry */
WDOG_ID reqdata_wd; /* Support send timeout and retry */
uint8_t frameid; /* For differentiating AT request/response */
sem_t tx_sem; /* Support a single pending transmit */
sem_t txdone_sem; /* For signalling tx is completed */
bool txdone;
/******************* Fields related to Xbee radio ***************************/
+52 -4
View File
@@ -55,6 +55,7 @@
****************************************************************************/
#define XBEE_ASSOC_POLLDELAY 100
#define XBEE_RESPONSE_TIMEOUT 100
/****************************************************************************
* Private Types
@@ -149,6 +150,40 @@ static void xbee_assocworker(FAR void *arg)
(void)wd_start(priv->assocwd, XBEE_ASSOC_POLLDELAY, xbee_assoctimer, 1, (wdparm_t)arg);
}
/****************************************************************************
* Name: xbee_reqdata_timeout
*
* Description:
* This function runs when a send request has timed out waiting for a response
* from the XBee module. This really should never happen, but if it does,
* handle it gracefully by retrying the query. Although I still think this
* should not happen, it does seem to happen. The XBee seemingly randomly drops
* the request and never sends a response.
*
* Parameters:
* argc - The number of available arguments
* arg - The first argument
*
* Returned Value:
* None
*
* Assumptions:
*
****************************************************************************/
static void xbee_reqdata_timeout(int argc, uint32_t arg, ...)
{
FAR struct xbee_priv_s *priv = (FAR struct xbee_priv_s *)arg;
DEBUGASSERT(priv != NULL);
wlwarn("Send timeout\n");
/* Wake the pending reqdata thread so it can retry */
nxsem_post(&priv->txdone_sem);
}
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -327,12 +362,25 @@ int xbee_req_data(XBEEHANDLE xbee,
xbee_insert_checksum(&frame->io_data[frame->io_offset],
(frame->io_len - frame->io_offset));
xbee_send_apiframe(priv, &frame->io_data[frame->io_offset],
(frame->io_len - frame->io_offset));
priv->txdone = false;
/* Wait for a transmit status to be received. Does not necessarily mean success */
do
{
/* Setup a timeout in case the XBee never responds with a tx status */
while (nxsem_wait(&priv->txdone_sem) < 0);
(void)wd_start(priv->reqdata_wd, XBEE_RESPONSE_TIMEOUT, xbee_reqdata_timeout,
1, (wdparm_t)priv);
/* Send the frame */
xbee_send_apiframe(priv, &frame->io_data[frame->io_offset],
(frame->io_len - frame->io_offset));
/* Wait for a transmit status to be received. Does not necessarily mean success */
while (nxsem_wait(&priv->txdone_sem) < 0);
}
while (!priv->txdone);
nxsem_post(&priv->tx_sem);
iob_free(frame);