Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

Semaphore between ISR and thread (Thread Waiting for the semaphore forever)

Posted by holim on June 15, 2017

Hello,

I'm working on a custom board with STM32F407 MCU. The code was generated by CubeMX of ST Micro. And it has FreeRTOS v8.2.3.

The issue resides in Ethernet side. From a PC, I ping the custom board. Ethernet communication is ok after reset. But the traffic is blocked after some time (minutes or hours). Only power reset resolves the situation.

From my investigation, I've found this issue is related with semaphore. ISR (Interrupt Service Routine) releases the semaphore. And ethernet thread obtains the semaphore to handle the frames.

When the problem happens, ISR continuously tries to release the semaphore, but fails 'cause the semaphore is already full. But the thread doesn't receive the semaphore but seems to be suspended forever. The thread stops LED blinking, which is fine until it blocks.

I tried replacing the semaphore in thread with osDelay(1). (1 ms Sleep). Then the communication was OK for half a day. But it shows a performance degradation of ethernet.

Please, refer to the following codes which is unchanged after being taken from CubeMX.

I also tested the counting semaphore with max count 10. (Original code has binary semaphore.)

Count 10 is consumed very quickly. And thread waits for the semaphore forever.

FreeRTOS v9.0 was also tried, but no change.

Any idea or suggestion will be greatly appreciated.

Thank you so much.

static void lowlevelinit(struct netif netif) { .... / create a binary semaphore used for informing ethernetif of frame reception */ osSemaphoreDef(SEM); s_xSemaphore = osSemaphoreCreate(osSemaphore(SEM) , 1 );

/* create the task that handles the ETHMAC */ osThreadDef(EthIf, ethernetifinput, osPriorityRealtime, 0, INTERFACETHREADSTACKSIZE); ethinput_handle = osThreadCreate (osThread(EthIf), netif); ... }

void ethernetif_input( void const * argument )

{

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

for( ;; ) { if (osSemaphoreWait( sxSemaphore, TIMEWAITINGFORINPUT)==osOK) { do {
p = lowlevelinput( netif ); if (p != NULL) { if (netif->input( p, netif) != ERROK ) { pbuffree(p); } } } while(p!=NULL); } } }


Semaphore between ISR and thread (Thread Waiting for the semaphore forever)

Posted by rtel on June 15, 2017

There are several things here which are out of our control. First you are using the ST OS abstraction layer, rather than the native API, plus (by the looks of it) lwIP which is not our code, the project was created by the Cube tool, not us, etc. It is hard then to know if there are any implementation issues within that whole stack of software.

The first thing you need to do is see what the task that 'takes' the semaphore is actually doing rather than doing what it should be. You might be able to make use of the trace tool, or just use the debugger, to work that out.

From experience of all the other support requests I would say the most common cause (by far) of similar problems is an incorrect priority assignment. Keep with FreeRTOS V9 (as it has more asserts defined) and ensure configASSERT() is defined. http://www.freertos.org/a00110.html#configASSERT Does the assert ever fail? Also, see the note about ensuring no subpriority bits are defined - you can find info on that by searching for "stm32" on the following page: http://www.freertos.org/RTOS-Cortex-M3-M4.html

If the interrupt priority settings are coming from the Cube software I would expect them to be right though.


Semaphore between ISR and thread (Thread Waiting for the semaphore forever)

Posted by heinbali01 on June 15, 2017

in addition to Richard remarks:

I also tested the counting semaphore with max count 10. (Original code has binary semaphore.)

I think I would leave it to a binary semaphore. When the semaphore is set, it means that 1 or more packet segments have been received.

As you indicate, the problem is "caused" by the Ethernet task that hangs after a while.

Does that port check the Link Status ( LS ) of the PHY? As soon as the LS goes down, the device can not deliver its packets and it may block quite a while. Test: what happens if you unplug the device for a minute or so?

I don't know how much time you already have invested in this lwIP project? You might want to have a look at FreeRTOS's own TCP/IP stack here It has a good driver for both the STM32F4 and STM32F7.

Regards.


Semaphore between ISR and thread (Thread Waiting for the semaphore forever)

Posted by holim on June 19, 2017

First of all, thank you for the answer.

OK. I agree that there are many softwares incorporated in my current application. And it's another reason to make it hard for me to debug this issue. I also posted this issue on ST Micro, but it's not solved yet.

Anyhow, according to your comment, I did some more jobs on configASSERT and subpriority mechanism. I added the following in my application and checked there's no assertion error.

  1. define configASSERT( x ) if ((x) == 0) {termprintf(TPIDUART, "Assertion Failed, %s %drn", FILE, LINE );}
  2. NVICSetPriorityGrouping(NVICPriorityGroup_4);

If there's anything more to check, please let me know. It would help me a lot to resolve this issue.


Semaphore between ISR and thread (Thread Waiting for the semaphore forever)

Posted by holim on June 20, 2017

Thank you very much for your reply.

Ok. I will keep the semaphore as a binary one.

Current firmware doesn't check the Link Status of PHY. I tested the unplugging of LAN cable for a few minutes and plugging the cable again to the port. "Ping" was not replied while being unplugged and replied some seconds after the cable is connected. So, it seems to be working well for this case.

And according to your proposal, I have ported FreeRTOS-Plus-TCP package (RTOS v9 with TCP) after removing LWIP package. But it is quite strange that the same symptom is happening again.

When the issue happens, RBUS (Receive Buffer Unavailable Status) register is set, which causes the MCU's DMA not to handle any incoming frames since there's no buffer. At this moment, the frame handling task "prvEMACHandlerTask" should copy the frame and release the buffer by changing the owner bit. But the "prvEMACHandlerTask" does not seem to free the buffer successfully so that MCU's DMA waits forever for the buffer to be released for itself.

In my opnion, this seems to be a synchronization issue between DMA and a thread.

Anyhow, just to step forward, I changed some codes in "HALETHRxCpltCallback" as follows.

~~~ void HALETHRxCpltCallback( ETHHandleTypeDef *heth ) { BaseTypet xHigherPriorityTaskWoken = 0;

ulISREvents |= EMAC_IF_RX_EVENT;
if( xEMACTaskHandle != NULL )
{
	//vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
	//portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}

} ~~~

I just blocked the context switching from ISR for the task "prvEMACHandlerTask". This test code worked for 12 hours until now without problem. But the ping is very slow since the task has a very low priority. Please, note that from the tracing of previous firmware, the task was suspended forever after executing the context swtiching.

portYIELDWITHINAPI(); Line 1526 of Queue.C of FreeRTOS V8.2.3

~~~ vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); prvUnlockQueue( pxQueue ); if( xTaskResumeAll() == pdFALSE ) { portYIELDWITHINAPI(); // !!!! Line 1526 } else { mtCOVERAGETESTMARKER(); }

            //queue.c -> Line 1526

~~~

I'm pinging from 5 consoles with the following command. ping 192.168.0.100 -t -l 1400 A bit large packet test actually. But the problem also happens with one console of simple ping command (ping x.x.x.x). It just take more time to reproduce the issue.

Well, this is just a ping test and should be working fine. I also wonder if I am the only one who has this kind of issue.

Anyhow, please give me some more idea on this.

Thank you again.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists