4. CAPL编程基础与测试脚本框架
CAPL(Communication Access Programming Language)是Vector为CANoe提供的类C事件驱动脚本语言。它不像普通程序那样从main函数顺序执行,而是由总线报文、定时器、键盘、系统变量变化等事件触发对应的处理函数。理解这一机制,是写出稳定、可维护整车网络测试脚本的前提。
事件驱动:CAPL脚本的运行骨架
CAPL脚本由若干事件处理块组成,常见的有:on message(收到指定报文时触发)、on timer(定时器到期触发)、on key(按键触发)、on sysvar(系统变量变化触发)、on envVar(环境变量变化触发)以及on start(测量开始时触发一次)。每个事件块内部是顺序执行的C风格代码,但不同事件之间由CANoe内核调度,互不阻塞。
例如,要监测ID为0x123的报文是否在100ms内持续出现,可以这样组织:
variables
{
msTimer tCheck;
int gMsgCount = 0;
}
on start
{
setTimer(tCheck, 100);
}
on message 0x123
{
gMsgCount++;
}
on timer tCheck
{
if (gMsgCount == 0)
{
write("0x123 超时未收到");
}
gMsgCount = 0;
setTimer(tCheck, 100);
}
这里on start启动第一个100ms定时器,on message负责计数,on timer负责判断并重启定时器,形成周期检测。注意:CAPL中定时器到期后不会自动重装,必须显式再次setTimer,这是初学者最容易忽略的一点。
系统变量与环境变量
系统变量(System Variable)定义在CANoe工程的System Variables命名空间中,可被CAPL、面板、IG模块共同读写,是脚本与外部交互的主要通道。环境变量(Environment Variable)则更偏向与外部工具或旧版配置交互。测试脚本中推荐优先使用系统变量,因为其支持命名空间、数据类型更丰富,且可在Test Setup中直接引用。
系统变量常见类型包括int、float、string、data、int array等。在CAPL中通过@sysvar::Namespace::VarName读写,例如:
on key 'a'
{
@sysvar::Test::Voltage = 13.5;
write("设定电压 = %f", @sysvar::Test::Voltage);
}
on sysvar sysvar::Test::Voltage
{
if (@this > 14.0)
{
write("过压告警");
}
}
其中on sysvar块在变量值变化时触发,@this代表当前变量值。这种“写变量—触发事件—执行判断”的链路,正是CAPL与面板、测试序列联动的核心方式。
定时器与时间控制
CAPL提供msTimer(毫秒级)和timer(秒级)两类定时器。定时器是测试脚本实现超时判断、周期发送、延时等待的基础。常用函数有setTimer、cancelTimer、setTimerCyclic(周期触发)。
需要特别注意:CAPL是单线程事件驱动,定时器回调中不要执行长时间阻塞操作,否则会延迟其他事件处理。若需等待某个条件成立,推荐用状态机+定时器轮询,而不是死循环。
测试用例组织方式
在CANoe中,CAPL测试脚本通常以Test Node形式挂载到Test Setup,配合Test Module或Test Case结构组织。一个典型的测试用例包含:初始化、激励施加、条件等待、结果判定、清理五个阶段。CAPL提供testcase关键字和TestReport相关函数,可直接生成测试报告。
testcase TC_VoltageOver()
{
@sysvar::Test::Voltage = 15.0;
testWaitForTimeout(200);
if (@sysvar::Test::Alarm == 1)
testPass("过压告警正确触发");
else
testFail("过压告警未触发");
}
对于多个用例,建议按功能域拆分为多个.can文件,通过includes共享公共函数,避免单文件过大难以维护。
上图展示了CAPL脚本从事件源到处理逻辑再到输出判定的整体框架。左侧是各类事件入口,中间是脚本内部的处理单元,右侧是测试结果与告警输出。实际项目中,一个测试节点往往同时挂载多个事件块,通过系统变量和定时器协同完成复杂测试序列。
掌握上述机制后,就可以在CANoe中搭建结构清晰、可复用的整车网络测试脚本框架,为后续的自动化测试序列和报告生成打下基础。