OpenPIC timer usage?
Nick Withers
nick.withers at anu.edu.au
Thu Aug 14 00:39:42 UTC 2014
On Wed, 2014-08-13 at 10:31 -0400, Gedare Bloom wrote:
> I'm not a powerpc expert, but I have some questions for you to
> consider.
Thanks for taking the time, much appreciated.
> How long does it take the openpic_settimer() to take effect?
> If the isr was delayed, could another timer interrupt fire before
> setting the inhibit bit? Will both interrupts be received? This is
> hw-dependent, and I don't know the answer for powerpc.
Interestingly, my interpretation of the MPIC manual (2.3, from points 5
particularly) seems to suggest I should see two interrupts if I break at
my interrupt handler (after IACK, before End-of-Interrupt) before the
openpic_settimer(), if the timer would fire again. I don't... But there
are a few layers between my handler and the hardware and no doubt I just
dont understand it properly.
> Perhaps the
> powerpc ISR_Handler clears the interrupt source before calling the
> isr, so there might be time for another timer to fire? Or perhaps the
> hardware buffers multiple interrupts received from the same source. If
> so, then you would need to acknowledge the interrupt after clearing
> the inhibit bit, so another interrupt that was queued from the same
> source doesn't fire.
I think all this might indicate that it's in not-trivial-to-solve
territory for me and I might go back to using the MPC8540's timers.
Thanks for your time!
> -Gedare
>
> On Wed, Aug 13, 2014 at 3:58 AM, Nick Withers <nick.withers at anu.edu.au> wrote:
> > 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)
> >
> > _______________________________________________
> > users mailing list
> > users at rtems.org
> > http://lists.rtems.org/mailman/listinfo/users
--
Nick Withers
Embedded Systems Programmer
Department of Nuclear Physics, Research School of Physics and Engineering
The Australian National University (CRICOS: 00120C)
More information about the users
mailing list