正常CAN发送标准帧速率在总线上能到8000帧左右/s,但是
两块幸狐板子对接一问一答,总线只有1300帧左右/s,单侧只有650左右
一块幸狐板子与另一个CAN设备通讯,总线2000帧/s,
我这边能查到的原因是接收中断大概每800us才响应一次,但不知道是什么导致的,该怎么修改
问到rockchip的工程师,写这个驱动的工程师说他们的板子测试没有问题,
希望能获取论坛各位大神的帮助
求助解决CAN 速率慢的问题
我的 测试过程是板子发送0x403,设备接收到0x403后立刻回复0x404,板子在接收到0x404后就立刻发送0x403,如此反复。
我设置的指令是
ifconfig can0 down
ip link set can0 type can bitrate 1000000 fd off
ip link set can0 txqueuelen 8000
ip link set can0 type can restart-ms 100
ifconfig can0 up
下面是我发送的代码,这里好像上层不了附件,图片也不知道如何发送
#include <stdio.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <linux/socket.h>
#include <linux/can.h>
#include <linux/can/error.h>
#include <linux/can/raw.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
// 全局变量,用于存储套接字文件描述符
int s;
// 打开 CAN 套接字的函数
int can_open(char* name) {
int ret;
struct sockaddr_can addr;
struct ifreq ifr;
// 创建一个套接字,用于 CAN 通信
s = socket(AF_CAN, SOCK_RAW, CAN_RAW);
if (s < 0) {
perror("socket PF_CAN failed");
return 1; // 如果创建失败,返回错误
}
// 设置 CAN 接口名称
strcpy(ifr.ifr_name, name);
// 获取接口索引
ret = ioctl(s, SIOCGIFINDEX, &ifr);
if (ret < 0) {
perror("ioctl failed");
s = -1;
return 1; // 如果获取失败,返回错误
}
// 配置套接字地址结构
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
// 将套接字绑定到 CAN 接口
ret = bind(s, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0) {
perror("bind failed");
s = -1;
return 1; // 如果绑定失败,返回错误
}
return 0; // 成功返回 0
}
// 写入 CAN 帧的函数
int can_write(struct can_frame frame) {
if (s < 0) return -1; // 检查套接字是否有效
// 写入 CAN 帧到套接字
return write(s, &frame, sizeof(frame));
}
// 读取 CAN 帧的函数
int can_read(struct can_frame *frame) {
if (s < 0) return -1; // 检查套接字是否有效
// 从套接字读取 CAN 帧
return read(s, frame, sizeof(struct can_frame));
}
// 关闭 CAN 套接字的函数
int can_close() {
if (s > 0)
close(s); // 关闭套接字
}
int main(int argc, char *argv[]) {
printf("This is CAN interface \n");
// 打开名为 'can0' 的 CAN 接口
can_open("can0");
struct can_frame frame;
struct can_frame recv_frame;
// 设置要发送的 CAN 帧
frame.can_dlc = 8; // 数据长度
frame.can_id = 0x403; // CAN ID
frame.data[0] = 0xff; // 数据
frame.data[1] = 0xff; // 数据
// 循环发送和接收 CAN 帧
for (int i = 0; i < 100000; i++) {
can_write(frame); // 发送帧
can_read(&recv_frame); // 接收帧
if (recv_frame.can_id != 0x404) {
printf("not 404 \n"); // 如果接收到的 ID 不是 0x404,打印信息并退出循环
break;
}
}
// 关闭套接字
can_close();
return 0; // 程序结束
}
下面是接收代码
#include <stdio.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <linux/socket.h>
#include <linux/can.h>
#include <linux/can/error.h>
#include <linux/can/raw.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
// 全局变量,用于存储套接字文件描述符
int s;
// 打开 CAN 套接字的函数
int can_open(char* name) {
int ret;
struct sockaddr_can addr;
struct ifreq ifr;
// 创建一个套接字,用于 CAN 通信
s = socket(AF_CAN, SOCK_RAW, CAN_RAW);
if (s < 0) {
perror("socket PF_CAN failed");
return 1; // 如果创建失败,返回错误
}
// 设置 CAN 接口名称
strcpy(ifr.ifr_name, name);
// 获取接口索引
ret = ioctl(s, SIOCGIFINDEX, &ifr);
if (ret < 0) {
perror("ioctl failed");
s = -1;
return 1; // 如果获取失败,返回错误
}
// 配置套接字地址结构
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
// 将套接字绑定到 CAN 接口
ret = bind(s, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0) {
perror("bind failed");
s = -1;
return 1; // 如果绑定失败,返回错误
}
return 0; // 成功返回 0
}
// 写入 CAN 帧的函数
int can_write(struct can_frame frame) {
if (s < 0) return -1; // 检查套接字是否有效
// 写入 CAN 帧到套接字
return write(s, &frame, sizeof(frame));
}
// 读取 CAN 帧的函数
int can_read(struct can_frame *frame) {
if (s < 0) return -1; // 检查套接字是否有效
// 从套接字读取 CAN 帧
return read(s, frame, sizeof(struct can_frame));
}
// 关闭 CAN 套接字的函数
int can_close() {
if (s > 0)
close(s); // 关闭套接字
}
int main(int argc, char *argv[]) {
printf("This is CAN interface \n");
// 打开名为 'can0' 的 CAN 接口
can_open("can0");
struct can_frame frame;
struct can_frame recv_frame;
// 等待接收数据
for(;;)
{
can_read(&recv_frame);
recv_frame.can_id = 0x404;
can_write(recv_frame);
}
// 关闭套接字
can_close();
return 0; // 程序结束
}
希望有人能看下并解决下这个问题
我设置的指令是
ifconfig can0 down
ip link set can0 type can bitrate 1000000 fd off
ip link set can0 txqueuelen 8000
ip link set can0 type can restart-ms 100
ifconfig can0 up
下面是我发送的代码,这里好像上层不了附件,图片也不知道如何发送

