Skip to content

Commit a90537c

Browse files
committed
[linux] Enable FDCAN in socketcan
1 parent b8edf5b commit a90537c

File tree

1 file changed

+27
-6
lines changed

1 file changed

+27
-6
lines changed

src/modm/platform/can/socketcan/socketcan.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ modm::platform::SocketCan::open(std::string deviceName)
4848
return false;
4949
}
5050

51+
/* Enable FDCAN support */
52+
int recv_can_fd = 1;
53+
if (setsockopt(skt, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &recv_can_fd, sizeof(recv_can_fd)) < 0)
54+
{
55+
MODM_LOG_ERROR << MODM_FILE_INFO;
56+
MODM_LOG_ERROR << "Failed to enable FDCAN support: " << strerror(errno) << modm::endl;
57+
close();
58+
return false;
59+
}
60+
5161
/* Locate the interface you wish to use */
5262
struct ifreq ifr{};
5363
if (deviceName.empty() || deviceName.size() > IFNAMSIZ - 1) {
@@ -104,8 +114,8 @@ modm::platform::SocketCan::getBusState()
104114
bool
105115
modm::platform::SocketCan::isMessageAvailable()
106116
{
107-
struct can_frame frame;
108-
int nbytes = recv(skt, &frame, sizeof(struct can_frame), MSG_DONTWAIT | MSG_PEEK);
117+
struct canfd_frame frame;
118+
int nbytes = recv(skt, &frame, sizeof(struct canfd_frame), MSG_DONTWAIT | MSG_PEEK);
109119

110120
// recv returns 'Resource temporary not available' which is wired but ignored here.
111121
/* if (nbytes < 0)
@@ -120,11 +130,17 @@ modm::platform::SocketCan::isMessageAvailable()
120130
bool
121131
modm::platform::SocketCan::getMessage(can::Message& message)
122132
{
123-
struct can_frame frame;
124-
int nbytes = recv(skt, &frame, sizeof(struct can_frame), MSG_DONTWAIT);
133+
struct canfd_frame frame;
134+
int nbytes = recv(skt, &frame, sizeof(frame), MSG_DONTWAIT);
125135

126136
if (nbytes > 0)
127137
{
138+
if (frame.len > modm::can::Message::capacity)
139+
{
140+
MODM_LOG_ERROR << MODM_FILE_INFO;
141+
MODM_LOG_ERROR << "Received can frame too big for configured buffer." << modm::endl;
142+
return false;
143+
}
128144
message.identifier = frame.can_id;
129145
message.setLength(frame.len);
130146
message.setExtended(frame.can_id & CAN_EFF_FLAG);
@@ -140,8 +156,9 @@ modm::platform::SocketCan::getMessage(can::Message& message)
140156
bool
141157
modm::platform::SocketCan::sendMessage(const can::Message& message)
142158
{
143-
struct can_frame frame;
159+
struct canfd_frame frame;
144160

161+
frame.flags = 0;
145162
frame.can_id = message.identifier;
146163
if (message.isExtended()) {
147164
frame.can_id |= CAN_EFF_FLAG;
@@ -156,7 +173,11 @@ modm::platform::SocketCan::sendMessage(const can::Message& message)
156173
frame.data[ii] = message.data[ii];
157174
}
158175

159-
int bytes_sent = write( skt, &frame, sizeof(frame) );
176+
// Send can_frame when length < 8, since other applications may not accept
177+
// canfd_frame. Both structs intentionally share the same layout
178+
// for this purpose
179+
int size = message.getLength() > 8 ? sizeof(canfd_frame) : sizeof(can_frame);
180+
int bytes_sent = write(skt, &frame, size);
160181

161182
return (bytes_sent > 0);
162183
}

0 commit comments

Comments
 (0)