I have a Raspberry Pi that interface a CAN Bus though SPI. I've installed canutils
and if I do a cansend the message is received by the controller and applied, but if I do it through code it doesn't. It must be something that I'm doing wrong in building the frame, so if somebody can help me to point out my error I'll appreciate it.
This is the cansend message that I send.
cansend can0 01f801f2#1212121223232323
This is my code to send the same message. The code runs in a pthread.
void *CANUpdate(void *userParam)
{
struct sockaddr_can addr;
struct ifreq ifr;
const char *ifname = "can0";
int can_s;
if ((can_s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
{
LogEntry(LOG_ERR, "Error while opening socket\n");
return 0;
}
strcpy(ifr.ifr_name, ifname);
ioctl(can_s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(can_s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
LogEntry(LOG_ERR, "Error in CAN socket bind\n");
return 0;
}
while (!stopServer)
{
if (can_s)
{
struct can_frame frame;
frame.can_id = 0x01f801f2;
frame.can_dlc = 8;
frame.data[0] = 0x12;
frame.data[1] = 0x12;
frame.data[2] = 0x12;
frame.data[3] = 0x12;
frame.data[4] = 0x34;
frame.data[5] = 0x34;
frame.data[6] = 0x34;
frame.data[7] = 0x34;
int res = write(can_s, &frame, sizeof(struct can_frame));
}
msleep(800);
}
}
There was basically 2 problems with the code. 1. I should have used the canfd_frame struct, and I should've 0'ed the values. Here is the code that worked at the end
void *CANUpdate(void *userParam)
{
struct sockaddr_can addr;
struct ifreq ifr;
const char *ifname = "can0";
int can_s;
if ((can_s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
{
LogEntry(LOG_ERR, "Error while opening socket\n");
return 0;
}
strcpy(ifr.ifr_name, ifname);
ioctl(can_s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
setsockopt(can_s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
if (bind(can_s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
LogEntry(LOG_ERR, "Error in CAN socket bind\n");
return 0;
}
while (!stopServer)
{
if (can_s)
{
struct canfd_frame frame;
memset(&frame, 0, sizeof(frame)); /* init CAN FD frame, e.g. LEN = 0 */
frame.can_id = 0x01f801f2;
frame.len = 8;
if (!(frame.can_id & CAN_ERR_FLAG)) /* 8 digits but no errorframe? */
frame.can_id |= CAN_EFF_FLAG; /* then it is an extended frame */
frame.data[0] = 0x12;
frame.data[1] = 0x12;
frame.data[2] = 0x12;
frame.data[3] = 0x12;
frame.data[4] = 0x34;
frame.data[5] = 0x34;
frame.data[6] = 0x34;
frame.data[7] = 0x34;
if(write(can_s, &frame, sizeof(struct can_frame)) != sizeof(struct can_frame);
LogEntry(LOG_ERR, "Unable to write CAN message\n");
}
msleep(800);
}
}