can: Merge cd_error and rx_overflow into rx_error so the error could dispath to each client without interference

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2024-04-06 13:19:50 +08:00 committed by Lup Yuen Lee
parent f791311138
commit 4324970980
2 changed files with 35 additions and 72 deletions

View File

@ -365,10 +365,6 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer,
FAR struct can_rxfifo_s *fifo;
irqstate_t flags;
int ret = 0;
#ifdef CONFIG_CAN_ERRORS
FAR struct inode *inode = filep->f_inode;
FAR struct can_dev_s *dev = inode->i_private;
#endif
caninfo("buflen: %zu\n", buflen);
@ -388,18 +384,9 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer,
flags = enter_critical_section();
#ifdef CONFIG_CAN_ERRORS
/* Check for reader fifo overflow */
if (fifo->rx_overflow)
{
dev->cd_error |= CAN_ERROR5_RXOVERFLOW;
fifo->rx_overflow = false;
}
/* Check for internal errors */
if (dev->cd_error != 0)
if (fifo->rx_error != 0)
{
FAR struct can_msg_s *msg;
@ -422,11 +409,11 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer,
#endif
msg->cm_hdr.ch_unused = 0;
memset(&(msg->cm_data), 0, CAN_ERROR_DLC);
msg->cm_data[5] = dev->cd_error;
msg->cm_data[5] = fifo->rx_error;
/* Reset the error flag */
dev->cd_error = 0;
fifo->rx_error = 0;
ret = CAN_MSGLEN(CAN_ERROR_DLC);
goto return_with_irqdisabled;
@ -572,6 +559,7 @@ static int can_xmit(FAR struct can_dev_s *dev)
if (ret < 0)
{
canerr("dev_send failed: %d\n", ret);
dev->cd_xmit.tx_queue = tmpndx;
break;
}
}
@ -893,19 +881,24 @@ static int can_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
break;
/* FIONWRITE: Return the number of CAN messages in the send queue */
/* FIONWRITE: Return the number of CAN messages in the send queue */
case FIONWRITE:
{
*(FAR uint8_t *)arg = dev->cd_xmit.tx_tail;
*(FAR uint8_t *)arg = CONFIG_CAN_FIFOSIZE - 1 -
(dev->cd_xmit.tx_tail - dev->cd_xmit.tx_head);
}
break;
/* FIONREAD: Return the number of CAN messages in the receive FIFO */
/* FIONREAD: Return the number of CAN messages in the receive FIFO */
case FIONREAD:
{
*(FAR uint8_t *)arg = reader->fifo.rx_tail;
*(FAR uint8_t *)arg =
#ifdef CONFIG_CAN_ERRORS
(reader->fifo.rx_error != 0) +
#endif
reader->fifo.rx_tail - reader->fifo.rx_head;
}
break;
@ -934,9 +927,8 @@ static int can_poll(FAR struct file *filep, FAR struct pollfd *fds,
FAR struct can_dev_s *dev = inode->i_private;
FAR struct can_reader_s *reader = NULL;
pollevent_t eventset = 0;
int ndx;
int sval;
irqstate_t flags;
int ndx;
int ret;
int i;
@ -1001,21 +993,8 @@ static int can_poll(FAR struct file *filep, FAR struct pollfd *fds,
/* Should we immediately notify on any of the requested events?
* First, check if the xmit buffer is full.
*
* Get exclusive access to the cd_xmit buffer indices. NOTE: that
* we do not let this wait be interrupted by a signal (we probably
* should, but that would be a little awkward).
*/
DEBUGASSERT(dev->cd_ntxwaiters < 255);
dev->cd_ntxwaiters++;
do
{
ret = nxsem_wait(&dev->cd_xmit.tx_sem);
}
while (ret < 0);
dev->cd_ntxwaiters--;
ndx = dev->cd_xmit.tx_tail + 1;
if (ndx >= CONFIG_CAN_FIFOSIZE)
{
@ -1027,29 +1006,17 @@ static int can_poll(FAR struct file *filep, FAR struct pollfd *fds,
eventset |= POLLOUT;
}
nxsem_post(&dev->cd_xmit.tx_sem);
/* Check whether there are messages in the RX FIFO. */
ret = nxsem_get_value(&reader->fifo.rx_sem, &sval);
if (ret < 0)
if (reader->fifo.rx_head != reader->fifo.rx_tail
#ifdef CONFIG_CAN_ERRORS
|| reader->fifo.rx_error != 0
#endif
)
{
DEBUGPANIC();
goto return_with_irqdisabled;
}
else if (sval > 0)
{
if (reader->fifo.rx_head != reader->fifo.rx_tail)
{
/* No need to wait, just notify the application immediately */
/* No need to wait, just notify the application immediately */
eventset |= POLLIN;
}
else
{
canerr("RX FIFO sem not locked but FIFO is empty.\n");
}
eventset |= POLLIN;
}
poll_notify(&fds, 1, eventset);
@ -1102,14 +1069,11 @@ int can_register(FAR const char *path, FAR struct can_dev_s *dev)
dev->cd_crefs = 0;
dev->cd_npendrtr = 0;
dev->cd_ntxwaiters = 0;
#ifdef CONFIG_CAN_ERRORS
dev->cd_error = 0;
#endif
list_initialize(&dev->cd_readers);
/* Initialize semaphores */
nxsem_init(&dev->cd_xmit.tx_sem, 0, 1);
nxsem_init(&dev->cd_xmit.tx_sem, 0, 0);
nxmutex_init(&dev->cd_closelock);
nxmutex_init(&dev->cd_polllock);
@ -1251,21 +1215,14 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr,
fifo->rx_tail = nexttail;
/* Notify all poll/select waiters that they can read from the
* cd_recv buffer
*/
poll_notify(dev->cd_fds, CONFIG_CAN_NPOLLWAITERS, POLLIN);
if (nxsem_get_value(&fifo->rx_sem, &sval) < 0)
{
DEBUGPANIC();
#ifdef CONFIG_CAN_ERRORS
/* Report unspecified error */
dev->cd_error |= CAN_ERROR5_UNSPEC;
fifo->rx_error |= CAN_ERROR5_UNSPEC;
#endif
return -EINVAL;
continue;
}
/* Unlock the binary semaphore, waking up can_read if it is
@ -1285,11 +1242,20 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr,
{
/* Report rx overflow error */
fifo->rx_overflow = true;
fifo->rx_error |= CAN_ERROR5_RXOVERFLOW;
}
#endif
}
/* Notify all poll/select waiters that they can read from the
* cd_recv buffer
*/
if (ret == OK)
{
poll_notify(dev->cd_fds, CONFIG_CAN_NPOLLWAITERS, POLLIN);
}
return ret;
}

View File

@ -549,7 +549,7 @@ struct can_rxfifo_s
sem_t rx_sem;
#ifdef CONFIG_CAN_ERRORS
bool rx_overflow; /* Indicates the RX FIFO overflow event */
uint8_t rx_error; /* Flags to indicate internal device errors */
#endif
uint8_t rx_head; /* Index to the head [IN] in the circular buffer */
uint8_t rx_tail; /* Index to the tail [OUT] in the circular buffer */
@ -666,9 +666,6 @@ struct can_dev_s
uint8_t cd_crefs; /* References counts on number of opens */
uint8_t cd_npendrtr; /* Number of pending RTR messages */
volatile uint8_t cd_ntxwaiters; /* Number of threads waiting to enqueue a message */
#ifdef CONFIG_CAN_ERRORS
uint8_t cd_error; /* Flags to indicate internal device errors */
#endif
struct list_node cd_readers; /* List of readers */
mutex_t cd_closelock; /* Locks out new opens while close is in progress */
mutex_t cd_polllock; /* Manages exclusive access to cd_fds[] */