linux socket can程序cantool

2023-05-16

最近写了个自认为不错的基于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 组合键结束程序运行

部分源码

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;//id for shared memo


    if (parse_options(argc, argv))
    {
        usage();    return  0;
    }

    if (!find_can(port))
    {
        sprintf(buf, "\n\t错误:CAN%d设备不存在\n\n", port + 1);
        panic(buf);
        return  -1;
    }

    close_can(port);// 必须先关闭CAN,才能成功设置CAN波特率
    set_bitrate(port, bitrate);// 操作CAN之前,先要设置波特率
    open_can(port, bitrate);

    send_socket_fd = socket_connect(port);
    recv_socket_fd = socket_connect(port);
    //printf("send_socket_fd = %d, recv_socket_fd = %d\n", send_socket_fd, recv_socket_fd);
    if (send_socket_fd < 0 || send_socket_fd < 0)
    {
        disconnect(&send_socket_fd);
        disconnect(&recv_socket_fd);
        panic("\n\t打开socket can错误\n\n");
        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);// allocate memo
    pframeno = (int *)shmat(segment_id, NULL, 0);// attach the memo
    if (pframeno == NULL)
    {
        panic("\n\t创建共享内存失败\n\n");
        return  -1;
    }
    *pframeno = 1;

    run = true;

    pid = fork();
    if(pid == -1) 
    { 
        panic("\n\t创建进程失败\n\n");
        return  -1;
    }
    else if(pid == 0) // 子进程,用于发送CAN帧
    {
        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 // 父进程,接收CAN帧
    {
        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);// detach memo
    shmctl(segment_id, IPC_RMID, NULL);// remove

    return  0;
}
使用示例

程序源码

下载地址:linux socket can程序cantool

如果觉得好用,记得给个好评!

»  本文地址:  http://velep.com/archives/1177.html
»  文章出处:  reille博客—http://velep.com  , 如果没有特别声明,文章均为reille博客原创作品
»  郑重声明:  原创作品未经允许不得转载,如需转载请联系reille#qq.com(#换成@)


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux socket can程序cantool 的相关文章

  • 如何仅将整个嵌套目录中的头文件复制到另一个目录,在复制到新文件夹后保持相同的层次结构

    我有一个目录 其中有很多头文件 h 和其他 o 和 c 文件以及其他文件 这个目录里面有很多嵌套的目录 我只想将头文件复制到一个单独的目录 并在新目录中保留相同的结构 cp rf oldDirectory newDirectory将复制所有
  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • Windows 与 Linux 文本文件读取

    问题是 我最近从 Windows 切换到 Ubuntu 我的一些用于分析数据文件的 python 脚本给了我错误 我不确定如何正确解决 我当前仪器的数据文件输出如下 Header 有关仪器等的各种信息 Data 状态 代码 温度 字段等 0
  • R 未获取用户库

    我有一个带 R 3 6 0 的 Fedora 30 系统 用户库设置在Renviron就像这个 R LIBS USER R LIBS USER R x86 64 redhat linux gnu library 3 6 事实上 它出现在交互
  • 我应该使用哪个 Linux 发行版作为 Xen 主机? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我为家庭办公室订购了一台服务器 我想用 Xen 对其进行分区 我认为这将使事情保持干净并且更容易维护 我将运行 MySQL PostgreSQL
  • 错误:NVIDIA-SMI 失败,因为无法与 NVIDIA 驱动程序通信

    NVIDIA SMI 抛出此错误 NVIDIA SMI 失败 因为无法与 NVIDIA 通信 司机 确保安装了最新的 NVIDIA 驱动程序并且 跑步 我清除了 NVIDIA 并按照提到的步骤重新安装了它here https askubun
  • 是否从页面缓存中的脏页面进行文件读取?

    当字节写入文件时 内核不会立即将这些字节写入磁盘 而是将这些字节存储在页缓存中的脏页中 回写缓存 问题是 如果在脏页刷新到磁盘之前发出文件读取 则将从缓存中的脏页提供字节 还是首先将脏页刷新到磁盘 然后进行磁盘读取以提供字节 将它们存储在进
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理
  • 确保 config.h 包含一次

    我有一个库项目 正在使用 Linux 中的 autotools 套件移植到该项目 我对自动工具很陌生 本周 我已经了解了其操作的基础知识 我有一个关于如何保留内容的问题config h免遭重新定义 我惊讶地发现生成的config h文件也没
  • 如何从linux命令行运行.exe可执行文件? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在 Windows 中有一个 abc exe 可执行文件 我可以使用 DOS 命令提示来执行此应用程序 并为其提供一些运行时变量 我想从
  • 如何调用位于其他目录的Makefile?

    我正在尝试这样做 我想打电话给 make Makefile存在于其他目录中 abc可以使用位于不同目录中的 shell 脚本的路径 我该怎么做呢 由于 shell 脚本不允许我cd进入Makefile目录并执行make 我怎样才能编写she
  • gethostbyname() 或 getnameinfo() 如何在后台工作?

    How gethostbyname or getnameinfo 在后台工作 include
  • InstaPy:“错误,无法确定 64 位 Linux 的正确文件名”

    有人知道如何解决或解决这个问题吗 来自控制台的堆栈跟踪 执行后报告错误 InstaPy Version 0 6 9 Workspace in use home zanettra InstaPy Error unable to determi
  • 如何让 clangd 转向 c++20

    当没有其他信息时 如何让 clangd 回退到 c 20 例如 在第一次构建之前 cmake 可以生成一个 这是在带有最新 LLVM 的 Arch Linux 上 这是通过 Emacs LSP 运行的 但这应该没有什么区别 你可以加 Com
  • 停止服务时单元陷入故障状态(状态=143)[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 这是我的问题 我有 CentOS 和 java 进程在上面运行 Java进程是通过启动 停止脚本来操作的 它也创建了 java 实例的 p
  • 在 LINUX 上使用 Python 连接到 OLAP 多维数据集

    我知道如何在 Windows 上使用 Python 连接到 MS OLAP 多维数据集 嗯 至少有一种方法 通常我使用 win32py 包并调用 COM 对象进行连接 import win32com client connection wi
  • 标准头文件中的 C 编译器错误 - 未定义的 C++ 定义

    我正在尝试编译 C 程序 但收到许多错误 这些错误是在标准 C 头文件 inttypes h stdio h stat h 等 中遇到的 错误的来源是以下未定义的常量 BEGIN DECLS END DECLS BEGIN NAMESPAC
  • 适用于 KDE 和 Gnome 的 Gui [重复]

    这个问题在这里已经有答案了 我想为一个现在是 CLI 的应用程序编写一个 gui 它需要在 KDE 和 Gnome DE 中 看起来不错 充分利用用户的外观设置 如果我选择 Qt 或 GTK 我能够做到这一点吗 它们与两个 DE 集成良好吗
  • 为什么 Linux 对目录使用 getdents() 而不是 read()?

    我浏览 K R C 时注意到 为了读取目录中的条目 他们使用了 while read dp gt fd char dirbuf sizeof dirbuf sizeof dirbuf code Where dirbuf是系统特定的目录结构
  • 如何查找连接到 AF_INET 套接字的客户端的 UID?

    有什么方法或类似的东西ucred for AF UNIX如果是AF INET插座 TCP在我的例子中 找出连接到我的套接字的客户端的UID 还有 proc net tcp但它显示了UID of the creator插座的而不是连接的cli

随机推荐

  • ROS-melodic 安装 及:rosdep init 和 rosdep update 失败问题解决总结

    正常安装ros流程 ros 安装 melodic sudo sh c 39 etc lsb release amp amp echo 34 deb http mirrors tuna tsinghua edu cn ros ubuntu D
  • ubuntu 安装Opencv4版本后安装Opencv3,并在项目中区分使用

    安装 xff1a ubuntu 安装OpenCV3版本后安装OpenCV4 xff0c 且多版本共存 wyyang2的博客 CSDN博客 https blog csdn net wyyang2 article details 1039894
  • Ubuntu 16.04录屏软件

    Ubuntu 16 04安装录屏软件Simple Screen Recorder https www maartenbaert be simplescreenrecorder https jingyan baidu com article
  • debug时一个非常坑爹的问题——单步调试正常但是运行没结果

    单步调试能得到正确答案 xff0c 运行不出来 本人用的是codeblocks xff0c 20 03版本 话说有一天晚上 xff0c 那个不平凡的夜 xff0c 还有不到十个小时数据结构的实验课就要上交报告了 xff0c 而自己的程序却出
  • DataX使用、同步MySQL数据到HDFS案例

    文章目录 4 DataX使用4 1 DataX使用概述4 1 1 DataX任务提交命令4 1 2 DataX配置文件格式 4 2 同步MySQL数据到HDFS案例4 2 1 MySQLReader之TableMode4 2 1 1 编写配
  • 支持期限提至10年,Ubuntu 18.04 LTS

    给技术最前线加星标 xff0c 每天看技术热点 综合自 xff1a cnBeta COM Solidot Mark Shuttleworth宣布将支持Ubuntu 18 04 LTS长达十年时间 xff0c 让LTS版本的含金量更足 xff
  • 实训第五天:我的页面布局,API接口(一言,天气预报)

    1 不用不用脚本和弹窗获取手机信息 xff0c 用微信公众平台的组件开发能力 open data用于展示微信开放的数据 部分代码 xff1a lt view class 61 34 container 34 gt lt view class
  • 这是一个失败的程序员

    写程序至今 xff0c 未入门 xff0c 什么都不懂 xff01
  • adb dumpsys命令用法

    dumpsys命令功能很强大 xff0c 能dump系统服务的各种状态 xff0c 非常有必要熟悉该命令的用法以及含义 一 概述 1 1 dumpsys命令用法 可通过dumpsys命令查询系统服务的运行状态 对象的成员变量属性值 xff0
  • matlab subs函数

    在matlab命令行查看subs函数的帮助 subs函数一共有三种使用方法 xff1a subs s old new subs s new subs s 点击 subs 的参考页可以看到下面的详细说明 第一种使用方法 说明 xff1a su
  • Docker----如何更改docker镜像的存储路径

    原文链接 Docker 如何更改docker镜像的存储路径 背景 随着docker容器已经镜像的使用 xff0c docker镜像占用大量磁盘空间 xff0c 当然可以通过不断的删除镜像或者设置定时任务删除镜像 xff0c 但是有时候还是挺
  • ROS的geometry_msgs/PoseWithCovarianceStamped Message 消息格式

    溪西创客小屋 geometry msgs PoseWithCovarianceStamped Message Raw Message Definition This expresses an estimated pose with a re
  • 线程和进程的理解

    一 介绍线程和进程 什么是线程 是程序执行的最小单位 xff0c 一个进程在执行过程中产生建多个线程 xff0c 同一进程中的 多个 线程共享同一块内存空间及系统资源 xff0c 线程数进程的一部分 xff0c 因此线程数也被称为轻量级进程
  • Windows安装tensorflow-gpu

    0 想在Windows环境安装tensorflow gpu xff0c 显卡必须是N卡 xff08 本文以3070显卡为例进行说明 xff09 1 安装好Anaconda以及Pycharm xff08 安装教程 xff1a https ww
  • 16.进程-进程间通信概述

    进程间通信 xff0c 也就是大家常说的 IPC Inter Process Communication xff0c 指的是不同的进程间进行交流 xff0c 本质上就是进程之间发送和接收数据 xff1b 本质上 xff0c 信号也是属于进程
  • PNP问题-位姿估计方法梳理(pose estimation)

    tags 单目视觉 位姿测量 目标3D精确模型已知 xff08 建立2D 3D对应关系 xff09 xff1a 点特征 P3P问题 基于针孔成像模型 Gao的方法 xff08 opencv emgucv xff09 Kneip 的 P3P
  • 室内无人机定位导航

    个人观点 xff1a 可研究的方向 1 静态规划方面 xff1a 将控制与定位结合起来 xff1b 修正回环检测误差 xff0c 提高算法的计算精度和执行效率 xff1b 2 动态规划方面 xff1a 用神经网络识别运动物体的行进方向 xf
  • 树莓派3b程序控制无人机 (一)——电脑连树莓派

    设备 xff1a 树莓派3b xff08 备有键盘 xff0c 鼠标 xff09 xff1b win10 x64笔记本 xff1b UAV pixhawk飞控板 etc network interfaces 的设置可参考以下链接 xff1a
  • 三星6410裸机程序开发

    网上关于S3C6410裸机程序开发都是基于RealView RVDS 也有一些是基于eclipse的 xff0c 但都没有详细介绍在eclipse中如何建立S3C6410裸机程序工程 尽管友善之臂提供的6410裸机程序示例使用了eclips
  • linux socket can程序cantool

    最近写了个自认为不错的基于linux socket can程序 xff0c 主要功能 xff1a 程序具备全部CAN功能 xff0c 包括CAN标准帧 扩展帧接收与发送 CAN总线错误判断 环回等功能适用基于LINUX SOCKET机制实现