RTOS with serial interrupts seems to be broken.

09 Apr 2012

I have an application that requires both multithreading (hence the RTOS) and serial interrupt handling. Basically, one thread is acquiring data while the other is controlling the system, and time spent polling for serial commands is time wasted for data logging. So I want to implement a serial ISR handler that wakes the serial command handler thread while otherwise the processor is free for the data acquisition thread. But for whatever reason, whenever my interrupt handler gets called (even if it's totally empty and just exits immediately), the system deadlocks and stops doing anything. I'll try to upload a sample LED program in a little bit that exhibits the problem, but long story short, serial interrupt handling seems to be broken while using the RTOS. Any ideas? Has anyone seen this? Other interrupts (tick, etc) work fine.

10 Apr 2012

The problem is caused by the interrupt flag not being cleared on the NXP. This appears to be a bug with the mbed library. A workaround for the time being is to query the RBR register of the appropriate UART. For example:

void ISR_Handle_UART0()
{
uint32_t RBR = LPC_UART0->RBR; 
//whatever you wanted the handler to do
}

will clear the pending interrupt flag for UART0 (Tied to PC USB for debug)

10 Apr 2012

from what I understand, you have to read the IIR and RBR register to clear the flag

<<code>>iir=LPC_UART1->IIR;<</code>>

10 Apr 2012

So BURT and I are actually the same, in this case the above BURT comment was from a friend, Ryan. His test program works fine reading only the RBR register.

The better question is, why is this not automatically handled by the API when running the RTOS as it is when NOT running the RTOS? I think I smell a bug.

Also, is it required to actually set a value to the register, or can one simply evaluate it without setting anything equal? Does the compiler just optimize that away? I'll have to test tomorrow.

10 Apr 2012

Also worth noting, the command to use to clear the register is dependent on WHICH UART the interrupt handler is attached to. For example, above, the ISR is handling the PC connection, which is UART0. So you'd use UART3 for the port on pins 9/10, UART2 for pins 28/27, and UART1 for pins 13/14.

EDIT: So here's some example code: http://mbed.org/users/alexwhittemore/programs/threadinterrupt/m89a6l

Note the line mentioned above to handle register clearing to stop ISR looping. Also, the example code implements some thread pointer handling to send a signal to a thread from an interrupt - not necessarily related, but something I needed to do and couldn't find examples of.

10 Apr 2012

The IIR register enables you to identify the source of the interrupt. If you look at the lpc17xx.h file, each UART is afforded only a single interrupt handler. and since you can have different sources of interrupt for the UART (overrun, transmit complete, received complete, etc), it is generally read upon entry on the handler to make sure you are serving the proper interrupt source.

05 Aug 2013

Hey,

We got the same problem here. We can't include a library without our interrupts crashing the system. You suggested entering this:

void ISR_Handle_UART0()
{
uint32_t RBR = LPC_UART0->RBR; 
//whatever you wanted the handler to do
}

But what exactly goes to 'whatever you wanted the handler to do'? Could someone post a code example of this?

Thanks in advance,

Any help on this matter is very welcome and would help us a lot.

05 Aug 2013

There goes whatever you wanted the handler to do.

Okay not really much of a help, but can you make clear what you want to know exactly? You wanted to have an interrupt handler for your serial interrupts. So whatever you wanted your handler to do, do it there.

If you don't have anything for it to do, then just dont attach an interrupt?

Also related, I do have a MODSERIAL fork that should allow for some interrupt handling when used with RTOS, getc, putc and puts are supposed to work. It is more a proof of concept beta thingie, that one day when I got time for it and feeling like it will be expanded. (For one printf is on my todo list there, but using sprintf and then puts you can effectively get the same). https://mbed.org/users/Sissors/code/MODSERIAL-RTOS/