DBLookup 动态读取数据库中的信息
//Transmitter 属性以及数据库属性只能通过 DBLookup 动态读取。
//返回数据库中存储的 DLC
on message *
{int myAttributeValue;myAttributeValue = DBLookup(this).MyAttribute;write(this.Transmitter); // compiler errorwrite(DBLookup(this).Transmitter); // OK
}//返回特定消息的当前值
on message EngineData
{int myDLC;myDLC = DBLookup(this).DLC;
}myDLC = EngineData.DLC;
它们可能会有所不同,因为 DLC 可以更改,例如 在 CAPL 程序中。
在数据库中动态搜索消息可能需要一些时间,尤其是对于大型数据库。 因此,如果消息类型已知,最好静态访问属性。
// 检查特定节点的所有消息,表明 DLC 正确。
// 在测量结束变量的表中总结不正确 DLC 的 DLC 信息
{// system under testchar gNodeUnderTest[30] = "Gateway";// max DLC, min DLC, counter, channel; key is always the idint gFrameMaxDLC[long];int gFrameMinDLC[long];int gFrameCounter[long];byte gFrameChannel[long];
}
on message *
{// 检查来自一个节点的所有帧是否有正确的 dlc 并对其进行计数// 框架是在数据库中定义的吗?if (DBLookup(this)){// 被测节点的帧是否定义为 Tx-Frame?// 注意:比较区分大小写if (strncmp(DBLookup(this).Transmitter, gNodeUnderTest, 30) == 0){// 检查DLC是否正确; 如果没有,请记住最小值// 或接收帧的最大 DLCif (this.dlc < DBLookup(this).DLC){gFrameCounter[this.id]++;gFrameChannel[this.id] = this.can;if (!gFrameMinDLC.containsKey(this.id) || this.dlc < gFrameMinDLC[this.id])gFrameMinDLC[this.id] = this.dlc;}else if (this.dlc > DBLookup(this).DLC){gFrameCounter[this.id]++;gFrameChannel[this.id] = this.can;// 注意:第一次访问映射元素返回 0,它总是较小的if (this.dlc > gFrameMaxDLC[this.id]) gFrameMaxDLC[this.id] = this.dlc;}} // else: another node, not interesting} // else: event is not defined in the databaseoutput(this); // 仅当节点位于测量设置中时使用
}
on stopMeasurement
{message * m;for (long currentId : gFrameCounter){m.id = currentId;m.can = gFrameChannel[currentId];write ("Frame %s[%d]:", DBLookup(m).Name, currentId);write (" Incorrect count: %d", gFrameCounter[currentId]);write (" DLC as in DB: %d", DBLookup(m).DLC);if (gFrameMinDLC.containsKey(currentId))write ("Actual min DLC: %d", gFrameMinDLC[currentId]);if (gFrameMaxDLC.containsKey(currentId))write ("Actual max DLC: %d", gFrameMaxDLC[currentId]);}
}
Access to Node
对于某些应用程序,了解特定节点发送或接收哪些消息非常有用。 可以通过专门的预定义字段访问特定节点的所有消息的 ID,并特别迭代这些字段的内容。
以下字段可用:
Nodename.Tx:包含节点发送的所有消息
Nodename.Rx:包含节点接收到的所有消息
Nodename.ALL:包含节点发送和接收的所有消息
如果多个数据库中包含同名节点,则可以使用数据库名称对其进行限定: DBName::Nodename.Tx。
// 检查节点的所有消息,表明 DLC 正确。
// 在测量结束时在表中汇总消息的 DLC 信息。
// 仅在测量之前或之后使用数据库查找
variables
{// max DLC, min DLC, counter, channel; key is always the idint gFrameMaxDLC[long];int gFrameMinDLC[long];int gFrameDefaultDLC[long];dword gFrameCounter[long];dword gFrameIncorrectCounter[long];
}
on preStart
{dword i;message * m;m.can = 2;// 使用 DB 中定义的默认 DLC 初始化 DLC 映射for (i = 0; i < elcount(PowerTrain::Gateway.TX); ++i){m.id = PowerTrain::Gateway.TX[i];gFrameMaxDLC[m.id] = gFrameMinDLC[m.id] = gFrameDefaultDLC[m.id]= DBLookup(m).DLC;}
}
on message *
{// is the frame one of those transmitted by the node?if (gFrameDefaultDLC.containsKey(this.id)){gFrameCounter[this.id]++;// check if the DLC is correct; if not, remember the minimum// or maximum DLC of the received framesif (this.dlc != gFrameDefaultDLC[this.id])gFrameIncorrectCounter[this.id]++;if (this.dlc < gFrameMinDLC[this.id])gFrameMinDLC[this.id] = this.dlc;else if (this.dlc > gFrameMaxDLC[this.id])gFrameMaxDLC[this.id] = this.dlc;} // else: another node, not interestingoutput(this); // 仅当节点位于测量设置中时使用
}
on stopMeasurement
{message * m;m.can = 2;for (long currentId : gFrameDefaultDLC){m.id = currentId;write ("Frame %s[%d]:", DBLookup(m).Name, currentId);write (" Received count: %d", gFrameCounter[currentId]);write (" Incorrect count: %d", gFrameIncorrectCounter[currentId]);write (" DLC as in DB: %d", DBLookup(m).DLC);write (" Actual min DLC: %d", gFrameMinDLC[currentId]);write (" Actual max DLC: %d", gFrameMaxDLC[currentId]);}
}