linux socket can程序cantool

2019-07-13 04:20发布

转自:http://velep.com/archives/1177.html最近写了个自认为不错的基于linux socket can程序,主要功能:
  1. 程序具备全部CAN功能,包括CAN标准帧/扩展帧接收与发送、CAN总线错误判断、环回等功能
  2. 适用基于LINUX SOCKET机制实现的CAN接口,可用于嵌入式LINUX的CAN测试
  3. 程序采用标准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 组合键结束程序运行 部分源码001int main(int argc, char **argv)002{003    S_CanFrame sendframe, recvframe;004    byte *psendframe = (byte *)&sendframe;005    byte *precvframe = (byte *)&recvframe;006    u_canframe_data_t *psend_data = (u_canframe_data_t *)sendframe.data;007    const int can_frame_len = sizeof(S_CanFrame);008 009    pid_t pid = -1;010    int   status;011 012    int  ret = 0;013    char buf[128] = {0};014    bool carry_bit = false;// 进位标志015 016    int segment_id;//id for shared memo017 018 019    if (parse_options(argc, argv))020    {021        usage();    return  0;022    }023 024    if (!find_can(port))025    {026        sprintf(buf, " 错误:CAN%d设备不存在 ", port + 1);027        panic(buf);028        return  -1;029    }030 031    close_can(port);// 必须先关闭CAN,才能成功设置CAN波特率032    set_bitrate(port, bitrate);// 操作CAN之前,先要设置波特率033    open_can(port, bitrate);034 035    send_socket_fd = socket_connect(port);036    recv_socket_fd = socket_connect(port);037    //printf("send_socket_fd = %d, recv_socket_fd = %d ", send_socket_fd, recv_socket_fd);038    if (send_socket_fd < 0 || send_socket_fd < 0)039    {040        disconnect(&send_socket_fd);041        disconnect(&recv_socket_fd);042        panic(" 打开socket can错误 ");043        return  -1;044    }045    set_can_filter();046    set_can_loopback(send_socket_fd, lp);047 048    printf_head();049 050    memset(&sendframe, 0x00, sizeof(sendframe));051    memset(&recvframe, 0x00, sizeof(recvframe));052 053    if (extended_frame) // 指定发送帧类型:扩展帧或标准帧054    {055        sendframe.can_id = (send_frame_id & CAN_EFF_MASK) | CAN_EFF_FLAG;056    }057    else058    {059        sendframe.can_id = (send_frame_id & CAN_SFF_MASK);060    }061    sendframe.can_dlc = dlc;062    memcpy(sendframe.data, send_frame_data, dlc);063