Loading...
墨滴

jasonj333

2021/07/16  阅读:63  主题:红绯

capl-消息声明、选择器

消息声明

在capl中,用关键字message声明消息,格式为

message 消息id/消息名称 自定义名称;

如果导入了dbc文件,就可以用dbc里的消息名称声明它,如果没有dbc,就需要用消息id来声明,当然,即使有dbc,也可以用消息id声明

消息id可以用16进制或10进制表示,都是可以的

message 0xA m1;
message 100 m2;
message EngineData m3;  

这里有个注意点

用消息id声明扩展帧时,需要在扩展帧id后面加x,以表明它是一条扩展帧

对于不是固定某一条消息的声明,可以用message *

它常用在传入消息类参数的情形下

关键字message和dbMsg的不同,message是把消息声明为自定义名称,而dbMsg代表dbc里的消息,它们作为参数用在不同的函数中

传入的消息是message声明的消息
传入的消息是message声明的消息
传入的消息是dbMsg类型的消息
传入的消息是dbMsg类型的消息

可以通过数据选择器和字节值偏移访问消息的数据区域,例如

message 100 msg;
msg.DLC = 1;
msg.BYTE(0) = 0xff;
output(msg);  

在总线上传输dlc = 1和第一个字节为0xff的消息100

选择器

在capl中,可以使用不同的选择器访问消息、信号和系统变量的信息

我更愿意把它理解成是类中的属性,消息、信号和系统变量作为类的对象,当然可以获取它们的属性

各类型的总线消息、信号和系统变量的选择器有哪些,可以在help文档上查找

信号访问

信号是从不同的消息发出的,信号名有可能相同,但是承载它的消息就不能相同,消息名有可能相同,但是发出消息的节点就不能够相同,节点名称有可能相同,但是节点所在的通道就不能相同

所以,如果想访问的信号具有唯一性,可以使用通道或网络、节点名称和消息名称等前缀来限定它

正确的限定语法是

[(channel | network)::][[dbNode::]node::][[dbMsg::]message::][dbSig::]signal

举例

$LightSwitch::OnOff              // Node + Signal
$LightSwitch::LightState::OnOff  // Node + Message + Signal
$CAN1::Gateway::Status           // Channel + Node + Signal
$PowerTrain::Gateway::Status     // Network + Node + Signal
$CAN1::Status                    // Channel + Signal  

如果你想获取信号值,只需要在信号前加一个美元符号$

value = $EngineSpeed;  

这里需要注意

信号名称是区分大小写的哦

上面获取的信号值,默认是物理值

如果你想明确使用物理值,可以用信号.phys,如果你想获取初始值,可以用.raw,如果初始值长度超过52位,可以使用.raw64

int64 largeValue;
largeValue = $Some64bitSignal.raw64;

可以用美元符合$获取信号值,也可以用它设置信号值

$EngineSpeed = 500.0;  

当设置信号值时,节点必须要有交互层,而且设置后不会立刻生效,需要等待信号所在的消息再次在总线上传输时才会生效

如果想读出传输到网络的最后一个值,还可以将 .rx 附加到信号名称

像下面的这两条程序

$EngineSpeed = 500.0;
if ($EngineSpeed != 500.0) write("Unequal!");  

打印的结果是Unequal,为什么呢,我明明已经在capl中设置了信号值为500,为什么我接下来获取的信号值不是500

因为设置了信号值后并不是马上传输到网络上的,所以如果你想读出一个在程序中已经改变但还没有在网络上传输的值,可以使用后缀.txrq

if ($EngineSpeed.txrq != 500.0)   

还可以在信号值发生变化时立即调用事件,这就是on signal回调函数

on signal LightSwitch::OnOff
{
  v1 = this.raw;
  v2 = $LightSwitch::OnOff.raw;
}  

如果想在即使信号值没有发生改变,但是只要接收到,就会调用事件,可以用on signal_update

on signal_update signalname

信号值发生变化时的回调函数,还可以用on signal_change

on signal_change signalname

可以看出,on signal和on signal_change具有相同的语义,而on signal_update则有所不同

如果想在多个信号中的其中一个信号发生变化时,调用事件,可以如下写法

on signal ( signalname1 | signalname2 | ...)

举例

on signal ( LightSwitch::OnOff | MotorSwitch::OnOff )

一旦其中一个信号发生变化,就会调用该事件

但是,但是,多信号的回调函数,不能用this关键字,请注意

和消息一样,信号也可以作为参数传递给函数,形参的写法是signal *

foo ( signal * s )
{
   write("Signal value: %g"$s);
}

但是不能用signal *声明信号

还可以用.name访问信号名称

以上就是本篇的内容,转发,投币,你选一个!!!


jasonj333

2021/07/16  阅读:63  主题:红绯

作者介绍

jasonj333