5 years, 5 months ago.

Different interrupt behavior starting with mbed-os-5.5.4

We had code developed in mbed-os-5.4.7 that works fine for our MTS_MDOT_F411RE target. When we updated to mbed-os-5.7.7, our transmit interrupt routine appears to be causing our program to hang. I say this because as soon as the program executes the below line (let's call it "Line A" for reference), no lines following it will ever execute.

USART1_DATA.pSerialPort->attach(&INT_USART1_TX_Handler, Serial::TxIrq);

Some additional related findings through using printf to gauge the program’s progression:

  1. The Rx equivalent line does not exhibit this issue.
  2. Emptying the contents of INT_USART1_TX_Handler does not resolve this issue.
  3. Calling _ _disable_irq() before "Line A" resolves the hang, and calling _ _enable_irq() later in the code causes the hang to emerge.

Through process of elimination and scoping out a pin, we've seen that up to mbed-os-5.5.3 will properly generate waveforms (which occur after all the initializations). Using the same setup, mbed-os-5.5.4 does not generate these waveforms, and neither do several other versions we tested up to 5.7.7 inclusive.

Is there a known change implemented in mbed-os-5.5.4 that could result in this sort of issue with interrupts for F411RE? Is there a known workaround or solution for this situation?

I can try to provide additional information if needed. Any thoughts or feedback would be greatly appreciated, thank you.

1 Answer

5 years, 5 months ago.

Are you using the plain mbed provided Serial class? I've been hunting similar ISR issues with Serial. If you open the source you can see that every member function is protected by a mutex. Mutexes of course should not be called from ISR context. Even functions one would assume are safe like putc(), getc() use mutexes. On older versions of mbed I had used functions like readable() and getc() in ISR without crashing things. But on new mbed builds this crashes for me with mutex lock errors. There are some suggestions on the forums about handling class Serial in ISR but I have not seen one that did not end up calling illegal mutex inside ISR because all Serial methods have mutexes. As far as I can tell as soon as you get into an ISR routine with Serial you are beat as you can't even legally clear the interrupt flag that got you there.

The solution I found was to use the RawSerial class instead of regular Serial - this is in standard mbed library as well. It has the basics like putc(), getc() and a printf() that are supposed to resolve this issue and allow sending and receiving in ISR context. It may be as simple as changing your object from type Serial to type RawSerial. RawSerial has resolved the random mutex issues for me.

For regular Serial class (I haven't tried this) but for printing you could spin up a dedicated Thread with a mailbox input. Should allow other parts of the program to run at normal speed while sending does it's thing.