最近写了个自认为不错的基于linux socket can程序,主要功能:
- 程序具备全部CAN功能,包括CAN标准帧/扩展帧接收与发送、CAN总线错误判断、环回等功能
- 适用基于LINUX SOCKET机制实现的CAN接口,可用于嵌入式LINUX的CAN测试
- 程序采用标准LINUX命令行参数选项形式,接受用户参数
现把源码进行分享
功能介绍SOCKET CAN工具程序 – Ver1.0 Build Nov 20 2015, COPYRIGHT (C) 2015 reille @
http://velep.com/介绍:
本SOCKET CAN程序具备全部CAN功能,包括CAN标准帧/扩展帧接收与发送、CAN总线错误判断、环回等功能
适用基于LINUX SOCKET机制实现的CAN接口,可用于嵌入式LINUX中的CAN测试程序
程序采用标准LINUX命令行参数选项形式,接受用户参数用法: ./cantool [选项]…选项:
-p, –port=CAN接口号 指定CAN接口号,从1开始, 默认为 1(即CAN1接口)
-b, –baud=波特率 指定CAN通讯波特率,单位Kbps,默认为 250 Kbps
可用波特率:5,10,20,40,50,80,100,125,200,250,400,500,666,800,1000-i, –frame-id=帧ID 指定CAN发送帧ID(Hex格式), 默认为1801F456
-d, –data=数据 指定CAN发送帧数据, 默认为:00 01 FF FF FF FF FF FF,字节数据间以空格隔开
-f, –freq=间隔 指定CAN帧发送间隔,单位ms, 默认为250ms, 最小值为1ms
-t, –times=次数 指定CAN帧发送次数, 默认为0次
-s, 指定CAN发送帧为标准帧, 默认为发送扩展帧
-I, 帧ID每发送一帧递增, 默认不递增
-g, 发送数据每发送一帧递增, 默认不递增
-l, 发送数据时本地环回, 默认不环回–help 显示此帮助信息并退出注意,以下CAN帧ID作为系统使用:
0x00000001 – TX timeout (by netdevice driver)
0x00000002 – lost arbitration / data[0]
0x00000004 – controller problems / data[1]
0x00000008 – protocol violations / data[2..3]
0x00000010 – transceiver status / data[4]
0x00000020 – received no ACK on transmission
0x00000040 – bus off
0x00000080 – bus error (may flood!)
0x00000100 – controller restarted使用 Ctrl^C 组合键结束程序运行
部分源码[cpp] view plain copy- int main(int argc, char **argv)
- {
- S_CanFrame sendframe, recvframe;
- byte *psendframe = (byte *)&sendframe;
- byte *precvframe = (byte *)&recvframe;
- u_canframe_data_t *psend_data = (u_canframe_data_t *)sendframe.data;
- const int can_frame_len = sizeof(S_CanFrame);
-
- pid_t pid = -1;
- int status;
-
- int ret = 0;
- char buf[128] = {0};
- bool carry_bit = false;
-
- int segment_id;
-
-
- if (parse_options(argc, argv))
- {
- usage(); return 0;
- }
-
- if (!find_can(port))
- {
- sprintf(buf, "
错误:CAN%d设备不存在
", port + 1);
- panic(buf);
- return -1;
- }
-
- close_can(port);
- set_bitrate(port, bitrate);
- open_can(port, bitrate);
-
- send_socket_fd = socket_connect(port);
- recv_socket_fd = socket_connect(port);
-
- if (send_socket_fd < 0 || send_socket_fd < 0)
- {
- disconnect(&send_socket_fd);
- disconnect(&recv_socket_fd);
- panic("
打开socket can错误
");
- return -1;
- }
- set_can_filter();
- set_can_loopback(send_socket_fd, lp);
-
- printf_head();
-
- memset(&sendframe, 0x00, sizeof(sendframe));
- memset(&recvframe, 0x00, sizeof(recvframe));
-
- if (extended_frame)
- {
- sendframe.can_id = (send_frame_id & CAN_EFF_MASK) | CAN_EFF_FLAG;
- }
- else
- {
- sendframe.can_id = (send_frame_id & CAN_SFF_MASK);
- }
- sendframe.can_dlc = dlc;
- memcpy(sendframe.data, send_frame_data, dlc);
-
-
- segment_id = shmget(IPC_PRIVATE, sizeof(int), S_IRUSR | S_IWUSR);
- pframeno = (int *)shmat(segment_id, NULL, 0);
- if (pframeno == NULL)
- {
- panic("
创建共享内存失败
");
- return -1;
- }
- *pframeno = 1;
-
- run = true;
-
- pid = fork();
- if(pid == -1)
- {
- panic("
创建进程失败
");
- return -1;
- }
- else if(pid == 0)
- {
- while (run && (send_frame_times > 0))
- {
- ret = send_frame(send_socket_fd, (char *)&sendframe, sizeof(sendframe));
- printf_frame(sendframe.can_id & CAN_EFF_MASK, sendframe.data, sendframe.can_dlc,
- ((sendframe.can_id & CAN_EFF_FLAG) ? true : false),
- ret > 0 ? true : false,
- true);
- delay_ms(send_frame_freq_ms);
-
- if (send_frame_id_inc_en)
- {
- sendframe.can_id++;
- if (extended_frame)
- {
- sendframe.can_id = (sendframe.can_id & CAN_EFF_MASK) | CAN_EFF_FLAG;
- }
- else
- {
- sendframe.can_id = (sendframe.can_id & CAN_SFF_MASK);
- }
- }
-
- if (send_frame_data_inc_en && dlc > 0)
- {
- if (dlc > 4 && psend_data->s.dl == ((__u32)0xFFFFFFFF))
- {
- carry_bit = true;
- }
- psend_data->s.dl++;
-
- if (dlc <= 4)
- {
- if (psend_data->s.dl >= (1 << (dlc * 8)))
- {
- psend_data->s.dl = 0;
- }
- }
- else if (dlc <= 8)
- {
- if (carry_bit)
- {
- psend_data->s.dh++;
- if (psend_data->s.dh >= (1 << ((dlc - 4) * 8)))
- {
- psend_data->s.dh = 0;
- }
-
- carry_bit = false;
- }
- }
- }
-
- send_frame_times--;
- }
-
- exit(0);
- }
- else
- {
- install_sig();
-
- while (run)
- {
- memset(precvframe, 0x00, can_frame_len);
- ret = recv_frame(recv_socket_fd, precvframe, can_frame_len, 5 * 1000);
- if (ret > 0)
- {
- printf_frame(recvframe.can_id & CAN_EFF_MASK, recvframe.data, recvframe.can_dlc,
- ((recvframe.can_id & CAN_EFF_FLAG) ? true : false),
- true,
- false);
- }
- }
-
- while(((pid = wait(&status)) == -1) && (errno == EINTR))
- {
- delay_ms(10);
- }
- }
-
- disconnect(&send_socket_fd);
- disconnect(&recv_socket_fd);
-
- shmdt(pframeno);
- shmctl(segment_id, IPC_RMID, NULL);
-
- return 0;
- }
使用示例程序源码下载地址:
linux socket can程序cantool如果觉得好用,记得给个好评!»
本文地址: http://velep.com/archives/1177.html»
文章出处: reille博客—http://velep.com , 如果没有特别声明,文章均为reille博客原创作品