I don't know how many systems are affected by this problem, but apparently there are still some.  I do know that the reference BSP for the Intel PXA25x processor boards has a problem.  This problem is still biting people because there have recently been questions about it in the Platform Builder newsgroup.

The cause is really quite simple.  A shared resource with nothing to protect it from interrupts during read-modify-write operations.

In this case, there are two sets of code that access the time match register.  One is in OEMIdle() which is called when the scheduler doesn't have any threads to run.  The other is in the system timer Interrupt Service Routine (ISR).

The timer match register (OSMR0) is used with the timer counter register (OSCR) to cause an interrupt to occur when a certain time is reached.  When the two registers contain the same value the interrupt is fired.   The counter register increments with the CPU ocsilator.  Both registers roll over in just under 20 minutes.  Anyone see a coorilation between that rollover and the amount of time that the system halts?

So what is happening in the reference BSP?  The code in OEMIdle is setting the match register by:

 1.  Reading the OSCR value
 2.  Adding something to it
 3.  Then writing it to OSMR0

That makes sense, unless you consider that the interrupts are still enabled.  Imagine that the time interrupt fires just after reading the OSCR and before writing it back.  And maybe we have one or more other interrupts.  If everything goes wrong for us, by the time we write OSMR0, OSCR has incremented past OSMR0.  That means that we must wait until OSCR rolls over to reach a match with OSMR0 and the next system tick occurs.

How can you know if this is happening?  A simple application that outputs the current time and the current tick count can tell you.  If the output indicates that 20 minutes past and the current tick count didn't increment, you have this problem.

How can you fix it?  Disable interrupts while modifying the counter register.

Copyright © 2008 – Bruce Eitman
All Rights Reserved