I am using a C++ library with the following code:
#include <linux/can.h>
#include <linux/can/raw.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cstring>
#include <net/if.h>
#include <sys/ioctl.h>
#include <vector>
#include <iostream>
#include <stdexcept>
#include <cstdio>
class Can {
private:
int socket_fd;
struct sockaddr_can addr;
struct ifreq ifr;
public:
Can() {
system("modprobe can");
system("modprobe can-dev");
system("modprobe can-raw");
system("modprobe slcan");
system("sudo slcand -o -c -s8 /dev/ttyACM1 can0"); //have to install slcand
//-s8 is the speed of the CAN bus 1Mbit/s
system("sudo ip link set can0 up"); //turnign
// Creation of the socket CAN
if ((socket_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
throw std::runtime_error("Failed to create socket");
}
// Bind the socket to one of the interfaces (vcan0 or canx x=0,1):
struct ifreq ifr;
struct sockaddr_can addr;
const char *ifname = "can0";
// Configuration du socket
strcpy(ifr.ifr_name, ifname);
ioctl(socket_fd, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
throw std::runtime_error("Failed to bind socket");
}
}
~Can() {
close(socket_fd);
}
void sendCanMessage(int can_id, const std::vector<uint8_t>& data) {
struct can_frame frame;
frame.can_id = can_id;
frame.can_dlc = data.size();
std::memcpy(frame.data, data.data(), data.size());
if (write(socket_fd, &frame, sizeof(frame)) != sizeof(frame)) {
throw std::runtime_error("Failed to send CAN message");
}
}
void receiveCanMessage() {
struct can_frame frame;
int nbytes = read(socket_fd, &frame, sizeof(struct can_frame));
if (nbytes < 0) {
throw std::runtime_error("CAN read error");
} else if (nbytes == sizeof(struct can_frame)) {
std::cout << "Received CAN message with ID: 0x" << std::hex << frame.can_id << std::dec << " Data: ";
for (int i = 0; i < frame.can_dlc; i++) {
std::cout << std::hex << static_cast<int>(frame.data[i]) << " ";
}
std::cout << std::endl;
} else {
throw std::runtime_error("Incomplete CAN frame received");
}
}
};
int main() {
try {
Can canInterface;
std::vector<uint8_t> data(8, 0x0F);
canInterface.sendCanMessage(0x123, data);
std::cout << "En attente de la réception d'un message CAN..." << std::endl;
canInterface.receiveCanMessage();
} catch (const std::exception& e) {
std::cerr << "Une erreur est survenue : " << e.what() << std::endl;
return 1;
}
return 0;
}
My main goal is to send a CAN message from my PC which is on Linux to a CAN bus trough a CANable module. When I run the code, I get the following error:
write: Input/output error
It seems that there is a problem with the method "write". The module CANable works properly, it can send and receive CAN msg (I test it with the linux Terminal).
I am completely new to the protocol CAN. Thanks to all of those who reply in advance.