I am using stm32f407 with freertos 7.5.0. I have an ethernet task (it has the highest priority) which gets stuck in running queue and is not getting executed anymore. All other tasks with lower priority are actually running in the system. Selected portion of the code is displayed below. On startup i have created a binary semaphore which is given by the interrupt handler whenever a packet is received. I have tried to implement a NAPI sort of behaviour so i am disabling the interrupt and it is reenabled later when descriptor chain is traversed. There is a high priority task running which takes the above mentioned semaphore and calls a function to traverse the descriptor chain. After some time, 15-20 minutes of packet processing (flood ping), my ethernet thread which was supposedly waiting on the semaphore stops responding i.e. my led 2 stops blinking and since my function which enables ethernet interrupt is not called, so does my interrupts.
Now there is a low priority blinker task which is responsible for blinking another led. That keeps on running. Via gdb i can see idle task getting scheduled regularly. the state of all the tasks as reported by vTaskList() is
Eth_if R 4 302 2
IDLE R 0 38 6
tcpip_thr B 3 858 1
blinker B 0 93 3
Tmr Svc B 2 224 7
server S 0 39 4
data_hand S 4 38 5
xSemaphoreHandle eth_Semaphore = NULL;
//ethernet interrupt handler
void ETH_handler(void)
{
uint32_t tmp,tmp2;
signed portBASE_TYPE sem_ret;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
tmp = ETHDMA->SR;
/* Frame received */
if ( tmp & ETH_DMASR_RS)
{
//received a packet
/* Give the semaphore to wakeup LwIP task */
ETH_STATS(stats.ints.rs);
sem_ret = xSemaphoreGiveFromISR( eth_Semaphore, &xHigherPriorityTaskWoken );
if (sem_ret == pdPASS)
{
eth_int_ds++;
NVIC_DISABLE_INT(ETH_IRQn);
}
}
if( xHigherPriorityTaskWoken != pdFALSE )
{
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
}
void ethernetif_input( void * pvParameters ) // task named eth_if
{
struct pbuf *p,*n;
char i=0;
eth_start(); // enables the ethernt interrupt and creates a binary semaphore vSemaphoreCreateBinary(eth_Semaphore);
for( ;; )
{
if (xSemaphoreTake( eth_Semaphore, 100)==pdTRUE) //blocking time is 100 ticks
{
//traverse the descriptors and send to lwip from here
//currently lwip code is commented out to debug the problem
}
if (i%2)
led_off(LED_RED2);
else
led_on(LED_RED2);
}
}