Quality RTOS & Embedded Software

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




Loading

Starting a simple task

Posted by laurent grosbois on November 28, 2011
Hello,

I'm currently discovering RTOS for a school project and I am trying to implement a unique simple task printing a Hello word each 100 ms. Once I will be able to do that, hope I will be able to begin my project...
Only PB : my task looks like beeing never starting.
I've set the heap size to 40000 ( it's useless but this is a way to be sure it is not the PB).
My xTaskCreate function returns 1 and my code enter the scheduler without leaving it - as expected.
I am using a freescale MCF5282 evaluation board and wodewarrior IDE.

Here is my code, I'm sure it is a stupid mistake, but I would be very glad if someone could help me.

main.c

/* Standard includes. */
#include "support_common.h"
#include

/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

/*-----------------------------------------------------------*/
//prototypes
static void prvSetupHardware( void );
static void myTask1( void *pvParameters );

/*-----------------------------------------------------------*/

int main( void )
{
portBASE_TYPE creation_return;
xTaskHandle xHandleTask1;
printf("\r\nEntering main function ... \n\r");
/* Setup the hardware */
prvSetupHardware();

/* Start the reg test tasks - defined in this file. */
if(xTaskCreate( myTask1, ( signed portCHAR * ) "Task1", 50, NULL, tskIDLE_PRIORITY+10, &xHandleTask1)==pdPASS)
printf("Task 1 was properly created\n\r");

/* Start the scheduler. */
printf("Starting scheduler...\n\r");
vTaskStartScheduler();

/* Should never get there */
printf("Error. Scheduler exited.\n\r");
for( ;; );
}


/*-----------------------------------------------------------*/

static void myTask1( void *pvParameters )
{
portTickType lastTimeRun;

for(;;)
{
vTaskDelayUntil( &lastTimeRun, 100 );
printf("Hello world !\n\r");
}


}
/*-----------------------------------------------------------*/

void prvSetupHardware( void )
{
extern void mcf5xxx_wr_cacr( unsigned portLONG );

portDISABLE_INTERRUPTS();

/* Enable the cache. */
//mcf5xxx_wr_cacr( MCF5XXX_CACR_CENB | MCF5XXX_CACR_CINV | MCF5XXX_CACR_DISD | MCF5XXX_CACR_CEIB | MCF5XXX_CACR_CLNF_00 );
asm volatile( "NOP" ); /* As per errata. */

/* Multiply 8Mhz reference crystal by 8 to achieve system clock of 64Mhz. */
MCF_CLOCK_SYNCR = MCF_CLOCK_SYNCR_MFD( 2 );

/* Wait for PLL to lock. */
while( !( MCF_CLOCK_SYNSR & MCF_CLOCK_SYNSR_LOCK ) )
{
__asm__ volatile ( "NOP" );
}

}

/*-----------------------------------------------------------*/


FreeRTOSconfig file


/*
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.


***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************


This file is part of the FreeRTOS distribution.

FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS 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 and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.

1 tab == 4 spaces!

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_PREEMPTION1
#define configUSE_IDLE_HOOK0
#define configUSE_TICK_HOOK0
#define configCPU_CLOCK_HZ( ( unsigned long ) 64000000 )
#define configTICK_RATE_HZ( ( portTickType ) 100 )
#define configMINIMAL_STACK_SIZE( ( unsigned short ) 190 )
#define configTOTAL_HEAP_SIZE( ( size_t ) ( 40000 ) )
#define configMAX_TASK_NAME_LEN( 12 )
#define configUSE_TRACE_FACILITY1
#define configUSE_16_BIT_TICKS0
#define configIDLE_SHOULD_YIELD0
#define configUSE_CO_ROUTINES 0
#define configUSE_MUTEXES1
#define configCHECK_FOR_STACK_OVERFLOW0
#define configUSE_RECURSIVE_MUTEXES1
#define configQUEUE_REGISTRY_SIZE10
#define configUSE_COUNTING_SEMAPHORES0

#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_vTaskPrioritySet1
#define INCLUDE_uxTaskPriorityGet1
#define INCLUDE_vTaskDelete1
#define INCLUDE_vTaskCleanUpResources0
#define INCLUDE_vTaskSuspend0
#define INCLUDE_vTaskDelayUntil1
#define INCLUDE_vTaskDelay1
#define INCLUDE_uxTaskGetStackHighWaterMark1

#define configYIELD_INTERRUPT_VECTOR16UL
#define configKERNEL_INTERRUPT_PRIORITY 1
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4

void vApplicationSetupInterrupts( void );

#endif /* FREERTOS_CONFIG_H */

