how to run some codes before tasks?

runfirst wrote on Friday, July 05, 2013:

I need some codes runs before tasks. it is very simple, just turn on LED for a while.
However it seems doesnt support delay method. It jams at delay  mothod.
int main( void ) {
HwInit();
EXTILine14_Config();
RTC_Config();
STM_EVAL_LEDOn(LED4);
delay(100);
STM_EVAL_LEDOff(LED4);
xTaskCreate( vTimeTask, (signed char *) “TIME1”, configMINIMAL_STACK_SIZE,
            NULL, mainTIME_TASK_PRIORITY, &T1 );
    vTaskStartScheduler();
    for( ;; ); 
}

However, it jams at line delay(100);
I guess it is because systick_handler conflig. But I dont know how to make another delay method.
However, If I put this method inside taks, it runs well.

Any one can share a delay method not depent on systick handler?
Or tell me how to delay here?

And then I can only create 5 tasks. from 6th task, doesn’t start at all. How to config it to run more tasks?

Thanks for any help!

rtel wrote on Friday, July 05, 2013:

I can only speculate as I don’t have the implementation of your delay() function, but if it is using the SysTick and assumes there is a SysTick interrupt handler then it won’t run because the FreeRTOS SysTick handler should be installed.

I presume you have tried calling delay() in an application that does not include FreeRTOS?  If so, you can step through it and see how it is working.  Does it need a special interrupt handler (probably)?

There would be several options for doing this.  For example:

1) Write a delay function that reads the SysTick value directly, but does not rely on SysTick interrupts.  (it polls the SysTick value itself)

2) Uses a peripheral timer for the delay rather than the SysTick timer.

3) Just create 1 task before starting the scheduler.  Use the task to perform any pre-processing you need to do (it can then use vTaskDelay()) and when it is ready the task can create the rest of the application tasks to start up the full application.

4) Just write an old fashioned null loop delay function and calibrate it to give the delay you required.

Regards.

runfirst wrote on Saturday, July 06, 2013:

Hi Richard

Thanks for your help.

That is what I want. I dont know how to make another delay not rely on systick handler. Could you please provide some sample codes? I am new at this.

1. How to create a task runs on time only? and other tasks run cycling?
2. how to make it runs more than 5 tasks? In my app, it can run only 5 tasks.

rtel wrote on Saturday, July 06, 2013:

I dont know how to make another delay not rely on systick handler. Could you please provide some sample codes?

Sorry - no.  That is outside the scope of FreeRTOS support, and this is a FreeRTOS support forum.  You will find lots of examples on the internet, in books, and you can ask the question on a forum that is specific to the chip you are using.

1. How to create a task runs on time only? and other tasks run cycling?

Do you mean a task that runs *one* time only?  If so, generally that is not a good idea, but you can do it by not having a loop in the task and calling vTaskDelete( NULL ) at the end of the task to make the task delete itself (do not exit the task function, but delete the task).

2. how to make it runs more than 5 tasks? In my app, it can run only 5 tasks.

You are probably running out of heap space.  Have you checked the return value of the xTaskCreate() function, and read the documentation for the xTaskCreate() function?  You may also want to look at the memory management documentation.

Regards.

runfirst wrote on Saturday, July 06, 2013:

Hi Richard, thanks a lot.

Now only 3rd question left.
I add :
portBASE_TYPE xReturn;
  xReturn=xTaskCreate( vT1, (signed char *) “TIME”, configMINIMAL_STACK_SIZE,
            NULL, mainTIME_TASK_PRIORITY, &hTimeTask );
……Same to vT6

Total 6 tasks. If I mark any one task, all runs well.
If 6 tasks, none of them runs. Their return codes are “pdPASS”

How do I change the heap space? My MCU is STM32F407V.  I am very new at FreeRTOS. I can not even understand the document you give me above. Appreciate very much if you could prove more detail or sample codes.

richard_damon wrote on Saturday, July 06, 2013:

The task that is failing to be created will be the Idle task, created in vTaskStartScheduler (or possibly the Timer task if you have enabled the use of Timer call backs).

The heap size is controlled one of two ways depending on which heap file you include from the MemMang directory. Most use a define  named configfTOTAL_HEAP_SIZE in FreeRTOSConfig.h to set it. The exception is heap_3.c, which uses the compiler supplied heap via malloc/free. This normally has it size set in a linker option.

runfirst wrote on Sunday, July 07, 2013:

Hi Richard

Is it this line? it is in  FreeRTOSConfig.h
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 5 * 1024 ) )

I change it to 6*1024, it can run 6 tasks now. I am not sure about this. Is it the only one place I should modify?

Regards

richard_damon wrote on Sunday, July 07, 2013:

If that helps things then you are not using heap_3.c, so that is the place to adjust the heap size. 6k should support more tasks than that unless you are setting up some big queues or your tasks have large stacks being allocated.

