SocketCAN Programming Practice
API
SocketCAN official API: https://docs.kernel.org/networking/can.html
Examples
kcanfdtest
KH-UCANFD_Linux_SDK contains test code such as kcanfd_test.c, cantx_1KHz.c, etc. Following is part of code in kcanfd_test.c, used for creating socket, sending, and receiving:
For detailed code content, you can download to view: https://gitee.com/ChengDu-KunHong/KH-UCANFD_Linux_SDK/releases/download/latest/KH-UCANFD_Linux_SDK.zip
Creating Socket
if ((sockfd = socket(family, type, proto)) < 0) // Create CAN raw socket
{
perror("socket");
return 1;
}if (echo_gen) // Enable echo mode { if (setsockopt(sockfd, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &enable_socket_option, sizeof(enable_socket_option)) == -1) { perror("setsockopt CAN_RAW_RECV_OWN_MSGS"); return 1; } }
if (is_can_fd) // Enable CAN FD frames { if (setsockopt(sockfd, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &enable_socket_option, sizeof(enable_socket_option)) == -1) { perror("setsockopt CAN_RAW_FD_FRAMES"); return 1; } }
#### Sending Frames
```c
static int send_frame(struct canfd_frame *frame)
{
ssize_t ret, len;
if (is_can_fd)
len = sizeof(struct canfd_frame);
else
len = sizeof(struct can_frame);
if (bit_rate_switch)
frame->flags |= CANFD_BRS;
while ((ret = send(sockfd, frame, len, 0)) != len)
{
if (ret >= 0)
{
fprintf(stderr, "send returned %zd", ret);
return -1;
}
if (errno != ENOBUFS)
{
perror("send failed");
return -1;
}
if (verbose)
{
printf("n");
fflush(stdout);
}
}
return 0;
}Receiving Frames
static int recv_frame(struct canfd_frame *frame, int *flags)
{
struct iovec iov = {
.iov_base = frame,
.iov_len = is_can_fd ? sizeof(struct canfd_frame) : sizeof(struct can_frame),
};
struct msghdr msg = {
.msg_iov = &iov,
.msg_iovlen = 1,
};
ssize_t ret;
ret = recvmsg(sockfd, &msg, 0);
if (ret < 0)
{
perror("recvmsg() failed");
return -1;
}
if ((size_t)ret != iov.iov_len)
{
fprintf(stderr, "recvmsg() returned %zd", ret);
return -1;
}
if (flags)
*flags = msg.msg_flags;
return 0;
}can-utils
can-utils is implemented based on SocketCAN. All tools provided in the project are good reference examples.
can-utils open source project: https://gitee.com/ChengDu-KunHong/can-utils
openarm_can
openarm_can is part of the OpenArm project, which is a library for CAN communication, providing applications and test code specifically for motors, which can serve as reference.
openarmcan open source project: https://gitee.com/ChengDu-KunHong/openarmcan