OpenPIC timer usage?

Nick Withers nick.withers at
Wed Aug 13 07:58:10 UTC 2014

Sorry, hit "Send" a bit quick...

On Wed, 2014-08-13 at 16:42 +1000, Nick Withers wrote:
> On Tue, 2014-08-12 at 12:48 +1000, Nick Withers wrote:
> > Hullo all,
> > 
> > Has anyone used an OpenPIC timer (see
> > "c/src/lib/libbsp/powerpc/shared/openpic/") in single-shot mode before?
> > I seem to be having some trouble with them, in particular ensuring that
> > an ISR fires only once.
> > 
> > According to "c/src/lib/libbsp/powerpc/mvme3100/README", "The setup
> > routine allows for specifying single-shot or periodic mode", but I can't
> > seem to see how to achieve the former.
> > 
> > Going off
> > "c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/nested_irq_test.c" I
> > should at least openpic_maptimer(..., 0) and openpic_inittimer(..., ...,
> > 0) to stop the timer. I've tried that in the ISR and the
> > openpic_inittimer() call can stall indefinitely in
> > openpic_safe_writefield() on "while (openpic_read(addr=0xe1041120) &
> Turns out the "OpenPIC" on at least the MVME3100 is actually an IBM
> MPIC, which has documentation[1]! Huzzah!
> So, to follow up, neigher openpic_inittimer() and openpic_maptimer()
> need to be called to halt the timer and prevent further interrupts (but
> need to be done to set the timer up before first use).
> An openpic_settimer(..., OPENPIC_TIMER_COUNT_INHIBIT, 0) will do it.
> Also note that for the hardware to latch a new time programmed through
> openpic_settimer(), the OPENPIC_TIMER_COUNT_INHIBIT bit has to
> transition from a 1 to a 0.

So I think I'm driving the timer correctly (but if anyone else's ever
used 'em, a double-check'd be loverly :-P).

Any yet, it seems I'm potentially getting a double-ISR-hit, though I
haven't been able to trigger it reliably; it feels like some kind of fun
race condition.

I've attached a minimised code sample (build with, e.g., "[g]make
RTEMS_ROOT=/home/nick/rtems/rtems-4.11 BSP=mvme3100") which has been
tested successfully (i.e., it shows the failure) through PSim and on
MVME3100 hardware (though it's timing-dependent, so YMMV!). When
mvme3100_timer_set()'s called, it:
  - Asserts that a semaphore's locked*
  - Asserts that the timer's currently stopped
  - printk()s 's'
  - Starts the timer
  - printk()s 'S'
  - Blocks on the semaphore
  - Asserts that the semaphore's locked
  - printk()s '_'
  - returns

The timer's vectored to mvme3100_timer_interrupt() and when this is
called, it:
  - Stops the timer (notionally, anyway! I've stepped through it in GDB
and it seems to work as expected), through openpic_settimer(...,
  - printk()s 'p'
  - Increments the semaphore
  - printk()s 'P'

So I'm expecting, for each '_'-delimited block of text, to see one set
of "s(...)S" for each "p(...)P".

Here's part of a run in PSim:

psim-cmds:5: Error in sourced command file:
No symbol "the_source" in current context.
(gdb) run
Starting program: /usr/home/nick/projects/sem_isr/sem_isr.debug 
warning: failed to reevaluate condition for breakpoint 1: No symbol "the_source" in current context.
OpenPIC Version 1.2 (2 CPUs and 17 IRQ sources) at 0x0C130000
OpenPIC Vendor 0 (Unknown), Device 0 (Unknown), Stepping 0
Overriding NumSources (17) from configuration with 16
OpenPIC timer frequency is 1 Hz
sSpP_sSpP_sSpP_sSpP_sSpP_sSpP_sSpP_sSpP_sSpPpP_assertion "rtems_semaphore_count(timer->semaphore) == 0" failed: file "mvme3100_timer.c", line 207, function: mvme3100_timer_wait

[The reported OpenPIC timer frequency's not valid and certainly not
being honoured in terms of actual timings - this is expected with PSim,
isn't it?]

That's consistent with what I see when running it on MVME3100 hardware
(albeit typically with different interleavings of the ISR / task),
except that there's no obvious double-up (e.g., the "pPpP" just before
the assertion failure, above) - I presume because printk()'s output
isn't guaranteed to make it out to a serial console before the assertion
crashes it...?

I guess it'd be nice for me to provide code that perhaps generates
interrupts in another manner. Would anyone have any suggestions here? is
there an rtems_interrupt_cause()-like that's implemented? Even if there
is it might be hard to get the timings right without a higher-precision

> > Any ideas? Perhaps I'm going about this the wrong way to begin with...
> > What I'm after is a microsecond-precision-ish one-shot timer that'll be
> > used thousands of times per second.
> > 
> > Ta all!
> [1]

* Possibly dodgily: I implemented an rtems_semaphore_count kludge, but
can't claim to actually understand what I did properly. I have observed
the same symptoms using a POSIX semaphore (which to my knowledge isn't
explicitly specified as being allowed in an RTEMS ISR, though ISTR
seeing it somewhere before)
Nick Withers

Embedded Systems Programmer
Department of Nuclear Physics, Research School of Physics and Engineering
The Australian National University (CRICOS: 00120C)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: sem_isr.tar.gz
Type: application/x-compressed-tar
Size: 3998 bytes
Desc: not available
URL: <>

More information about the users mailing list