CAPL内置的时间函数

CAPL内置的时间函数

在CAPL中我们要经常和时间打交道,为了方便的写CAPL脚本,所以我整理了Vector官方提供的与时间有关的函数,并对常用的进行简单说明。

本文主体部分摘录了Vector的官方文档,做了整理与翻译;另外增加了一些我自己的理解与编写的实际函数 。

一、CAPL中与时间管理有关的函数

Windows和Linux支持这些CAPL功能。Linux下的功能尚未经过全面测试。

FunctionsShort Description
addTimeToMeasurementStartTime计算测量开始的绝对日期/时间加上偏移量
cancelTimer停止一个已经激活的定时器
convertGPSTimestamp将GPS时间戳转换为基于UTC的日期和时间信息
convertTimestamp将时间戳转换为单独的部分
convertTimestampNS将时间戳转换为单独的部分
convertTimestampToNS将以天、小时、分钟和秒为单位的时间戳转换为纳秒时间戳
convertUTCDateToUnixTimestamp将给定的UTC时间和日期转换为UNIX时间戳(自1970-01-01以来的秒数)
EnvVarTimeNS返回环境变量 envVariable 的时间戳(以纳秒为单位)
getDriftDetermines the constant deviation when Drift is set.
getGPSTimeStringCopies a printed representation of the GPS time stamp represented as UTC date and time into the supplied character buffer.
getJitterMax确定设置抖动(Jitter)时允许偏差的上限
getJitterMin确定设置抖动(Jitter)时允许偏差的下限
getLocalTime返回当前日期和时间的详细信息
getLocalTimeString复制当前日期和时间的打印表示
getMeasurementStartTime返回有关开始测量的绝对时间的详细信息
isTimerActive返回值指示特定计时器是否处于活动状态
MessageTimeNS返回以纳秒为单位的时间戳
setDrift为网络节点的计时器设置恒定偏差
setJitter设置网络节点的计时器的抖动间隔(Jitter interval)
setTimer设置一个定时器
setTimerCyclic设置一个周期性的定时器
timeDiff消息之间或消息与当前时间之间的时间差(毫秒)
timeNow提供当前模拟时间[10微秒]
timeNowFloat提供当前模拟时间[10微秒]
timeNowInt64提供当前模拟时间[纳秒]
timeNowNS提供当前模拟时间[纳秒]
timeToElapse返回一个值,该值指示在调用计时器上的事件过程之前还要经过多少时间

二、 获取当前的模拟时间

这里主要介绍 timeNow()timeNowFloat()TimeNowNS() 三个函数,它们的作用几乎相同,主要是返回值类型不同。

2.1 函数: timeNow()

返回当前模拟时间(最长时间:.2^32*10微秒 = 11小时55分49秒672毫秒96微秒)

函数语法
dword timeNow();
函数功能描述

模拟时间(The simulation time)可以与网络接口的硬件结果相关联。这个时间的分辨率取决于所使用的硬件(通常是一毫秒或更好)。

根据硬件配置的不同,模拟时间(The simulation time)可能有两种情况:

  • 将与网络接口计算的消息时间相同。
  • 消息时间将具有更高的准确性(accuracy)
返回值介绍

模拟时间(单位:10微秒)

举例说明

示例代码:

float x;
x = timeNow()/100000.0; //current time in seconds

2.2 函数: timeNowFloat()

这个函数与timeNow()函数功能几乎完全相同,只有返回值类型有点不同,语法如下:

float timeNowFloat();

示例代码:

float x;
x = timeNowFloat()/100000.0; //current time in seconds

2.3 函数: TimeNowNS()

这个函数与timeNowFloat()函数功能相同,提供当前模拟时间,但是以纳秒为单位,语法如下:

float TimeNowNS();

三、获取机器的绝对时间以及测量的绝对时间

这里主要介绍:

  1. getLocalTime()getLocalTimeString() 它们的作用几乎相同,主要是返回值类型不同。
  2. getMeasurementStartTime()addTimeToMeasurementStartTime() 它们通常配合使用,记录测量的绝对时间。

3.1. 函数: getLocalTime()

函数语法
void getLocalTime(long time[]);
函数功能描述

long类型的数组(array)返回当前日期和时间的详细信息。

