4

consider we're writing a firmware for a baremetal MCU, i.e. no OS. I'm told it's not possible (illegal?) to pass arguments to interrupt handler function?

I can't precisely understand why it is so? What's wrong with this?

PS. is it possible to do in some RTOS-es, embedded Linux etc. or it si fundamentally wrong ?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Mark
  • 1,751
  • 3
  • 14
  • 14

6 Answers6

8

Interrupts. do just that...interrupt. Imagine the doorbell at your home, interrupting you at any particular random time day or night. Can you be expected to at any moment have all the right items in your hand for any particular interrupt that can occur. You have to be able to cook dinner, take a shower, fold the laundry but just BEFORE the doorbell rings you must have exactly the correct items in both hands depending on the person ringing the bell, without any way of knowing they are there or are coming or are about to ring the bell. Not really possible. Same deal here, interrupts come at any particular time, for most processors immediately after the currently executing instruction, the interrupt handler is called, which means every single instruction would have to be trying to perform the foreground application while keeping all the parameters for the interrupt handler, and do all of this in one instructions time.

Now what is possible is with an operating system, or rtos or call it what you will, some layer. To have the real interrupt handler that knows nothing going in and has to figure it out, once it figures out what the interrupt is about to gather info and then call a high level interrupt handler that is passed parameters. Certainly possible and most/many operating systems do it this way.

old_timer
  • 69,149
  • 8
  • 89
  • 168
  • 1
    Good example! Best answer. Put another way: At the bare metal hardware level, there can be no parameters, no return value etc. On platforms such as Linux {and other RTOSes} there is an "interrupt driver" (common code used by all interrupts) that driver (1) typically reads a hardware register to determine which interrupt occurred, (2) using that number as an index software looks up in a table to find the handler function and perhaps parameters. In contrast, tiny chip RTOSes (Cortex M3) do something different in HW, the HW calls a different function for each interrupt – user3696153 Jun 14 '14 at 04:46
5

No parameters can be explicitly passed to an interrupt handler because it is designed to be called by the hardware. Each architecture imposes a particular stack frame when it is called, typically including the saved state of the CPU.

If you also intend to call the interrupt handler from elsewhere in the code, you have either a design flaw, or there is some common code which could be factored out to be shared between the interrupt handler and the algorithmic code.

wallyk
  • 56,922
  • 16
  • 83
  • 148
  • thanks for the replies. If I understood you well, the main point is that an IRQ handler is invoked asynchronously with the program flow and compiler has no idea *when* to pass arguments. – Mark Dec 07 '10 at 03:40
4

The only other thing I'll point out (that hasn't been mentioned so far) is the concept of a "software interrupt" (sometimes called a "trap"), which most processors support.

The idea is that a special instruction causes an exception to take place, and often with a software interrupt, either the opcode causing the exception, or registers set up prior to the exception, can contain values/arguments.

For example, in ARM processors, look up "SWI" or "SVC", depending on your architecture. I believe with the SWI instruction, the lower 8 bits are not part of the opcode - you can fill in whatever you want & pass a value from 0-255 (memory a little fuzzy here).

Unlike a hardware-initiated interrupt, which is totally asynchronous to the code running on the CPU, a software interrupt is synchronous - it occurs when the initiating instruction is executed (barring interrupt masking, nesting, etc.)

Dan
  • 10,303
  • 5
  • 36
  • 53
3

An interrupt handler is called by the hardware. It is "passed" whatever "arguments" the hardware passes it.

That's all there is.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
0

when you setup an interrupt handler using the call below, it looks like the interrupt handler takes some args and returns irqreturn_t. Is this not the same interrupt handler OP is talking about?

int request_irq(unsigned int irq,
                irqreturn_t (*handler)(int, void *, struct pt_regs *),
                unsigned long flags, 
                const char *dev_name,
                void *dev_id);
montezuma
  • 61
  • 1
  • 2
0

You can use shared variables set during normal code flow to affect the behaviour of an interrupt handler the next time it runs. But because you do not call the ISR directly, you cannot pass arguments. It is not a matter of legality, but rather technicality.

eg:

volatile enum
{
    DO_NOTHING,
    DO_A,
    DO_B,
    DO_C

} isr_action ;

__interrupt (SOME_IRQ) myISR()
{
    switch isr_action
    {
        case DO_A :
        {
            // A
        }
        break ;

        case DO_B :
        {
            // B
        }
        break ;

        case DO_C :
        {
            // C
        }
        break ;
    }
}

int main()
{
    // Make ISR do A on next SOME_IRQ
    isr_action = DO_A ;

    for(;;)
    {
        // wait for interrupt
    }
}
Clifford
  • 88,407
  • 13
  • 85
  • 165