AnsweredAssumed Answered

RBUS issue on STM32F407

Question asked by Ho Lim on Jun 15, 2017
Latest reply on Jun 15, 2017 by Imen D

I'm working on a new board with STM32F407 MCU.
Currently, there's an issue with Ethernet.

After board reset, Ethernet communication is working well.
But after some time (minutes or hours), the Ethernet seems to be blocked.

ETH_DMASR_RBUS bit (0x00000080) is set when the communication is not ok.

My code was from STM32CubeMX and the versions are as follows.

STM32CubeMX : Version 4.17.0
FreeRTOS : V8.2.3

So, I have added "ethernet_watchdog" function in the thread "ethernetif_input"

       after searching the web for this issue.

However, it didn't solve the issue.

From my investigation, I have found
that the thread "ethernetif_input" is waiting forever for the semaphore (s_xSemaphore) to be released.
HAL_ETH_RxCpltCallback is being called continuously by the Ethernet ISR (interrupt service routine).

s_xSemaphore is a binary semaphore.

I tried changing the semaphore as a counting one (MAX. 10), but no change.

When I replaced the semaphore with osDelay(1), the Ethernet is working well for a long time.

But it has some performance issue possibly because of the delay in the thread.

Well, I'm not sure if it is an issue with the OS.
Please, let me have any help for my issue.

Thank you.

ps) Some code for better understanding.

      Except ethernet_watchdog, all the codes are directly from STM32CubeMX. 

//Function called directly from ISR...
void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)



//Ethernet Thread...
void ethernetif_input( void const * argument )

   struct pbuf *p;
   struct netif *netif = (struct netif *) argument;


   for( ;; )
     if (osSemaphoreWait( s_xSemaphore, TIME_WAITING_FOR_INPUT)==osOK)
            p = low_level_input( netif );
            if (p != NULL)
              if (netif->input( p, netif) != ERR_OK )
       } while(p!=NULL);


static void ethernet_watchdog(void)
     /* When Rx Buffer unavailable flag is set: clear it and resume reception */
     if ((heth.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET)
          /* Clear RBUS ETHERNET DMA flag */
          heth.Instance->DMASR = ETH_DMASR_RBUS;
          /* Resume DMA reception */
          heth.Instance->DMARPDR = 0;


// Semaphore and Thread creation...

static void low_level_init(struct netif *netif)


/* create a binary semaphore used for informing ethernetif of frame reception */
s_xSemaphore = osSemaphoreCreate(osSemaphore(SEM) , 1 );


/* create the task that handles the ETH_MAC */
osThreadDef(EthIf, ethernetif_input, osPriorityRealtime, 0, INTERFACE_THREAD_STACK_SIZE);
eth_input_handle = osThreadCreate (osThread(EthIf), netif);