分布式模式(distributed mode)使用的注意事项:
此函数始终返回用户计算机的本地时间。

函数参数介绍

类型为long的数组(array),至少有9个条目。
数组的条目将填充以下信息:

IndexInformation
0Seconds (0 - 59)
1Minutes (0 - 59)
2Hours (0 - 23)
3Day of month (1 - 31)
4Month (0 - 11)
5Year (0 - xxx, offset of 1900, e.g. 117 = 2017)
6Day of week (0 - 6, sunday is 0)
7Day of Year (0 - 365)
8Flag for daylight saving time (0 - 1, 1 = daylight saving time)

注意: 这个精确度只能到秒,如果需要更高的精确度,则不能使用这个函数。

举例说明

示例代码:

long tm[9];
getLocalTime(tm);
// now tm contains the following entries:
// tm[0] = 3; (seconds)
// tm[1] = 51; (minutes)
// tm[2] = 16; (hours)
// tm[3] = 21; (day of month)
// tm[4] = 7; (month stating with 0)
// tm[5] = 98; (year)
// tm[6] = 5; (weekday)
// tm[7] = 232;(day of year)
// tm[8] = 1; (Summer time)

我写的一个可以格式化当前时间的函数(本文的后面章节中,我会用到这个函数):

// 获取当前时间(精确到秒), 入参保证至少要容纳20个字符
void get_current_Local_Time(char time_str[]){
  long tm[9];
  getLocalTime(tm);
  snprintf(time_str, elcount(time_str), "%04d-%02d-%02d %02d:%02d:%02d",
  tm[5]+ 1900, tm[4]+1, tm[3], tm[2], tm[1], tm[0]);
}

3.2 函数: getLocalTimeString()

函数语法
void getLocalTimeString(char timeBuffer[]);
函数功能描述

将当前日期和时间的打印表示复制到提供的字符缓冲区中。字符串的格式为ddd mmm dd hh:mm:ss jjj(例如"Fri Aug 21 15:22:24 1998")。

分布式模式(distributed mode)使用的注意事项:
此函数始终返回用户计算机的本地时间。

函数参数介绍
参数含义
timeBuffer将写入字符串的缓冲区(buffer)。此缓冲区必须至少有26个字符长
举例说明

示例代码:

char timeBuffer[64];

getLocalTimeString(timeBuffer);
// now timeBuffer contains for example. "Fri Aug 21 15:22:24 1998"

3.3 函数: getMeasurementStartTime()

函数语法
long getMeasurementStartTime(long time[]);
函数功能描述

返回有关开始测量的绝对时间的详细信息。

注意事项:
在CANoe的offline模式下,函数返回日志文件中存储的最早开始时间。

函数参数介绍

只有一个参数time, 它的类型为 long类型的数组(array) ,至少有8个条目。数组的条目将填充以下信息:

IndexInformation
0Milliseconds (0 - 999)
1Seconds (0 - 59)
2Minutes (0 - 59)
3Hours (0 - 23)
4Day of month (1 - 31)
5Month (0 - 11)
6Year (0 - xxx, offset of 1900, e.g. 117 = 2017)
7Day of week (0 - 6, Sunday is 0)
返回值介绍

1 if successful, 0 if not (e.g. array to small).

举例说明

我写的一个获取测量开始时间的函数:

variables
{
  char g_Measure_Start_Time[24];
}

// 获取测量开始时间(精确到毫秒), 存储到全局变量g_Measure_Start_Time中
void get_MeasurementStartTime_Str(){
  long time[8];
  getMeasurementStartTime(time);
  snprintf(g_Measure_Start_Time, elcount(g_Measure_Start_Time), "%04d-%02d-%02d %02d:%02d:%02d",
  time[6]+ 1900, time[5]+1, time[4], time[3], time[2], time[1], time[0]);
}

获取测量开始时间的举例,注意:这里使用到了本文前面部分定义的两个函数:

on key 's'
{
  char temp_local_time[20];
  get_MeasurementStartTime_Str();
  write("Measurement was started on %s",g_Measure_Start_Time);
  
  get_current_Local_Time(temp_local_time);
  write("current time is: %s",temp_local_time);
}

输出结果:

请添加图片描述

