FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [May 2012 Threads] Semaphore ProblemPosted 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 ProblemPosted by garypty on May 29, 2012 Sorry the first line should be #define TASK_ACTIVE 1
RE: Semaphore ProblemPosted 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 ProblemPosted 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 ProblemPosted 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 ProblemPosted 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 ProblemPosted 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 ProblemPosted 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 ProblemPosted 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 ProblemPosted 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 ProblemPosted 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 ProblemPosted 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 ProblemPosted 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 :)
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|