Can’t create more than 5 task plus IDLE

Hi, I am having a little problem. I reduced my code to a really simple example. I cannot create more then 5 task (excluding IDLE). When I put on more, I think there is memory corruption and that interupt call a function that does not exist (use an invalid function pointer…) Any hints on that behavior? here is my code: #include "FreeRTOS.h" #include "task.h" #include "BSP_WDOG_API.h" #include "Printf.h" #define DBUG_TASK_STACK_SIZE            configMINIMAL_STACK_SIZE + 200 #define DBUG_TASK_PRIORITY              tskIDLE_PRIORITY + 2 void vDbugTask( void *pvParameters ); void vDbugTask2( void * pvParameters ); static volatile unsigned portLONG TestCounter = 0; static volatile unsigned portLONG TestCounter2 = 0; /************************************************************************** FUNCT: ***************************************************************************/ int main(void) {    //——————————————    char *str_running  = "running from ????    ";    char *str_Flash_0  = "running from Flash 0 ";    char *str_Flash_A  = "running from Flash A ";    char *str_Flash_B  = "running from Flash B ";    char *str_SRAM     = "running from Int SRAM  ";      char *str_SDRAM    = "running from Ext SDRAM ";      //————————-       xTaskHandle thDebug;    xTaskHandle thDebug2;        static unsigned char ucParamDebug;             // Point to string    if(__RUNNING_FROM == __FLASH_RUNNING_0) str_running= str_Flash_0;      if(__RUNNING_FROM == __FLASH_RUNNING_A) str_running= str_Flash_A;    if(__RUNNING_FROM == __FLASH_RUNNING_B) str_running= str_Flash_B;    if(__RUNNING_FROM == __SRAM_RUNNING)    str_running= str_SRAM;    if(__RUNNING_FROM == __SDRAM_RUNNING)   str_running= str_SDRAM;       // Start Message    printf("n======== MCF5282: %s ========n", str_running );    // Init Timer    Timer_init( );      //WDog_init(FALSE, 0);    /* Start debug task */    xTaskCreate( vDbugTask, ( signed portCHAR * ) "DEBUG", DBUG_TASK_STACK_SIZE, &ucParamDebug, DBUG_TASK_PRIORITY, &thDebug );    xTaskCreate( vDbugTask2, ( signed portCHAR * ) "DEBUG2", DBUG_TASK_STACK_SIZE, &ucParamDebug, DBUG_TASK_PRIORITY, &thDebug2 );    xTaskCreate( vDbugTask2, ( signed portCHAR * ) "DEBUG2", DBUG_TASK_STACK_SIZE, &ucParamDebug, DBUG_TASK_PRIORITY, &thDebug2 );    xTaskCreate( vDbugTask2, ( signed portCHAR * ) "DEBUG2", DBUG_TASK_STACK_SIZE, &ucParamDebug, DBUG_TASK_PRIORITY, &thDebug2 );    xTaskCreate( vDbugTask2, ( signed portCHAR * ) "DEBUG2", DBUG_TASK_STACK_SIZE, &ucParamDebug, DBUG_TASK_PRIORITY, &thDebug2 );    xTaskCreate( vDbugTask2, ( signed portCHAR * ) "DEBUG2", DBUG_TASK_STACK_SIZE, &ucParamDebug, DBUG_TASK_PRIORITY, &thDebug2 );    // Start the scheduler.    vTaskStartScheduler();    return 0; } /************************************************************************** FUNCT: vDbugTask ***************************************************************************/ void vDbugTask( void * pvParameters ) {    portTickType xLastWakeTime;    const portTickType xFrequency = 200;       signed char pcWriteBuffer[200];        (void) pvParameters;        // Initialise the xLastWakeTime variable with the current time.    xLastWakeTime = xTaskGetTickCount();       for( ;; )    {       vTaskList(pcWriteBuffer );       printf("n%sn", "task name    status  priority  HWMTS    ID");       printf("%sn", pcWriteBuffer );          printf("%dn", TestCounter );               TestCounter++;            // Wait for the next cycle.       vTaskDelayUntil( &xLastWakeTime, xFrequency );    } } /************************************************************************** FUNCT: vDbugTask ***************************************************************************/ void vDbugTask2( void * pvParameters ) {    portTickType xLastWakeTime2;    const portTickType xFrequency = 600;        (void) pvParameters;        // Initialise the xLastWakeTime variable with the current time.    xLastWakeTime2 = xTaskGetTickCount();       for( ;; )    {             TestCounter2++;            // Wait for the next cycle.       vTaskDelayUntil( &xLastWakeTime2, xFrequency );    } } /************************************************************************** FUNCT: vApplicationStackOverflowHook ***************************************************************************/ void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTaskName ) {    /* This will get called if a stack overflow is detected during the context    switch.  Set configCHECK_FOR_STACK_OVERFLOWS to 2 to also check for stack    problems within nested interrupts, but only do this for debug purposes as    it will increase the context switch time. */    ( void ) pxTask;    ( void ) pcTaskName;    for( ;; )    {    } } And my freeRTOS config: /*    FreeRTOS.org V5.1.1 – Copyright (C) 2003-2008 Richard Barry.    This file is part of the FreeRTOS.org distribution.    FreeRTOS.org is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    FreeRTOS.org is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with FreeRTOS.org; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    A special exception to the GPL can be applied should you wish to distribute    a combined work that includes FreeRTOS.org, without being obliged to provide    the source code for any proprietary components.  See the licensing section    of http://www.FreeRTOS.org for full details of how and when the exception    can be applied.     ***************************************************************************     ***************************************************************************     *                                                                         *     * SAVE TIME AND MONEY!  We can port FreeRTOS.org to your own hardware,    *     * and even write all or part of your application on your behalf.          *     * See http://www.OpenRTOS.com for details of the services we provide to   *     * expedite your project.                                                  *     *                                                                         *     ***************************************************************************     ***************************************************************************    Please ensure to read the configuration and relevant port sections of the    online documentation.    http://www.FreeRTOS.org – Documentation, latest information, license and    contact details.    http://www.SafeRTOS.com – A version that is certified for use in safety    critical systems.    http://www.OpenRTOS.com – Commercial support, development, porting,    licensing and training services. */ #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H #include "MCF5282.h" /*———————————————————– * Application specific definitions. * * These definitions should be adjusted for your particular hardware and * application requirements. * * THESE PARAMETERS ARE DESCRIBED WITHIN THE ‘CONFIGURATION’ SECTION OF THE * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. * * See http://www.freertos.org/a00110.html. *———————————————————-*/ #define configUSE_PREEMPTION                  1 #define configUSE_IDLE_HOOK                   0 #define configUSE_TICK_HOOK                   0 #define configCPU_CLOCK_HZ                    ( ( unsigned portLONG ) SYSTEM_CLOCK_HZ ) #define configTICK_RATE_HZ                    ( ( portTickType ) 100 ) #define configMINIMAL_STACK_SIZE              ( ( unsigned portSHORT ) /*150*/300 ) #define configTOTAL_HEAP_SIZE                 ( ( size_t ) ( 18/*12*/*1024 ) ) #define configMAX_TASK_NAME_LEN               ( 12 ) #define configUSE_TRACE_FACILITY              1 #define configUSE_16_BIT_TICKS                0 #define configIDLE_SHOULD_YIELD               1 #define configUSE_CO_ROUTINES                 0 #define configUSE_MUTEXES                     1 #define configCHECK_FOR_STACK_OVERFLOW        1 #define configUSE_RECURSIVE_MUTEXES           1 #define configQUEUE_REGISTRY_SIZE             10 #define configUSE_COUNTING_SEMAPHORES         0 #define configMAX_PRIORITIES                  ( ( unsigned portBASE_TYPE ) 6 ) #define configMAX_CO_ROUTINE_PRIORITIES       ( 2 ) /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ #define INCLUDE_vTaskPrioritySet              1 #define INCLUDE_uxTaskPriorityGet             1 #define INCLUDE_vTaskDelete                   1 #define INCLUDE_vTaskCleanUpResources         0 #define INCLUDE_vTaskSuspend                  1 #define INCLUDE_vTaskDelayUntil               1 #define INCLUDE_vTaskDelay                    1 #define INCLUDE_uxTaskGetStackHighWaterMark   1 #define configYIELD_INTERRUPT_VECTOR          16UL #define configKERNEL_INTERRUPT_PRIORITY       1 #define configMAX_SYSCALL_INTERRUPT_PRIORITY  4 void vApplicationSetupInterrupts( void ); #endif /* FREERTOS_CONFIG_H */ Thanks!

