This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Timer, t1-t0, integral promotion

For ARM7, A hardware timer is 32-bits, and unsigned int is 32-bits too;
For a 16-bits MCU, A hardware timer is 16-bits, and unsigned int is 16-bits too;

So,

t0 = timer_val;
while ( ( timer_val - t0 ) < delay_val );

provide a simple and good delay;

Not so sure about, if a cast is needed.

t0 = timer_val;
while ( (unsigned int)( timer_val - t0 ) < delay_val );

Just noticed that, due to the integral promotion,

unsigned short t0, t1;
( t1 - t0 ) is a signed int.

It seems that,

unsigned int t0, t1;
( t1 - t0 ) is still an unsigned int.

I noticed this, because I use unsigned short to present a 16-bits timer_val on my X86-PC for testing/simulating purpose, and the result is not what I expected.

Parents
  • For Addition, it says:

    Noncompliant Code Example

    unsigned int ui1, ui2, usum;
    
    /* Initialize ui1 and ui2 */
    
    usum = ui1 + ui2;
    

    Compliant Solution (Pre-Condition Test)

    unsigned int ui1, ui2, usum;
    
    /* Initialize ui1 and ui2 */
    
    if (UINT_MAX - ui1 < ui2) {
      /* handle error condition */
    }
    else {
      usum = ui1 + ui2;
    }
    

    ===================================================

    UINT_MAX - ui1 == ui1 ^ UINT_MAX ==> b ^ 0xFFFFFFFF

    ===================================================

    For Subtraction, it says:

    Noncompliant Code Example

    unsigned int ui1, ui2, udiff;
    
    /* Initialize ui1 and ui2 */
    
    udiff = ui1 - ui2;
    

Reply
  • For Addition, it says:

    Noncompliant Code Example

    unsigned int ui1, ui2, usum;
    
    /* Initialize ui1 and ui2 */
    
    usum = ui1 + ui2;
    

    Compliant Solution (Pre-Condition Test)

    unsigned int ui1, ui2, usum;
    
    /* Initialize ui1 and ui2 */
    
    if (UINT_MAX - ui1 < ui2) {
      /* handle error condition */
    }
    else {
      usum = ui1 + ui2;
    }
    

    ===================================================

    UINT_MAX - ui1 == ui1 ^ UINT_MAX ==> b ^ 0xFFFFFFFF

    ===================================================

    For Subtraction, it says:

    Noncompliant Code Example

    unsigned int ui1, ui2, udiff;
    
    /* Initialize ui1 and ui2 */
    
    udiff = ui1 - ui2;
    

Children
  • #define LWIP_U32_DIFF(a, b) (((a) >= (b)) ? ((a) - (b)) : (((a) + ((b) ^ 0xFFFFFFFF) + 1)))
    


    When ( a < b ), max_a is (b-1), min_a is 0,
    the result == a + (UINT_MAX - b) + 1,
    max_result == (b-1) + (UINT_MAX - b) + 1,
    min_result == 0 + (UINT_MAX - b) + 1,
    no wrapping.

  • #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            uint16_t a16 = 0xFFFF, b16 = 1234, r16;
            uint32_t a32 = 0xFFFF, b32 = 1234, r32;
    
            r16 = a16 * b16;
            r32 = a32 * b32;
            printf("r16 = %u\n", r16);
            printf("r32 = %u\n", r32);
            printf( "r32 mod 0x10000 = %u\n", ( r32 % 0x10000 ) );
    
            system("PAUSE");
    }
    


    r16 = 64302
    r32 = 80870190
    r32 mod 0x10000 = 64302

  • #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            int16_t a16 = 32760, b16 = 1234, r16, r16_chk = -9872;
            int32_t a32 = 32760, b32 = 1234, r32;
    
            r16 = a16 * b16;
            r32 = a32 * b32;
            printf("r16 = %d\n", r16);
            printf("r32 = %d\n", r32);
            printf( "r32 mod 0x10000 = %d\n", ( r32 % 0x10000 ) );
            printf( "r16_chk = %u\n", (uint16_t)r16_chk );
    
            system("PAUSE");
    }
    

    r16 = -9872
    r32 = 40425840
    r32 mod 0x10000 = 55664
    r16_chk = 55664

  • Modular arithmetic

    en.wikipedia.org/.../Modular_arithmetic

    (It is too difficult for me, so I simply skip it.)

  • Noncompliant Code Example

    Careful dragging that into this discussion. Compliance to some rules that have been invented, with no particular relation to the language itself---which that's about---s an entirely different issue than the well-definedness of operations specified by the language itself.

    if (UINT_MAX - ui1 < ui2) {
      /* handle error condition */
    }
    

    It is by no means clear that this is even is any kind of "error condition". In the case this thread is about it most decidedly would not be.

    There is absolutely nothing wrong with a 32-bit timer rolling over from a starting point of, say, 0xFFFFFF80 to 0x00000003. Plain and simple subtraction of those numbers yields exactly the elapsed number of counts: 0x00000083. Look, Ma, no error!