RE: Starting a simple task

Posted by Erich Styger on November 28, 2011
Hello,
you are using a stack size of 50 in
xTaskCreate( myTask1, ( signed portCHAR * ) "Task1", 50, NULL, tskIDLE_PRIORITY+10, &xHandleTask1)==pdPASS
which sounds very low to me, especially as you are using printf() which usually uses a lot of stack.

Better use
xTaskCreate( myTask1, ( signed portCHAR * ) "Task1", configMINIMAL_STACK_SIZE+50, NULL, tskIDLE_PRIORITY+10, &xHandleTask1)==pdPASS

RE: Starting a simple task

Posted by laurent grosbois on November 28, 2011
Hi,

Thank you for your answer.

I've just tried with a stack size of configMINIMAL_STACK_SIZE+50 and configMINIMAL_STACK_SIZE+300, but it still doesn't work.
I keep looking for what could be wrong but I still don't get it...

When setting a breakpoint into my task, the debugger never stops at the infinite loop. I believe the program never enter the task. The question is why ?
Moreover, as this is my only task for test, I don't have any way to resume it manually.

I' will tryto display a trace this afternoon, hoping this will help finding what goes wrong.

Cheers !

RE: Starting a simple task

Posted by Richard on November 28, 2011
I am told that the later versions of CodeWarrior have changed their stack frame usage, and that that has introduced an incompatibility into the port.

I have some new code, but this is not tested by me, so I have no way of verifying it:

In portasm.S, change the function ulPortSetIP:


ulPortSetIPL:
_ulPortSetIPL:
link A6,#-8
movem.l D6-D7,(SP)

move.w SR,D7 /* current sr */
move.w D7,D6 /* prepare return value */
andi.l #0x0700,D6 /* mask out IPL */
lsr.l #8,D6 /* IPL */

andi.l #0x07,D0 /* least significant three bits */
lsl.l #8,D0 /* move over to make mask */

andi.l #0x0000F8FF,D7 /* zero out current IPL */
or.l D0,D7 /* place new IPL in sr */
move.w D7,SR

move.l D6, D0
movem.l (SP),D6-D7
unlk A6
rts


In port.c change the function pxPortInitialiseStack():


portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
pxTopOfStack--;

*pxTopOfStack = (portSTACK_TYPE) 0xDEADBEEF;
pxTopOfStack--;

/* Exception stack frame starts with the return address. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
pxTopOfStack--;

*pxTopOfStack = ( portINITIAL_FORMAT_VECTOR << 16UL ) | ( portINITIAL_STATUS_REGISTER );
pxTopOfStack--;

*pxTopOfStack = ( portSTACK_TYPE ) 0x0; /*FP*/
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) _SDA_BASE; /* For compatibility with A5 relative addressing. */
pxTopOfStack -= 5; /* A5 to A1. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
pxTopOfStack -= 8; /* D7 to D0. */
return pxTopOfStack;
}



Please let me know (through this thread) if these changes allow your task to be started.

Regards.

RE: Starting a simple task

Posted by laurent grosbois on November 28, 2011
Thanks, it works !

