This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: AW: help needed: interrupt + semaphore


>>>>> "Gary" == Gary Thomas <gthomas@ecoscentric.com> writes:

    Gary> On Tue, 2002-08-20 at 04:56, Edelmann Thomas wrote:
    >> But this doesn't solve the problem. The ISR is always called,
    >> but then nothing happens, no DSR, no INTThread.
    >> 
    >> Knows someone something else?

    Gary> You need to start the scheduler, otherwise nothing else will
    Gary> happen - the threads won't run and the DSR will never be
    Gary> called.

Not quite true. See infra/current/src/startup.cxx, there is an
implicit call to Cyg_Scheduler::start() once cyg_user_start() has
returned, assuming the kernel is present. You can start the scheduler
inside cyg_user_start() if you really want to, but typical
applications are not going to gain anything.

However you are right that cyg_user_start() must not enable
interrupts - and at this point there may well be a clock interrupt
pending, not to mention some other interrupts. I am not quite sure
just what could go wrong if DSRs started running that early.

I assume the hardware is some sort of edb7xxx variant, and I am not
really familiar with that hardware. My first guess would be that the
FPGA hardware (or possibly some other interrupt source) is
interrupting continuously, so the system is spending all its time
running ISRs and never gets a chance to run a DSR or thread. Possibly
the interrupt mask hardware or HAL macros are misbehaving. A logic
probe may prove helpful here, as would a gdb breakpoint on the kernel
function interrupt_end().

>>>>> "Robert" == Robert Cragie <rcc@jennic.com> writes:

    Robert> I do it like this and it works for me:

    Robert> static cyg_uint32 intE1ISR(cyg_vector_t vector, cyg_addrword_t data)
    Robert> {
    Robert> 	cyg_interrupt_mask(vector);
    Robert> 	cyg_interrupt_acknowledge(vector);
    Robert> 	return CYG_ISR_CALL_DSR;
    Robert> }

    Robert> static void intDSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
    Robert> {
    Robert>     cyg_semaphore_post(&semEINT1);
    Robert>     cyg_interrupt_unmask(vector);
    Robert> }

    Robert> I also commented that cyg_interrupt_acknowledge() must be
    Robert> called in the ISR - the docs. seem to say this must be
    Robert> done.

The effect of cyg_interrupt_acknowledge() is somewhat
hardware-specific, but typically it tells the interrupt controller
that the interrupt has been processed so the appropriate bit in the
interrupts-pending register can be cleared. The exact interaction
between the pending and mask registers depends on the hardware.
Calling cyg_interrupt_acknowledge() in the ISR is nearly always the
right thing to do.

Re. the mask and unmask, that depends on the device and the
application. If you can handle another interrupt for the same device
straightaway, e.g. because bytes arrive one at a time and there is
plenty of buffer space left, then there is no need to mask the
interrupt at all. If you cannot handle another interrupt until after
the DSR, mask the interrupt source in the ISR and unmask it at the end
of the DSR. If some work is needed at thread level, mask in the ISR
and unmask in the thread.

Bart

-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]