Quality RTOS & Embedded Software

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




Loading

Semaphore Problem

Posted by garypty on May 29, 2012
I got my system hang, please see my code first:

#define TASK_ACTIVE 0
#if TASK_ACTIVE == 0
...
#else
// I want the program wait here to take a sem, if success, then
// the program continue...
while( xSemaphoreTake ( sem, 200 ) == 0);
#endif


I have checked that the semaphore has never been given, so I expect it wait here with a block time 200, however the whole system just hang.
Then if I add a delay after the take semaphore line, the system can run without problem! like this:

#define TASK_ACTIVE 0
#if TASK_ACTIVE == 0
...
#else
// I want the program wait here to take a sem, if success, then
// the program continue...
while( xSemaphoreTake ( sem, 200 ) == 0);
while(1) { vTaskDelay(500); }
#endif


I am really confused.....anybody can give me advise? Thank you very much.

RE: Semaphore Problem

Posted by garypty on May 29, 2012
Sorry the first line should be
#define TASK_ACTIVE    1


RE: Semaphore Problem

Posted by Dave on May 29, 2012
You have not shown enough code for anybody to be able to comment. For example, what is there after the call to xSemaphoreTake()? How do you know the system hangs, what is it actually doing while it is hanging? Has it crashed, or is the idle task running, or something else?

RE: Semaphore Problem

Posted by garypty on May 30, 2012
I noticed it is hanging because I have other task to blink a LED and display something on a LCD, when it is hang the LED stopped blinking and the LCD stopped to refresh. Also when I run it in debug mode, when I pause it, the program counter stopped at a line like this:
80016834    rjmp  0x80016834
.

#define TASK_ACTIVE 0
portTASK_FUNCTION(thisTask, pvParameters)
{
char buffer[200];
for(;;)
{
#if TASK_ACTIVE == 0
...
#else
// I want the program wait here to take a sem, if success, then
// the program continue...
while( xSemaphoreTake ( sem, 200 ) == 0);
while(1) { vTaskDelay(500); }
#endif

parseBufferFunction( buffer );
}
}


I have a new founding....if I put the buffer[200] to be a global variable, then the system has no problem....As the semaphore has never been given, it should not run to the parseBufferFunction().....so why it can run just if I put the buffer to be a global variable? I have checked with the HighWaterMark method that the stack size is enough.

RE: Semaphore Problem

Posted by Dave on May 30, 2012
You posted the code you said was working, I was wanting to see the code that wasn't working.

“checked with the HighWaterMark method that the stack size is enough”


How big is the stack of the task? Do you have stack overflow checking switched on?

RE: Semaphore Problem

Posted by garypty on May 30, 2012
Sorry again, it should be
#define TASK_ACTIVE    0
again.
Just delete the line
while(1)  {  vTaskDelay(500);  }
than the code is not working....
I did not switch on the overflow checking hook function, I just put
myWaterMark = uxTaskGetStackHighWaterMark(NULL) 
in the loop of the task, and check this value while the code is working (that is when I included the
while(1)  {  vTaskDelay(500);  }
). Now this water mark is about 40, but I have tried to increase the stack size and the result is the same.

I have just found another even more weird thing...

xSemaphoreHandle sem = NULL;
int count1, count2, count3;
char val;
portTASK_FUNCTION(thisTask, pvParameters) {
vSemaphoreCreateBinary( sem );
xSemaphoreTake(sem, 0);
val = 0;
while(1) {
count1++;
while(sem == NULL){ // if I remove this while loop, then the code not working, but I checked the program
vTaskDelay(200); // never reach inside this while loop....
}
if ( sem != NULL ) {
count2++;
}
if (val == 1) {
....
} else {
count3++;
toggleLEDFunction(LED);
vTaskDelay(500);
}
} // end forever while loop
} // end task


I get the result that count1 only equal to 1 but count3 increase continuosly ! The count1/i] is just in the while(1) forever loop, so I expect it should increase continuously.....Any idea about that?

I am using the Atmel Studio5.1, which is using the gcc compiler, the microcontroller is AVR32UC3A and actually I am modifing their FreeRTOS+LWIP+DHCP example.

Btw, can I preview my post before I posted it? It is very difficult to check the code in the small box.

RE: Semaphore Problem

Posted by Richard Damon on May 30, 2012
My first feeling is that if removing a while(sam == NULL) loop changes the behavior, that you may be out of heap and the semaphore never was created. Is sam == 0? If so, that first xSemaphoreTake(sam, 0) may corrupt your system at which poin all bets are off on behavior.

Note that one danger of creating a semaphore in a task, is that the other users of the semaphore need to check that the semaphore has been created before using it. I tend to create all my queues and semaphores in the startup code before any tasks start to run or interrupts are enabled, so that I don't have this issue.

RE: Semaphore Problem