Can’t create more than 5 task plus IDLE

Just want to add that I’m using heap_2.c for my freeRTOS mem management.

Can’t create more than 5 task plus IDLE

Look at item 2 here http://www.freertos.org/FAQHelp.html Also try placing an infinite loop after vTaskStartScheduler(). If vTaskStartScheduler() returns then you will hit the infinite loop and it means the idle task could not allocate heap space.

Can’t create more than 5 task plus IDLE

Hi,    I have put the infinit loop at the end. All the tasks are created correctly. I dont get into the infinite loop " // loop forever while(1) {     // Make a delay of 2000000Us = 2sec     Timer_Pause_usec(2000000);             Timer_read_elapsed_time (&t1,&err);     printf("MCF5282Lite: %s. t1.ticks = %d, t.sec = %d", str_running, t1.ticks, t1.seconds ); } " The interupt still call a wrong function. The address vary depending on the size of the code. I couldnt find yet what was causing the corruption neither find wich pointer got corrupted

Can’t create more than 5 task plus IDLE

Have you checked that you are not just overflowing a task stack?

Can’t create more than 5 task plus IDLE

to continue: as vDbugTask() allocates a large buffer on its stack and calls printf() which can use a lot of stack. Where is printf directed to? What happens if you don’t create vDbugTask()?