#include <stdio.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <linux/socket.h>
#include <linux/can.h>
#include <linux/can/error.h>
#include <linux/can/raw.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
// 全局变量,用于存储套接字文件描述符
int s;
// 打开 CAN 套接字的函数
int can_open(char* name) {
int ret;
struct sockaddr_can addr;
struct ifreq ifr;
// 创建一个套接字,用于 CAN 通信
s = socket(AF_CAN, SOCK_RAW, CAN_RAW);
if (s < 0) {
perror("socket PF_CAN failed");
return 1; // 如果创建失败,返回错误
}
// 设置 CAN 接口名称
strcpy(ifr.ifr_name, name);
// 获取接口索引
ret = ioctl(s, SIOCGIFINDEX, &ifr);
if (ret < 0) {
perror("ioctl failed");
s = -1;
return 1; // 如果获取失败,返回错误
}
// 配置套接字地址结构
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
// 将套接字绑定到 CAN 接口
ret = bind(s, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0) {
perror("bind failed");
s = -1;
return 1; // 如果绑定失败,返回错误
}
return 0; // 成功返回 0
}
// 写入 CAN 帧的函数
int can_write(struct can_frame frame) {
if (s < 0) return -1; // 检查套接字是否有效
// 写入 CAN 帧到套接字
return write(s, &frame, sizeof(frame));
}
// 读取 CAN 帧的函数
int can_read(struct can_frame *frame) {
if (s < 0) return -1; // 检查套接字是否有效
// 从套接字读取 CAN 帧
return read(s, frame, sizeof(struct can_frame));
}
// 关闭 CAN 套接字的函数
int can_close() {
if (s > 0)
close(s); // 关闭套接字
}
int main(int argc, char *argv[]) {
printf("This is CAN interface \n");
// 打开名为 'can0' 的 CAN 接口
can_open("can0");
struct can_frame frame;
struct can_frame recv_frame;
// 设置要发送的 CAN 帧
frame.can_dlc = 8; // 数据长度
frame.can_id = 0x403; // CAN ID
frame.data[0] = 0xff; // 数据
frame.data[1] = 0xff; // 数据
// 循环发送和接收 CAN 帧
for (int i = 0; i < 100000; i++) {
can_write(frame); // 发送帧
can_read(&recv_frame); // 接收帧
if (recv_frame.can_id != 0x404) {
printf("not 404 \n"); // 如果接收到的 ID 不是 0x404,打印信息并退出循环
break;
}
}
// 关闭套接字
can_close();
return 0; // 程序结束
}
下面是接收代码
#include <stdio.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <linux/socket.h>
#include <linux/can.h>
#include <linux/can/error.h>
#include <linux/can/raw.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
// 全局变量,用于存储套接字文件描述符
int s;
// 打开 CAN 套接字的函数
int can_open(char* name) {
int ret;
struct sockaddr_can addr;
struct ifreq ifr;
// 创建一个套接字,用于 CAN 通信
s = socket(AF_CAN, SOCK_RAW, CAN_RAW);
if (s < 0) {
perror("socket PF_CAN failed");
return 1; // 如果创建失败,返回错误
}
// 设置 CAN 接口名称
strcpy(ifr.ifr_name, name);
// 获取接口索引
ret = ioctl(s, SIOCGIFINDEX, &ifr);
if (ret < 0) {
perror("ioctl failed");
s = -1;
return 1; // 如果获取失败,返回错误
}
// 配置套接字地址结构
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
// 将套接字绑定到 CAN 接口
ret = bind(s, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0) {
perror("bind failed");
s = -1;
return 1; // 如果绑定失败,返回错误
}
return 0; // 成功返回 0
}
// 写入 CAN 帧的函数
int can_write(struct can_frame frame) {
if (s < 0) return -1; // 检查套接字是否有效
// 写入 CAN 帧到套接字
return write(s, &frame, sizeof(frame));
}
// 读取 CAN 帧的函数
int can_read(struct can_frame *frame) {
if (s < 0) return -1; // 检查套接字是否有效
// 从套接字读取 CAN 帧
return read(s, frame, sizeof(struct can_frame));
}
// 关闭 CAN 套接字的函数
int can_close() {
if (s > 0)
close(s); // 关闭套接字
}
int main(int argc, char *argv[]) {
printf("This is CAN interface \n");
// 打开名为 'can0' 的 CAN 接口
can_open("can0");
struct can_frame frame;
struct can_frame recv_frame;
// 等待接收数据
for(;;)
{
can_read(&recv_frame);
recv_frame.can_id = 0x404;
can_write(recv_frame);
}
// 关闭套接字
can_close();
return 0; // 程序结束
}
希望有人能看下并解决下这个问题