Hello,
I have a free running hardware timer on a LPC2478 (timers are 32 bit). no interrupts related to that timer are used.
can the following code corrupt the value latched from the hardware timer, if the timer ticks just when the copy is done? can it cause a misbehavior of the loop? I know this is not a good programming example - I'm just curious.
unsigned long timer_value_ref = T2TC ; do { } while (T2TC - timer_value_ref < 1000) ;
is this something built into the architecture itself?
The capability for it is built into the architecture - an ARM core can read a 32-bit value to a register with a single read access to memory.
This is different from, say, an 8051 which needs multiple read accesses to move 16- or 32-bit values to its registers. In this case, consider the following scenario:
Cycle n Timer value: 0xFFFFFFFF CPU reads byte0: 0xFF
Cycle n+1 Timer value: 0x00000000 CPU reads byte1: 0x00
Cycle n+2 Timer value: 0x00000001 CPU reads byte2: 0x00
Cycle n+3 Timer value: 0x00000002 CPU reads byte3: 0x00
So the CPU read the value 0x000000FF, which is clearly wrong. An ARM MCU would read the full 32 bits in the first cycle, 0xFFFFFFFF.
or is it a result of the generated assembly?
Well, the compiler could technically, theoretically, read the 32-bit value with multiple read accesses (2 if it reads 16-bit halfwords, 4 if it reads 8-bit chars), but that would be a fairly evil compiler, since there's only disadvantages to doing so (takes longer than a single 32-bit read and creates the possibility of atomicity issues).
do you mean that reading the value of a hardware timer prevents it from being updated by hardware?
If there's only a single 32-bit read, then the read value should be valid even if an update happened on the timers side. (Unless it's a borked timer implementation that's prone to glitches in the register, but that should be documented in the datasheet).
thank you very much for your explanations.
Just a note. If the ARM core/memory interface requires that the compiler switches to multiple smaller read/write operations for unaligned accesses, then you must not request that the compiler packs data that gets accesses from multiple threads or from application loop and ISR. The default is of course that the compiler do not pack the data.