Fix another corner case in the upper half CAN driver
This commit is contained in:
parent
d6cc75dc64
commit
1ed69cd535
|
@ -1044,6 +1044,12 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr,
|
|||
* Returned Value:
|
||||
* OK on success; a negated errno on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* Interrupts are disabled. This is required by can_xmit() which is called
|
||||
* by this function. Interrupts are explicitly disabled when called
|
||||
* through can_write(). Interrupts are expected be disabled when called
|
||||
* from the CAN interrupt handler.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int can_txdone(FAR struct can_dev_s *dev)
|
||||
|
@ -1143,6 +1149,10 @@ int can_txdone(FAR struct can_dev_s *dev)
|
|||
* Returned Value:
|
||||
* OK on success; a negated errno on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* Interrupts are disabled. This is required by can_xmit() which is called
|
||||
* by this function.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CAN_TXREADY
|
||||
|
@ -1154,26 +1164,20 @@ int can_txready(FAR struct can_dev_s *dev)
|
|||
dev->cd_xmit.tx_head, dev->cd_xmit.tx_queue, dev->cd_xmit.tx_tail,
|
||||
dev->cd_ntxwaiters);
|
||||
|
||||
/* Are there any threads waiting for space in the xmit FIFO? */
|
||||
/* Verify that the xmit FIFO is not empty. This is safe because interrupts
|
||||
* are always disabled when calling into can_xmit(); this cannot collide
|
||||
* with ongoing activity from can_write().
|
||||
*/
|
||||
|
||||
if (dev->cd_ntxwaiters > 0)
|
||||
if (dev->cd_xmit.tx_head != dev->cd_xmit.tx_tail)
|
||||
{
|
||||
/* Verify that the xmit FIFO is not empty.
|
||||
*
|
||||
* REVISIT: This probably should be an assertion since we should only
|
||||
* be waiting for space in the xmit FIFO if the xmit FIFO is full.
|
||||
/* Send the next message in the S/W FIFO. In the case where the
|
||||
* H/W TX FIFO is not empty, this should add one more CAN message
|
||||
* to the H/W TX FIFO and can_txdone() should be called, making
|
||||
* space in the S/W FIFO
|
||||
*/
|
||||
|
||||
if (dev->cd_xmit.tx_head != dev->cd_xmit.tx_tail)
|
||||
{
|
||||
/* Send the next message in the S/W FIFO. In the case where the
|
||||
* H/W TX FIFO is not empty, this should add one more CAN message
|
||||
* to the H/W TX FIFO and can_txdone() should be called, making
|
||||
* space in the S/W FIFO
|
||||
*/
|
||||
|
||||
(void)can_xmit(dev);
|
||||
}
|
||||
(void)can_xmit(dev);
|
||||
|
||||
/* Inform one waiter that new xmit space is available in the S/W FIFO.
|
||||
* NOTE that is can_txdone() is, indeed, called twice that the tx_sem
|
||||
|
@ -1181,7 +1185,12 @@ int can_txready(FAR struct can_dev_s *dev)
|
|||
* harmful.
|
||||
*/
|
||||
|
||||
ret = sem_post(&dev->cd_xmit.tx_sem);
|
||||
/* Are there any threads waiting for space in the xmit FIFO? */
|
||||
|
||||
if (dev->cd_ntxwaiters > 0)
|
||||
{
|
||||
ret = sem_post(&dev->cd_xmit.tx_sem);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue