I'm seeing some strange quantization when I sample OSClock 0 (OSCR0) in a tight loop.  (I'm using memory mapping like that used in the gpregs (GPIO) sample code.)

According to the PXA270 documentation, OSCR0 ticks at 3.25 MHz; I've confirmed that via manual timing of busy code running for several minutes.

However, when I sample OSCR0 in a tight loop, over 1000 samples the clock ticks an average of 3.5 times between samples - just over 1 microsecond per sample (removing the very few anomalous samples when Linux was obviously busy doing something else.)

I'm running the test on an XM4; at 400 MHz, I'd expect to loop more than a few times recording the same clock value before seeing the clock change; instead, it appears that over 400 instruction cycles have gone by between samples.

Here's the core of the test (OSCR0 is defined as 0x40A00010):


    for (i = 0; i < N; i++) {
        times[i] = getmem(OSCR0);

    for (i = 0; i < N; i++) {
        printf("%u\n", times[i]);

Here's the result for N = 10:

# ./clock

Here's something else that's funny: if you remove the first getmem(OSCR0), the sample values never change, even over 3000 samples.

I've pored over the PXA270 Processor Developer's Manual looking for an explanation.  The closest I've come is an isolated remark that OSCR0 ticks at 3.25 MHz "with a resolution of 1 microsecond" - but no explanation of what that means.  I'd still expect to see a number of samples go by without changing before seeing a change - even if that change averages 3.25 ticks.  Instead, it appears that the act of looking at OSCR0 causes the program to hang for ~1 usec.

I'm seeing almost the same behavior when running a uboot standalone app which directly accesses OSCR0 (instead of via memory mapping).

----- Original Message ----
From: pvm <pvmorici@gmail.com>
Sent: Saturday, December 22, 2007 2:23:31 PM

Grahame Jordan wrote:
> Mmmmm? Where, who? That is just nuts - 20ms. Anyone would think that
> usleep(1) would sleep 1us?

Is what you are doing in kernel or user space?  If you want very acurate
delay times you should use the udelay function in the kernel.  Since the
idea of sleeping means the process will be taken off the run queue for some
amount of time it makes sense that the sleep times would have to be in
denominations of the scheduling time slice.

If you want acurate delays in user space you could write your own delay loop
in asm using some instruction that has a known number of clock cycles etc...
gumstix-users mailing list