实时处理 CAN 报文
目录
选择 CAN 设备
在打开 CAN 端口之前,我们首先必须选择一个设备。
ksError = KS_enumDevices(
"CAN", // 搜索 CAN 卡
deviceIndex, // 设备索引
pDeviceNameXmit, // 设备名称缓冲区
0); // 标志
if (ksError)
// ...
如果设备尚未使用 Kithara 驱动程序进行更新,则将对 Kithara 驱动程序进行动态更新。有关更多详细信息,请参阅 如何查找设备。
打开 CAN 端口
要打开 CAN 端口,可以使用功能 KS_openCan 和 KS_openCanEx。函数 ‘KS_openCan’ 具有指向 CAN 句柄的指针、设备名称、端口、波特率和标志作为参数。
作为设备名称,应传递一个有效的设备字符串,该字符串使用函数 KS_enumDevices 检索(参见选择 CAN 设备。波特率由常数指定,例如 ‘KS_CAN_BAUD_125K’ 或 ‘KS_CAN_BAUD_1M’。标志 ‘KSF_REALTIME_EXEC’ 启用实时访问。
函数 ‘KS_openCanEx’ 有一个指向 CAN 句柄的指针、一个连接句柄、一个端口、一个波特率和标志作为参数。连接手柄的参数可以是从属手柄,例如用于 EL6751。这样做,可以打开 EtherCAT 从站的 CAN 接口端口。其他参数类似于函数 ‘KS_openCan’ 。
// ...
KSHandle hCanRecv;
ksError = KS_openCanEx(
&hCanRecv, // CAN 端口句柄地址
hEL6751, // EL6751 手柄
0, // 端口 (EL6751 只有一个端口)
KS_CAN_BAUD_125K, // 波特率
0); // 标志,此处为 0
if (ksError)
// ...
关闭 CAN 端口
要关闭 CAN 端口并释放分配的资源,可以使用函数 KS_closeCan。
发送和接收 CAN 报文
对于发送和接收 CAN 消息,可以使用 KS_xmitCanMsg 和 KS_recvCanMsg 功能。
函数 ‘KS_xmitCanMsg’ 有一个 CAN 句柄、一个指向 KSCanMsg 结构的指针和作为参数的标志。在调用 KS_xmitCanMsg 之前,必须设置数据结构 KSCanMsg’ 中的 CAN 报文。
调用 KS_xmitCanMsg 时,消息将立即发送。为此,CAN 端口必须处于 send-ready 状态。如果不是这种情况,则消息将保存在内部缓冲区中,并在端口准备就绪后尝试发送消息。同时,可以准备发送更多消息,然后将其复制到缓冲区,并在以后按顺序发送。
函数 ‘KS_recvCanMsg’ 有一个 CAN 句柄、一个指向 KSCanMsg 结构的指针和作为参数的标志。为了确定是否可以接收 CAN 报文,可以循环调用函数 ‘KS_recvCanMsg’ (“polling”)。如果未收到任何消息,则函数返回 ‘KSERROR_NO_DATA_AVAILABLE’。更好的方法是安装 CAN 接收处理程序(参见: 安装处理程序)。仅当可以接收消息时,才会执行处理程序代码。这两种方法是互斥的,即您可以使用 ‘KS_recvCanMsg’ 或安装 CAN 接收处理程序。
安装处理程序
要安装 CAN 处理程序,可以使用函数 KS_installCanHandler。作为参数,CAN 句柄、事件代码、回调句柄和标志被传递。使用事件代码指定处理程序的类型。可以使用以下处理程序:
活动代码 | 描述 |
---|---|
‘KS_CAN_RECV’ | 新收到的消息。 |
‘KS_CAN_XMIT_EMPTY’ | 传输缓冲区为空。 |
‘KS_CAN_XMIT_RTR’ | 发生远程传输请求。 |
‘KS_CAN_ERROR’ | 发生错误。 |
‘KS_CAN_FILTER’ | 立即筛选收到的消息。 |
‘KS_CAN_TIMEOUT’ | 已达到传输消息超时。 |
调用处理程序时应执行的代码作为回调句柄传递(参见 创建回调)。对于不同的事件代码,特殊的上下文结构将传递给 context 参数中的 callback 函数。可以在函数 KS_installCanHandler 的 API 文档中找到列表。对于 ‘KS_CAN_RECV’、‘KS_CAN_XMIT_RTR’ 和 ‘KS_CAN_FILTER’ 事件代码,相应的上下文结构为 CanMsgUserContext。如果输入了 ‘null/NULL/NIL’ 作为回调句柄,则会再次卸载处理程序。
安装过滤器处理程序
用户定义的 CAN 报文过滤器可以通过安装事件代码为 ‘KS_CAN_FILTER’ 的 CAN 处理程序来实现。对于此处理程序,必须使用 ring 0 回调。以下代码演示如何筛选标识符介于 124hex 和 225hex 之间的标准帧格式 (SFF) 消息。
KSError __stdcall _filterCallBackR0(void\* pArgs, void\* pContext) {
CanMsgUserContext\* pMsgUserContext = (CanMsgUserContext\*)pContext;
if (pMsgUserContext->msg.msgType != KS_CAN_MSGTYPE_STANDARD ||
pMsgUserContext->msg.identifier < 0x124 || pMsgUserContext->msg.identifier > 0x225) {
pMsgUserContext->discarded = 1;
}
return KS_OK;
}
接受 RTR 消息
为了接受 RTR 消息,必须安装事件代码为 ‘KS_CAN_XMIT_RTR’ 的处理程序。否则 RTR 消息将被拒绝!对于此处理程序,必须使用 ring 0 回调。
‘Transmit Empty’ 处理程序
使用事件代码 ‘KS_CAN_XMIT_EMPTY’ 可以安装’Transmit Empty’ 处理程序,如果发送方缓冲区为空,则会发出信号。要激活处理程序,必须执行带有 KS_execCanCommand 的 CAN 命令 'KS_SIGNAL_XMIT_EMPTY"。
获取 CAN 状态
函数 KS_getCanState 提供当前的 CAN 端口状态。作为参数,传递一个 CAN 句柄和一个指向结构 KSCanState 的指针。在调用函数之前,请务必将结构成员 structSize 初始化为结构"KSCanState"的实际大小。
执行 CAN 命令
函数 KS_execCanCommand 在 CAN 端口上执行特定命令。作为参数,将传递 CAN 句柄、命令、可选参数和标志。具体命令的描述可以在 KS_execCanCommand 的 API 文档中找到。有关如何设置可选参数 pParam 或 flags 的信息也可以在此处找到。
项目实例
请参阅示例 :
- smp/CanFDBasics
- smp/CanFDRecv
- smp/CanFDSend