interrupt handling by C code - c

I am trying to disable interrupts through C code but stuck at request_irq(). One argument to request_irq() is flag and SA_INTERRUPT flag is now deprecated. Can anyone tell me alternative to SA_INTERRUPT?. I am using kernel version 3.8.
Any other alternative to request_irq() for disabling interrupts?

request_irq() does not "disable" an interrupt. It is called by a driver that wants to attach an interrupt service routine to an IRQ. The flag is IRQF_SHARED if the interrupt is shared or 0 otherwise.
Here is an example from a driver for Realtek 8169 PCIe network adapter: http://lxr.free-electrons.com/source/drivers/net/ethernet/realtek/r8169.c
retval = request_irq(pdev->irq, rtl8169_interrupt,
(tp->features & RTL_FEATURE_MSI) ? 0 : IRQF_SHARED,
dev->name, dev);
In the example above, rtl8169_interrupt is the interrupt service routine (ISR) that will be invoked each time an IRQ is raised.
It is the job of the ISR to find out if the interrupt was indeed fired by the "owned" device (relevant for shared interrupts) then if the device indeed fired the interrupt, the ISR reads interrupt status then clears the interrupt.

Related

linux disable_irq() and local_irq_save()

I have a piece of code where there is:
disable_irq(irq_clk);
local_irq_save(flags);
I found that the disable_irq() disables a specific interrupt, on the other hand local_irq_save() disables all the interrupt.
So I wonder the meaning of the above code.
This makes sense, because interrupts are disabled at different levels.
disable_irq(irq_clk);
This code disables (masks) interrupt in interrupt controller. If you have disabled interrupt at this level, the interrupt wouldn't be passed to internal interrupt controller pipeline. It would not be prioritized, it would not be routed to the destination CPU.
local_irq_save(flags);
This code disables all interrupts at the level of CPU IRQ interface. Interrupts are passed to CPU IRQ interface after they have passed priority & routing pipeline of the interrupt controller and have been asserted to the CPU.

interrupt flag vs interrupt pending bit stm32

I'm using the std library. I don't know what the difference between I2C_FLAG_TXE and I2C_IT_TXE is.
Why when in interrupt function we don't use I2C_ClearFlag instead I2C_ClearITPendingBit? When do we used I2C_ClearFlag?
I'm starting learn stm32f4. I have very little experience.
I'm using the std library. I don't know what the difference between
I2C_FLAG_TXE and I2C_IT_TXE is.
From the processor point of view - the interrupt flag which has to be cleared by interrupt routine is set when the processor enters the interrupt.
Interrupt pending flag - indicates that the event which triggers the interrupt occurred but for some reason the interrupt routine has not been invoked yet.
It is good to know your hardware before using any libraries.

ARM Cortex M NonMaskable Interrupt is NonClearable also?

I am working with a very custom and not public Secure IC which has ARM Cortex M3 core.
In case of hw security violation, this IC triggers an NMI interrupt so it is fine, I am doing whatever I need for violation.
But It always enters into NMI Handler again and again when a violation is occurred.
We probably need to clear interrupt pending flag not sure but it should be cleaned directly.
Because SCB->ICSR bit31 says that "entering the handler clears this bit to 0".
I also tried to clear pending flag using NVIC_ClearPendingIRQ() but it does not accept negative IRQ values while NMI is -14.
I tried to set manually NVIC->ICPR[0] = (1 << 2); like as manufacturer examples (but manufacturer example resets device in NMI handler which is different case) but it does not work.
It is custom IC and custom external event which triggers generic Cortex M NMI interrupt and can be a specific case to IC but is there any limitation for NMI like "you can not clear NMI pending flag and you have to reset it bla bla"?
Thank you
The NMI is acting just like any other interrupt here.
From the Cortex-M Generic Device User Guide:
For a level-sensitive interrupt, when the processor returns from the ISR, the NVIC samples the interrupt signal. If the signal is
asserted, the state of the interrupt changes to pending, which might
cause the processor to immediately re-enter the ISR. Otherwise, the
state of the interrupt changes to inactive.
For a pulse interrupt, the NVIC continues to monitor the interrupt signal, and if this is pulsed the state of the interrupt changes to
pending and active. In this case, when the processor returns from the
ISR the state of the interrupt changes to pending, which might cause
the processor to immediately re-enter the ISR.
What this is saying is that unless you clear the hardware state which is generating the interrupt request, the interrupt will pend again.
Clearing the interrupt pending state only allows you to disable an IRQ if the request has already been cleared.
For details on how your secure device operates, you need to speak to your vendor. They may be unhappy about you discussing their product here...

ARM Cortex-M4 Interrupt priorities

I'm using an ARM Cortex-M4 MCU. If I have an interrupt handler for a GPIO at priority 2 and an SPI driver at priority 3 (i.e., lower priority than the GPIO's), and I call a (blocking) SPI read from within the GPIO's interrupt handler, will the SPI function work?
The answer to your question depends on how it is blocking to handle the transfer, as #Notlikethat said.
If your SPI driver is a polling driver, then it will most likely work. In this case, your GPIO interrupt would spin on flags within the SPI peripheral, waiting for each part of the transfer to complete.
If your SPI driver is interrupt driven, then it will not work. Since you are executing a priority 2 interrupt (GPIO), the priority 3 interrupt (SPI) will not execute until the GPIO interrupt finishes. Depending on how your SPI driver is written, this may entirely hang your system, or it may result in a timeout.
If your SPI driver is DMA driven, then the answer is not so clear and depends on how the driver works. It is possible in this case, that your transaction would complete, but if the function has blocked waiting for a DMA interrupt, it may never arrive depending on its priority.
In any of the above cases, it would generally be considered not a good idea to do something like that inside of an interrupt. If you have an RTOS, you could use a high priority task that is waiting on a semaphore to execute the SPI transaction, or if the OS supports it, used deferred interrupt processing. If you aren't running with an RTOS, I would consider if there is a way you can signal a lower priority interrupt (i.e use PendSV at the lowest priority) or monitor a flag from within the main process. Using a lower priority interrupt, you can still preempt the main process (if that's what is needed), but all your other interrupts can continue executing. If you can monitor a flag in your main process, then that would also allow your interrupts to continue, but if you are time constrained, this may not be as possible (again, depending on how your application is structured)

Sysfs GPIO level-triggered interrupts

I'm a newbie trying to get level triggered interrupts on an embedded linux board. I'm using poll() to wait for the interrupt event. I was successful in getting edge triggered interrupts.
How can I get level-triggered interrupts?
What do I set the edge to?
The falling or rising transition triggers edge-triggered interrupt. Though polling is an option to handle such interrupts, to save CPU cycles, create a thread that can be scheduled by kernel to sleep until interrupt happens, and wake it up when the interrupt happens. In this way, the main program does not get locked in polling.
The interrupt line is at a high or low level for level-triggered interrupt. Concept of edge does not apply for level-triggered interrupt. Here the CPU shall scan the devices to find the one who triggered the interrupt. Once the device is serviced, it will continue to recheck the interrupt line status for other devices that may need the service(interrupt sharing). If this is not immediately Acked(cleared/handled), the system can go into a hanging state due to repeated/continuous calling of interrupt handler attention. That is, the external device shall assert the IRQ signal until the pending interrupt is cleared by software in-terms of writing to the device register. If many devices have triggered IRQ signal, the high or low level will be present until all the device drivers have serviced their respective devices. So, this should be handled immediately.

Resources