Binding and Unbinding

This document describes how device drivers bind and unbind interrupts.

To handle events, the interrupt source and the ISR have to be registered with the OS: this is called binding the interrupt. An interrupt has to be unbound when its use is complete.

Binding

An interrupt source ID is bound with the driver's interrupt service routine. This is done using the function Interrupt::Bind() in the second stage constructor of the physical channel. Interrupt binding can fail if the source has been already used or bound.

TInt DExUartPhysicalChannelH4::DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
    {
    ...
    // Bind the interrupt service routine (ISR) to a specific 
    // interrupt ID. When the ISR is called, the value aPtr,
    // (here this object) is passed as the argument. The ISR 
    // must be a static void function, taking a single TAny* 
    // parameter: void Isr(TAny* aParam). Interrupt::Enable() 
    // must be called to start receiving interrupts. Bind() 
    // returns KErrInUse if the ISR is already bound.
    //
    TInt r = Interrupt::Bind(iIrqId,UartIsr,this);
    if (r!=KErrNone)
        {
        KDBG(Kern::Printf("DExUartPhysicalChannel::Interrupt Binding 
                for UART failed"));
        return r;
        }

    return KErrNone;
    }

Unbinding

An interrupt is unbound by calling Interrupt::UnBind(), which de-registers the interrupt source and routine. This must be done before or during physical channel destruction. Unbinding an interrupt does not disable its source. Interrupts have to be disabled explicitly before unbinding to avoid spurious interrupts.

/**
 Physical channel destructor. Delete and free any objects created and
 allocated by the physical channel. This is called by the    
 framework while unloading the driver (PDD).
 */
DExUartPhysicalChannelH4::~DExUartPhysicalChannelH4()
    {
    // Unbind the UART interrupt. Interrupt::Unbind() frees the  
    // interrupt service routine (ISR) function from the specified
    // interrupt ID.
    // 
    Interrupt::Unbind (iIrqId);
    }