Did you change configMINIMAL_STACK_SIZE or do you have some task marked as needed a lot more stack than minimal (if your tasks do much work, they likely need more than the minimum, so should be created using configMINIMAL_STACK_SIZE + nnnn, where nnnn is the amount of additional stack they need, not just bumping up configMINIMAL_STACK_SIZE.

runfirst wrote on Monday, July 08, 2013:

Hi  Richard

Yes, app is freeze after couple hours. How to determind which task drains more size? And how much are they?
I see MINIMAL_STACK_SIZE is 160. What is its unit? bytes?

Rgards

runfirst wrote on Monday, July 08, 2013:

sorry, currently,  MINIMAL_STACK_SIZE is 130

rtel wrote on Monday, July 08, 2013:

I see MINIMAL_STACK_SIZE is 160. What is its unit? bytes?

http://www.freertos.org/a00110.html#configMINIMAL_STACK_SIZE

How to determind which task drains more size?

http://www.freertos.org/uxTaskGetStackHighWaterMark.html
http://www.freertos.org/Stacks-and-stack-overflow-checking.html

Regards.

runfirst wrote on Monday, July 08, 2013:

Hi Richard

After reading the document, I can see that configCHECK_FOR_STACK_OVERFLOW must be set to 1. then it start monitror the stack overflow even.

But what happen after stack overflow? is there a sample code such as flash a LED?

I see there is a line:
extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName );
it is in task.c. However, I could not location its defination.
Do I miss something?

davedoors wrote on Monday, July 08, 2013:

Quoting from the page referenced above

The application must provide a stack overflow hook function if configCHECK_FOR_STACK_OVERFLOW is not set to 0. The hook function must be called vApplicationStackOverflowHook(), and have the prototype below:

void vApplicationStackOverflowHook( xTaskHandle xTask,
                                    signed portCHAR *pcTaskName );

so if you define configCHECK_FOR_STACK_OVERFLOW to 1 or 2 then you have to provide the vApplicationStackOverflowHook() function yourself, and you can implement it to do whatever you want.

runfirst wrote on Monday, July 08, 2013:

Continue with above post.
I add own code for this function as below:

void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )
{
pxTask = pxTask;
pcTaskName = pcTaskName;
STM_EVAL_LEDOn(LED4);
}

And then call it by :
vApplicationStackOverflowHook( T1,“test” );

will this LED4 on when task T1 is overflow?

davedoors wrote on Monday, July 08, 2013:

The callback is called only if the stack has overflowed, so don’t let the function exit. If the stack is corrupt there is nothing sensible to return to. Add a null loop for(;;); to the end of your function and it should be ok.

runfirst wrote on Monday, July 08, 2013:

Hi Dave

I change it like :

void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )
{
pxTask = pxTask;
pcTaskName = pcTaskName;
STM_EVAL_LEDOn(LED3);
  for(;;);
}

Then it freeze from beginning, and LED3 is on showing stack overflow.  If I mark for(;;);, app can run well so far.

So what does it mean now? stack overflow? and then it can not go forward?

runfirst wrote on Monday, July 08, 2013:

Continue with post above.

I increase stack size and heap size. It seems doesnt help.

#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 1000 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 10 * 8192 ) )

The LED3 is ON when app starts. However, it can still go forward. still running well so far.  But not sure how long it will stay.

runfirst wrote on Tuesday, July 09, 2013:

no matter what  I change the code/stack size/heap size, app will freeze after 1 hour.
I think 10 * 8192  is enough for regular app. size of my app is 105KB of HEX file.
And it is just simple uart /led communicating.

any idea?

And I see there is warnning when I build the app:
…\src\FreeRTOS\tasks.c(456): warning:  #174-D: expression has no effect
it is this line:
portALIGNMENT_ASSERT_pxCurrentTCB( ( ( ( unsigned long ) pxNewTCB->pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );

richard_damon wrote on Tuesday, July 09, 2013:

If you are getting stack overflow traps, you need to increase the stack for the task that is overflowing (or do something to reduce the stack size it needs), it is that simple. Note that one of the parameters given to the overflow hook is the name of the task that overflowed.

If you can run under a debugger, then set a breakpoint in the overflow hook to find out who is overflowing, otherwise, have the hook somehow communicate this name to you (send to a debug serial port or something).

runfirst wrote on Tuesday, July 09, 2013:

I had tried increasing stack size to 2600, after 2600, it can not run. So I think it might be other problem. Because it freeze after 1 hour-1hour and couple minutes.

I can run it under debugger. Could you please provide more steps helping me find out the prolbem?

Add breakpoint at function below?

void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName ) { pxTask = pxTask; pcTaskName = pcTaskName; STM_EVAL_LEDOn(LED3); for(;;); }