3.4 函数: addTimeToMeasurementStartTime()

函数语法
long addTimeMeasurementStartTime(int64 timeSpan, long time[]);
函数功能描述

计算测量开始的绝对日期/时间加上偏移量(例如时间戳)。

函数参数介绍
  • 参数timeSpan : 要添加到测量开始时间的时间,例如测量帧的时间戳。

  • 参数time : 与 getMeasurementStartTime() 函数中的入参完全一致

示例代码:

on errorframe
{
  long time[8];
  addTimeToMeasurementStartTime(timeNowNS(), time);
  write("ErrorFrame occured on %02d/%02d/%02d %02d:%02d:%02d.%-3d",
  time[5]+1, time[4], time[6]-100, time[3], time[2], time[1], time[0]);
  getMeasurementStartTime(time);
  write("Measurement was started on %02d/%02d/%02d %02d:%02d:%02d.%-3d",
  time[5]+1, time[4], time[6]-100, time[3], time[2], time[1], time[0]);
}

// Output e.g.:
// ErrorFrame occured on 08/15/17 14:39:46.787
// Measurement was started on 08/15/17 14:39:29.547

四、时间转换

这里主要介绍 convertTimestamp(), convertTimestampNS() 两个函数。

4.1. 函数: convertTimestamp()

函数语法
void convertTimestamp(dword timestamp, 
                      dword& days, byte& hours, byte& minutes, 
                      byte& seconds, word& milliSeconds, 
                      word& microSeconds);
函数功能描述

将时间戳转(time stamp)换为单独的部分(最长时间:.2^32*10微秒=11小时55分49秒672毫秒96微秒)。

函数参数介绍
参数含义
timestamp以10微秒为单位的时间戳
days接收的时间戳的天数
hours接收的时间戳的小时数(介于0和23之间)
minutes接收的时间戳的分钟数(介于0和59之间)
seconds接收的时间戳的秒数(介于0和59之间)
milliseconds接收的时间戳的毫秒数(介于0和999之间)
microseconds接收的时间戳的微秒(介于0和999之间)

示例代码可以参见函数convertTimestampNS()中的介绍。

4.2. 函数: convertTimestampNS()

函数语法
void convertTimestampNS(qword timestamp, 
                        dword& days, byte& hours, byte& minutes, 
                        byte& seconds, word& milliSeconds, 
                        word& microSeconds, word& nanoSeconds);
函数功能描述

将时间戳转(time stamp)换为单独的部分。

函数参数介绍
参数含义
timestamp以纳秒为单位的时间戳
days接收的时间戳的天数
hours接收的时间戳的小时数(介于0和23之间)
minutes接收的时间戳的分钟数(介于0和59之间)
seconds接收的时间戳的秒数(介于0和59之间)
milliseconds接收的时间戳的毫秒数(介于0和999之间)
microseconds接收的时间戳的微秒(介于0和999之间)
nanoseconds接收的时间戳的纳秒(介于0和999之间)
举例说明

示例代码:

on envVar EnvGearUp
{
   dword d;
   byte h, m, s;
   word ms, us, ns;
   convertTimestampNS(timeNowNS(), d, h, m, s, ms, us, ns);
   write("Gear up at %d days, %d::%d::%d,%d.%d.%d", d, h, m, s, ms, us, ns);
}

五、定时器

这里主要介绍:

  1. setTimer() : 普通的单次定时器。
  2. setTimerCyclic(): 普通的周期性定时器
  3. cancelTimer(): 停止一个定时器

5.1. 函数: setTimer()

函数语法
void setTimer(msTimer t, long duration); // form 1

void setTimer(timer t, long duration); // form 2

void setTimer(timer t, long durationSec, long durationNanoSec); // form 3

如果使用面向对象编程,语法如下:

void msTimer::set(long);
函数功能描述

设置一个定时器

函数参数介绍

Timer or msTimer variable and an expression which specifies the duration of the timer.

举例说明

示例代码:

variables
{
  msTimer t1;
  Timer t23;
  char press_key[4];
  float current_time;
}

void print_current_time(char press_key[]){
  current_time = timeNow()/100000.0;
  write("%s press time: %fs", press_key, current_time);
}

