1:signal的基本性质
先看一段CANoe官方文档的描述:“CAPL中的信号表示交互层中的总线信号,与消息(message)不同,它们不是CAPL数据类型。”
注意两点
1.1:信号表示的是交互层中的总线信号,交互层可以理解为信号的物理值和总线值之间的一个层。
写过DBC文件的同学,应该都知道我们设置一个车速信号 VehicleSpeed信号,该信号起始位 2bit,位长度,12位。我们设置好这些之后还要设置下面两个属性
factor 与 offset
总线值= Factor(物理值)+Offset;
我们看 物理值能够表示的范围【0-0xFFF(4095)】,一般情况下车速能显示0-250km/h就差不多够用了,家用代步车很多都开不到这个时速。于是这个值是不是就浪费了吗?
我们键入一下数值
看Minimum 和Maximum可以看到总线值的取值范围为【-50,395】,其中负数可以表示为倒车车速。
Factor和Offset相当于配置了交互层的参数。factor可以是小数,整数,负数,正数,offset也可以是任意实数。
1.2:signal,并不是CAPL中的数据类型,对应的message则属于CAPL的数据类型,这就表明了我们是不可以直接定义一个signal类型的变量。
不仅仅是CAPL,我接触任何语言基本都是以Byte的整数倍,定义数据的。C51中可以定义bit(是个例外)。而且数据的读取也是按照字节的整数倍来读取的。故CAPL中的signal是需要交互层来处理的。
2:信号的具体用法
使用信号的前提是,必须导入DBC文件(不知道导入ARXML文件管用不管用),
$这个符号,我称为信号访问符
$,这个信号在输入时,一定要注意的是,必须切换到英文输入法下,如果是中文输入法会出现¥。
例如以下两种情况
1)int NUM_1=100;
$VehicleSpeed = NUM;是符合要求的
int NUM_2 = $VehicleSpeed;
在代码中VehicleSpeed赋值给NUM_1的是总线值。
此处还有两个比较隐蔽的知识点。回到上面的一张图:
1)我们下拉箭头,可以看到Signal,可以设置为()以下四种类型。
这里的有符号/无符号和C中一样的作用。选择signed或unsigned时,也是可以表示小数的
IEEE Float和IEEE Double会自动将长度固定为32和64Bit。
2)就是注意赋值,可能被溢出的问题,比如:
Byte num_3=$VehicleSpeed;就可能发生溢出情况。
另外在CAPL中Byte默认是无符号的,当VehicleSpeed是有符号时(负数时),就会产生错误.。
3.signal被当做函数的形参、实参时。
不能被直接使用的,需要在前面加上signal+*信号名称
这里,又出来一个问题,图中标注出来的都是DBC中已经定义的信号,
1)因为DBC文件在DB++中定义Signal时,是可以重复名称的。这样会不会导致冲突存在。
2)因为问题1,我们模仿on signal +message名称::+ 信号名称,发现会报错
3)第三;我们发现信号作为实参时,并不需要加上signal*
4)
故,我建议,在capl编程中,我们尽量不要使用,信号,message,系统变量作为实参或形参。可以添加中间量代替,如 int a=$ message_1::RearWheelSpeed_ChkSun,然后用a来作为函数实参。形参也尽量使用CAPL自带的数据格式。
4:signal引用的另外几种格式
之前我们说过在capl程序中引用signal需要使用$作为前缀。这里延伸讲一下,Signal可以带的后缀,
1)raw, .raw64 或.phys 例如:$VehicleSpeed.raw/raw64/phys。这些都是可以直接赋值给signal物理值,而非总线值。
注意事项:
*1 只有在信号再次在网络上(也就是总线上)之后,信号值才会立即改变。
*2 语法规定总是读取传输到网络的最后一个值。
*3 要显式读取传输到网络的最后一个值,还可以将.txrq附加到信号名称。
前两条放在一起看,是什么意思?
$VehicleSpeed.raw/raw64/phy=200; //第一次设置
if ($VehicleSpeed.raw != 200.0) write("Unequal!");
//此时write窗口输出的是Unequal。因为此信号还没有被发送出去
output(message_1); //message_1是包含VehicleSpeed的信号
if ($VehicleSpeed.raw != 200.0)
write("Unequal!");
else
write("Equal");
//此时信号已经发送到总线上,if括号内的表达式,就会从总线上读取数据。
看第三条,也就是说如果想立即读取Signal的值,可以将Txrq,添加在Signal的末尾处。此外Txrq还能和raw、raw64、phys联合起来使用。如:$VehicleSpeed.txrq.raw的模式。
注意:
保存信号值始终是离散的。如果指定了物理值,则会在缩放后输入下一个最接近的离散原始值。如果信号随后被读出,则结果不一定是原始值。
此处的意思是,所输入的物理值,必须和信号的类型相匹配