sometimes my program crashes and I do not know why. I have a error
I read the information Keil :
I followed the advice but nothing happens.
I use a lot of interruptions in my program.
I'd like to know what interruptions are in the buffer "os_fifo"
when my programm craches. It would give me a direction to look.
someone is how it works?
Its obvious to get os_err_fifo_ovf if you are doing debugging and
stop at some breakpoint, while the other off-chip system peripherals
are running (eg: a peripheral is sending a string on uart, will
generate too many uart_rx interrupts). you just prevent such an
situation only by disabling the breakpoint.
if above is not the case then, just check if you have any
interrupt that consumes too much of processing time. minimize the
processing in the interrupt as much as possible.
few techniques to minimize the processing & hence the
processing time in the interrupt are
1. using signals (or events as known in keil rtos)
when an interrupt occurs, generate an event.
a dedicated task awaits the occurrence of event.
__task void TASK_Task1(void)
os_evt_wait_or(CHECK_EVENT_FLAGS, INFINITE_TIME); //Wait for an Event to occur
rx_event = os_evt_get();
//... process data
//... store data or whatever
2. using mailbox (mailbox can be preferred for communication
interrupts like uart_rx interrupts)
static uint8_t crflg = 0;
static uint16_t cnt=1;
uint32_t intsrc, tmp, tmp1, txdata, rxdata;
intsrc = (UART_GetIntId(DISPLAY_PORT_UART) & 0x03CF); /* Determine the interrupt source */
tmp = intsrc & UART_IIR_INTID_MASK;
if (tmp == UART_IIR_INTID_RLS) // Receive Line Status
tmp1 = UART_GetLineStatus(DISPLAY_PORT_UART); // Check line status
tmp1 &= (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE | UART_LSR_BI | UART_LSR_RXFE); // Mask out the Receive Ready and Transmit Holding empty status
// If any error exist
if ((tmp == UART_IIR_INTID_RDA)) // Receive Data Available or Character time-out
rxdata = UART_ReceiveByte(DISPLAY_PORT_UART) | 0x100; // Really COOL concept. Check READ ME!! - Section: Reference Files - Using Mail Box.
if (isr_mbx_check (&MailDisplay) != 0)
isr_mbx_send(&MailDisplay, (void *)rxdata);
if (tmp == UART_IIR_INTID_THRE) // Transmit Holding Empty
txdata = *(DISPLAY_PORT_TXBUF+cnt);
__task void TASK_RxComPort(void)
uint8_t sofflg=0, crflg=0;
os_mbx_wait(&MailComPort, &prx, 0xFFFF);
data = (uint32_t)prx & 0x00FF;
//... Process received data
Thank you for your help.
No, I do not make breakpoint in the program to get the
I used interruptions : 4 uarts, 1 can, 1 usb device hid, 1
ethernet, 1 RTC, several timer, ...
it makes a lot of interruptions. Each interruptions are as short as
I use keil MDK for IP, CAN and USB, and I do not control their
I seek to understand how interruptions does not work well before
an idea to determine the interruption that crashes?
So what interrupt load do you have - how much time is spent in
In the interrupts, I make no processing, I just use
And I have a pending task for each interruption.
Each tasks running in less than 20us.
Against by the USB stack runs every 1ms, it can slow down? I did
not find how.
You don't do anything at all in the interrupts? Not even reading
out any received data and clearing the interrupt state?
If I read the received data, and I prevent the task.
look at my code :
void UART0_IRQHandler (void)
IIRValue = LPC_UART0->IIR;
IIRValue >>= 1;
IIRValue &= 0x07;
if ( IIRValue == IIR_RDA )
if (LPC_UART0->LSR & LSR_RDR)
else if ( IIRValue == IIR_THRE )
Why don't you have a ring buffer for received data, so you have
room for multiple received characters before your task needs to start
working? Right now, you are forced to have that task react within a
single character cycle - actually even shorter than that if the UART
interrupt happens to be a bit delayed.
Same with transmit - why not have a ring buffer with pending data,
so the interrupt handler can instantly feed the UART? This part of
your code has a big issue - when your interrupt ends, the UART is
still hungry. And depending on interrupt priority, that UART will
instantly again want to generate a THRE interrupt. Never ever leave
an UART interrupt ignoring a THRE interrupt. Either feed the UART or
deactivate that interrupt if you have no more data to send and then
have the sending code reactivate the transmit interrupt at the same
time it finally has new data to send and feeds the first new byte to
Forgot about another issue:
else if ( IIRValue == IIR_THRE )
Remember that you can have both a receive and transmit event pending
when you enter your interrupt handler - so there should not be any
"else" there. You should always test all relevant flags that you have
enabled for interrupt generation. Your "else" means that you
sometimes directly leaves the ISR after handling a received byte and
then directly enters the ISR again to handle the transmit empty
I use it because I'm half-duplex.
I disable the reception when I transmit and I disable the
transmission when I receive.
I will review this part of my code.
I'm not sure my problem is there.
is there a trick to a debugger?
how you set the size of the variable OS_FIFOSZ? how do you
calculate for the size you need?
I would like to understand and not just increase the size because
my program crashes.
No easy formula. But how many interrupts do you have that requires
slots in the FIFO? And how many slots do the different interrupt
handlers need? And how much time is there to process these entries
before you add new entries?
I don't think you should go for less than twice the number of
ticks you need if every interrupt that uses the RTOS functionality
performs all posts they can.
But note again that your transmit interrupt can result in a
flooding of isr_evt_set() calls because of your "do nothing" design
of your ISR. If the transmit interrupt has a high enough priority
then I don't think any FIFO length will be long enough.
But how many interrupts do you have that requires slots in the
FIFO? And how many slots do the different interrupt handlers
8 for UARTs
4 for CAN
1 for GPIO
4 for RTC
10 for USB
1 for IP
But they do not trigger all at the same time.
And how much time is there to process these entries before you
add new entries?
tasks run in less than 20us.
tasks that manages the UART have the highest priority.
I feel that the problem is with the USB HID device, but it is the
stack of KEIL. Every 1ms, the USB interrupt triggers even when the
USB cable is unplugged.
The RTOS doesn't care about the exact number of interrupts.
It cares about the total amount of time the process spends
servicing interrupts. And it cares about how many events you trig
from the interrupts.
Next thing - I ask how much time before interrupts can trig again
and push new events but you instead think about how fast the
processor may do a task switch. But if the top priority isn't to do a
task switch then you don't get a task switch.
And it's only when the interrupts are disabled that the processor
will not try to push in any new, pending, interrupt.
Unless your specific processor has an edge-trigged UART transmit
interrupt, it can generate maybe 100000 UART-empty interrupts in a
second. And then do 100000 calls to that set-event function. That
type of code is extremely dangerous for any processor that has a
level-trigged UART-empty interrupt, so it's a coding style that
should better be avoided.
By the way - you have the option of using volatile unsigned
variables that you count up in every interrupt handler. Then you can
see how many interrupts of the different sort you have had. And you
can also count the number of times you have set or cleared an event.
That is a great way to verify if the number of events you think you
should get matches reality. Such a counter can quickly tell if the
number of UART interrupts matches the expected, or if the number of
UART interrupts that received a character matches the number of
characters your task code did manage to find and pick up. Or if the
number of transmit empty interrupts matches the number of characters
you managed to send.
OK, thank you for all your advice.
So you tell me to do the UARTs treatment in interrupts.
Then the example above with the mailbox is not good.
The volatile unsigned variables that I count up in every interrupt
handler, it's good trick.
It applies well to the UARTs but not for USB device.
The use of a mailbox in the previously posted example was for
handling received bytes. It's ok to send them to a consumer using a
mailbox. Or insert them into a ring buffer and use an event to wake
up the consumer.
It's the handling - or non-handling - of the transmit interrupt
that is the critical part. If there are characters to send, then the
interrupt should feed the UART directly. If there are no characters
to send, then the interrupt handler should deactivate the transmit
empty interrupt. The event should instead be used to inform a
producer thread that there is room in the output buffer and request
that the producer tries to fill up this output ring buffer.
But in the end, code should always be written so reduce issues
with latency and response time of main application. So if a UART has
FIFO support, then that should be used. This allows multiple bytes to
be received without character loss if the interrupt is a bit slow to
react and pick up a received byte. And a transmit FIFO that gets
filled with multiple outgoing characters means that the UART transmit
can continue to run at max speed even if the processor is a bit slow
reacting and adding new data.
If the UART hasn't FIFO support, then the interrupt handler itself
should at least be written so that it can keep the UART going without
requiring the main program to react to every incoming or outgoing
event at a guaranteed pace that is faster than the inter-character
delay. A ring buffer for incoming data means the consumer thread can
sleep for several character periods and still not miss any data. A
ring buffer for outgoing data means that the producer thread can
sleep for multiple character intervals and the UART can still be fed
with new data at maximum speed by the interrupt handler. Obviously -
a device that supports DMA transfers can make use of that instead of
a FIFO. But the rule is the same: a good design should try to keep
down the hard real-time requirements of as large parts of the
application code as possible. This means that a critical thread can
be given a critical priority to get activated, perform the critical
task and then go to sleep - without having resulted in all
UART/CAN/SPI/... transmissions being starved because the interrupt
handlers had no outgoing data or no free space for incoming data.
View all questions in Keil forum