Hi,
sometimes my program crashes and I do not know why. I have a error "OS_ERR_FIFO_OVF". I read the information Keil : http://www.keil.com/support/docs/3604.htm and http://www.keil.com/support/man/docs/rlarm/rlarm_ar_cfgfifosz.htm 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?
Thanks. JB
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.
void TIMER2_IRQHandler(void) { TIM_ClearIntPending(LPC_TIM2, TIM_MR0_INT); if(Flg) isr_evt_set(EVENT_1, TID_Task1); else isr_evt_set(EVENT_2, TID_Task1); } __task void TASK_Task1(void) { uint16_t rx_event=0; while(1) { os_evt_wait_or(CHECK_EVENT_FLAGS, INFINITE_TIME); //Wait for an Event to occur rx_event = os_evt_get(); switch(rx_event) { case EVENT_1: //... process data break; case EVENT_2: //... store data or whatever break; } } }
2. using mailbox (mailbox can be preferred for communication interrupts like uart_rx interrupts)
void DISPLAY_PORT_IRQHandler(void) { 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 (tmp1) { // 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); UART_SendByte(DISPLAY_PORT_UART, txdata); cnt++; //... } } __task void TASK_RxComPort(void) { uint8_t sofflg=0, crflg=0; uint8_t rxlrc=0; uint16_t bufcntr=0; uint32_t data=0; void *prx; while(1) { 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 problem.
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 possible.
I use keil MDK for IP, CAN and USB, and I do not control their interruptions.
I seek to understand how interruptions does not work well before breaking everything.
an idea to determine the interruption that crashes?
So what interrupt load do you have - how much time is spent in interrupts?
In the interrupts, I make no processing, I just use "isr_evt_set()". 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.
Regards, JB
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) { U8 IIRValue; IIRValue = LPC_UART0->IIR; IIRValue >>= 1; IIRValue &= 0x07; if ( IIRValue == IIR_RDA ) { if (LPC_UART0->LSR & LSR_RDR) { UARTbuff[UART0]=LPC_UART0->RBR; isr_evt_set(UART(0), tsk_reception_RS); } } else if ( IIRValue == IIR_THRE ) { isr_evt_set(UART(0), tsk_transmission_RS); } }
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 the UART.
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 case.
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?
View all questions in Keil forum