On 27.10.20 14:06, Marc Kleine-Budde wrote:
On 10/23/20 10:30 PM, Oliver Hartkopp wrote:
ISO 11898-1 Chapter 8.4.2.3 defines a 4 bit data length code (DLC) table which
maps the DLC to the payload length of the CAN frame in bytes:
DLC -> payload length
0 .. 8 -> 0 .. 8
9 .. 15 -> 8
Although the DLC values 8 .. 15 in Classical CAN always result in a payload
length of 8 bytes these DLC values are transparently transmitted on the CAN
bus. As the struct can_frame only provides a 'len' element (formerly 'can_dlc')
which contains the plain payload length ( 0 .. 8 ) of the CAN frame, the raw
DLC is not visible to the application programmer, e.g. for testing use-cases.
To access the raw DLC values 9 .. 15 the len8_dlc element is introduced, which
is only valid when the payload length 'len' is 8 and the DLC is greater than 8.
The len8_dlc element is filled by the CAN interface driver and used for CAN
frame creation by the CAN driver when the CAN_CTRLMODE_CC_LEN8_DLC flag is
CC stands for Classic CAN? Is this the "official" name?
No. It is 'Classical CAN'. I'm not very happy with that naming as there
was already a 'CAN2.0B' specification to separate from the first version
which only had 11 Bit identifiers. This could be Ancient CAN now :-D
For example there was a press release to harmonize the CAN transceiver nameing
recently:
https://can-cia.org/news/press-releases/view/harmonized-transceiver-naming/2020/7/16/
Yes, there you can find:
"CAN high-speed transceivers might be used in Classical CAN, CAN FD, or
CAN XL networks"
Maybe we could update some comments and documentation for CAN2.0 ->
Classical CAN later.
supported by the driver and enabled via netlink configuration interface.
Signed-off-by: Oliver Hartkopp <socketcan@xxxxxxxxxxxx>
---
include/uapi/linux/can.h | 36 ++++++++++++++++++++------------
include/uapi/linux/can/netlink.h | 1 +
2 files changed, 24 insertions(+), 13 deletions(-)
diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h
index 6a6d2c7655ff..bcf28ae7f14c 100644
--- a/include/uapi/linux/can.h
+++ b/include/uapi/linux/can.h
@@ -82,34 +82,44 @@ typedef __u32 canid_t;
*/
typedef __u32 can_err_mask_t;
/* CAN payload length and DLC definitions according to ISO 11898-1 */
#define CAN_MAX_DLC 8
+#define CAN_MAX_RAW_DLC 15
#define CAN_MAX_DLEN 8
/* CAN FD payload length and DLC definitions according to ISO 11898-7 */
#define CANFD_MAX_DLC 15
#define CANFD_MAX_DLEN 64
/**
* struct can_frame - basic CAN frame structure
- * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
- * @can_dlc: frame payload length in byte (0 .. 8) aka data length code
- * N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
- * mapping of the 'data length code' to the real payload length
- * @__pad: padding
- * @__res0: reserved / padding
- * @__res1: reserved / padding
- * @data: CAN frame payload (up to 8 byte)
+ * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
+ * @len: CAN frame payload length in byte (0 .. 8)
+ * @can_dlc: deprecated name for CAN frame payload length in byte (0 .. 8)
+ * @__pad: padding
+ * @__res0: reserved / padding
+ * @len8_dlc: optional DLC value (9 .. 15) at 8 byte payload length
+ * len8_dlc contains values from 9 .. 15 when the payload length is
+ * 8 bytes but the DLC value (see ISO 11898-1) is greater then 8.
+ * CAN_CTRLMODE_CC_LEN8_DLC flag has to be enabled in CAN driver.
+ * @data: CAN frame payload (up to 8 byte)
*/
struct can_frame {
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
- __u8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
- __u8 __pad; /* padding */
- __u8 __res0; /* reserved / padding */
- __u8 __res1; /* reserved / padding */
- __u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
+ union {
+ /* CAN frame payload length in byte (0 .. CAN_MAX_DLEN)
+ * was previously named can_dlc so we need to carry that
+ * name for legacy support
+ */
+ __u8 len;
+ __u8 can_dlc; /* deprecated */
+ };
There was an old compiler version, which struggled with C99 initialized unions
within structs.....So this change would break existing source, but I think that
old compilers are long gone (for good).
Good to know. Do you know 'version numbers', so that we may place a
warning somewhere?
I still have a 2.6.28 system here (gcc 2.95) - but I would not know why
updating the can-utils there today. Maybe for the cansniffer ;-)
Btw. when it is only about the initialization of static struct
can_frame's, I can also check for these cases in can-utils.
Best,
Oliver