mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-17 02:52:12 +01:00
OP-1218 fix thread safety issue with pios_com PIOS_COM_SendBufferNonBlocking
(kudos @filnet for finding this)
This commit is contained in:
parent
c7ada40c2e
commit
590c27af29
@ -51,6 +51,7 @@ struct pios_com_dev {
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreHandle tx_sem;
|
||||
xSemaphoreHandle rx_sem;
|
||||
xSemaphoreHandle sendbuffer_sem;
|
||||
#endif
|
||||
|
||||
bool has_rx;
|
||||
@ -155,6 +156,9 @@ int32_t PIOS_COM_Init(uint32_t *com_id, const struct pios_com_driver *driver, ui
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
(com_dev->driver->bind_tx_cb)(lower_id, PIOS_COM_TxOutCallback, (uint32_t)com_dev);
|
||||
}
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
com_dev->sendbuffer_sem = xSemaphoreCreateMutex();
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
|
||||
*com_id = (uint32_t)com_dev;
|
||||
return 0;
|
||||
@ -275,6 +279,8 @@ int32_t PIOS_COM_ChangeBaud(uint32_t com_id, uint32_t baud)
|
||||
* \return -1 if port not available
|
||||
* \return -2 if non-blocking mode activated: buffer is full
|
||||
* caller should retry until buffer is free again
|
||||
* \return -3 another thread is already sending, caller should
|
||||
* retry until com is available again
|
||||
* \return number of bytes transmitted on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendBufferNonBlocking(uint32_t com_id, const uint8_t *buffer, uint16_t len)
|
||||
@ -287,7 +293,11 @@ int32_t PIOS_COM_SendBufferNonBlocking(uint32_t com_id, const uint8_t *buffer, u
|
||||
}
|
||||
|
||||
PIOS_Assert(com_dev->has_tx);
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
if(xSemaphoreTake(com_dev->sendbuffer_sem, 0) != pdTRUE){
|
||||
return -3;
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
if (com_dev->driver->available && !com_dev->driver->available(com_dev->lower_id)) {
|
||||
/*
|
||||
* Underlying device is down/unconnected.
|
||||
@ -297,10 +307,16 @@ int32_t PIOS_COM_SendBufferNonBlocking(uint32_t com_id, const uint8_t *buffer, u
|
||||
* no longer accepting data.
|
||||
*/
|
||||
fifoBuf_clearData(&com_dev->tx);
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGive(com_dev->sendbuffer_sem);
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
return len;
|
||||
}
|
||||
|
||||
if (len > fifoBuf_getFree(&com_dev->tx)) {
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGive(com_dev->sendbuffer_sem);
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
/* Buffer cannot accept all requested bytes (retry) */
|
||||
return -2;
|
||||
}
|
||||
@ -314,7 +330,9 @@ int32_t PIOS_COM_SendBufferNonBlocking(uint32_t com_id, const uint8_t *buffer, u
|
||||
fifoBuf_getUsed(&com_dev->tx));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGive(com_dev->sendbuffer_sem);
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
return bytes_into_fifo;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user