OpenPIC timer usage?
Nick Withers
nick.withers at anu.edu.au
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) &
> > OPENPIC_ACTIVITY);".
>
> 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(...,
OPENPIC_TIMER_COUNT_INHIBIT, 0)
- 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
Starting...
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
timer.
> > 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]
> https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/F27971551C9EED8E8525774A0048770A/$file/mpic_db_05_16_2011.pdf
* 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: <http://lists.rtems.org/pipermail/users/attachments/20140813/4822cb5d/attachment-0002.bin>
More information about the users
mailing list