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.
If you analyze the code sample carefully, you'll note how it gracefully handles the overflow issue.
I don't note, because it doesn't. It causes signed integer overflows every time the TIMER_VALUE is bigger than int32_t variables can hold --- which it is 50% of the time.
What that code does is it assumes signed arithmetic overflows cleanly. It doesn't do anything to handle the possibility it might not.
Exactly. This was meant by design. I think you'll struggle to find an ARM compiler where 'signed arithmetic does not overflow cleanly.' In fact, I don't think one exists. Of course, it should be easy to add some protection against the unlikely event in the form of an assertion. I consulted the C99 standard. Indeed, it does not specify the behavior of a signed integer overflow, while it does for unsigned.
The standard two-complement arithmetic can really be assumed.
I do not thing any new chip vendor would dare to implement a different alternative because they would not save any transistors but would instead get into a shitload of problems.
The two-complement form really is trivial to implement in hardware (and a not too uncommon exercise for students to implement using VHDL or similar), both when having a very strict transistor count, and when having to implement an extremely wide ALU.