orifai01 wrote on Tuesday, January 17, 2017:
Hello,
I have a working FreeRTOS + TCP/IP application which manages to transmit and receive packets. The Ethernet interrupt + a deferred interrupt handler task are being used in order to read received packets. I’m using ARM Cortex-M3.
During packets reception (it can be after a few seconds or couple of minutes), a hard fault is asserted.
Additional details:
-
configKERNEL_INTERRUPT_PRIORITY is set to 255.
-
configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 191
-
ETHERNET_IRQn priority is set to 223 (i.e. 0b11011111, lower than configMAX_SYSCALL_INTERRUPT_PRIORITY, no sub priority bits) in xNetworkInterfaceInitialise() as mentioned below.
-
Startup_CMSDK_CM3.s is left without any changes.
-
I defined a function of mine (xEthernetHandler) to be the ETHERNET_Handle (#define xEthernetHandler ETHERNET_Handler) in FreeRTOSConfig.h.
xNetworkInterfaceInitialise:
portBASE_TYPE xNetworkInterfaceInitialise(void)
{
portBASE_TYPE xreturn;/* The Rx deferred interrupt handler task is created at the
highest possible priority to ensure the interrupt handler can
return directly to it no matter which task was running when the
interrupt occurred. */
xreturn = xTaskCreate( xDeferredInterruptHandlerTask,
“RCV”,
configMINIMAL_STACK_SIZE * 5,
NULL,
mainDEFERRED_IRQ_TASK_PRIORITY,
&xDeferredInterruptTaskHandle);Common_EnableIrq(ETHERNET_IRQn, 223);
return xreturn;
}
Interrupt handler:
void xEthernetHandler(void)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;if(SMSC9220_RxStatusFifoLevelIrq()) { vTaskNotifyGiveFromISR(xDeferredInterruptTaskHandle, (BaseType_t *)&xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); CLEAR_BIT(SMSC9220->INT_EN, 3); } /* Additional handlers will be added here */
SMSC9220_ClearAllIrqs();
NVIC_ClearPendingIRQ(ETHERNET_IRQn);
}
xDeferredInterruptHandlerTask:
void xDeferredInterruptHandlerTask( void * pvParameter1, uint32_t ulParameter2 )
{
NetworkBufferDescriptor_t *pxBufferDescriptor;
size_t xBytesReceived;
unsigned int index;
IPStackEvent_t xRxEvent;
unsigned int dwords_to_read;for( ;; )
{
ulTaskNotifyTake( pdFALSE, portMAX_DELAY );for ( ;; ) { xBytesReceived = SMSC9220_RecvSize(); if(xBytesReceived <= 0) { break; } /* Reading dwords, so xBytesReceived shall be divisible by 4 */ if(xBytesReceived % 4 != 0) { dwords_to_read = (xBytesReceived + 3) >> 2; xBytesReceived = dwords_to_read << 2; } pxBufferDescriptor = pxGetNetworkBufferWithDescriptor(xBytesReceived, 0); if(pxBufferDescriptor == NULL) { iptraceETHERNET_RX_EVENT_LOST(); break; } index = 0; if(SMSC9220_RecvPacket((unsigned int *)pxBufferDescriptor->pucEthernetBuffer, &index)) { printf("Packet receive failed.\n"); vReleaseNetworkBufferAndDescriptor(pxBufferDescriptor); continue; } pxBufferDescriptor->xDataLength = index << 2; /* See if the data contained in the received Ethernet frame needs to be processed */ if(eConsiderFrameForProcessing(pxBufferDescriptor->pucEthernetBuffer) != eProcessBuffer) { vReleaseNetworkBufferAndDescriptor(pxBufferDescriptor); continue; } /* The event about to be sent to the TCP/IP is an Rx event. */ xRxEvent.eEventType = eNetworkRxEvent; /* pvData is used to point to the network buffer descriptor that now references the received data. */ xRxEvent.pvData = (void *)pxBufferDescriptor; /* Send the data to the TCP/IP stack. */ if(xSendEventStructToIPTask(&xRxEvent, 0) == pdFALSE) { vReleaseNetworkBufferAndDescriptor(pxBufferDescriptor); iptraceETHERNET_RX_EVENT_LOST(); continue; } /* The message was successfully sent to the TCP/IP stack. Call the standard trace macro to log the occurrence. */ iptraceNETWORK_INTERFACE_RECEIVE(); } SET_BIT(SMSC9220->INT_EN, 3);
}
}
Is there anything wrong with the ethernet interrupt configuration? What could be the source of the problem?
Thank you,
Orit