๐ Understanding non blocking mode in SocketCAN.
๐ก Newskategorie: Linux Tipps
๐ Quelle: reddit.com
Hi all,
I am currently working with the socketCAN implementation for my project.
The issue i am facing is that in the non blocking mode, while trying to receive the data using the read() file descriptor, I am not able to distinguish whether I have received data or not in my buffer.
It is continuously returning -1 irrespective of the data available or not, any help with the issue would be appreciated.
The code I am using to check is as follows:
include <stdio.h>
include <stdlib.h>
include <string.h>
include <unistd.h>
include <fcntl.h>
include <sys/socket.h>
include <linux/can.h>
include <linux/can/raw.h>
include <net/if.h>
include <sys/ioctl.h>
include <errno.h>
// Function to send a CAN frame
int send_can_frame(int sock, struct can_frame *frame) {
ssize_t nbytes;
nbytes = write(sock, frame, sizeof(struct can_frame));
if (nbytes != sizeof(struct can_frame)) {
perror("write");
return -1;
}
printf("Sent CAN frame: ID=%X, DLC=%d, Data=", frame->can_id, frame->can_dlc);
for (int i = 0; i < frame->can_dlc; ++i) {
printf("%02X ", frame->data[i]);
}
printf("\n");
return 0;
}
int main() {
int sock;
struct sockaddr_can addr;
struct ifreq ifr;
struct can_frame frame;
struct can_frame frame1;
// Create a CAN socket
sock = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (sock < 0) {
perror("socket");
return 1;
}
// Set the socket to non-blocking mode
int flags = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flags | O_NONBLOCK);
// Specify the CAN interface (change can1 to your interface name)
strcpy(ifr.ifr_name, "can0");
if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
perror("SIOCGIFINDEX");
close(sock);
return 1;
}
// Bind the socket to the CAN interface
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
close(sock);
return 1;
}
printf("Socket bound to CAN interface %s\n", ifr.ifr_name);
// Example: Prepare a CAN frame to send
frame.can_id = 0x123;
frame.can_dlc = 2;
frame.data[0] = 0xAB;
frame.data[1] = 0xCD;
while(1)
{
// Send the CAN frame
if (send_can_frame(sock, &frame) < 0) {
close(sock);
return 1;
}
ssize_t nbytes = read(sock, &frame1, sizeof(struct can_frame));
if (nbytes < 0) {
if (errno == EWOULDBLOCK || errno == EAGAIN) {
// No data available, continue loop or other actions
printf("1.No data available\n");
printf("\nCAN DLC: %d",frame1.can_dlc);
continue;
} else {
perror("read");
break;
}
} else if (nbytes > 0) {
printf("Received CAN frame: ID=%X, DLC=%d, Data=", frame.can_id, frame.can_dlc);
for (int i = 0; i < frame1.can_dlc; ++i) {
printf("%02X ", frame1.data[i]);
}
printf("\n");
}
close(sock);
return 0;
}
[link] [comments] ...