On 20.07.22 08:49, Vincent Mailhol wrote:
On Mon. 18 Jul. 2022 at 20:16, Pavel Pisa <pisa@xxxxxxxxxxxxxxxx> wrote:
Hello Oliver,
On Sunday 17 of July 2022 15:27:25 Oliver Hartkopp wrote:
V2: Major rework after discussion and feedback on Linux-CAN ML
- rework of struct canxl_frame
- CANXL_XLF flag is now the switch between CAN XL and CAN/CANFD
- variable length in r/w operations for CAN XL frames
- write CAN XL frame to raw socket enforces size <-> canxl_frame.len sync
I generally like the idea but I would like even to extend it to process
all CAN messages types through same API.
+struct canxl_frame {
+ canid_t prio; /* 11 bit priority for arbitration (canid_t) */
+ __u8 flags; /* additional flags for CAN XL */
+ __u8 sdt; /* SDU (service data unit) type */
+ __u16 len; /* frame payload length in byte */
+ __u32 af; /* acceptance field */
+ __u8 data[CANXL_MAX_DLEN];
+};
I would suggest to think about possibility to have single structure type
for processing of all CAN frames types in usersace.
I thought about it.
The prio is 11 bits, the XLF and SEC flags are 2 bits together, the
SDT is 8 bits, the length is 12 bits (1~2048) and finally the af is 32
bits. The total is thus 11+2+8+12+32 = 65 bits. Arg… one bit short to
fit in the struct can(fd)_frame!
However, if we use the DLC instead, the length information can fit on
11 bits (0~2047). With this, we have just enough to squeeze in the
CAN-XL flags.
And so, let me introduce you the Frankenstein monster version of the
canxl_frame:
#include <asm/byteorder.h>
struct canxl_frame {
union {
canid_t can_id; /* CAN(-FD) ID */
__u32 af; /* CAN-XL acceptance field */
};
union {
struct {
__u8 len; /* CAN(-FD) frame length */
__u8 flags; /* additional flags for CAN FD */
__u8 __res0; /* reserved / padding */
__u8 len8_dlc; /* optional Classic CAN DLC for
8 byte payload length (9 .. 15) */
};
struct {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u32 xlf:1; /* is CAN-XL frame? */
#endif
__u32 sec:1; /* Simple Extended Content
(security/segmentation) */
__u32 xl_dlc:11; /* CAN-XL data length code (0..2047) */
__u32 prio:11; /* 11 bit priority for arbitration */
__u32 sdt:8; /* SDU (service data unit) type */
#if defined(__BIG_ENDIAN_BITFIELD)
__u32 xlf:1; /* is CAN-XL frame? */
#endif
};
};
__u8 data[] __attribute__((aligned(8)));
};
Pretty scary, isn’t it?
To be honest, I am sharing this for fun. No need to disprove this
idea, I do *not* support it myself.
But sometimes it is valuable to formulate an idea as code to see that
this is definitely NOT what you want ;-)
Best regards,
Oliver