嵌入式计时器包装

时间:2012-07-25 09:48:18

标签: c timer embedded

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

我已经搜索了许多解决方案,以避免计时器翻滚的问题,但还有一件事让我感到困惑。

目前,我正在使用这种无符号长号的两个补码。

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

其他人已经建议,有必要将t2-t1的结果转换为已签名的实体,然后才能生效,但我无法理解为什么。还有其他任何见解或建议吗?

3 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:0)

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

测试

if ( t2 - t1 >= limit ){
如果当前滴答计数与之前没有包装计时器之间的差异变得大于ULONG_MAX

将会中断,否则它会起作用。

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

答案 2 :(得分: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;
     }
 }