这是使用Kvaser Memorator第二代设备通过kvmlib进行配置和读取记录数据4篇系列文章的第二篇:
技术博客
在配置中添加脚本和触发器
- kvmlib入门指南
- 在配置中添加脚本和触发器
- 深入了解kvmlib
- 使用kvmlib配置SD卡
在第一篇文章中,我们讲述了如何使用kvmlib通过可记录所有内容的简单配置对设备进行设置。现在让我们通过添加一个t程序和一些触发器来增加我们配置的复杂性。全部程序列表可在GitHub上获得。
2.1 准备t程序以添加至配置中
让我们准备t程序,为了测试目的,要生成一些CAN流量并添加到配置中。此脚本实际上是测试的一部分,该测试中我们能够对使用触发器控制记录的开始和结束进行验证。从脚本启动的0.5秒开始,脚本本身每秒发送一条CAN报文。对于每个发送的CAN报文,CAN报文标识将会增加1。在CAN总线上总共可以发送11条CAN报文。
// This script is intended to be used to check a configuration set as:
//
// [ ] Log everything
// [ ] FIFO mode
// Power settings: 5 Time to live after CAN power disconnected, in seconds
//
// CAN 1 should be connected to CAN 2
//
// Triggers:
// CAN1 Trigger1 Timer [4s] : Start logging, post-trigger=0
// CAN1 Trigger2 Timer [7s] : Stop logging, post-trigger=3000
//
// Script sends msg id:
// Id 1 at 0.5s
// Id 2 at 1.5s
// Id 3 at 2.5s
// Id 4 at 3.5s
// Id 5 at 4.5s
// ... and so on until
// Id 11 at 10.5s
variables {
// Base channel. CAN messages will be sent on channel ch and received on
// channel ch + 1
const int ch = 0;
// The singleshot timer is used to get a delay before the first CAN message
// is sent.
Timer singleshot;
// The periodic timer is then used between each CAN message
Timer periodic;
// The message id of the sent CAN messages, will be incremented
int msgId = 1;
// The CAN message to be sent
CanMessage msg;
}
on Timer singleshot {
// Start the periodic timer to send 10 more CAN messages
timerStart(periodic, 10);
// After using the current CAN message id, increment before next use
msg.id = msgId++;
msg.flags = 0;
msg.dlc = 8;
msg.data = "\x12\x21\x13\x31\x22\x34\x41\x15";
// Send CAN message
canWrite(ch, msg);
printf("Single shot MsgId: %d\n", msg.id);
}
on Timer periodic {
// After using the current CAN message id, increment before next use
msg.id = msgId++;
// Send CAN message
canWrite(ch, msg);
printf("Periodic MsgId: %d\n", msg.id);
if (!timerIsPending(periodic)) {
printf("Timer done!");
}
}
on start {
printf("Starting testlogger companion script\n");
// Setup the two CAN channels and go bus on.
// This will override the settings in the binary configuration,
// most notably the channels will no longer be in silent mode.
canBusOff(ch);
canBusOff(ch + 1);
canSetBitrate(ch, canBITRATE_1M);
canSetBitrate(ch + 1, canBITRATE_1M);
canSetBusOutputControl(ch, canDRIVER_NORMAL);
canSetBusOutputControl(ch + 1, canDRIVER_NORMAL);
canBusOn(ch);
canBusOn(ch + 1);
singleshot.timeout = 500; // Wait half a second
periodic.timeout = 1000; // One second period
// Start the singleshot timer to send the first CAN message
timerStart(singleshot);
printf("Start periodic transmission\n");
}
on stop {
printf("Stopping script\n");
canBusOff(ch);
canBusOff(ch + 1);
}
列表7:生成CAN报文的示例t程序
t程序需要在添加到配置之前进行编译。t编译器称为“scc.exe’”,当安装CANlib SDK时通常放在“C:\Program Files (x86)\Kvaser\Canlib\Bin\scc.exe”。如果在没有任何参数的情况下调用,将打印使用帮助。
scc.exe No input file found. Script compiler for Kvaser t-script. This is version 3.3.305 built on Sun Dec 13 19:38:53 2015. Usage: scc [-v -verbose] [-c] [-g] [-dx] [-devlines] [-addsrc] [-comment=XXX] [-pkey=N] [-skey=K] @<filename>] [-dbase=<filename>] <filename> where -c Compile only. No output is produced. -dbase=XXX.dbc Use the database XXX.dbc to define CAN messages in the script. -devlines Supress line numbers in generated code. Generates faster and smaller code, but line numbers cannot be reported in exceptions. -g Generate symbol tables for debug. -addsrc Include the source code. -comment=XXX Include the comment XXX. Note that spaces can be used in arguments "like this". Encryption of script and source code: Script and source are protected by a symmetric crypto (-skey). The symmetric key is then protected by a public key crypto (-pkey). -pkey=N Use Kvaser public key number N. Default: 0 - (no encryption) if no skey is entered 2 - (1024 bit RSA) if a skey is entered -skey=K Use the symmetric key K. If no K is entered and a pkey is, a random key K (hex) will be generated for you Key K formats: -skey=0x11223344FFACAC - Hexadecimal format. -skey=mysecretkey - ASCII format. Contains multiple-precision arithmetic code originally written by David Ireland, copyright (c) 2001-8 by D.I. Management Services Pty Limited , and is used with permission.
我建议你总是使用-comment参数(在描述文本旁保存程序版本号)进行编译,还可以选择 -addsrc,它可将sourcet程序附加到生成的.txe文件。.txe文件可以使用Kvaser TRX打开,它是用于为Kvaser设备开发t程序的轻量级集成开发环境,如果使用-addsrc参数进行编译,源代码将显示在Kvaser TRX内置的.txe检查器的Source选项卡中。如果要隐藏脚本,可以使用加密。
scc.exe myCanGenerator.t -addsrc -comment="My CAN generator program v1.0"
列表8:在添加注释和源代码的同时编译t程序
scc.exe myCanGenerator.t -addsrc -comment="My CAN generator program v1.0" Source size: 2516 bytes Compilation succeeded
2.2 创建配置
现在我们已经编译了t程序“myCanGenerator.txe”,让我们创建一个包含编译的t程序的配置,并设置两个触发器。配置是以XML格式编写的,具体见文档Kvaser Memorator设备配置XML格式规范。我们创建配置,在通道0和1上将波特率设置为1Mbps,在CAN通道0或1上添加CAN报文标识3的触发语句,并在CAN通道1上为CAN报文标识6添加第二个触发语句。我们指定第一个语句应直接开始记录,第二个语句应在延迟2.5秒后停止记录(通过使用posttrigger)。
使用此设置,将CAN 1连接到CAN 2,并要考虑到我们的脚本每秒发送一个CAN报文,预期的结果是捕获CAN报文3到8。日志记录从CAN报文标识3开始,并在CAN报文标识6停止,但是由于我们有一个2.5秒的posttrigger,CAN报文标识7和8也预期在日志文件中结束。
XML配置中特别注意的一个标记是标记BINARY_VERSION,它在创建用于下载到设备的二进制配置时由转换库使用。我们的设备(运行固件版本3.0)应使用二进制配置格式v6.0。
有关XML格式的详细信息,请参阅Kvaser Memorator设备配置XML格式的规范。
<?xml version="1.0" ?>
<!DOCTYPE KVASER>
<KVASER>
<VERSION>2.0</VERSION>
<BINARY_VERSION>6.0</BINARY_VERSION>
<SETTINGS>
<MODE fifo_mode="NO" log_all="NO"/>
<CANPOWER timeout="5000"/>
</SETTINGS>
<CAN_BUS>
<PARAMETERS bitrate="1000000" channel="0" silent="YES" sjw="1" tseg1="5" tseg2="2"/>
<PARAMETERS bitrate="1000000" channel="1" silent="YES" sjw="1" tseg1="5" tseg2="2"/>
</CAN_BUS>
<TRIGGERBLOCK>
<TRIGGERS>
<TRIGGER_MSG_ID can_ext="NO" can_fd="NO" channel="0" msgid="3" msgid_min="3"
name="trigger_0" protocol="NONE" timeout="0"/>
<TRIGGER_MSG_ID can_ext="NO" can_fd="NO" channel="1" msgid="6" msgid_min="6"
name="trigger_1" protocol="NONE" timeout="0"/>
<TRIGGER_MSG_ID can_ext="NO" can_fd="NO" channel="1" msgid="3" msgid_min="3"
name="trigger_2" protocol="NONE" timeout="0"/>
</TRIGGERS>
<STATEMENTS>
<STATEMENT posttrigger="0" pretrigger="0">
<EXPRESSION>trigger_0 OR trigger_2</EXPRESSION>
<ACTIONS>
<ACTION_START_LOG/>
</ACTIONS>
</STATEMENT>
<STATEMENT posttrigger="2500" pretrigger="0">
<EXPRESSION>trigger_1</EXPRESSION>
<ACTIONS>
<ACTION_STOP_LOG/>
</ACTIONS>
</STATEMENT>
</STATEMENTS>
</TRIGGERBLOCK>
<SCRIPTS>
<SCRIPT default_channel="0" primary="YES">
<FILENAME>myCanGenerator.txe</FILENAME>
<PATH></PATH>
</SCRIPT>
</SCRIPTS>
</KVASER>
列表9:XML配置示例
2.3 验证配置
如果发现任何错误,即使从XML配置到二进制配置的转换会失败,我仍然建议使用kvaMemoLibXml显式验证XML配置。当你创建未包含任何表达式以启动日志记录的配置时,此验证会给你警告。调用验证后,我们可以读出检测到的错误和警告的数量,以及每个的代码和文本摘要。
xl = kvaMemoLibXml.kvaMemoLibXml()
print "kvaMemoLibXml version: v" + xl.getVersion()
# Read in the XML configuration file
with open("config.xml", 'r') as myfile:
config_xml = myfile.read()
# Validate the XML configuration
xl.kvaXmlValidate(config_xml)
# Get number of validation messages
(countErr, countWarn) = xl.xmlGetValidationStatusCount()
print "Errors: %d, Warnings: %d" % (countErr, countWarn)
# If we have any validation errors, print those
if countErr != 0:
code = -1
while code != 0:
(code, text) = xl.xmlGetValidationError()
print "%d: %s" % (code, text)
# If we have any validation warnings, print those
if countWarn != 0:
code = -1
while code != 0:
(code, text) = xl.xmlGetValidationWarning()
print "%d: %s" % (code, text)
# Exit if we had any validation errors or warnings
if countErr != 0 or countWarn != 0:
raise Exception('Please fix validation Errors/Warnings.')
列表10:验证XML配置
这篇文章对配置增加了的一些复杂性,在下一篇文章,我们将回到kvmlib,看看如何调用kvmlib在C语言API级别运行。