I'm working with a Cortex M4 (Freescale's Freedom-K64F dev-board). I'm trying to write a long sequence of data to flash. The state machine for this sequence operates in the interrupt handler. This means that in the handler for the processor's flash-controller interrupt, I launch further flash controller operations. The last of my sequence of data operations is short, and is likely to finish very quickly. Launching a successive flash operation from a IRQ handler means that it is possible (in some cases such as the last operation) for the `successive` operation to complete before the IRQ-handler which launched it; and in fact I do see this happening. The problem is that such a sequence where a an active interrupt is made active_and_pending from an internal peripheral seems to not be working reliably for me. I find that the `active and pending state` does not restart the interrupt handler automatically upon return from the handler.
My application fails to field a successive interrupt when a `successive` operation launched from an active interrupt handler completes early. The only way I have been able to reason about it is by arguing that returning from an interrupt clears the pending flag and therefore causes my application to miss pending IRQ-handling.
To support my hypothesis further, I've re-written my IRQ handler in the following fashion:
void IRQ_Handler(void)
{
do {
handleCompletedOperationsAndProgressStateMachine();
} while (NVIC_GetPendingIRQ(...) != 0);
}
This does help, but there is still a small window between while (NVIC_GetPendingIRQ(...) != 0); and the actual return of the IRQ where the interrupt could be set as pending again and be lost.
Is it a processor-implementation thing that the pending status of an interrupt is cleared upon interrupt return?
Hi,
do you want that an ISR should be launched with the same times as the number of occurrence of interrupts?
If it is correct, it would be very difficult.
NVIC would be so designed that the next interrupt should occur at least one more time while handling the first interrupt regarding the same interrupts.
If the interrupts occurred two times while handling the previous interrupt, you would see only one interrupt was pending.
A pending interrupt would be cleared automatically when initiating the corresponding ISR.
When returning from the ISR, the corresponding interrupt would not be cleared and the ISR would be initiated again if the interrupt had been pending.
In this case, you cannot observe the interrupt was pending because it had been cleared at the entrance of ISR.
If you would like to do what you intended, you should complete one interrupt handling before the next interrupt will occur.
Best regards,
Yasuhiko Koumoto.
My question relates to the 'active_and_pending' state as described in ARM Information Center
From the completion IRQ handler of a flash data-transfer operation, let’s call it the ‘base invocation’, I launch a successive flash operation to operate asynchronously. This successive transaction is short enough to get completed before the return of the base invocation, and raises the interrupt-pending flag for the completion interrupt. Unfortunately, the completion IRQ handler does *not* get re-triggered following the return from the base invocation. This can only be explained if the pending flag gets cleared by the interrupt-return sequence of the base invocation, or if the processor implementation doesn’t handle the ‘active_and_pending’ state correctly.
yasuhikokoumoto San : I'm not expecting to receive N (where N > 1) successive interrupts in response to N interrupt pulses received during the lifetime of my base invocation. I'd like to receive *one* successive interrupt if a currently active interrupt is marked as pending by asynchronous activity during its lifetime.
This is beginning to look like a faulty implementation on the part of my particular processor (K64F). What I see can only be explained if the 'pending' flag of the flash interrupt somehow gets cleared automatically upon return from its handler. I know that the pending flag gets cleared upon exception entry; but it seems it is also getting cleared upon exception return.
I understand what you say.
However, the 'active_and_pending' state is not one which is implemented.
It is the state in which will be falling by chance.
There would not always be such the state.
I think you had better check your software other than processor hardware.
The problem was in my software. I had accidentally disabled all interrupts at one point before returning from my completion handler. The system was unable to handle pending Interrupts in that state. Sorry for have taken up time.
It is almost as if the flash controller though the interrupt was edge triggered but the interrupt controller though it was level sensitive and managed to interrupt the controller always when it wasn't actually handling the interrupt. The other option I can see is that there is some software lurking in the interrupt handler which does a software acknowledge of the interrupt. Neither seems very likely so I'm a bit stumped. It would be interesting to put a delay between the handleCompletedOperationsAndProgressStateMachine() and the while (NVIC_GetPendingIRQ(...) != 0) to see if the next interrupt disappears in between. This would tell you it has nothing to do with the return and the interrupt is level triggered. And it would still leave me wondering why the level is dropped.
The fault lay in my software. I had set PRIMASK by accident during the state machine.
Sorry I hadn't noticed your reply, and thanks. That certainly explains things and shows there's always some other good explanation.
I am glad you solved the problem.