Just a thing, your code doesn't compile because _SDA_BASE is not defined.
It works by adding this declaration at the beginning of the pxPortInitialiseStack function :

extern unsigned long far _SDA_BASE;


To finish, i've just another question, unrelated to my problem.
Is there an easy way to calculate the size of the stack I need for my tasks ?
Right now, I see 2 ways to do it. The first is adjusting it aproximatively, so my tasks run.
I could also do it manually when using functions I developped, calculating the size of each argument passed through every function encapsulated in one another, but when I'm using libraries (for instance stdio), that becomes much harder...

Again, thanks a lot for your answer. Your support was incredibly quick and efficient !

RE: Starting a simple task

Posted by laurent grosbois on November 29, 2011
In fact, it didn't work as it should be. My task was ignoring the delay.

I've found this was because the interrupt vectors are badly configured and the tick function was never called.
I've tried to configure the following vectors in exceptions.c :


//beginning of the file, declarations
extern void __cs3_isr_interrupt_119( void );
extern void vPortYieldISR( void );

//in the vector table
vPortYieldISR, /* 80 (0x140) Device-specific interrupts */
__cs3_isr_interrupt_119, /* 119 (0x___) Reserved */


Now, only the first execution of my loop happen. By using the debugger, I could notice that the __cs3_isr_interrupt_119 (from FreeRTOSTickSetup.c), and though
vTaskIncrementTick();
are only called once.

NB : I don't know if it can be of any help, but when I restore the old code of ulPortSetIP, the delay is again skipped and my task goes into an infinite loop.
NB2 : if I restore the old code of pxPortInitialiseStack(), my task doesn't start.

RE: Starting a simple task

Posted by laurent grosbois on November 29, 2011
Ok, sorry for the bother, it works.
If it can help anyone, Here is how to set up codewarior for a MCF5282 project. It seems beeing working but I've not tested all OS functionnalities yet.

0 - Create a new mcf5282 project with CW. Keep all files provided, you will need them
1 - Get freeRTOS core files in the project
2 - Add the memory management files you need
3 - Use the coldfire port files (CFv2)
4 - Replace the codes as in richardbarry post
5 - Copy the FreeRTOS_Tick_Setup.c and FreeRTOSConfig.h files from the MCF5282 example project
6 - Set up the interruptions & add usefull functions.
In exceptions.c

/* new definitions */
extern void __cs3_isr_interrupt_119( void );
extern void vPortYieldISR( void );

/* new vectors (replace in good place) */
vPortYieldISR, /* 80 (0x140) Device-specific interrupts */
__cs3_isr_interrupt_119, /* 119 (0x___) Reserved */

/*in the MCF5xxx ASM utility functions section */
asm void __declspec(register_abi) mcf5xxx_wr_sr (uint32)
{
move.l4(sp),d0
move.wd0,SR
rts
}



In exceptions.h, add
“asm void __declspec(register_abi) mcf5xxx_wr_sr (unsigned long);”


7 - enable interuptions
In FreeRTOS_Tick_Setup.c, use this vApplicationSetupInterrupts function instead of the one provided.
void vApplicationSetupInterrupts( void )
{
const unsigned portSHORT usCompareMatchValue = ( ( configCPU_CLOCK_HZ / portPRESCALE_VALUE ) / configTICK_RATE_HZ );

/* Configure interrupt priority and level and unmask interrupt for PIT0. */
MCF_INTC0_ICR55 = ( 1 | ( configKERNEL_INTERRUPT_PRIORITY << 3 ) );
MCF_INTC0_IMRH &= ~( MCF_INTC_IMRH_INT_MASK55 );

/* Do the same for vector 16 (interrupt controller 0). I don't think the
write to MCF_INTC0_IMRH is actually required here but is included for
completeness. */
MCF_INTC0_ICR16 = ( 0 | ( configKERNEL_INTERRUPT_PRIORITY << 3 ) );
MCF_INTC0_IMRH &= ~( MCF_INTC_IPRL_INT16 );


/* Configure PIT0 to generate the RTOS tick. */
MCF_PIT0_PCSR |= MCF_PIT_PCSR_PIF;
MCF_PIT0_PCSR = ( portPRESCALE_REG_SETTING | MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_EN );
MCF_PIT0_PMR = usCompareMatchValue;

mcf5xxx_wr_sr(0x2000);
}


