Skip to content

Commit 5eb58d6

Browse files
committed
nuttx/can: add read watermark
This provides an optional way to limit number of frames to be copied to the buffer on read operation. The idea is to allow not only binary decision if more than one frame can be read but a more granular control. The size of the buffer itself can't be used for this purpose because even on plain CAN up three small frames can fit into buffer prepared for a full sized frame. The explicit change of the behavior of course is not desirable but having ability to control this is advantageous. The motivation behind this is the compatibility with socket CAN. It is easier to port applications to NuttX's CAN driver if only one frame is provided at the time. This is achieved by setting watermark to zero. This solution was suggested by Pavel Pisa <[email protected]> as a more versatile variant of plain boolean disabling the multiple frame retrieval. Signed-off-by: Karel Kočí <[email protected]>
1 parent a391959 commit 5eb58d6

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

drivers/can/can.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ static FAR struct can_reader_s *init_can_reader(FAR struct file *filep)
193193
DEBUGASSERT(reader != NULL);
194194

195195
nxsem_init(&reader->fifo.rx_sem, 0, 0);
196+
reader->rxwatermark = SIZE_MAX;
196197
filep->f_priv = reader;
197198

198199
return reader;
@@ -489,7 +490,7 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer,
489490
fifo->rx_head = 0;
490491
}
491492
}
492-
while (fifo->rx_head != fifo->rx_tail);
493+
while (fifo->rx_head != fifo->rx_tail && ret < reader->rxwatermark);
493494

494495
if (fifo->rx_head != fifo->rx_tail)
495496
{
@@ -964,6 +965,22 @@ static int can_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
964965
}
965966
break;
966967

968+
/* Set read watermark */
969+
970+
case CANIOC_SET_IWATERMARK:
971+
{
972+
reader->rxwatermark = *(FAR size_t *)arg;
973+
}
974+
break;
975+
976+
/* Set read watermark */
977+
978+
case CANIOC_GET_IWATERMARK:
979+
{
980+
*(FAR size_t *)arg = reader->rxwatermark;
981+
}
982+
break;
983+
967984
/* Not a "built-in" ioctl command.. perhaps it is unique to this
968985
* lower-half, device driver.
969986
*/

include/nuttx/can/can.h

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,29 @@
305305
* is returned with the errno variable set to indicate the
306306
* nature of the error.
307307
* Dependencies: None
308+
*
309+
* CANIOC_SET_IWATERMARK
310+
* Description: Set read watermark. This watermark limits number of
311+
* bytes multiple frames can take in read. The frame is not
312+
* placed to the provided buffer if it would start after
313+
* the watermark offset (thus value 0 ensures only one
314+
* frame to be placed into the buffer). The default valued
315+
* is SIZE_MAX.
316+
*
317+
* Argument: A pointer to an size_t type with watermark value.
318+
* returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR)
319+
* is returned with the errno variable set to indicate the
320+
* nature of the error.
321+
* Dependencies: None
322+
*
323+
* CANIOC_GET_IWATERMARK
324+
* Description: Get read watermark.
325+
*
326+
* Argument: A pointer to an size_t type for watermark value.
327+
* returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR)
328+
* is returned with the errno variable set to indicate the
329+
* nature of the error.
330+
* Dependencies: None
308331
*/
309332

310333
#define CANIOC_RTR _CANIOC(1)
@@ -326,9 +349,11 @@
326349
#define CANIOC_GET_STATE _CANIOC(17)
327350
#define CANIOC_SET_TRANSVSTATE _CANIOC(18)
328351
#define CANIOC_GET_TRANSVSTATE _CANIOC(19)
352+
#define CANIOC_SET_IWATERMARK _CANIOC(20)
353+
#define CANIOC_GET_IWATERMARK _CANIOC(21)
329354

330355
#define CAN_FIRST 0x0001 /* First common command */
331-
#define CAN_NCMDS 19 /* 20 common commands */
356+
#define CAN_NCMDS 21 /* 21 common commands */
332357

333358
/* User defined ioctl commands are also supported. These will be forwarded
334359
* by the upper-half CAN driver to the lower-half CAN driver via the
@@ -796,13 +821,15 @@ struct can_ops_s
796821
*
797822
* The elements of 'cd_ops', and 'cd_priv'
798823
*
799-
* The common logic will initialize all semaphores.
824+
* The common logic will initialize all semaphores and set 'watermark' to
825+
* 'SIZE_MAX'.
800826
*/
801827

802828
struct can_reader_s
803829
{
804830
struct list_node list;
805831
struct can_rxfifo_s fifo; /* Describes receive FIFO */
832+
size_t rxwatermark;
806833
FAR struct pollfd *cd_fds;
807834
};
808835

0 commit comments

Comments
 (0)