Can’t create more than 5 task plus IDLE

I Tried removing the vDbugTask which as the printf call. Now I can put as many task I want… If I increase the heap that is.. I putted my lwip task also and it work.. I tried to put a printf in my other task (vDbugTask2). And there is no problem.. I dont think printf cause problem. Now the only difference I can see is vTaskList(pcWriteBuffer ); I added the call to this function in vDbugTask2 and it fails again. Is vTaskList problematic? Must it be called in a special way^

Can’t create more than 5 task plus IDLE

Oh I see it.. My char buffer is not big enough! I think thats it! Let me try :)

Can’t create more than 5 task plus IDLE

Sorry, this doesn’t seem to correct the problem.

Can’t create more than 5 task plus IDLE

After doing some test, I can call vTaskList, there is no overflow in my char variable. The problem occur when I call printf with the returned char If I dont call printf, there is no error. I use the standard printf and use UART to communicate with my computer.

Can’t create more than 5 task plus IDLE

I love you, I found my problem. Was not heap Was not stack overflow Was not vTaskList Was not synchronisation thread problem The problem was effectively my printf. I increased my character size for the vTaskList parameter, but I could printf it because printf buffer was not big enough BUFFER_SIZE was 125.. I putted it to 400 just for test.. I have 10 task, and I have no memory error :) ************************************************************************************/ void printf(char* str, …) {     char formatted_str[BUFFER_SIZE];       va_list arg_list;       size_t len;     /* Format message */       va_start(arg_list, str);       vsprintf(formatted_str, str, arg_list);       va_end(arg_list);           len = strlen(formatted_str);             // Truncate       if(len > BUFFER_SIZE)           len = BUFFER_SIZE – 5;             // Add CR       formatted_str[len] = ‘r’;       formatted_str[len+1] = ‘’;       len++;         WriteUARTN(formatted_str, len);   } Thanks for pointing me the problem hehe!