From b8edf5babcd7140551b87ac1f0d4a91b2aa0c009 Mon Sep 17 00:00:00 2001 From: Michael Jossen Date: Wed, 30 Oct 2024 22:40:57 +0100 Subject: [PATCH 1/2] [linux] Replace deprecated can_dlc with len --- src/modm/platform/can/socketcan/socketcan.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/modm/platform/can/socketcan/socketcan.cpp b/src/modm/platform/can/socketcan/socketcan.cpp index 68976d5d69..9008684089 100644 --- a/src/modm/platform/can/socketcan/socketcan.cpp +++ b/src/modm/platform/can/socketcan/socketcan.cpp @@ -3,6 +3,7 @@ * Copyright (c) 2017, Fabian Greif * Copyright (c) 2017, Niklas Hauser * Copyright (c) 2023, Christopher Durand + * Copyright (c) 2024, Michael Jossen * * This file is part of the modm project. * @@ -125,10 +126,10 @@ modm::platform::SocketCan::getMessage(can::Message& message) if (nbytes > 0) { message.identifier = frame.can_id; - message.setDataLengthCode(frame.can_dlc); + message.setLength(frame.len); message.setExtended(frame.can_id & CAN_EFF_FLAG); message.setRemoteTransmitRequest(frame.can_id & CAN_RTR_FLAG); - for (uint8_t ii = 0; ii < frame.can_dlc; ++ii) { + for (uint8_t ii = 0; ii < frame.len; ++ii) { message.data[ii] = frame.data[ii]; } return true; @@ -149,7 +150,7 @@ modm::platform::SocketCan::sendMessage(const can::Message& message) frame.can_id |= CAN_RTR_FLAG; } - frame.can_dlc = message.getLength(); + frame.len = message.getLength(); for (uint8_t ii = 0; ii < message.getLength(); ++ii) { frame.data[ii] = message.data[ii]; From a90537ca6f3239c1fee6435b0990aace069c56af Mon Sep 17 00:00:00 2001 From: Michael Jossen Date: Wed, 30 Oct 2024 22:42:35 +0100 Subject: [PATCH 2/2] [linux] Enable FDCAN in socketcan --- src/modm/platform/can/socketcan/socketcan.cpp | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/modm/platform/can/socketcan/socketcan.cpp b/src/modm/platform/can/socketcan/socketcan.cpp index 9008684089..7ddc56aa77 100644 --- a/src/modm/platform/can/socketcan/socketcan.cpp +++ b/src/modm/platform/can/socketcan/socketcan.cpp @@ -48,6 +48,16 @@ modm::platform::SocketCan::open(std::string deviceName) return false; } + /* Enable FDCAN support */ + int recv_can_fd = 1; + if (setsockopt(skt, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &recv_can_fd, sizeof(recv_can_fd)) < 0) + { + MODM_LOG_ERROR << MODM_FILE_INFO; + MODM_LOG_ERROR << "Failed to enable FDCAN support: " << strerror(errno) << modm::endl; + close(); + return false; + } + /* Locate the interface you wish to use */ struct ifreq ifr{}; if (deviceName.empty() || deviceName.size() > IFNAMSIZ - 1) { @@ -104,8 +114,8 @@ modm::platform::SocketCan::getBusState() bool modm::platform::SocketCan::isMessageAvailable() { - struct can_frame frame; - int nbytes = recv(skt, &frame, sizeof(struct can_frame), MSG_DONTWAIT | MSG_PEEK); + struct canfd_frame frame; + int nbytes = recv(skt, &frame, sizeof(struct canfd_frame), MSG_DONTWAIT | MSG_PEEK); // recv returns 'Resource temporary not available' which is wired but ignored here. /* if (nbytes < 0) @@ -120,11 +130,17 @@ modm::platform::SocketCan::isMessageAvailable() bool modm::platform::SocketCan::getMessage(can::Message& message) { - struct can_frame frame; - int nbytes = recv(skt, &frame, sizeof(struct can_frame), MSG_DONTWAIT); + struct canfd_frame frame; + int nbytes = recv(skt, &frame, sizeof(frame), MSG_DONTWAIT); if (nbytes > 0) { + if (frame.len > modm::can::Message::capacity) + { + MODM_LOG_ERROR << MODM_FILE_INFO; + MODM_LOG_ERROR << "Received can frame too big for configured buffer." << modm::endl; + return false; + } message.identifier = frame.can_id; message.setLength(frame.len); message.setExtended(frame.can_id & CAN_EFF_FLAG); @@ -140,8 +156,9 @@ modm::platform::SocketCan::getMessage(can::Message& message) bool modm::platform::SocketCan::sendMessage(const can::Message& message) { - struct can_frame frame; + struct canfd_frame frame; + frame.flags = 0; frame.can_id = message.identifier; if (message.isExtended()) { frame.can_id |= CAN_EFF_FLAG; @@ -156,7 +173,11 @@ modm::platform::SocketCan::sendMessage(const can::Message& message) frame.data[ii] = message.data[ii]; } - int bytes_sent = write( skt, &frame, sizeof(frame) ); + // Send can_frame when length < 8, since other applications may not accept + // canfd_frame. Both structs intentionally share the same layout + // for this purpose + int size = message.getLength() > 8 ? sizeof(canfd_frame) : sizeof(can_frame); + int bytes_sent = write(skt, &frame, size); return (bytes_sent > 0); }