[ECOS] DSRs and scheduling thread-context work
Fri Oct 22 20:03:00 GMT 2010
On Fri, 22 Oct 2010, Tomas Whitlock wrote:
> Dear all,
> I have been tasked with porting a driver for a PCI device from VxWorks /
> Linux to eCOS 3.0. While most things look reasonably straight-forward, I
> have a few queries relating to how a driver can schedule work to be done
> in a thread context.
Only in brief
> The ISR of this driver must handle interrupts that originate from
> several distinct sources inside the device being controlled. These
> sources are in reality DMA channels that can run independently of one
> another, but share the same physical interrupt pin for signalling
> completion of DMA. I'd like to be sure that my proposed interrupt
> handling scheme won't lose interrupts.
> Will the following logic work?
> 1. Read interrupt status register in device to sample what interrupt
> sources are currently active. If nothing active, call
> cyg_drv_interrupt_acknowledge and return 0.
> 2. For each active interrupt source set an "active flag" somewhere in
> the device context structure (for use in the DSR).
> 3. Write to the device's interrupt status register to clear the
> interrupt sources that we sampled in step 1.
> 4. Acknowledge the hardware interrupt using
> 5. Return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR.
> 1. If active flag 0 is set,
> clear active flag 0
> do any necessary processing
> 2. If active flag 1 is set,
> clear active flag 1
> do any necessary processing
> 3. ... other sources ...
> n. Return.
> (assume that by design of the driver and hardware, an active flag can
> never transition to "set" while the corresponding DSR processing is
> Now my question is: suppose the DSR is executing any of steps 2 to n-1,
> interrupt source 0 becomes active and the ISR runs to completion. Is the
> DSR guaranteed to be rescheduled even though it is still executing?
> If the answer is 'yes' then everything should be fine.
Of course, if that won't be some king of ISR storm, although DSRs have
been planned (=pended) at the least.
* Threads and Interrupt Handling
* Calling Contexts
> If the answer is 'no', then it seems that even masking the hardware
> interrupt in the ISR and unmasking it right at the end of the DSR isn't
> 100% guaranteed to work correctly...
> Alternatively, maybe I could create multiple interrupt objects using the
> same vector / priority parameters, so that we have one ISR and one DSR
> for each interrupt source in the device. That seems like an odd way to
> do things, though. Is it legal?
> I'm a bit confused about the need for cyg_drv_interrupt_acknowledge. If
> my ISR is called as part of a chain of ISRs because our interrupt vector
> is shared by other devices, shouldn't whoever traverses the chain (i.e.
> not me) call cyg_drv_interrupt_acknowledge? If everyone in the chain
> including me calls it, then the interrupt gets acknowledged multiple
> times, which may be a bad thing. Or is cyg_drv_interrupt_acknowledge
> smart enough to be a no-op in that situation?
This depends on the implementation details in a HAL as the
driver's/kernel's interrupt acknowledge functions in fact call
externC void cyg_drv_interrupt_acknowledge
> It's quite common that a driver has to perform some periodic work in a
> thread context, much like a DSR function. In our case, we want to read a
> hardware monitoring chip periodically, to get temperatures and voltages
> It looks like there has been some effort to "wall off" drivers from
> everything else with their own API, as can be seen from the cyg_drv_*
> functions. However, that API doesn't seem to have generalised timer and
> work-scheduling functionality. So a driver has to use non-cyg_drv_*
> functions. For example, the driver could call cyg_thread_create to
> create a worker thread and have that thread wait on something in a loop.
> If one were coming from Linux or Windows land, one might argue that it's
> a job for a user-mode daemon that periodically makes a special call to
> the driver, but that adds the complexity of having to create a special
> user-mode interface.
>From eCos islet that is a job for an eCos thread.
> I guess I'm wondering why there is this set of cyg_drv_* functions that
> seem to be insufficient for nontrivial drivers. Are there some
> guidelines on what non-cyg_drv_* functions a driver can/should use? Is
> this API going to be expanded in the future? In any case, the
> distinction between a "driver" and any other eCOS module seems a bit
> artificial to me...
I hope you will find answers here as well:
* Calling Contexts
and here (eCos driver "Big picture"):
* Synchronization Levels
I hope my "come-off" will help a bit.
> Thanks in advance for any answers / advice
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
More information about the Ecos-discuss