on key F1 {
  print_current_time("F1");
  setTimer(t1, 200); // set timer t1 to 200 ms
}

on key F2 {
  print_current_time("F2");
  setTimer (t23, 2); // set timer t23 to 2 sec
}

on key F3 {
  print_current_time("F3");
  setTimer (t23, 0, 1250*1000 ); // set timer t23 to 1.250 milliseconds
}

on timer t1 {
  write("current_time:%fs, F1 was pressed 200ms ago", timeNow()/100000.0);
}

on timer t23 {
  write("current_time:%fs, F2 was pressed 2 sec ago or F3 1250000 nsec ago", timeNow()/100000.0);
}

输出结果:

请添加图片描述

5.2. 函数: setTimerCyclic()

函数语法
void setTimerCyclic(msTimer t, long firstDuration, long period); // form 1

void setTimerCyclic(msTimer t, long period); // form 2

void setTimerCyclic(timer t, int64 periodInNs); // form 3

如果使用面向对象编程,语法如下:

void msTimer::setCyclic(long firstDuration, long period);

void msTimer::setCyclic(long period);

void timer::setCyclic(int64 periodInNs);
函数功能描述

设置一个周期性的定时器;

对于形式2,firstDuration隐式地与period相同,即计时器精确地根据第一次的period运行。

函数参数介绍
参数含义
tThe timer to be set.
firstDuration计时器第一次用完之前的时间(以毫秒为单位)
period计时器在过期时重新启动的时间(以毫秒为单位)
periodInNs计时器在过期时重新启动的时间(以纳秒为单位)

举例说明

start 中通过setTimerCyclic设置周期性定时器, 示例代码:

variables
{
  msTimer t;
  float current_time;
}
on start {
   setTimerCyclic(t, 10, 20);
}

void print_current_time(){
  current_time = timeNow()/100000.0;
  write("current time: %fs", current_time);
}

on Timer t
{
  print_current_time();
}

输出结果:

请添加图片描述

通过键盘按键,使用setTimerCyclic设置周期性定时器, 示例代码:

variables
{
  msTimer t;
  float current_time;
}

void print_current_time(){
  current_time = timeNow()/100000.0;
  write("current time: %fs", current_time);
}

on Timer t
{
  print_current_time();
}

on key 's'
{
  write("current time: %fs, 'S' key Pressed , start timer", timeNow()/100000.0);
  setTimerCyclic(t, 10, 20);
}

请添加图片描述

输出结果:

5.3. 函数: cancelTimer()

函数语法
void cancelTimer(msTimer t); // from 1

void cancelTimer(timer t); // from 2

如果使用面向对象编程,语法如下:

void msTimer::cancel();
函数功能描述

停止一个已经激活的定时器

函数参数介绍

一个 Timer 或者 msTimer 变量

举例说明

使用cancelTimer()停止普通的定时器,示例代码:

variables {
  float current_time;
  char print_time_info[100];
  msTimer ms_t_key;
  message 0x100 test_msg = {dlc = 1, byte(0) = 0xFF, dir = Tx};
}

void print_current_time(char time_info[]){
  current_time = timeNow()/100000.0;
  write("current time: %fs, %s", current_time, time_info);
}

on Timer ms_t_key{
  output(test_msg);
  setTimer(ms_t_key, 200);
}

on key F2 {
  setTimer(ms_t_key, 200);  // set timer to 200ms
  print_current_time("F2 key pressed, Start timer!!");
}

on key F3 {
  cancelTimer(ms_t_key);    // cancel timer
  print_current_time("F3 key pressed, Cancel timer!!");
}

输出结果:

请添加图片描述

使用cancelTimer()停止周期性的定时器,示例代码:

variables
{
  msTimer t;
  float current_time;
}

void print_current_time(){
  current_time = timeNow()/100000.0;
  write("current time: %fs", current_time);
}

on Timer t
{
  print_current_time();
}

on key 's'
{
  write("current time: %fs, 'S' key Pressed , start timer", timeNow()/100000.0);
  setTimerCyclic(t, 30, 100);
}

on key 't' {
  write("current time: %fs, 'T' key Pressed , Stop timer", timeNow()/100000.0);
  cancelTimer(t);    // cancel timer
}

输出结果:

请添加图片描述

  • 5
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值