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.
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:
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)
from what I understand, you have to read the IIR and RBR register to clear the flag
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.
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.
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.
Please log in to post a reply.
mbed, the fastest way to prototype with ARM based microcontrollers.
^ back to top