【c++基础】测试SocketCAN的收发功能
前言
CAN收发的过程
基本编程模板的流程为:
(1)创建套接字socket
(2)指定can设备号
(3)绑定bind
(4)如果是发送,就禁用过滤;如果是接受就设置过滤条件
(5)对套接字的fd进行read,write操作实现收发功能;
code

/* * cantest.c * * Created on: 2017-5-16 * Author: simon */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <net/if.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <linux/can.h> #include <linux/can/raw.h> int main(int argc, char *argv[]) { int s, nbytes; char *array[2] = {"-r", "-s"}; struct sockaddr_can addr; struct ifreq ifr; struct can_frame frame; struct can_filter rfilter[1]; /* handle (optional) flags first */ if(argc != 3) { fprintf(stderr, "Usage: %s <-r> <can interface name> for receiving\nor <-s> <can interface name> for sending\n", argv[0]); exit(1); } /* create socket */ if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { perror("Create socket failed"); exit(-1); } /* set up can interface */ strcpy(ifr.ifr_name, argv[2]); printf("can port is %s\n",ifr.ifr_name); /* assign can device */ ioctl(s, SIOCGIFINDEX, &ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; /* bind can device */ if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("Bind can device failed\n"); close(s); exit(-2); } /* configure receiving */ if(!strcmp(argv[1],array[0])) { /* set filter for only receiving packet with can id 0x1F */ rfilter[0].can_id = 0x1F; rfilter[0].can_mask = CAN_SFF_MASK; if(setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)) < 0) { perror("set receiving filter error\n"); close(s); exit(-3); } /* keep reading */ while(1){ nbytes = read(s, &frame, sizeof(frame)); if(nbytes > 0) { printf("%s ID=%#x data length=%d\n", ifr.ifr_name, frame.can_id, frame.can_dlc); for (int i=0; i < frame.can_dlc; i++) printf("%#x ", frame.data[i]); printf("\n"); } } } /* configure sending */ else if(!strcmp(argv[1],array[1])) { /* configure can_id and can data length */ frame.can_id = 0x1F; frame.can_dlc = 8; printf("%s ID=%#x data length=%d\n", ifr.ifr_name, frame.can_id, frame.can_dlc); /* prepare data for sending: 0x11,0x22...0x88 */ for (int i=0; i<8; i++) { frame.data[i] = ((i+1)<<4) | (i+1); printf("%#x ", frame.data[i]); } printf("Sent out\n"); /* Sending data */ if(write(s, &frame, sizeof(frame)) < 0) { perror("Send failed"); close(s); exit(-4); } } /* wrong parameter input situation */ else { printf("wrong parameter input\n"); } close(s); return 0; }
CMakeLists.txt

cmake_minimum_required(VERSION 3.3) project(cantest LANGUAGES C) set(CMAKE_BUILD_TYPE Release) set(INCLUDE_DIRS include) include_directories (${INCLUDE_DIRS}) set(LIBS_DIRS) link_directories(${LIBS_DIRS}) set(LIBS) link_libraries(${LIBS}) aux_source_directory(src SRC_DIRS) add_executable(${PROJECT_NAME} ${SRC_DIRS}) target_link_libraries(${PROJECT_NAME} ${LIBS}) install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_SOURCE_DIR}/cmake/make_uninstall.cmake")
run
~/workspace/cantest/build$ ./cantest -s vcan0 can port is vcan0 vcan0 ID=0x1f data length=8 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 Sent out
但是运行-r的时候,一直没有反应。。。。
~/workspace/cantest/build$ ./cantest -r vcan0
can port is vcan0
但是,如果同时运行-s,则-r可以接收到信息。不知道是什么原因。。。。
~/workspace/cantest/build$ ./cantest -r vcan0 can port is vcan0 nbytes: 16 vcan0 ID=0x1f data length=8 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 nbytes: 16 vcan0 ID=0x1f data length=8 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88
应该是接收程序被阻塞,等待接收数据,接收到数据之后等待下一次的数据。。。但是为什么ioctl和bind前后的debug信息不能显示呢??难道是多线程之类的。。。。
update 20220718
基于TX2板子,使用CAN分析仪和调试工具测试CAN通信;
1)运行测试程序,-s可以正常发送数据,不论can0和can1;
2)同时运行-r和-s,可以正常发送和接收,但是CAN调试工具只有接收的TX2发送的数据;
3)通过CAN调试工具发送数据,-r不能接收到;
4)can0端口-s可以发送数据,但是CAN调试工具没有看到接收数据,同时-r can0也没有接收到数据,可能can0端口硬件有问题;
5)TX2端运行candump can1,然后CAN调试工具发送报文,TX2端可以接收到数据,但是can0端口没有接收到数据;
总结,can1可以在TX2和CAN调试工具之间使用cansend、candump收发,且重启也没有影响;而can0没有反应;
can1使用cantest程序可以完成收发,同时CAN调试工具也可以接收,但是调试工具发送数据,程序不能接收到数据;
而can0使用程序只能发送,程序和调试工具都不能接收,且调试工具发送数据,程序也不能接收;
奇怪的是,最开始的时候使用cansend和candump却没有反应。。。。
问题
参考
1. SocketCAN_test_receive_send;
完
心正意诚,做自己该做的事情,做自己喜欢做的事情,安静做一枚有思想的技术媛。
版权声明,转载请注明出处:https://www.cnblogs.com/happyamyhope/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2019-06-19 【leetcode_easy】589. N-ary Tree Preorder Traversal
2018-06-19 Segmentation fault (core dumped)
2018-06-19 suggest parentheses around comparison in operand of &|