CAPL 报文收发与周期定时器
先定义一个可以观察的小协议
本例在 CAN1 上发送 ID 为 0x200 的经典 CAN 数据帧,载荷为两个字节:固定标记 0xAA 和循环计数器。毫秒定时器在 100 ms 后请求下一次发送;接收端先检查长度,再读取字节。这样可以分别检查报文构造、定时调度和实际观察结果。
请在独立仿真或测试台架中运行,配置好 CAN1,避免另一个发送节点使用同一 ID。这些数值是教学协议,不是实际 ECU 规范。数字 ID 示例不依赖 DBC。代码已对照可用的 Vector 参考资料,但没有在你的 CANoe 版本中编译或运行;使用前核对节点类型、通道映射和已安装帮助中的 API 支持。
周期发送与明确停止
将以下源代码放入 CAPL 仿真节点。第一帧在初始定时器到期后请求发送,不会在测量启动的瞬间立即发送。
variables
{
msTimer heartbeatTimer;
message CAN1.0x200 heartbeat;
int running;
byte sequence;
}
on start
{
running = 1;
sequence = 0;
heartbeat.DLC = 2;
heartbeat.RTR = 0;
setTimer(heartbeatTimer, 100);
}
on timer heartbeatTimer
{
if (!running) return;
heartbeat.byte(0) = 0xAA;
heartbeat.byte(1) = sequence;
output(heartbeat);
sequence = (sequence + 1) & 0xFF;
setTimer(heartbeatTimer, 100);
}
on key 'x'
{
running = 0;
cancelTimer(heartbeatTimer);
write("Heartbeat scheduling stopped");
}
on key 's'
{
if (running) return;
running = 1;
setTimer(heartbeatTimer, 100);
}
on preStop
{
running = 0;
cancelTimer(heartbeatTimer);
}
在发送前明确设置 DLC,标记和计数器分别占用不同字节。计数器达到 255 后回到 0,是预期的载荷行为,与测量时间戳重置不同。
定时器处理函数中明确安排下一次到期;单独调用一次 setTimer 不会建立无限重复调度。按 x 停止,按 s 以新的 100 ms 延迟重新启动。running 判断避免重复启动按键不断重置正在运行的周期。cancelTimer 取消的是尚未触发的定时器,不能撤回已经交给 output 的报文。
先确认计时器类型,再看数字
| 调用 | 请求的延迟 | 容易混淆之处 |
|---|---|---|
| setTimer(anMsTimer, 100) | 100 毫秒 | 误读成微秒 |
| setTimer(aTimer, 1) | 两参数 timer 重载中的 1 秒 | 误以为所有定时器都是毫秒 |
| cancelTimer(aTimerVariable) | 取消尚未触发的定时器 | 误以为能撤回已发出的帧 |
时间戳以纳秒表示,并不等于定时调度有纳秒精度。定时器调度、控制器发送和接收观察是不同环节。重载规则见 setTimer,取消规则见 cancelTimer。
用独立观察节点检查接收
下面的处理函数放在另一个观察节点中。先核实该节点位置中 Rx 的含义;仿真节点与测量链中的节点,对事件转发的要求可能不同。
on message CAN1.0x200
{
if (this.DIR != Rx || this.RTR != 0) return;
if (this.DLC < 2)
{
write("0x200: payload shorter than two bytes");
return;
}
write("0x200: marker=0x%02X counter=%u", this.byte(0), this.byte(1));
}
这个处理函数只观察,不重新发送收到的报文。不要为了“让数据继续流动”就在通配处理函数中随意加入 output(this):它会改变流量,行为也依赖节点所在的配置。若把 CAPL 放在测量分析分支中,必须另外检查下游数据是否需要转发;本课优先使用独立观察配置。
验证矩阵
以下是需要实际检查的预期行为,不是实测记录:
| 操作 | 应检查什么 | 可以说明什么 |
|---|---|---|
| 启动测量 | CAN1、0x200、数据帧、DLC 2、首字节 AA | 构造和通道选择 |
| 记录多帧 | 第二字节递增,255 后回到 0 | 发送序列行为,不能单独证明没有漏采 |
| 按 x | 已提交流量结束后,不再出现新调度的心跳 | 停止逻辑 |
| 按一次 s | 经过新的延迟后恢复发送 | 重启逻辑 |
| 从受控来源注入 DLC 1 | 接收端输出长度不足提示 | 长度保护分支确实执行 |
筛选并导出时间戳列后,使用间隔分析工具与有依据的容差比较。代码中写了 100,不代表观察到的每个间隔都精确等于 100 ms。继续阅读时间戳教程,明确时钟和报文流。
行为不符合预期时
没有报文,先检查测量状态、通道映射及定时器处理函数是否执行。字节不符,检查 DLC 和是否有其他节点占用 0x200。看起来频率翻倍,先分开通道与方向。停止后仍有最后一帧,区分已经提交的发送与新的定时重启。需要自动化检查时,继续阅读有界等待与测试模块。
解释和示例组织由本站编写,API 语义依据获授权的 Vector 参考资料。详见来源与验证边界。