8 - Create your main function. You can use this example running 1 tasks. Each of them displays a counter.
- Task 1 runs avery second and has a higher priority
- Tast 2 runs each 10ms and has a lower priority


/* Standard includes. */
#include "support_common.h"
#include "uart_support.h"
#include

/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

/*-----------------------------------------------------------*/
//prototypes
static void prvSetupHardware( void );
static void myTask1( void *pvParameters );
static void myTask2( void *pvParameters );
void vApplicationTickHook(void);

/*-----------------------------------------------------------*/

int main( void )
{
xTaskHandle xHandleTask1;
printf("\r\nEntering main function ... \n\r");
/* Setup the hardware */
prvSetupHardware();

/* Start the reg test tasks - defined in this file. */
if(xTaskCreate( myTask1, ( signed portCHAR * ) "Task1", configMINIMAL_STACK_SIZE+100, NULL, tskIDLE_PRIORITY+2, &xHandleTask1)==pdPASS)
if(xTaskCreate( myTask2, ( signed portCHAR * ) "Task2", configMINIMAL_STACK_SIZE+100, NULL, tskIDLE_PRIORITY+1, &xHandleTask1)==pdPASS)
printf("Task 1 was properly created\n\r");

/* Start the scheduler. */
printf("Starting scheduler...\n\r");
vTaskStartScheduler();

/* Should never get there */
printf("Error. Scheduler exited.\n\r");
for( ;; );
}


/*-----------------------------------------------------------*/

static void myTask1( void *pvParameters )
{
unsigned long i;
for(i=0;1;i++)
{
printf("Task 1 call :%d\n\r",i);
asm
{
nop;
}
vTaskDelay(100);
}


}
/*-----------------------------------------------------------*/
static void myTask2( void *pvParameters )
{
unsigned long i;
for(i=0;1;i++)
{
printf("Task 2 call %d\n\r",i);
asm
{
nop;
}
vTaskDelay(10);
}


}
/*-----------------------------------------------------------*/

void prvSetupHardware( void )
{
extern void mcf5xxx_wr_cacr( unsigned portLONG );


portENABLE_INTERRUPTS();

/* Enable the cache. */
//mcf5xxx_wr_cacr( MCF5XXX_CACR_CENB | MCF5XXX_CACR_CINV | MCF5XXX_CACR_DISD | MCF5XXX_CACR_CEIB | MCF5XXX_CACR_CLNF_00 );
asm volatile( "NOP" ); /* As per errata. */

/* Multiply 8Mhz reference crystal by 8 to achieve system clock of 64Mhz. */
MCF_CLOCK_SYNCR = MCF_CLOCK_SYNCR_MFD( 2 );

/* Wait for PLL to lock. */
while( !( MCF_CLOCK_SYNSR & MCF_CLOCK_SYNSR_LOCK ) )
{
__asm__ volatile ( "NOP" );
}

}

/*-----------------------------------------------------------*/

void vApplicationTickHook( void )
{

}

RE: Starting a simple task

Posted by https://www.google.com/accounts on September 11, 2012
What about this?

main():

if(xTaskCreate( myTask1, ( signed portCHAR * ) "Task1", 50, NULL, tskIDLE_PRIORITY+10, &xHandleTask1)==pdPASS)



FreeRTOSconfig.h

#define configMAX_PRIORITIES( ( unsigned portBASE_TYPE ) 6 )



Your task is getting a priority beyond the maximum priority available in your system.


[ 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