From 1401f4e1444fc94d0b9d6bf65c04391a24b28162 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sat, 6 Apr 2024 13:19:50 +0800 Subject: [PATCH 1/6] 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 --- 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 dea1d0fa67d1b..be8165f44142c 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 054876418fa64..1d53e8442bdfe 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[] */ From 85c10af744b9fc90d754071f3fba51a896720bd9 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sat, 6 Apr 2024 14:45:25 +0800 Subject: [PATCH 2/6] can: Add more critical section to fix the race condition. since routines called by IRQ need to be protected in SMP too. Signed-off-by: Xiang Xiao --- drivers/can/can.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/can/can.c b/drivers/can/can.c index be8165f44142c..9816a83fdb7fb 100644 --- a/drivers/can/can.c +++ b/drivers/can/can.c @@ -300,6 +300,8 @@ static int can_close(FAR struct file *filep) return ret; } + flags = enter_critical_section(); /* Disable interrupts */ + list_for_every(&dev->cd_readers, node) { if (((FAR struct can_reader_s *)node) == @@ -341,11 +343,10 @@ static int can_close(FAR struct file *filep) /* Free the IRQ and disable the CAN device */ - flags = enter_critical_section(); /* Disable interrupts */ - dev_shutdown(dev); /* Disable the CAN */ - leave_critical_section(flags); + dev_shutdown(dev); /* Disable the CAN */ errout: + leave_critical_section(flags); nxmutex_unlock(&dev->cd_closelock); return ret; } @@ -719,15 +720,10 @@ static inline ssize_t can_rtrread(FAR struct file *filep, { FAR struct can_dev_s *dev = filep->f_inode->i_private; FAR struct can_rtrwait_s *wait = NULL; - irqstate_t flags; int i; int sval; int ret = -ENOMEM; - /* Disable interrupts through this operation */ - - flags = enter_critical_section(); - /* Find an available slot in the pending RTR list */ for (i = 0; i < CONFIG_CAN_NPENDINGRTR; i++) @@ -801,7 +797,6 @@ static inline ssize_t can_rtrread(FAR struct file *filep, } } - leave_critical_section(flags); return ret; } @@ -815,9 +810,14 @@ static int can_ioctl(FAR struct file *filep, int cmd, unsigned long arg) FAR struct can_dev_s *dev = inode->i_private; FAR struct can_reader_s *reader = filep->f_priv; int ret = OK; + irqstate_t flags; caninfo("cmd: %d arg: %ld\n", cmd, arg); + /* Disable interrupts through this operation */ + + flags = enter_critical_section(); + /* Handle built-in ioctl commands */ switch (cmd) @@ -913,6 +913,7 @@ static int can_ioctl(FAR struct file *filep, int cmd, unsigned long arg) break; } + leave_critical_section(flags); return ret; } @@ -1120,6 +1121,7 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr, { FAR struct can_rxfifo_s *fifo; FAR struct list_node *node; + irqstate_t flags; int nexttail; int ret = -ENOMEM; int i; @@ -1127,6 +1129,8 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr, caninfo("ID: %" PRId32 " DLC: %d\n", (uint32_t)hdr->ch_id, hdr->ch_dlc); + flags = enter_critical_section(); + /* Check if adding this new message would over-run the drivers ability to * enqueue read data. */ @@ -1256,6 +1260,7 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr, poll_notify(dev->cd_fds, CONFIG_CAN_NPOLLWAITERS, POLLIN); } + leave_critical_section(flags); return ret; } @@ -1332,10 +1337,13 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr, int can_txdone(FAR struct can_dev_s *dev) { int ret = -ENOENT; + irqstate_t flags; caninfo("xmit head: %d queue: %d tail: %d\n", dev->cd_xmit.tx_head, dev->cd_xmit.tx_queue, dev->cd_xmit.tx_tail); + flags = enter_critical_section(); + /* Verify that the xmit FIFO is not empty */ if (dev->cd_xmit.tx_head != dev->cd_xmit.tx_tail) @@ -1379,6 +1387,7 @@ int can_txdone(FAR struct can_dev_s *dev) } } + leave_critical_section(flags); return ret; } @@ -1443,11 +1452,14 @@ int can_txdone(FAR struct can_dev_s *dev) int can_txready(FAR struct can_dev_s *dev) { int ret = -ENOENT; + irqstate_t flags; caninfo("xmit head: %d queue: %d tail: %d waiters: %d\n", dev->cd_xmit.tx_head, dev->cd_xmit.tx_queue, dev->cd_xmit.tx_tail, dev->cd_ntxwaiters); + flags = enter_critical_section(); + /* 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(). @@ -1495,6 +1507,7 @@ int can_txready(FAR struct can_dev_s *dev) #endif } + leave_critical_section(flags); return ret; } #endif /* CONFIG_CAN_TXREADY */ From 0ed47efef8dd4de0e6b0d9e7f3df7daa26a22d31 Mon Sep 17 00:00:00 2001 From: zhaohaiyang1 Date: Thu, 20 Jun 2024 14:11:02 +0800 Subject: [PATCH 3/6] nuttx/can: add can controller state setting and getting in uppercan. add can controller state setting and getting in uppercan. Signed-off-by: zhaohaiyang1 --- include/nuttx/can/can.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/include/nuttx/can/can.h b/include/nuttx/can/can.h index 1d53e8442bdfe..2947c48135887 100644 --- a/include/nuttx/can/can.h +++ b/include/nuttx/can/can.h @@ -246,6 +246,26 @@ * is returned with the errno variable set to indicate the * nature of the error. * Dependencies: None + * + * CANIOC_SET_STATE + * Description: Set specfic can controller state + * + * Argument: A pointer to an enumeration type that describes the CAN + * state + * returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) + * is returned with the errno variable set to indicate the + * nature of the error. + * Dependencies: None + * + * CANIOC_GET_STATE + * Description: Get specfic can controller state + * + * Argument: A pointer to an enumeration type that describes the CAN + * state + * returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) + * is returned with the errno variable set to indicate the + * nature of the error. + * Dependencies: None */ #define CANIOC_RTR _CANIOC(1) @@ -263,6 +283,8 @@ #define CANIOC_IFLUSH _CANIOC(13) #define CANIOC_OFLUSH _CANIOC(14) #define CANIOC_IOFLUSH _CANIOC(15) +#define CANIOC_SET_STATE _CANIOC(16) +#define CANIOC_GET_STATE _CANIOC(17) #define CAN_FIRST 0x0001 /* First common command */ #define CAN_NCMDS 15 /* 16 common commands */ @@ -438,6 +460,14 @@ #define CAN_FILTER_DUAL 1 /* Dual address match */ #define CAN_FILTER_RANGE 2 /* Match a range of addresses */ +/* the state is default state. Indicates that the can controller is closed */ + +#define CAN_STATE_STOP 0 + +/* Indicates that the can controller is in the awake state */ + +#define CAN_STATE_START 1 + /* CAN bit timing support ***************************************************/ #define CAN_BITTIMING_NOMINAL 0 /* Specifies nominal bittiming */ From cf4b743e799db24ef120d81238e355b098e810c6 Mon Sep 17 00:00:00 2001 From: zhaohaiyang1 Date: Wed, 10 Jul 2024 14:12:15 +0800 Subject: [PATCH 4/6] add the ability that control CAN transceiver state. add the ability that control CAN transceiver state in nuttx. Signed-off-by: zhaohaiyang1 --- drivers/can/can.c | 47 +++++++++++++++++++++++++++ include/nuttx/can/can.h | 70 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 111 insertions(+), 6 deletions(-) diff --git a/drivers/can/can.c b/drivers/can/can.c index 9816a83fdb7fb..e7e8b5497be88 100644 --- a/drivers/can/can.c +++ b/drivers/can/can.c @@ -902,6 +902,53 @@ static int can_ioctl(FAR struct file *filep, int cmd, unsigned long arg) } break; + /* Set specfic can transceiver state */ + + case CANIOC_SET_TRANSVSTATE: + { + /* if we don't use dev->cd_transv->cts_ops, please initlize + * this poniter to NULL in lower board code when Board reset. + */ + + if (dev->cd_transv && dev->cd_transv->ct_ops + && dev->cd_transv->ct_ops->ct_setstate) + { + FAR const struct can_transv_ops_s *ct_ops = + dev->cd_transv->ct_ops; + ret = ct_ops->ct_setstate(dev->cd_transv, arg); + } + else + { + canerr("dev->cd_transv->cts_ops is NULL!"); + ret = -ENOTTY; + } + } + break; + + /* Get specfic can transceiver state */ + + case CANIOC_GET_TRANSVSTATE: + { + /* if we don't use dev->cd_transv->cts_ops, please initlize + * this poniter to NULL in lower board code when Board reset. + */ + + if (dev->cd_transv && dev->cd_transv->ct_ops + && dev->cd_transv->ct_ops->ct_getstate) + { + int *state = (FAR int *)arg; + FAR const struct can_transv_ops_s *ct_ops = + dev->cd_transv->ct_ops; + ret = ct_ops->ct_getstate(dev->cd_transv, state); + } + else + { + canerr("dev->cd_transv->cts_ops is NULL!"); + ret = -ENOTTY; + } + } + break; + /* Not a "built-in" ioctl command.. perhaps it is unique to this * lower-half, device driver. */ diff --git a/include/nuttx/can/can.h b/include/nuttx/can/can.h index 2947c48135887..9c62d5deb964a 100644 --- a/include/nuttx/can/can.h +++ b/include/nuttx/can/can.h @@ -250,8 +250,8 @@ * CANIOC_SET_STATE * Description: Set specfic can controller state * - * Argument: A pointer to an enumeration type that describes the CAN - * state + * Argument: A pointer to an int type that describes the CAN + * controller state. * returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) * is returned with the errno variable set to indicate the * nature of the error. @@ -260,8 +260,28 @@ * CANIOC_GET_STATE * Description: Get specfic can controller state * - * Argument: A pointer to an enumeration type that describes the CAN - * state + * Argument: A pointer to an int type that describes the CAN + * controller state. + * returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) + * is returned with the errno variable set to indicate the + * nature of the error. + * Dependencies: None + * + * CANIOC_SET_TRANSV_STATE + * Description: Set specfic can transceiver state + * + * Argument: A pointer to an int type that describes the CAN + * transceiver state. + * returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) + * is returned with the errno variable set to indicate the + * nature of the error. + * Dependencies: None + * + * CANIOC_GET_TRANSV_STATE + * Description: Get specfic can transceiver state + * + * Argument: A pointer to an int type that describes the CAN + * transceiver state. * returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) * is returned with the errno variable set to indicate the * nature of the error. @@ -285,9 +305,11 @@ #define CANIOC_IOFLUSH _CANIOC(15) #define CANIOC_SET_STATE _CANIOC(16) #define CANIOC_GET_STATE _CANIOC(17) +#define CANIOC_SET_TRANSVSTATE _CANIOC(18) +#define CANIOC_GET_TRANSVSTATE _CANIOC(19) #define CAN_FIRST 0x0001 /* First common command */ -#define CAN_NCMDS 15 /* 16 common commands */ +#define CAN_NCMDS 19 /* 20 common commands */ /* User defined ioctl commands are also supported. These will be forwarded * by the upper-half CAN driver to the lower-half CAN driver via the @@ -468,6 +490,22 @@ #define CAN_STATE_START 1 +/* Indicates that the can transceiver is in the sleep state */ + +#define CAN_TRANSVSTATE_SLEEP 0 + +/* Indicates that the can transceiver is in the standby state just called + * first-level power saving mode. + */ + +#define CAN_TRANSVSTATE_STANDBY 1 + +/* Indicates that the can transceiver is in the awake state + * the transceiver can transmit and receive data. + */ + +#define CAN_TRANSVSTATE_NORMAL 2 + /* CAN bit timing support ***************************************************/ #define CAN_BITTIMING_NOMINAL 0 /* Specifies nominal bittiming */ @@ -613,6 +651,21 @@ struct can_rtrwait_s */ struct can_dev_s; + +/* This is the device structure as struct can_dev_s's subdevice + * used by the driver. + */ + +struct can_transv_s; + +struct can_transv_ops_s +{ + CODE int (*ct_setstate)(FAR struct can_transv_s *transv, int state); + + CODE int (*ct_getstate)(FAR struct can_transv_s *transv, + FAR int *state); +}; + struct can_ops_s { /* Reset the CAN device. Called early to initialize the hardware. This @@ -691,6 +744,11 @@ struct can_reader_s struct can_rxfifo_s fifo; /* Describes receive FIFO */ }; +struct can_transv_s +{ + FAR const struct can_transv_ops_s *ct_ops; /* Arch-specific operations */ +}; + struct can_dev_s { uint8_t cd_crefs; /* References counts on number of opens */ @@ -707,7 +765,7 @@ struct can_dev_s struct can_rtrwait_s cd_rtr[CONFIG_CAN_NPENDINGRTR]; FAR const struct can_ops_s *cd_ops; /* Arch-specific operations */ FAR void *cd_priv; /* Used by the arch-specific logic */ - + FAR struct can_transv_s *cd_transv; /* Describes CAN transceiver */ FAR struct pollfd *cd_fds[CONFIG_CAN_NPOLLWAITERS]; }; From b68c871e62bb3e00a8d0a7ddabe969151973fef7 Mon Sep 17 00:00:00 2001 From: zhaohaiyang1 Date: Wed, 19 Jun 2024 14:41:34 +0800 Subject: [PATCH 5/6] chardriver upperCAN: support to independent set TX/RX FIFO size. support to independent set TX/RX FIFO size. Signed-off-by: zhaohaiyang1 --- .../samv7/boards/same70-xplained/README.txt | 3 ++- .../arm/samv7/boards/samv71-xult/README.txt | 3 ++- .../arm/stm32f1/boards/cloudctrl/index.rst | 6 ++++- .../arm/stm32f1/boards/fire-stm32v2/index.rst | 6 ++++- .../arm/stm32f1/boards/hymini-stm32/index.rst | 6 ++++- .../arm/stm32f1/boards/shenzhou/index.rst | 6 ++++- .../stm32f1/boards/stm3210e-eval/index.rst | 6 ++++- .../arm/stm32f1/boards/stm32_tiny/index.rst | 6 ++++- .../boards/stm32f103-minimum/index.rst | 6 ++++- Documentation/platforms/arm/stm32f2/index.rst | 7 ++++- Documentation/platforms/arm/stm32f3/index.rst | 7 ++++- Documentation/platforms/arm/stm32f4/index.rst | 7 ++++- Documentation/platforms/arm/stm32f7/index.rst | 8 +++++- drivers/can/Kconfig | 14 +++++++--- drivers/can/can.c | 14 +++++----- include/nuttx/can/can.h | 27 +++++++++++++------ 16 files changed, 101 insertions(+), 31 deletions(-) diff --git a/Documentation/platforms/arm/samv7/boards/same70-xplained/README.txt b/Documentation/platforms/arm/samv7/boards/same70-xplained/README.txt index 916b1d3456ac2..650b3a9c411d0 100644 --- a/Documentation/platforms/arm/samv7/boards/same70-xplained/README.txt +++ b/Documentation/platforms/arm/samv7/boards/same70-xplained/README.txt @@ -695,7 +695,8 @@ MCAN1 Loopback Test Device Drivers -> CAN Driver support CONFIG_CAN=y # Enable the upper-half CAN driver - CONFIG_CAN_FIFOSIZE=8 + CONFIG_CAN_TXFIFOSIZE=8 + CONFIG_CAN_RXFIFOSIZE=8 CONFIG_CAN_NPENDINGRTR=4 System Type -> SAMV7 Peripheral Selections diff --git a/Documentation/platforms/arm/samv7/boards/samv71-xult/README.txt b/Documentation/platforms/arm/samv7/boards/samv71-xult/README.txt index 30b2871dc8185..29881da3a528f 100644 --- a/Documentation/platforms/arm/samv7/boards/samv71-xult/README.txt +++ b/Documentation/platforms/arm/samv7/boards/samv71-xult/README.txt @@ -1288,7 +1288,8 @@ MCAN1 Loopback Test Device Drivers -> CAN Driver support CONFIG_CAN=y # Enable the upper-half CAN driver - CONFIG_CAN_FIFOSIZE=8 + CONFIG_CAN_TXFIFOSIZE=8 + CONFIG_CAN_RXFIFOSIZE=8 CONFIG_CAN_NPENDINGRTR=4 System Type -> SAMV7 Peripheral Selections diff --git a/Documentation/platforms/arm/stm32f1/boards/cloudctrl/index.rst b/Documentation/platforms/arm/stm32f1/boards/cloudctrl/index.rst index 653c357dc66b2..fb05c889560e3 100644 --- a/Documentation/platforms/arm/stm32f1/boards/cloudctrl/index.rst +++ b/Documentation/platforms/arm/stm32f1/boards/cloudctrl/index.rst @@ -385,7 +385,11 @@ Cloudctrl-specific Configuration Options CONFIG_CAN - Enables CAN support (one or both of CONFIG_STM32_CAN1 or CONFIG_STM32_CAN2 must also be defined) - CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. + CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer + of CAN messages. + Default: 8 + CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer + of CAN messages. Default: 8 CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. Default: 4 diff --git a/Documentation/platforms/arm/stm32f1/boards/fire-stm32v2/index.rst b/Documentation/platforms/arm/stm32f1/boards/fire-stm32v2/index.rst index 304a0c29f51b3..ad1dae3a7f37d 100644 --- a/Documentation/platforms/arm/stm32f1/boards/fire-stm32v2/index.rst +++ b/Documentation/platforms/arm/stm32f1/boards/fire-stm32v2/index.rst @@ -501,7 +501,11 @@ M3 Wildfire-specific Configuration Options CONFIG_STM32_CAN2 must also be defined) CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default Standard 11-bit IDs. - CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. + CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer + of CAN messages. + Default: 8 + CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer + of CAN messages. Default: 8 CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. Default: 4 diff --git a/Documentation/platforms/arm/stm32f1/boards/hymini-stm32/index.rst b/Documentation/platforms/arm/stm32f1/boards/hymini-stm32/index.rst index e130abc10550b..ffae6170a7d7a 100644 --- a/Documentation/platforms/arm/stm32f1/boards/hymini-stm32/index.rst +++ b/Documentation/platforms/arm/stm32f1/boards/hymini-stm32/index.rst @@ -282,7 +282,11 @@ HY-Mini specific Configuration Options CONFIG_STM32_CAN2 must also be defined) CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default Standard 11-bit IDs. - CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. + CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer + of CAN messages. + Default: 8 + CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer + of CAN messages. Default: 8 CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. Default: 4 diff --git a/Documentation/platforms/arm/stm32f1/boards/shenzhou/index.rst b/Documentation/platforms/arm/stm32f1/boards/shenzhou/index.rst index 4556641f8997b..ecdb3d49cf0a6 100644 --- a/Documentation/platforms/arm/stm32f1/boards/shenzhou/index.rst +++ b/Documentation/platforms/arm/stm32f1/boards/shenzhou/index.rst @@ -395,7 +395,11 @@ Shenzhou-specific Configuration Options CONFIG_CAN - Enables CAN support (one or both of CONFIG_STM32_CAN1 or CONFIG_STM32_CAN2 must also be defined) - CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. + CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer + of CAN messages. + Default: 8 + CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer + of CAN messages. Default: 8 CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. Default: 4 diff --git a/Documentation/platforms/arm/stm32f1/boards/stm3210e-eval/index.rst b/Documentation/platforms/arm/stm32f1/boards/stm3210e-eval/index.rst index 46567e01ec6dc..3f506d6276aba 100644 --- a/Documentation/platforms/arm/stm32f1/boards/stm3210e-eval/index.rst +++ b/Documentation/platforms/arm/stm32f1/boards/stm3210e-eval/index.rst @@ -444,7 +444,11 @@ STM3210E-EVAL-specific Configuration Options CONFIG_STM32_CAN2 must also be defined) CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default Standard 11-bit IDs. - CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. + CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer + of CAN messages. + Default: 8 + CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer + of CAN messages. Default: 8 CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. Default: 4 diff --git a/Documentation/platforms/arm/stm32f1/boards/stm32_tiny/index.rst b/Documentation/platforms/arm/stm32f1/boards/stm32_tiny/index.rst index be8e7d2c5f0ae..92f2c488ee0f3 100644 --- a/Documentation/platforms/arm/stm32f1/boards/stm32_tiny/index.rst +++ b/Documentation/platforms/arm/stm32f1/boards/stm32_tiny/index.rst @@ -231,7 +231,11 @@ STM32 Tiny - specific Configuration Options CONFIG_STM32_CAN2 must also be defined) CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default Standard 11-bit IDs. - CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. + CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer + of CAN messages. + Default: 8 + CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer + of CAN messages. Default: 8 CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. Default: 4 diff --git a/Documentation/platforms/arm/stm32f1/boards/stm32f103-minimum/index.rst b/Documentation/platforms/arm/stm32f1/boards/stm32f103-minimum/index.rst index 601f22c38c2c4..15b5abd7f86bf 100644 --- a/Documentation/platforms/arm/stm32f1/boards/stm32f103-minimum/index.rst +++ b/Documentation/platforms/arm/stm32f1/boards/stm32f103-minimum/index.rst @@ -740,7 +740,11 @@ STM32F103 Minimum - specific Configuration Options CONFIG_STM32_CAN2 must also be defined) CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default Standard 11-bit IDs. - CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. + CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer + of CAN messages. + Default: 8 + CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer + of CAN messages. Default: 8 CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. Default: 4 diff --git a/Documentation/platforms/arm/stm32f2/index.rst b/Documentation/platforms/arm/stm32f2/index.rst index 800d37c670082..d69e7ccab48ad 100644 --- a/Documentation/platforms/arm/stm32f2/index.rst +++ b/Documentation/platforms/arm/stm32f2/index.rst @@ -93,7 +93,12 @@ CAN - CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default Standard 11-bit IDs. -- CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. +- CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer + of CAN messages. + Default: 8 + +- CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer + of CAN messages. Default: 8 - CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. diff --git a/Documentation/platforms/arm/stm32f3/index.rst b/Documentation/platforms/arm/stm32f3/index.rst index a2a7829d309de..14604e975c81c 100644 --- a/Documentation/platforms/arm/stm32f3/index.rst +++ b/Documentation/platforms/arm/stm32f3/index.rst @@ -140,7 +140,12 @@ CAN character device - CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default Standard 11-bit IDs. -- CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. +- CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer + of CAN messages. + Default: 8 + +- CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer + of CAN messages. Default: 8 - CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. diff --git a/Documentation/platforms/arm/stm32f4/index.rst b/Documentation/platforms/arm/stm32f4/index.rst index 7242a16b56fac..a632dfeba335b 100644 --- a/Documentation/platforms/arm/stm32f4/index.rst +++ b/Documentation/platforms/arm/stm32f4/index.rst @@ -144,7 +144,12 @@ CAN - CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default Standard 11-bit IDs. -- CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. +- CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer + of CAN messages. + Default: 8 + +- CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer + of CAN messages. Default: 8 - CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. diff --git a/Documentation/platforms/arm/stm32f7/index.rst b/Documentation/platforms/arm/stm32f7/index.rst index 2e798d5dcc41b..caf122dad58fd 100644 --- a/Documentation/platforms/arm/stm32f7/index.rst +++ b/Documentation/platforms/arm/stm32f7/index.rst @@ -189,7 +189,13 @@ CAN - CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default Standard 11-bit IDs. -- CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. Default: 8 +- CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer + of CAN messages. + Default: 8 + +- CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer + of CAN messages. + Default: 8 - CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. Default: 4 diff --git a/drivers/can/Kconfig b/drivers/can/Kconfig index d6a2b88a1d6ed..2379a9c81a090 100644 --- a/drivers/can/Kconfig +++ b/drivers/can/Kconfig @@ -39,11 +39,19 @@ config CAN_FD ---help--- Enables support for the CAN_FD mode. -config CAN_FIFOSIZE - int "CAN driver I/O buffer size" +config CAN_TXFIFOSIZE + int "CAN driver I/O tx buffer size" default 8 + range 1 255 ---help--- - The size of the circular buffer of CAN messages. Default: 8 + The size of the circular tx buffer of CAN messages. Default: 8 + +config CAN_RXFIFOSIZE + int "CAN driver I/O rx buffer size" + default 8 + range 1 255 + ---help--- + The size of the circular rx buffer of CAN messages. Default: 8 config CAN_NPENDINGRTR int "Number of pending RTRs" diff --git a/drivers/can/can.c b/drivers/can/can.c index e7e8b5497be88..fd74f571c3add 100644 --- a/drivers/can/can.c +++ b/drivers/can/can.c @@ -465,7 +465,7 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer, /* Increment the head of the circular message buffer */ - if (++fifo->rx_head >= CONFIG_CAN_FIFOSIZE) + if (++fifo->rx_head >= CONFIG_CAN_RXFIFOSIZE) { fifo->rx_head = 0; } @@ -549,7 +549,7 @@ static int can_xmit(FAR struct can_dev_s *dev) */ tmpndx = dev->cd_xmit.tx_queue; - if (++dev->cd_xmit.tx_queue >= CONFIG_CAN_FIFOSIZE) + if (++dev->cd_xmit.tx_queue >= CONFIG_CAN_TXFIFOSIZE) { dev->cd_xmit.tx_queue = 0; } @@ -615,7 +615,7 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, */ nexttail = fifo->tx_tail + 1; - if (nexttail >= CONFIG_CAN_FIFOSIZE) + if (nexttail >= CONFIG_CAN_TXFIFOSIZE) { nexttail = 0; } @@ -885,7 +885,7 @@ static int can_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case FIONWRITE: { - *(FAR uint8_t *)arg = CONFIG_CAN_FIFOSIZE - 1 - + *(FAR uint8_t *)arg = CONFIG_CAN_TXFIFOSIZE - 1 - (dev->cd_xmit.tx_tail - dev->cd_xmit.tx_head); } break; @@ -1044,7 +1044,7 @@ static int can_poll(FAR struct file *filep, FAR struct pollfd *fds, */ ndx = dev->cd_xmit.tx_tail + 1; - if (ndx >= CONFIG_CAN_FIFOSIZE) + if (ndx >= CONFIG_CAN_TXFIFOSIZE) { ndx = 0; } @@ -1235,7 +1235,7 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr, fifo = &reader->fifo; nexttail = fifo->rx_tail + 1; - if (nexttail >= CONFIG_CAN_FIFOSIZE) + if (nexttail >= CONFIG_CAN_RXFIFOSIZE) { nexttail = 0; } @@ -1405,7 +1405,7 @@ int can_txdone(FAR struct can_dev_s *dev) /* Remove the message at the head of the xmit FIFO */ - if (++dev->cd_xmit.tx_head >= CONFIG_CAN_FIFOSIZE) + if (++dev->cd_xmit.tx_head >= CONFIG_CAN_TXFIFOSIZE) { dev->cd_xmit.tx_head = 0; } diff --git a/include/nuttx/can/can.h b/include/nuttx/can/can.h index 9c62d5deb964a..cf3f8ec1f5b8f 100644 --- a/include/nuttx/can/can.h +++ b/include/nuttx/can/can.h @@ -59,7 +59,11 @@ * CONFIG_CAN_FD - Enable support for CAN FD mode. * For the upper half driver, this just means handling encoded DLC values * (for values of DLC > 9). - * CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. + * CONFIG_CAN_TXFIFOSIZE - The size of the circular tx buffer + * of CAN messages. + * Default: 8 + * CONFIG_CAN_RXFIFOSIZE - The size of the circular rx buffer + * of CAN messages. * Default: 8 * CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. * Default: 4 @@ -81,11 +85,18 @@ * The configured size is limited to 255 to fit into a uint8_t. */ -#if !defined(CONFIG_CAN_FIFOSIZE) -# define CONFIG_CAN_FIFOSIZE 8 -#elif CONFIG_CAN_FIFOSIZE > 255 -# undef CONFIG_CAN_FIFOSIZE -# define CONFIG_CAN_FIFOSIZE 255 +#if !defined(CONFIG_CAN_TXFIFOSIZE) +# define CONFIG_CAN_TXFIFOSIZE 8 +#elif CONFIG_CAN_TXFIFOSIZE > 255 +# undef CONFIG_CAN_TXFIFOSIZE +# define CONFIG_CAN_TXFIFOSIZE 255 +#endif + +#if !defined(CONFIG_CAN_RXFIFOSIZE) +# define CONFIG_CAN_RXFIFOSIZE 8 +#elif CONFIG_CAN_RXFIFOSIZE > 255 +# undef CONFIG_CAN_RXFIFOSIZE +# define CONFIG_CAN_RXFIFOSIZE 255 #endif #if !defined(CONFIG_CAN_NPENDINGRTR) @@ -622,7 +633,7 @@ struct can_rxfifo_s 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 */ /* Circular buffer of CAN messages */ - struct can_msg_s rx_buffer[CONFIG_CAN_FIFOSIZE]; + struct can_msg_s rx_buffer[CONFIG_CAN_RXFIFOSIZE]; }; struct can_txfifo_s @@ -632,7 +643,7 @@ struct can_txfifo_s uint8_t tx_queue; /* Index to next message to send */ uint8_t tx_tail; /* Index to the tail [OUT] in the circular buffer */ /* Circular buffer of CAN messages */ - struct can_msg_s tx_buffer[CONFIG_CAN_FIFOSIZE]; + struct can_msg_s tx_buffer[CONFIG_CAN_TXFIFOSIZE]; }; /* The following structure define the logic to handle From a9c98f075dd7c1e7e59d48141a6369353aad4f98 Mon Sep 17 00:00:00 2001 From: zhaohaiyang1 Date: Mon, 17 Jun 2024 23:03:59 +0800 Subject: [PATCH 6/6] char driver CAN: add tx_confirm function in upperCAN driver. add tx_confirm function in upperCAN driver1 Signed-off-by: zhaohaiyang1 --- arch/arm/src/at32/at32_can.c | 4 ++-- arch/arm/src/lpc17xx_40xx/lpc17_40_can.c | 2 +- arch/arm/src/sama5/sam_can.c | 2 +- arch/arm/src/sama5/sam_mcan.c | 14 +++++++------- arch/arm/src/samv7/sam_mcan.c | 6 +++--- arch/arm/src/stm32/stm32_can.c | 4 ++-- arch/arm/src/stm32/stm32_fdcan.c | 4 ++-- arch/arm/src/stm32f7/stm32_can.c | 2 +- arch/arm/src/stm32l4/stm32l4_can.c | 2 +- drivers/can/Kconfig | 11 +++++++++++ drivers/can/can.c | 13 ++++++++++--- drivers/can/mcp2515.c | 4 ++-- include/nuttx/can/can.h | 4 ++-- 13 files changed, 45 insertions(+), 27 deletions(-) diff --git a/arch/arm/src/at32/at32_can.c b/arch/arm/src/at32/at32_can.c index 3470111a7d938..3bb5e0a4c30c5 100644 --- a/arch/arm/src/at32/at32_can.c +++ b/arch/arm/src/at32/at32_can.c @@ -1586,7 +1586,7 @@ static int at32can_rxinterrupt(struct can_dev_s *dev, int rxmb) #ifdef CONFIG_CAN_ERRORS hdr.ch_error = 0; /* Error reporting not supported */ #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; /* Extract the RTR bit */ @@ -1895,7 +1895,7 @@ static int at32can_sceinterrupt(int irq, void *context, void *arg) #ifdef CONFIG_CAN_EXTID hdr.ch_extid = 0; #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; /* And provide the error report to the upper half logic */ diff --git a/arch/arm/src/lpc17xx_40xx/lpc17_40_can.c b/arch/arm/src/lpc17xx_40xx/lpc17_40_can.c index 66035bb04216e..f1611e69d9059 100644 --- a/arch/arm/src/lpc17xx_40xx/lpc17_40_can.c +++ b/arch/arm/src/lpc17xx_40xx/lpc17_40_can.c @@ -1356,7 +1356,7 @@ static void can_interrupt(struct lpc17_40_can_s *dev) #ifdef CONFIG_CAN_EXTID hdr.ch_extid = ((rfs & CAN_RFS_FF) != 0); #else - hdr.ch_unused = 0; + hdr.ch_tcf = 0; if ((rfs & CAN_RFS_FF) != 0) { diff --git a/arch/arm/src/sama5/sam_can.c b/arch/arm/src/sama5/sam_can.c index 0ba5ba53c9d25..d114fe809d9ae 100644 --- a/arch/arm/src/sama5/sam_can.c +++ b/arch/arm/src/sama5/sam_can.c @@ -1318,7 +1318,7 @@ static inline void can_rxinterrupt(struct can_dev_s *dev, int mbndx, #ifdef CONFIG_CAN_ERRORS hdr.ch_error = 0; /* Error reporting not supported */ #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; /* And provide the CAN message to the upper half logic */ diff --git a/arch/arm/src/sama5/sam_mcan.c b/arch/arm/src/sama5/sam_mcan.c index 7126e033cd1b8..a6bc33f53eb07 100644 --- a/arch/arm/src/sama5/sam_mcan.c +++ b/arch/arm/src/sama5/sam_mcan.c @@ -3459,14 +3459,14 @@ static void mcan_error(struct can_dev_s *dev, uint32_t status) { /* Format the CAN header for the error report. */ - hdr.ch_id = errbits; - hdr.ch_dlc = CAN_ERROR_DLC; - hdr.ch_rtr = 0; - hdr.ch_error = 1; + hdr.ch_id = errbits; + hdr.ch_dlc = CAN_ERROR_DLC; + hdr.ch_rtr = 0; + hdr.ch_error = 1; #ifdef CONFIG_CAN_EXTID - hdr.ch_extid = 0; + hdr.ch_extid = 0; #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; /* And provide the error report to the upper half logic */ @@ -3628,7 +3628,7 @@ static void mcan_receive(struct can_dev_s *dev, uint32_t *rxbuffer, #ifdef CONFIG_CAN_ERRORS hdr.ch_error = 0; #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; if ((regval & BUFFER_R0_RTR) != 0) { diff --git a/arch/arm/src/samv7/sam_mcan.c b/arch/arm/src/samv7/sam_mcan.c index 3a5d8062ddbe1..92eb30763b4e4 100644 --- a/arch/arm/src/samv7/sam_mcan.c +++ b/arch/arm/src/samv7/sam_mcan.c @@ -3483,7 +3483,7 @@ static void mcan_error(struct can_dev_s *dev, uint32_t status) #ifdef CONFIG_CAN_EXTID hdr.ch_extid = 0; #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; /* And provide the error report to the upper half logic */ @@ -3535,9 +3535,9 @@ static void mcan_receive(struct can_dev_s *dev, uint32_t *rxbuffer, reginfo("R0: %08" PRIx32 "\n", regval); #ifdef CONFIG_CAN_ERRORS - hdr.ch_error = 0; + hdr.ch_error = 0; #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; if ((regval & BUFFER_R0_RTR) != 0) { diff --git a/arch/arm/src/stm32/stm32_can.c b/arch/arm/src/stm32/stm32_can.c index 9e9d8e08fb365..89480b88c2dc7 100644 --- a/arch/arm/src/stm32/stm32_can.c +++ b/arch/arm/src/stm32/stm32_can.c @@ -1581,7 +1581,7 @@ static int stm32can_rxinterrupt(struct can_dev_s *dev, int rxmb) #ifdef CONFIG_CAN_ERRORS hdr.ch_error = 0; /* Error reporting not supported */ #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; /* Extract the RTR bit */ @@ -1890,7 +1890,7 @@ static int stm32can_sceinterrupt(int irq, void *context, void *arg) #ifdef CONFIG_CAN_EXTID hdr.ch_extid = 0; #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; /* And provide the error report to the upper half logic */ diff --git a/arch/arm/src/stm32/stm32_fdcan.c b/arch/arm/src/stm32/stm32_fdcan.c index 8d573c976a78d..ef51fe710898e 100644 --- a/arch/arm/src/stm32/stm32_fdcan.c +++ b/arch/arm/src/stm32/stm32_fdcan.c @@ -2801,7 +2801,7 @@ static void fdcan_error(struct can_dev_s *dev, uint32_t status) #ifdef CONFIG_CAN_EXTID hdr.ch_extid = 0; #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; /* And provide the error report to the upper half logic */ @@ -2846,7 +2846,7 @@ static void fdcan_receive(struct can_dev_s *dev, #ifdef CONFIG_CAN_ERRORS hdr.ch_error = 0; #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; /* Extract the RTR bit */ diff --git a/arch/arm/src/stm32f7/stm32_can.c b/arch/arm/src/stm32f7/stm32_can.c index f65755efd42bf..4dad6cf795707 100644 --- a/arch/arm/src/stm32f7/stm32_can.c +++ b/arch/arm/src/stm32f7/stm32_can.c @@ -1518,7 +1518,7 @@ static int stm32can_rxinterrupt(struct can_dev_s *dev, int rxmb) #ifdef CONFIG_CAN_ERRORS hdr.ch_error = 0; /* Error reporting not supported */ #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; /* Extract the RTR bit */ diff --git a/arch/arm/src/stm32l4/stm32l4_can.c b/arch/arm/src/stm32l4/stm32l4_can.c index 48796dbf4c9e0..c9939ae91fad0 100644 --- a/arch/arm/src/stm32l4/stm32l4_can.c +++ b/arch/arm/src/stm32l4/stm32l4_can.c @@ -1445,7 +1445,7 @@ static int stm32l4can_rxinterrupt(int irq, void *context, int rxmb) #ifdef CONFIG_CAN_ERRORS hdr.ch_error = 0; /* Error reporting not supported */ #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; /* Extract the RTR bit */ diff --git a/drivers/can/Kconfig b/drivers/can/Kconfig index 2379a9c81a090..ff303d8713941 100644 --- a/drivers/can/Kconfig +++ b/drivers/can/Kconfig @@ -59,6 +59,17 @@ config CAN_NPENDINGRTR ---help--- The size of the list of pending RTR requests. Default: 4 +config CAN_TXCONFIRM + bool "can txconfirm ability" + default n + ---help--- + this section enables the can txconfirm ability. + + Enabling this feature adds support for the can txconfirm + ability, the ability is used from CAN interrupt handler + when the transfer is complete, the ability will notify all + readers that the canid has been transferred. + config CAN_TXREADY bool "can_txready interface" default n diff --git a/drivers/can/can.c b/drivers/can/can.c index fd74f571c3add..111ee38cca4ad 100644 --- a/drivers/can/can.c +++ b/drivers/can/can.c @@ -408,7 +408,7 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer, #ifdef CONFIG_CAN_EXTID msg->cm_hdr.ch_extid = 0; #endif - msg->cm_hdr.ch_unused = 0; + msg->cm_hdr.ch_tcf = 0; memset(&(msg->cm_data), 0, CAN_ERROR_DLC); msg->cm_data[5] = fifo->rx_error; @@ -1219,7 +1219,11 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr, memcpy(&waitmsg->cm_hdr, hdr, sizeof(struct can_hdr_s)); nbytes = can_dlc2bytes(hdr->ch_dlc); - memcpy(waitmsg->cm_data, data, nbytes); + if (nbytes) + { + memcpy(waitmsg->cm_data, data, nbytes); + } + dev->cd_npendrtr--; /* Restart the waiting thread and mark the entry unused */ @@ -1260,7 +1264,10 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr, sizeof(struct can_hdr_s)); nbytes = can_dlc2bytes(hdr->ch_dlc); - memcpy(fifo->rx_buffer[fifo->rx_tail].cm_data, data, nbytes); + if (nbytes) + { + memcpy(fifo->rx_buffer[fifo->rx_tail].cm_data, data, nbytes); + } /* Increment the tail of the circular buffer */ diff --git a/drivers/can/mcp2515.c b/drivers/can/mcp2515.c index f413f2da58892..af636d162d8d3 100644 --- a/drivers/can/mcp2515.c +++ b/drivers/can/mcp2515.c @@ -2031,7 +2031,7 @@ static void mcp2515_error(FAR struct can_dev_s *dev, uint8_t status, #ifdef CONFIG_CAN_EXTID hdr.ch_extid = 0; #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; /* And provide the error report to the upper half logic */ @@ -2141,7 +2141,7 @@ static void mcp2515_receive(FAR struct can_dev_s *dev, uint8_t offset) #ifdef CONFIG_CAN_ERRORS hdr.ch_error = 0; /* Error reporting not supported */ #endif - hdr.ch_unused = 0; + hdr.ch_tcf = 0; /* Extract the RTR bit */ diff --git a/include/nuttx/can/can.h b/include/nuttx/can/can.h index cf3f8ec1f5b8f..afc6522189048 100644 --- a/include/nuttx/can/can.h +++ b/include/nuttx/can/can.h @@ -589,7 +589,7 @@ begin_packed_struct struct can_hdr_s uint8_t ch_brs : 1; /* Bit Rate Switch */ uint8_t ch_esi : 1; /* Error State Indicator */ #endif - uint8_t ch_unused : 1; /* FIXME: This field is useless, kept for backward compatibility */ + uint8_t ch_tcf : 1; /* Tx confirmation flag */ } end_packed_struct; #else @@ -606,7 +606,7 @@ begin_packed_struct struct can_hdr_s uint8_t ch_brs : 1; /* Bit Rate Switch */ uint8_t ch_esi : 1; /* Error State Indicator */ #endif - uint8_t ch_unused : 1; /* FIXME: This field is useless, kept for backward compatibility */ + uint8_t ch_tcf : 1; /* Tx confirmation flag */ } end_packed_struct; #endif