[ECOS] DSRs and scheduling thread-context work

Sergei Gavrikov sergei.gavrikov@gmail.com
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.

Hi Tomas,

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.
>
> First:
>
> Will the following logic work?
>
> ISR:
> 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
> cyg_drv_interrupt_acknowledge.
> 5. Return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR.
>
> 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
> happening)
>
> 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.

- Yes

Of course, if that won't be some king of ISR storm, although DSRs have
been planned (=pended) at the least.

See, please,

   http://ecos.sourceware.org/docs-latest/ref/kernel-overview.html

Sections:

   * 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?
>
> Second:
>
> 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
HAL_INTERRUPT_ACKNOWLEDGE macro.

   hal/common/v3_0/src/drv_api.c:
   externC void cyg_drv_interrupt_acknowledge

   kernel/v3_0/src/intr/intr.cxx:
   Cyg_Interrupt::acknowledge_interrupt

> Third:

> 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
> etc.
>
> 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:

   http://ecos.sourceware.org/docs-latest/ref/kernel-overview.html

   * Calling Contexts

and here (eCos driver "Big picture"):

   http://ecos.sourceware.org/docs-latest/ref/devapi-device-driver-interface-to-the-kernel.html

   * Synchronization Levels

I hope my "come-off" will help a bit.

Sergei

> Thanks in advance for any answers / advice
> Tom

-- 
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 mailing list