How to deal with a wrapping counter in embedded C

后端 未结 11 878
时光取名叫无心
时光取名叫无心 2021-02-05 14:23

I need to deal with a counter that gives me ticks for my application. The counter is 32bits so what i need to know is how to deal with it when it wraps. for example:

I h

相关标签:
11条回答
  • 2021-02-05 14:50

    If you use unsigned variables to store your counter and timer expiry time, then you can simply use this test:

    if (current_time - expiry_time < 0x80000000UL)
        /* timer has expired */
    

    This assumes that you test for expiry at least once every 0x80000000 ticks, and that your longest timer is set to expire less than 0x80000000 ticks into the future.

    0 讨论(0)
  • 2021-02-05 14:53

    As you are embedded, you may have access to a CPU overflow bit. This would be set when an add overflows it's register. Useful for add AddCarry chaining.

    0 讨论(0)
  • 2021-02-05 14:55

    If you take two timestamp readings and your first reading is greater than the second, then your counter has wrapped. That is the basic way to detect a wrapping counter.

    This, however, won't detect if a counter has wrapped multiple times, or the case where a counter has wrapped and happens to be greater than the first reading. Since you said this was an embedded system and your description makes your "counter" sound like a clock, see if you can set an interrupt to fire whenever the clock reaches zero (so that you will get an interrupt every time the clock resets). When this interrupt fires, increment a separate counter. This should effectively add extra precision to your clock and allow your counter to wrap without causing problems.

    0 讨论(0)
  • 2021-02-05 14:57

    One of the possibilities is to cast both variables to 64-bit long and then do sum. After that compare with maximum 32-bit value to identify if it's wrapped.

    0 讨论(0)
  • 2021-02-05 15:01

    The question is a bit vague. One possibility is to set a flag when you first notice that the time has elapsed. A surefire way would be add a second counter which is incremented when the first counter overflows. This will in effect create a 64 bit counter which won't overflow.

    0 讨论(0)
  • 2021-02-05 15:06

    It will not matter so long as the difference between the start and end count is less than (2^32)/2, and assuming 2's complement 32bit arithmetic is performed (almost universally true), even if the count value spans the wrap-point. For example:

    Start count: 0xfffffff
    End Count:   0x00000002 (incremented through 0,1,2 - i.e. three counts)
    
    End - Start == 0x00000002 - 0xfffffff == 0x00000003
    

    So the right answer is achieved so long as the counter is the bit width of a built-in integer type, and that type is used. Where perhaps a counter register is not the width of a built-in integer type, you can achieve the same effect by masking the higher order "overflow" bits.

    If you need the larger count for other reasons or if the difference between successive timestamps is too large, then you can simply use another integer that is incremented when the lower-order counter wraps. This integer will form the high order bits of a larger integer, so the LSB of the second integer is the 33rd bit of this larger integer.

    0 讨论(0)
提交回复
热议问题