mirror of
https://github.com/apache/nuttx.git
synced 2026-09-20 21:06:58 +08:00
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:
committed by
Gregory Nutt
parent
8a648e8fa9
commit
7061d02f0f
@@ -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 */
|
||||
|
||||
@@ -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 ***************************/
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user