You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by lu...@apache.org on 2024/10/10 09:58:44 UTC
(nuttx) 01/06: can: Merge cd_error and rx_overflow into rx_error so the error could dispath to each client without interference
This is an automated email from the ASF dual-hosted git repository.
lupyuen pushed a commit to branch releases/12.7
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 4324970980edbddf60080c1d248da71c38d66d8e
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Sat Apr 6 13:19:50 2024 +0800
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 <xi...@xiaomi.com>
---
drivers/can/can.c | 102 ++++++++++++++++--------------------------------
include/nuttx/can/can.h | 5 +--
2 files changed, 35 insertions(+), 72 deletions(-)
diff --git a/drivers/can/can.c b/drivers/can/can.c
index dea1d0fa67..be8165f441 100644
--- a/drivers/can/can.c
+++ b/drivers/can/can.c
@@ -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)
- {
- DEBUGPANIC();
- goto return_with_irqdisabled;
- }
- else if (sval > 0)
+ if (reader->fifo.rx_head != reader->fifo.rx_tail
+#ifdef CONFIG_CAN_ERRORS
+ || reader->fifo.rx_error != 0
+#endif
+ )
{
- 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;
}
diff --git a/include/nuttx/can/can.h b/include/nuttx/can/can.h
index 054876418f..1d53e8442b 100644
--- a/include/nuttx/can/can.h
+++ b/include/nuttx/can/can.h
@@ -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[] */