Quality RTOS & Embedded Software

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




Loading

Can't create more than 5 task plus IDLE

Posted by Alexandre Malo on June 12, 2009
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%s\n", "task name status priority HWMTS ID");
printf("%s\n", pcWriteBuffer );
printf("%d\n", 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!


RE: Can't create more than 5 task plus IDLE

Posted by Alexandre Malo on June 12, 2009
Just want to add that I'm using heap_2.c for my freeRTOS mem management.

RE: Can't create more than 5 task plus IDLE

Posted by Dave on June 12, 2009
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.

RE: Can't create more than 5 task plus IDLE

Posted by Alexandre Malo on June 12, 2009
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

RE: Can't create more than 5 task plus IDLE

Posted by Dave on June 12, 2009
Have you checked that you are not just overflowing a task stack?

RE: Can't create more than 5 task plus IDLE

Posted by Dave on June 12, 2009
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()?

RE: Can't create more than 5 task plus IDLE

Posted by Alexandre Malo on June 12, 2009
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^

RE: Can't create more than 5 task plus IDLE

Posted by Alexandre Malo on June 12, 2009
Oh I see it.. My char buffer is not big enough! I think thats it!

Let me try :)

RE: Can't create more than 5 task plus IDLE

Posted by Alexandre Malo on June 12, 2009
Sorry, this doesn't seem to correct the problem.

RE: Can't create more than 5 task plus IDLE

Posted by Alexandre Malo on June 12, 2009
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.

RE: Can't create more than 5 task plus IDLE

Posted by Alexandre Malo on June 12, 2009
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] = '\0';
len++;



WriteUARTN(formatted_str, len);

}



Thanks for pointing me the problem hehe!


[ 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