7
\$\begingroup\$

I'm implementing a uart daisy-chain communication scheme with a Cortex M4. When a node receives a byte over one UART, an interrupt is generated (RXNE) and the byte is written out over another UART - since I use a send and receive buffer, this places the byte in the send buffer and enables the TXE interrupt which should be triggered subsequently.

This means for every byte received, two interrupts are triggered.

Now both UARTs can receive and transmit, and it is very much possible that both UARTs do receive a byte at the same time - now both will get a RXNE interrupt and trigger a TXE interrupt on the other UART.

But only one ISR can be processed at the same time - what happens with the other ones?

Is there an interrupt stack that can get full or interrupts simply called until all corresponding interrupt bits are cleared?

The thing is that my application tends to lock up under the situation described above (with multiple bytes being received). Not however when the UARTs are set to a lower speed (this seems counter intuitive) or when there is only one side connected.

\$\endgroup\$
1
  • \$\begingroup\$ I am sure it is documented under something like "interrupt controller" in the parts datasheet.. \$\endgroup\$
    – Eugene Sh.
    Commented Feb 9, 2016 at 22:06

3 Answers 3

5
\$\begingroup\$

What you are doing is quite normal and it should be possible to get it to work correctly.

The M4 processors have several dozen interrupt sources and it is very common for 2 or more interrupt requests (IRQ's) to become active at the same time. The IRQ's are "latched" by the interrupt logic and the interrupt controller decides on the basis of priority which one to process first (by vectoring to the interrupt handler). The 2nd IRQ is still latched, and is termed a "pending interrupt". In simple terms when an interrupt handler has completed its processing it has to execute a special instruction called a "return from interrupt" which allows the interrupt controller to process the next pending IRQ.

Although we sometimes talk about "stacked interrupts" in a situation like yours, they are not kept on a "stack" as such, and so it cannot run out of space and loose IRQ's. Generally the IRQ's remain latched until the corresponding IRQ bit is cleared by software.

It is difficult to know exactly why your system is locking up, you may have to provide more details. A couple of things to look at:

  1. Is your interrupt handler always clearing the corresponding IRQ flag? If the flag is not cleared then the processor can get locked in a loop constantly vectoring to the handler and not allowing other things to run.

  2. Does your interrupt handler always exit correctly by executing a "return from interrupt" special instruction? If it does not then it will not allow the interrupt controller to handle another IRQ at the same priority level, and it will appear that your processor is no longer responding to these interrupts.

\$\endgroup\$
2
  • \$\begingroup\$ Cortex M has no "return from interrupt" instruction. The usual call returns (bx lr and pop pc) work in interupt mode here. \$\endgroup\$
    – Turbo J
    Commented Feb 10, 2016 at 8:05
  • \$\begingroup\$ But do note that they only appear usual, lr has a special value, as there's more under the hood than just changing pc. Ref: infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/… \$\endgroup\$
    – domen
    Commented Feb 11, 2016 at 15:45
1
\$\begingroup\$

Usually in CPU/MCU sytem you have a priority setting which interrupt will be processed sooner. When interrupt is triggered it goes in queue list. STM32 has NVIC nested vector interrupt controller, maybe you should read some manual first.

\$\endgroup\$
1
\$\begingroup\$

You need to read up on the NVIC (Nested Vectored Interrupt Controller) that stm32 uses. What happens will depend on how you have configured the priorities attached to each interrupt in the NVIC, you will need to read RM0090 (STM32F4 reference manual) in detail.

Interrupts are processed on the call stack just like function calls. If one interrupt is in the middle of execution when a higher-priority interrupt occurs, then the second interrupt is stacked on top of the first and begins its execution. When the second interrupt is completed, the CPU goes back and finishes off the first one, and then goes back to the user-level thread.

If you set your UART interrupts to have the same priority, then the first one called will be allowed to complete before the second one begins execution.

Yes, you can run out of stack space, but it's the call-stack not some special interrupt stack. Note that the CPU has two stack pointers, and you have to be careful about which stack you're on, because that can change in an interrupt.

\$\endgroup\$
1
  • \$\begingroup\$ "call-stack not some special interrupt stack" is a bit confusing. As you note, stacks could be different (normal code could switch to Process stack / PSP, but interrupt code will always use Main stack / MSP). \$\endgroup\$
    – domen
    Commented Feb 11, 2016 at 15:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.