Introduce a single configuration option to provide strict transmit
priority ordering based on CAN ID.
The intention is to expose the user-visible behavior (strict TX
priority ordering) rather than the underlying implementation details.
Strict priority ordering is only meaningful when hardware transmit
buffer cancellation is available, so splitting this functionality into
separate configuration options was misleading and could result in
partially effective or incorrect configurations.
Signed-off-by: zhaohaiyang1 <zhaohaiyang1@xiaomi.com>
O_NONBLOCK open mode was broken since
https://github.com/apache/nuttx/pull/17360
MIN() comapres signed value (int) with unsigned value (size_t) which causes
an unexpected return value when ret is negative
Signed-off-by: raiden00pl <raiden00@railab.me>
This adds ability for read and write operations to work with messages
aligned to configured number of bytes. This has few different use
cases.
The alignment is specified as unsigned integer and can be changed with
ioctl command CANIOC_SET_MSGALIGN. The current value can be queried by
CANIOC_GET_MSGALIGN command.
The default value for the message alignment is 1. This will provide
behavior consistent with current one. Thus messages are placed to the
buffer right after data of the previous one. The same applies for
writes.
The special alignment value 0 disables read and write of multiple frames. Thus
read will always return at most one message and write will always write
only one message even if larger buffer size is provided.
Another use case is if message alignment is set to exactly message
representation size (`sizeof(struct can_msg_s)`). This allows writing
and reading arrays of messages.
Other values provide even more advanced and specialized use cases, such
as optimizations if architecture has to emulate some non-aligned
accesses, there alignment of for example 4 bytes could provide
performance boost.
The original motivation behind this is was 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 solution was suggested by Pavel Pisa
<pisa@fel.cvut.cz> as a more versatile variant of plain boolean
disabling the multiple frame retrieval.
Signed-off-by: Karel Kočí <kkoci@elektroline.cz>
The empty FIFO can happen only in two cases. Either there is some
inconsistency that made rx_sem ready but buffer is empty (that might
happen if multiple reads are blocked in parallel, or just due to the bug
in the logic), or if close is used. Until now the 0 would be returned
and thus EOF. The error is not EOF and actually it is still possible to
read afterwards. Thus we for sure should not signal EOF for the first
cause. The second cause for close matches the behavior that is expressed
even on glibc for some file descriptors (the waiting read will commonly
get error EINVAL there). We can't decide on the real cause of this
situation and thus we always report EIO error and thus generic
input/output error.
Signed-off-by: Karel Kočí <kkoci@elektroline.cz>
The previous version of the code was posting the semaphore every time
the value was less or equal to the zero. In case there is read already
waiting on the semaphore the value will be -1. The first frame will post
the value to 0 and thus unblocking the waiting read. The read will take
frames out of FIFO. During that time if next frame is received it will
be placed to the FIFO but because rx_sem has value 0 at that time it
will be posted to value 1. Once read finishes the execution it will
check if there is something still in the FIFO and posts semaphore back
(expecting that the value is 0) thus increasing value to 2. Thus we end
up with read being unblocked once more triggering 'RX FIFO sem posted
but FIFO is empty.' error branch and returning zero (signaling EOF?).
The intuitive fix is to check the value of the semaphore before posting
it in the read's tail. This could have race condition case when
interrupt is delivered between nxsem_get_value and nxsem_post and
can_receive is called.
This fix instead uses the same condition to detect if semaphore must be
posted as read does. Thus we check if previously the FIFO was empty. We
post the semaphore on in case FIFO was initially empty, otherwise we
expect semaphore to be fully managed by can_read.
Signed-off-by: Karel Kočí <cynerd@email.cz>
The message passed to the write can have `cm.hdr.ch_rtr` set and if
nonzero DLC is specified in the frame then invalid number of bytes is
removed from the buffer as RTR frames do not have any data even when DLC
is nonzero.
This was tested on SAMv7 (mcan). With this change a custom RTR can be
sent.
Signed-off-by: Karel Kočí <cynerd@email.cz>
The message size is being calculated from the message itself. If
application sets value cm_hdr.ch_dlc greater than buflen (that is
size_t) then calculation in while condition underflows and multiple
messages are attempted to be sent.
This check prevents that by verifying that the message size that was
encoded in the dlc is not greater than indicated size of the buffer.
Signed-off-by: Karel Kočí <cynerd@email.cz>
Nuttx currently has 2 types of sleep interfaces:
1. Signal-scheduled sleep: nxsig_sleep() / nxsig_usleep() / nxsig_nanosleep()
Weaknesses:
a. Signal-dependent: The signal-scheduled sleep method is bound to the signal framework, while some driver sleep operations do not depend on signals.
b. Timespec conversion: Signal-scheduled sleep involves timespec conversion, which has a significant impact on performance.
2. Busy sleep: up_mdelay() / up_udelay()
Weaknesses:
a. Does not actively trigger scheduling, occupy the CPU loading.
3. New interfaces: Scheduled sleep: nxsched_sleep() / nxsched_usleep() / nxsched_msleep() / nxsched_ticksleep()
Strengths:
a. Does not depend on the signal framework.
b. Tick-based, without additional computational overhead.
Currently, the Nuttx driver framework extensively uses nxsig_* interfaces. However, the driver does not need to rely on signals or timespec conversion.
Therefore, a new set of APIs is added to reduce dependencies on other modules.
(This PR also aims to make signals optional, further reducing the code size of Nuttx.)
Signed-off-by: chao an <anchao.archer@bytedance.com>
Move can_bytes2dlc() and can_dlc2bytes() to a common CAN file
that can be shared between socketCAN implementation and CAN
character driver.
This is the first step to simplifying the logic repeated in
many CAN drivers.
Signed-off-by: raiden00pl <raiden00@railab.me>
For clearing some variables corresponding with the pollfds of the felip in can_close API, we modify poll logic by binding can_reader_s and pollfd.
Signed-off-by: zhaohaiyang1 <zhaohaiyang1@xiaomi.com>
Most tools used for compliance and SBOM generation use SPDX identifiers
This change brings us a step closer to an easy SBOM generation.
Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
Some macro definitions have already been defined in other header files, redundant macro definitions have been removed in include/nuttx/can.h. Align some code. Remove no use struct (can_response_s) and some variables.
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit moves can_bytes2dlc and can_dlc2bytes from kernel internal
functions to API. These functions are necessary to convert bytes to
dlc for CAN FD frames and has to be accessible from the application
since can_hdr_s does not store message length in bytes but directly in
dlc.
Signed-off-by: Michal Lenc <michallenc@seznam.cz>
In this nested loop, the iteration variable is the same for both loops.
This is a typo and the inner loop should use a new loop variable.
Signed-off-by: Mingjie Shen <shen497@purdue.edu>
since mmap may exist in block_operations, but truncate may not,
moving mmap beforee truncate could make three struct more compatible
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
- Add mmap into file_operations and remove it from ioctl definitions.
- Add mm_map structure definitions to support future unmapping
- Modify all drivers to initialize the operations struct accordingly
Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
- Add truncate into file_operations
- Move truncate to be common for mountpt_operations and file_operations
- Modify all drivers to initialize the operations struct accordingly
Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
Gregory Nutt has submitted the SGA
Omni Hoverboards has submitted the SGA
Paul Alexander Patience has submitted the ICLA
as a result we can migrate the licenses to Apache.
Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
Because buflen is size_t (unsigned) and nsent is ssize_t (signed)
of the same size, (buflen - nsent) results in unsigned and
overflows if nsent > buflen.
This happens when sending CAN FD frame with DLC > 8 and a user
gets the buflen parameter as a result of CAN_MSGLEN(len)
where `len' is the size of data which is less then a size
for some extended DLC (e.g. 26 bytes is sent in a message with
DLC 0xD, which has 32 bytes of data).
The correct buflen value should be rather
CAN_MSGLEN(can_dlc2bytes(can_bytes2dlc(len)))
Signed-off-by: Jaroslav Beran <jara.beran@gmail.com>
There is a good case on sim platform:
When we input some cmd and click enter key to start application in terminal,
this context will change to application from IDLE loop. Althrough entey key '\r'
has been received to recv buffer and complete post semaphore of reader, but
pollnotify may not be called because context change. So when application run
poll function, because no events happend and poll enter wait, context will
again change to IDLE loop, this pollnotify of IDLE loop will run to send poll
events, poll function of applicaton will wake up. It's wrong!
Change-Id: I812a889f2e90781a9c3cb4b0251cccc4d32bebd1
Signed-off-by: dongjiuzhu <dongjiuzhu1@xiaomi.com>