5

目前,我正在从事一个嵌入式项目,其中大多数子系统都基于时序。

我已经寻找了许多解决方案来避免计时器翻转的问题,但有一件事仍然让我感到困惑。

目前,我正在使用 unsigned long 这样的二进制补码。

ulong t1 = tick of last event;
ulong t2 = current tick;
if ( t2 - t1 >= limit ){
 do something
}

其他人建议,有必要将 t2-t1 的结果转换为签名实体,然后才能工作,但我不明白为什么。还有其他见解或建议吗?

4

3 回答 3

2

有时我会这样做:

ulong t1 = tick of last event;
ulong t2 = current tick;

if ( t1 > t2 ){
    if ((ULONG_MAX-t1+t2+1)>=limit){
       do something
    }
} else {
if ( t2 - t1 >= limit ){
    do something
}
于 2012-07-25T20:51:58.220 回答
0

如果保证t2在概念上总是大于t1,则强制转换为已签名实体将是错误的。标准保证无符号整数的算术是正确的模数,因此当计算为s时UTYPE_MAX + 1,差异t2 - t1将是正确的模数。转换为签名实体时,如果值在目标类型中不可表示,则行为由实现定义。通常这会将大的正值转换为负值。ULONG_MAX + 1unsigned long

考试

if ( t2 - t1 >= limit ){

如果当前滴答计数与前一个不带计时器的滴答计数之间的差异大于ULONG_MAX,则会崩溃,否则它会起作用。

但是,如果t2可以早于t1,则真正的差异t2 - t1将是负数,但作为unsigned long,它可能是一个很大的正数。然后,在使用无符号类型不能正常工作的情况下,转换为有符号类型可以正常工作。

于 2012-07-25T09:59:16.867 回答
0

您不必将其强制转换为已签名。如果“做某事”是警报处理代码,限制是时间间隔。

定期间隔的最佳做法是:

 ulong next_alarm_ticks = 0;

 void poll_alarm()
 {
     if (get_ticks() - next_alarm_ticks < ULONG_MAX/2) { 
         // current time is "greater" than next_alarm_ticks
         handle_alarm();
         next_alarm_ticks += alarm_interval;
     }
 }
于 2012-07-25T10:01:56.030 回答