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
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); } }
You don't do anything at all in the interrupts? Not even reading out any received data and clearing the interrupt state?
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
So what interrupt load do you have - how much time is spent in interrupts?
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?
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 } }
View all questions in Keil forum