Posted by Richard on May 30, 2012
portTASK_FUNCTION(thisTask, pvParameters) 
{
vSemaphoreCreateBinary( sem );
xSemaphoreTake(sem, 0);
val = 0;

while(1)
{
count1++;
while(sem == NULL)
{
vTaskDelay(200);
}

if ( sem != NULL )
{
count2++;
}
if (val == 1)
{
....
}
else
{
count3++;
toggleLEDFunction(LED);
vTaskDelay(500);
}
} // end forever while loop
} // end task


Above is your existing code, slightly reformatted.

I'm not sure why you are checking for sem being NULL after it has already been used. Probably not an answer to your problem, but I would recommend changing the structure as follows:

portTASK_FUNCTION(thisTask, pvParameters) 
{
vSemaphoreCreateBinary( sem );
xSemaphoreTake(sem, 0);
val = 0;

while(1)
{
count1++;
while(sem == NULL)
{
vTaskDelay(200);
}

if ( sem != NULL )
{
count2++;
}
if (val == 1)
{
....
}
else
{
count3++;
toggleLEDFunction(LED);
vTaskDelay(500);
}
} // end forever while loop
} // end task



You have said two things that make me thing your general setup is to blame somewhere, rather than your code. First, moving an array off the stack makes a difference, although there is no obvious stack overflow. Second adding code that should never execute makes a difference.

I would suggest looking at your linker script first. Where are these variables being created? Are they being corrupted by other variables, or the heap, or the stack overlaying them?

Regards.

RE: Semaphore Problem

Posted by Richard on May 30, 2012
[to answer your other question, you should be able to resize the edit box by dragging the bottom right hand corner, at least you can in Google Chrome]

RE: Semaphore Problem

Posted by Richard on May 30, 2012
Hang on - I pasted the same code in twice! This is what the second code snippet was supposed to be:

portTASK_FUNCTION(thisTask, pvParameters) 
{
vSemaphoreCreateBinary( sem );

if( sem != NULL ) // Check it was actually created.
{
xSemaphoreTake(sem, 0);
val = 0;

while(1)
{
count1++;
while(sem == NULL) // Obsolete call, can't be null
{
vTaskDelay(200);
}

if ( sem != NULL ) // Obsolete call, can't be null
{
count2++;
}
if (val == 1)
{
....
}
else
{
count3++;
toggleLEDFunction(LED);
vTaskDelay(500);
}
} // end forever while loop
}
else
{
// Panic, task cannot continue.
vTaskDelete( NULL );
}
} // end task

RE: Semaphore Problem

Posted by garypty on May 31, 2012
Thanks all,

I would like to ask is that these portTask_FUNCTION() will only run after the vTaskStartScheduler() is called?
Now I used " portENTER_CRITICAL() " and " portEXIT_CRITICAL() " before and after the creation and take of the semaphore.
Actually I have also used the code: if(sem != NULL) ...but the behaviour still weird...
I have switched on the " configHEAP_INIT " to initialize the heap with 0xA5, I checked the memory in debug mode and I can see there are still many space filled with the A5, so I think the heap has not been full yet...
I have tested the code for many days....I have no idea now so I tried to include something weird....such as the code that should never execute and check the (sem != NULL) after it has been used...

RE: Semaphore Problem

Posted by Richard on May 31, 2012
In nearly every case in use today, portTASK_FUNCTION does nothing, and the line of code

portTASK_FUNCTION(thisTask, pvParameters)


just expands to the following

void thisTask( void *pvParameters )


so it is just a standard C function.

If you create the task using the xTaskCreate() API function, then the task does not execute until the scheduler has been started using the vTaskStartScheduler() API function.

DO NOT call the function, it must only run as a separate task.

You are going to have to single step through the code in your debugger to find out what the problem is. Concentrate on the environment (linker script, etc.) causing corruption and your own use of the API (http://www.freertos.org/FAQHelp.html) rather than looking for something in the FreeRTOS source code - if you are using an official FreeRTOS port it is highly unlikely that you will find a problem in the FreeRTOS source itself - although obviously not impossible.

Regards.

RE: Semaphore Problem

Posted by garypty on June 1, 2012
Dear all, I would like to thank you all, I have found the problem, yes you right, it is STACK OVERFLOW.......

However, I have switched on the stack overflow hook function and use the high watermark method to check the stack. I only put a line like
 overflow_flag = 1;
in the hook function. The hight watermark did not goes to 0 and the stack overflow hook function did not triggered (the overflow_flag equal to 0).....so I thought the stack size is okay....I found the problem when I try to merge other tasks into a single task. After I merged these tasks, the overflow hook function triggered....then I increase the stack size of "thisTask" even more.....then the system run without problem.

Could you suggest a good way to detect the stack overflow problem?

Anyway thank you very much for all your help....as you all know writing code is lonely.... forum like this one is really important :)


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




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

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

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

OpenRTOS and SafeRTOS