CAN总线开发必看! 如何使用CANlib检测CAN帧溢出情况? Kvaser三招帮你轻松解决

文章介绍了在开发依赖CAN通信协议的软件时,如何利用CANlib库检测CAN帧溢出问题,包括通过canRead标志参数、canReadStatus和canIOCTL_GET_RX_BUFFER_LEVEL方法检查接收缓冲区状态。监控溢出对于防止应用程序错误和确保报文完整性至关重要。

在这里插入图片描述
从1980年代,Kvaser就开始CAN产品的研发,在相关产品开发领域有近40多年的经验,对CAN和相关总线技术有着非常深入的研究。广州智维电子科技是KVASER的中国引进者,我们会不定期分享一些有趣的发现和特定情况的技术处理。

在开发严重依赖通信协议的软件应用程序时,关键问题之一是:应用程序快速地处理传入的报文,而不会丢弃报文。本文就将分享如何使用CANlib检测CAN帧溢出情况。

在将CAN数据导入应用程序时发生丢失CAN帧的情况,通常是由于应用程序花费太多时间处理某一报文,应用程序暂停等待用户交互,或者应用程序正在等待共享系统资源,如数据文件等等。不管什么原因,应用程序开发人员应该计划检测这些丢弃的报文,以防止在由应用程序行为导致错误时搜索系统问题。

为了检测这个问题,CANlib提供了三种方法来检查接收缓冲区状态和确定CAN帧是否已经丢弃:

1.canRead标志参数

用于确定CAN帧是否已被丢弃的第一种方法是监视由canRead函数返回的标志参数。标志参数包含两个位,它们表示在此函数调用和和当前调用返回的最后一个报文之间是否发生软件或硬件溢出。这些位被定义为用于硬件溢出的canMSGERR_HW_OVERRUN和用于软件溢出的canMSGERR_SW_OVERRUN。你也可以使用canMSGERR_OVERRUN掩码同时检查这两种情况。因此,当应用程序检查到这些位集中的一个时,应用程序就会获知在当前CAN帧和接收的前一个CAN帧之间丢弃了报文。

要了解在使用软件的情况下如何显示,可以假设一个接收缓冲区,它可容纳10帧(当然,CANlib中的实际默认接收缓冲区大小远大于10)。硬件已接收到10个CAN帧并将其放入可填入的缓冲区。
在这里插入图片描述

在Qt中使用KvaserCANlib实现CAN数据定时发送,可借助Qt的`QTimer`类来定时触发CAN数据发送操作。以下是具体实现步骤和示例代码: 首先,要确保已经完成Kvaser CANlib SDK的安装,并且在Qt项目里正确配置了头文件和库文件。若项目为32位,默认调用32位的导出库(canlib32.lib);若为64位项目,需采用Kvaser提供的64位的canlib32.lib(路径:C:\Program Files (x86)\Kvaser\Canlib\Lib\x64),并编辑项目的`.pro`文件进行配置[^1]。 以下是示例代码: ```cpp #include <QCoreApplication> #include <QTimer> #include <canlib.h> #include <stdio.h> canHandle h; // 初始化CAN通道 bool initCAN() { canInitializeLibrary(); h = canOpenChannel(0, canWANT_EXCLUSIVE); if (h < 0) { char msg[64]; canGetErrorText((canStatus)h, msg, sizeof(msg)); fprintf(stderr, "canOpenChannel failed (%s)\n", msg); return false; } canSetBusParams(h, BAUD_250K, 0, 0, 0, 0, 0); canSetBusOutputControl(h, canDRIVER_NORMAL); canBusOn(h); return true; } // 发送CAN数据的函数 void sendCANData() { canStatus status = canWrite(h, 123, "HELLO!", 6, 0); if (status != canOK) { char msg[64]; canGetErrorText(status, msg, sizeof(msg)); fprintf(stderr, "canWrite failed (%s)\n", msg); } canWriteSync(h, 500); } // 关闭CAN通道 void closeCAN() { canBusOff(h); canClose(h); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); if (!initCAN()) { return -1; } // 创建一个QTimer对象 QTimer timer; // 设置定时器的时间间隔,这里设置为1000毫秒(即1秒) timer.setInterval(1000); // 将定时器的timeout信号连接到sendCANData函数 QObject::connect(&timer, &QTimer::timeout, sendCANData); // 启动定时器 timer.start(); int result = a.exec(); closeCAN(); return result; } ``` ### 代码解释 - `initCAN`函数:对CAN库进行初始化,打开CAN通道,设置总线参数和输出控制模式,最后开启总线。 - `sendCANData`函数:负责发送CAN数据,并且对发送状态进行检查,若发送失败则输出错误信息。 - `closeCAN`函数:关闭CAN总线和通道。 - `main`函数:创建`QCoreApplication`对象,调用`initCAN`函数初始化CAN通道,创建`QTimer`对象,设置定时器的时间间隔,将定时器的`timeout`信号连接到`sendCANData`函数,启动定时器,最后在应用程序结束时调用`closeCAN`函数关闭CAN通道。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值