Interrupt handling Free RTOS + ARM cortex A9 - arm

I have implemented Interrupt handling for Free RTOS running on ARM cortex A9 ( Zedboard). I am facing the following problem.
I am able to see that the interrupt line is being raised ( by checking spi_status register for the corresponding interrupt)
But the interrupt is not being caught by Free RTOS
I also see this condition, I can see that for my interrupt the set-enable ( ICDISER) bits are set, but when i raise the interrupt line for that corresponding interrupt, The set enable bits are getting reset. I raise my interrupt when a Free Rtos task is running. This is quite weird and I do not know why the Set-enable bits for that interrupt is being reset when I raise my interrupt line. Any ideas would be appreciated?
I know this question is quite specific to Free rtos, but i am actually un-aware why the set-enable bits for the interrupt is being reset ( quite weird in my opinion), so does not any one know why this happens?
Regards,
N

Related

What happened when I clear the interrupt flag before entering the interrupt handler?

Let say an interrupt (interrupt 1) happens while I am in an ISR for another interrupt (interrupt 2) with the same or higher priority. Then before exiting the current ISR, I clear the interrupt flag of interrupt 1. Will the interrupt handler of interrupt 1 still be executed or interrupt 1 will be ignored?
For context, I am using STM32 microcontroller.
Thank you
AFAIK from the past experience of other CPUs, you loose the interrupt.
In such a case before clearing the interrupt 1 flag:
simply read the interrupt 1 flag bit and store it temporarily
clear the interrupt flag (in some CPUs reading it, clears it automatically)
at the end of the interrupt 2 check the stored bit
if it is not set, just leave interrupt 2 routine
if it is set and both interrupts have same priority (or it does not matter!):
just jump/call the other interrupt 1 routine ("stay" in interrupt 2 routine execution)
if it is set and interrupt 1 has not the same priority and you really have to assign it the proper one:
then it gets difficult, here some options:
once I forced the cpu to trigger an other unused interrupt 3 of the same priority like interrupt 1, so using interrupt 3 to execute "interrupt 1" routine
build the interrupt priority handling in code as far as you need it and can, using above trick and more...
PS: This should be described in the manual of the processor, whether clearing the interrupt bit will loose its execution - mostly yes, the interrupt bit is simply a "interrupt pending" bit. It's sometimes not easy to find the description, but daily business.

Disable IRQ on STM32

Is there any way to disable all irq from Cortex M3 MCU except one ?
My issue is that I have a system running several kinds of irq with various priority levels and I want to disable all irq except one in a particular state.
I know I can disable all irq by using "__disable_irq()" instruction but I can't enable one irq after calling this instruction if I didn't call "__enable_irq()" before.
Thanks for your help,
Regards
Use the BASEPRI register to disable all interrupts below the specified priority level.
This is a core register, described in the Cortex-M3 Programming Manual.
CMSIS provides the __get_BASEPRI() and __set_BASEPRI() functions to manipulate its value.
Note that bits 7-4 are used, the priority value must be shifted left by 4. To disable all interrupts with priority 1 or lower, use
__set_BASEPRI(1 << 4);
and to enable all, set it to 0
__set_BASEPRI(0);
You should of course set interrupt priorities accordingly, ensuring that no other interrupt has priority 0.
Other than by disabling all the enabled interrupts you don't want, no.
__disable_irq() is implemented as CPSID I, which turns off all exceptions which can have a priority set (those configured in the NVIC), it achieves this by changing the PRIMASK register (setting bit 0) within the CPU. There is no way to tell this to only enable a specific interrupt.

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.

x86 hardware Interrupt is not working on qemu

I'm writing a kernel (using qemu to simulate) for x86 as a school project and I ran into weird problem.
Even though I have set the interrupt flag in the eflags register, I'm sill not getting any clock interrupts (I checked with qemu info register command and I see eflag=0x292 which means it is set).
To be precise when I run a spin test (while(1); program) in user mode, I get one clock interrupt, but after that one, it stops, qemu does not seems to simulate more! did it happen to anyone else? Is there another mechanism that can affect interrupts?
Anyone have a clue?
Shai.
Apparently in x86, you have to acknowledge clock interrupts after each one.
I.e one must sent an acknowledgment to the lapic after every clock interrupt.
If you are expecting interrupts from the RTC, you must acknowledge the previous interrupt first by reading from REG_C (CMOS register 0x0C).

Cortex: NVIC, please demostrate how to make it level or edge detects by software

I have read the ARM document about Cortex-M3 (or M0) and it say it can be used as level sensetive or pulse (edge) interrupt within the NVIC controller. The problem that it rather vague on how to do this, if this is done by software.
I fails to see any kind of register within the NVIC or such that control the type of the interrupt (to select edge or level by adjusting the register bits). So something must be done by software within handler but again it vague in this field.
I like to hear anyone having a way to make it edge or level trigger interrupt by software.
Please demonstrate within the handler code (if this control it) that the make it detect for level or pulse.
If this is level detect, I can hold interrupt active and disable by the handler, until restore by external code for which it re-excute the interrupt. This is what I'm trying to do, but it will not work if this is pulse detect type.
Thx
A document that describes how the Cortex-M3 NIVC handles level or edge (pulse) triggered interrupts can be found here:
Cortex-M3 Devices Generic User Guide, 4.2.9. Level-sensitive and pulse interrupts
This may well be the document you refer to in your question. Joseph Yiu's book, "The Definitive Guide to the ARM Cortex-M3" also has a pretty good description.
There is no particular configuration of the NVIC for these two interrupt signal types - it handles either kind. Essentially, when an interrupt is asserted (whterh level-based or edge triggered) the NVIC latches that status in the SETPENDx register. When the ISR for that interrupt is vectored to, the corresponding bit in the ACTIVEx register will be set and the bit in the SETPENDx register will be cleared.
While the interrupt is active, if the interrupt line transitions from inactive to active, the pending bit will be turned on again, and upon return from the current active ISR instance, the interrupt will be handled again. This handles the edge triggered interrupt case.
Also, when the ISR returns (and the NVIC clears the 'active' bit), the NIVC will reexamine the state of the interrupt line - if it's still asserted it will set the pending bit again (even if there hasn't been a a transition from inactive to active). This handles the case where an interrupt is level triggered, and the ISR didn't manage to cause the interrupt to be de-asserted (maybe a second device on a shared IRQ line asserted its interrupt at just the critical moment so there was no time when the interrupt line was inactive).
If this is level detect, I can hold interrupt active and disable by the handler, until restore by external code for which it re-execute the interrupt.
I'm not sure I really understand what you're after here, but I think that you might be able to do what you want using the NVIC's SETENAx and CLRENAx registers to enable/disable the interrupt. These work independently of the pending bits, so an interrupt can be pending (or become pending) even if the interrupt is disabled. So you can hold off handling an interrupt for as long as you want.
If that's not quite enough, also note that you can cause an interrupt to pend via software by simply setting the pending bit in the corresponding SETPENDx register - the CPU will vector to the ISR just as if a hardware interrupt were asserted (assuming the interrupt is enabled in the SETENAx register). you can also use the "Software Trigger Interrupt Register" (STIR) to trigger an interrupt by software.

Resources