Quality RTOS & Embedded Software

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




Loading

compile doesn't get errors, But rtos task can not start.

Posted by sun1211 on August 23, 2017

Hi all,

My target: http://www.embeddedartists.com/products/kits/lpc4357_kit.php (LPC 4357 - ARM M0, M4)

Currently, I create a project with some simple task IN C project - It runs successfully(use heap1.c) When I change to C++ project, I create C static library project of RTOS V9.0.0 and my demo project include this library. It can compile without error and warning, but It can not run any task(use heap1.c) but if I use heap_3.c, it runs successfully.

I do not know what problems? anyone can help me? Thanks and best regards.

FreeRTOSConfig.h ~~~ /* FreeRTOS V7.1.0 - 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 FREERTOSCONFIGH
define FREERTOSCONFIGH
ifndef IASMARM

/* For SystemCoreClock */

include "board.h"
endif

/----------------------------------------------------------- * 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. *----------------------------------------------------------/

define configSUPPORTSTATICALLOCATION 1
define configSUPPORTDYNAMICALLOCATION 1
define configTOTALHEAPSIZE 8*1024//10240
define configAPPLICATIONALLOCATEDHEAP 1//1
define configTIMERTASKSTACKDEPTH configMINIMALSTACK_SIZE
define configUSE_PREEMPTION 1
define configUSEIDLEHOOK 1
define configMAXPRIORITIES ( ( UBaseTypet ) 8 )
define configUSETICKHOOK 0
define configCPUCLOCKHZ ( ( uint32_t ) SystemCoreClock )
define configTICKRATEHZ ( ( TickType_t ) 1000 )
define configMINIMALSTACKSIZE ( ( uint16_t ) 128 )

//#ifdef _CODERED //#define configTOTALHEAPSIZE ( ( sizet ) ( 16*1024 ) ) //#else //#define configTOTALHEAPSIZE ( ( sizet ) ( 0 ) ) //#endif

define configMAXTASKNAME_LEN ( 20 )
define configUSETRACEFACILITY 1
define configUSE16BIT_TICKS 0
define configIDLESHOULDYIELD 1
define configUSECOROUTINES 0
define configUSE_MUTEXES 1
define configUSETICKLESSIDLE 1
define configMAXCOROUTINE_PRIORITIES ( 2 )
define configUSECOUNTINGSEMAPHORES 1
define configUSEALTERNATIVEAPI 0
define configCHECKFORSTACK_OVERFLOW 0
define configUSERECURSIVEMUTEXES 1
define configQUEUEREGISTRYSIZE 10
define configGENERATERUNTIME_STATS 0

/* 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

/* Use the system definition, if there is one */

ifdef _NVICPRIO_BITS
#define configPRIO_BITS       __NVIC_PRIO_BITS
else
#define configPRIO_BITS       5        /* 32 priority levels */
endif
if defined(CORE_M3)

/* The lowest interrupt priority that can be used in a call to a "set priority" function. */

define configLIBRARYLOWESTINTERRUPT_PRIORITY 0x1f

/* The highest interrupt priority that can be used by any interrupt service routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values. */

define configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 5

/* Interrupt priorities used by the kernel port layer itself. These are generic to all Cortex-M ports, and do not rely on any particular library functions. */

define configKERNELINTERRUPTPRIORITY ( configLIBRARYLOWESTINTERRUPTPRIORITY << (8 - configPRIOBITS) )
define configMAXSYSCALLINTERRUPTPRIORITY ( configLIBRARYMAXSYSCALLINTERRUPTPRIORITY << (8 - configPRIOBITS) )
else
if defined(CORE_M4)

/* The lowest interrupt priority that can be used in a call to a "set priority" function. */

define configLIBRARYLOWESTINTERRUPT_PRIORITY 0x3f

/* The highest interrupt priority that can be used by any interrupt service routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values. */

define configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 5

/* Interrupt priorities used by the kernel port layer itself. These are generic to all Cortex-M ports, and do not rely on any particular library functions. */

define configKERNELINTERRUPTPRIORITY ( configLIBRARYLOWESTINTERRUPTPRIORITY << (8 - configPRIOBITS) )

/* !!!! configMAXSYSCALLINTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */

define configMAXSYSCALLINTERRUPTPRIORITY ( configLIBRARYMAXSYSCALLINTERRUPTPRIORITY << (8 - configPRIOBITS) )
else
if defined(CORE_M0)
error FreeRTOS CM0 support NOT YET DEFINED
else
error FreeRTOS setup NOT DEFINED
endif /* defined(CORE_M0) */
endif /* defined(CORE_M4) */
endif /* defined(CORE_M3) */

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS standard names - or at least those used in the unmodified vector table. */

define vPortSVCHandler SVC_Handler
define xPortPendSVHandler PendSV_Handler
define xPortSysTickHandler SysTick_Handler
endif /* FREERTOSCONFIGH */

~~~ port.c ~~~ /* FreeRTOS V8.0.1 - Copyright (C) 2014 Real Time Engineers Ltd. All rights reserved

VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

***************************************************************************
 *                                                                       *
 *    FreeRTOS provides completely free yet professionally developed,    *
 *    robust, strictly quality controlled, supported, and cross          *
 *    platform software that has become a de facto standard.             *
 *                                                                       *
 *    Help yourself get started quickly and support the FreeRTOS         *
 *    project by purchasing a FreeRTOS tutorial book, reference          *
 *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 *                                                                       *
 *    Thank you!                                                         *
 *                                                                       *
***************************************************************************

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.  Full license text is available from the following
link: http://www.freertos.org/a00114.html

1 tab == 4 spaces!

***************************************************************************
 *                                                                       *
 *    Having a problem?  Start by reading the FAQ "My application does   *
 *    not run, what could be wrong?"                                     *
 *                                                                       *
 *    http://www.FreeRTOS.org/FAQHelp.html                               *
 *                                                                       *
***************************************************************************

http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details.

http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.

http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
licenses offer ticketed support, indemnification and middleware.

http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.

1 tab == 4 spaces!

*/

/----------------------------------------------------------- * Implementation of functions defined in portable.h for the ARM CM4F port. *----------------------------------------------------------/

/* Scheduler includes. */

include "FreeRTOS.h"
include "task.h"
ifndef VFP_FP
#error This port can only be used when the project options are configured to enable hardware floating point support.
endif
ifndef configSYSTICKCLOCKHZ
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
/* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK_BIT	( 1UL << 2UL )
else
/* The way the SysTick is clocked is not modified in case it is not the same
as the core. */
#define portNVIC_SYSTICK_CLK_BIT	( 0 )
endif

/* Constants required to manipulate the core. Registers first... */

define portNVICSYSTICKCTRLREG ( * ( ( volatile uint32t * ) 0xe000e010 ) )
define portNVICSYSTICKLOADREG ( * ( ( volatile uint32t * ) 0xe000e014 ) )
define portNVICSYSTICKCURRENTVALUEREG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
define portNVICSYSPRI2REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) )

/* ...then bits in the registers. */

define portNVICSYSTICKINT_BIT ( 1UL << 1UL )
define portNVICSYSTICKENABLE_BIT ( 1UL << 0UL )
define portNVICSYSTICKCOUNTFLAGBIT ( 1UL << 16UL )
define portNVICPENDSVCLEARBIT ( 1UL << 27UL )
define portNVICPENDSYSTICKCLEARBIT ( 1UL << 25UL )
define portNVICPENDSVPRI ( ( ( uint32t ) configKERNELINTERRUPT_PRIORITY ) << 16UL )
define portNVICSYSTICKPRI ( ( ( uint32t ) configKERNELINTERRUPT_PRIORITY ) << 24UL )

/* Constants required to check the validity of an interrupt priority. */

define portFIRSTUSERINTERRUPT_NUMBER ( 16 )
define portNVICIPREGISTERSOFFSET16 ( 0xE000E3F0 )
define portAIRCRREG ( * ( ( volatile uint32t * ) 0xE000ED0C ) )
define portMAX8BITVALUE ( ( uint8t ) 0xff )
define portTOPBITOFBYTE ( ( uint8t ) 0x80 )
define portMAXPRIGROUPBITS ( ( uint8_t ) 7 )
define portPRIORITYGROUPMASK ( 0x07UL << 8UL )
define portPRIGROUP_SHIFT ( 8UL )

/* Constants required to manipulate the VFP. */

define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
define portASPENANDLSPEN_BITS ( 0x3UL << 30UL )

/* Constants required to set up the initial stack. */

define portINITIAL_XPSR ( 0x01000000 )
define portINITIALEXECRETURN ( 0xfffffffd )

/* The systick is a 24-bit counter. */

define portMAX24BIT_NUMBER ( 0xffffffUL )

/* A fiddle factor to estimate the number of SysTick counts that would have occurred while the SysTick counter is stopped during tickless idle calculations. */

define portMISSEDCOUNTSFACTOR ( 45UL )

/* Let the user override the pre-loading of the initial LR with the address of prvTaskExitError() in case is messes up unwinding of the stack in the debugger. */

ifdef configTASKRETURNADDRESS
#define portTASK_RETURN_ADDRESS	configTASK_RETURN_ADDRESS
else
#define portTASK_RETURN_ADDRESS	prvTaskExitError
endif

/* Each task maintains its own interrupt status in the critical nesting variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;

/* * Setup the timer to generate the tick interrupts. The implementation in this * file is weak to allow application writers to change the timer used to * generate the tick interrupt. */ void vPortSetupTimerInterrupt( void );

/* * Exception handlers. */ void xPortPendSVHandler( void ) attribute (( naked )); void xPortSysTickHandler( void ); void vPortSVCHandler( void ) attribute (( naked ));

/* * Start first task is a separate function so it can be tested in isolation. */ static void prvPortStartFirstTask( void ) attribute (( naked ));

/* * Function to enable the VFP. */ static void vPortEnableVFP( void ) attribute (( naked ));

/* * Used to catch tasks that attempt to return from their implementing function. */ static void prvTaskExitError( void );

/-----------------------------------------------------------/

/* * The number of SysTick increments that make up one tick period. */

if configUSETICKLESSIDLE == 1
static uint32_t ulTimerCountsForOneTick = 0;
endif /* configUSETICKLESSIDLE */

/* * The maximum number of tick periods that can be suppressed is limited by the * 24 bit resolution of the SysTick timer. */

if configUSETICKLESSIDLE == 1
static uint32_t xMaximumPossibleSuppressedTicks = 0;
endif /* configUSETICKLESSIDLE */

/* * Compensate for the CPU cycles that pass while the SysTick is stopped (low * power functionality only. */

if configUSETICKLESSIDLE == 1
static uint32_t ulStoppedTimerCompensation = 0;
endif /* configUSETICKLESSIDLE */

/* * Used by the portASSERTIFINTERRUPTPRIORITYINVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned * a priority above configMAXSYSCALLINTERRUPT_PRIORITY. */

if ( configASSERT_DEFINED == 1 )
 static uint8_t ucMaxSysCallPriority = 0;
 static uint32_t ulMaxPRIGROUPValue = 0;
 static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16;
endif /* configASSERT_DEFINED */

/-----------------------------------------------------------/

/* * See header file for description. / StackTypet *pxPortInitialiseStack( StackTypet *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { / Simulate the stack frame as it would be created by a context switch interrupt. */

/* Offset added to account for the way the MCU uses the stack on entry/exit
of interrupts, and to ensure alignment. */
pxTopOfStack--;

*pxTopOfStack = portINITIAL_XPSR;	/* xPSR */
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) pxCode;	/* PC */
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS;	/* LR */

/* Save code space by skipping register initialisation. */
pxTopOfStack -= 5;	/* R12, R3, R2 and R1. */
*pxTopOfStack = ( StackType_t ) pvParameters;	/* R0 */

/* A save method is being used that requires each task to maintain its
own exec return value. */
pxTopOfStack--;
*pxTopOfStack = portINITIAL_EXEC_RETURN;

pxTopOfStack -= 8;	/* R11, R10, R9, R8, R7, R6, R5 and R4. */

return pxTopOfStack;

} /-----------------------------------------------------------/

static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to its caller as there is nothing to return to. If a task wants to exit it should instead call vTaskDelete( NULL ).

Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */
configASSERT( uxCriticalNesting == ~0UL );
portDISABLE_INTERRUPTS();
for( ;; );

} /-----------------------------------------------------------/

void vPortSVCHandler( void ) { __asm volatile ( " ldr r3, pxCurrentTCBConst2 n" /* Restore the context. / " ldr r1, [r3] n" / Use pxCurrentTCBConst to get the pxCurrentTCB address. / " ldr r0, [r1] n" / The first item in pxCurrentTCB is the task top of stack. / " ldmia r0!, {r4-r11, r14} n" / Pop the registers that are not automatically saved on exception entry and the critical nesting count. / " msr psp, r0 n" / Restore the task stack pointer. / " isb n" " mov r0, #0 n" " msr basepri, r0 n" " bx r14 n" " n" " .align 2 n" "pxCurrentTCBConst2: .word pxCurrentTCB n" ); } /-----------------------------------------------------------*/

static void prvPortStartFirstTask( void ) { __asm volatile( " ldr r0, =0xE000ED08 n" /* Use the NVIC offset register to locate the stack. / " ldr r0, [r0] n" " ldr r0, [r0] n" " msr msp, r0 n" / Set the msp back to the start of the stack. / " cpsie i n" / Globally enable interrupts. / " dsb n" " isb n" " svc 0 n" / System call to start first task. / " nop n" ); } /-----------------------------------------------------------*/

/* * See header file for description. / BaseType_t xPortStartScheduler( void ) { / configMAXSYSCALLINTERRUPTPRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( configMAXSYSCALLINTERRUPTPRIORITY );

#if( configASSERT_DEFINED == 1 )
{
	volatile uint32_t ulOriginalPriority;
	volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
	volatile uint8_t ucMaxPriorityValue;

	/* Determine the maximum priority from which ISR safe FreeRTOS API
	functions can be called.  ISR safe functions are those that end in
	"FromISR".  FreeRTOS maintains separate thread and ISR API functions to
	ensure interrupt entry is as fast and simple as possible.

	Save the interrupt priority value that is about to be clobbered. */
	ulOriginalPriority = *pucFirstUserPriorityRegister;

	/* Determine the number of priority bits available.  First write to all
	possible bits. */
	*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;

	/* Read the value back to see how many bits stuck. */
	ucMaxPriorityValue = *pucFirstUserPriorityRegister;

	/* Use the same mask on the maximum system call priority. */
	ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;

	/* Calculate the maximum acceptable priority group value for the number
	of bits read back. */
	ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
	while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
	{
		ulMaxPRIGROUPValue--;
		ucMaxPriorityValue <<= ( uint8_t ) 0x01;
	}

	/* Shift the priority group value back to its position within the AIRCR
	register. */
	ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
	ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;

	/* Restore the clobbered interrupt priority register to its original
	value. */
	*pucFirstUserPriorityRegister = ulOriginalPriority;
}
#endif /* conifgASSERT_DEFINED */

/* Make PendSV and SysTick the lowest priority interrupts. */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;

/* Start the timer that generates the tick ISR.  Interrupts are disabled
here already. */
vPortSetupTimerInterrupt();

/* Initialise the critical nesting count ready for the first task. */
uxCriticalNesting = 0;

/* Ensure the VFP is enabled - it should be anyway. */
vPortEnableVFP();

/* Lazy save always. */
*( portFPCCR ) |= portASPEN_AND_LSPEN_BITS;

/* Start the first task. */
prvPortStartFirstTask();

/* Should never get here as the tasks will now be executing!  Call the task
exit error function to prevent compiler warnings about a static function
not being called in the case that the application writer overrides this
functionality by defining configTASK_RETURN_ADDRESS. */
prvTaskExitError();

/* Should not get here! */
return 0;

} /-----------------------------------------------------------/

void vPortEndScheduler( void ) { /* Not implemented in ports where there is nothing to return to. Artificially force an assert. / configASSERT( uxCriticalNesting == 1000UL ); } /-----------------------------------------------------------*/

void vPortYield( void ) { /* Set a PendSV to request a context switch. */ portNVICINTCTRLREG = portNVICPENDSVSET_BIT;

/* Barriers are normally not required but do ensure the code is completely
within the specified behaviour for the architecture. */
__asm volatile( "dsb" );
__asm volatile( "isb" );

} /-----------------------------------------------------------/

void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; __asm volatile( "dsb" ); __asm volatile( "isb" ); } /-----------------------------------------------------------/

void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting == 0 ) { portENABLE_INTERRUPTS(); } } /-----------------------------------------------------------/

attribute(( naked )) uint32t ulPortSetInterruptMask( void ) { __asm volatile ( " mrs r0, basepri n" " mov r1, %0 n" " msr basepri, r1 n" " bx lr n" :: "i" ( configMAXSYSCALLINTERRUPTPRIORITY ) : "r0", "r1" );

/* This return will not be reached but is necessary to prevent compiler
warnings. */
return 0;

} /-----------------------------------------------------------/

attribute(( naked )) void vPortClearInterruptMask( uint32_t ulNewMaskValue ) { __asm volatile ( " msr basepri, r0 n" " bx lr n" :::"r0" );

/* Just to avoid compiler warnings. */
( void ) ulNewMaskValue;

} /-----------------------------------------------------------/

void xPortPendSVHandler( void ) { /* This is a naked function. */

__asm volatile
(
"	mrs r0, psp							\n"
"	isb									\n"
"										\n"
"	ldr	r3, pxCurrentTCBConst			\n" /* Get the location of the current TCB. */
"	ldr	r2, [r3]						\n"
"										\n"
"	tst r14, #0x10						\n" /* Is the task using the FPU context?  If so, push high vfp registers. */
"	it eq								\n"
"	vstmdbeq r0!, {s16-s31}				\n"
"										\n"
"	stmdb r0!, {r4-r11, r14}			\n" /* Save the core registers. */
"										\n"
"	str r0, [r2]						\n" /* Save the new top of stack into the first member of the TCB. */
"										\n"
"	stmdb sp!, {r3}						\n"
"	mov r0, %0 							\n"
"	msr basepri, r0						\n"
"	bl vTaskSwitchContext				\n"
"	mov r0, #0							\n"
"	msr basepri, r0						\n"
"	ldmia sp!, {r3}						\n"
"										\n"
"	ldr r1, [r3]						\n" /* The first item in pxCurrentTCB is the task top of stack. */
"	ldr r0, [r1]						\n"
"										\n"
"	ldmia r0!, {r4-r11, r14}			\n" /* Pop the core registers. */
"										\n"
"	tst r14, #0x10						\n" /* Is the task using the FPU context?  If so, pop the high vfp registers too. */
"	it eq								\n"
"	vldmiaeq r0!, {s16-s31}				\n"
"										\n"
"	msr psp, r0							\n"
"	isb									\n"
"										\n"
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */
	#if WORKAROUND_PMU_CM001 == 1
"			push { r14 }				\n"
"			pop { pc }					\n"
	#endif
#endif
"										\n"
"	bx r14								\n"
"										\n"
"	.align 2							\n"
"pxCurrentTCBConst: .word pxCurrentTCB	\n"
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
);

} /-----------------------------------------------------------/

void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt executes all interrupts must be unmasked. There is therefore no need to save and then restore the interrupt mask value as its value is already known. / ( void ) portSETINTERRUPTMASKFROMISR(); { / Increment the RTOS tick. / if( xTaskIncrementTick() != pdFALSE ) { / A context switch is required. Context switching is performed in the PendSV interrupt. Pend the PendSV interrupt. / portNVICINTCTRLREG = portNVICPENDSVSETBIT; } } portCLEARINTERRUPTMASKFROM_ISR( 0 ); } /-----------------------------------------------------------*/

if configUSETICKLESSIDLE == 1
__attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
{
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL;
TickType_t xModifiableIdleTime;

	/* Make sure the SysTick reload value does not overflow the counter. */
	if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
	{
		xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
	}

	/* Stop the SysTick momentarily.  The time the SysTick is stopped for
	is accounted for as best it can be, but using the tickless mode will
	inevitably result in some tiny drift of the time maintained by the
	kernel with respect to calendar time. */
	portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;

	/* Calculate the reload value required to wait xExpectedIdleTime
	tick periods.  -1 is used because this code will execute part way
	through one of the tick periods. */
	ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
	if( ulReloadValue > ulStoppedTimerCompensation )
	{
		ulReloadValue -= ulStoppedTimerCompensation;
	}

	/* Enter a critical section but don't use the taskENTER_CRITICAL()
	method as that will mask interrupts that should exit sleep mode. */
	__asm volatile( "cpsid i" );

	/* If a context switch is pending or a task is waiting for the scheduler
	to be unsuspended then abandon the low power entry. */
	if( eTaskConfirmSleepModeStatus() == eAbortSleep )
	{
		/* Restart from whatever is left in the count register to complete
		this tick period. */
		portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;

		/* Restart SysTick. */
		portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;

		/* Reset the reload register to the value required for normal tick
		periods. */
		portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;

		/* Re-enable interrupts - see comments above the cpsid instruction()
		above. */
		__asm volatile( "cpsie i" );
	}
	else
	{
		/* Set the new reload value. */
		portNVIC_SYSTICK_LOAD_REG = ulReloadValue;

		/* Clear the SysTick count flag and set the count value back to
		zero. */
		portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;

		/* Restart SysTick. */
		portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;

		/* Sleep until something happens.  configPRE_SLEEP_PROCESSING() can
		set its parameter to 0 to indicate that its implementation contains
		its own wait for interrupt or wait for event instruction, and so wfi
		should not be executed again.  However, the original expected idle
		time variable must remain unmodified, so a copy is taken. */
		xModifiableIdleTime = xExpectedIdleTime;
		configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
		if( xModifiableIdleTime > 0 )
		{
			__asm volatile( "dsb" );
			__asm volatile( "wfi" );
			__asm volatile( "isb" );
		}
		configPOST_SLEEP_PROCESSING( xExpectedIdleTime );

		/* Stop SysTick.  Again, the time the SysTick is stopped for is
		accounted for as best it can be, but using the tickless mode will
		inevitably result in some tiny drift of the time maintained by the
		kernel with respect to calendar time. */
		ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG;
		portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT );

		/* Re-enable interrupts - see comments above the cpsid instruction()
		above. */
		__asm volatile( "cpsie i" );

		if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
		{
			uint32_t ulCalculatedLoadValue;

			/* The tick interrupt has already executed, and the SysTick
			count reloaded with ulReloadValue.  Reset the
			portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
			period. */
			ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );

			/* Don't allow a tiny value, or values that have somehow
			underflowed because the post sleep hook did something
			that took too long. */
			if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
			{
				ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
			}

			portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;

			/* The tick interrupt handler will already have pended the tick
			processing in the kernel.  As the pending tick will be
			processed as soon as this function exits, the tick value
			maintained by the tick is stepped forward by one less than the
			time spent waiting. */
			ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
		}
		else
		{
			/* Something other than the tick interrupt ended the sleep.
			Work out how long the sleep lasted rounded to complete tick
			periods (not the ulReload value which accounted for part
			ticks). */
			ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;

			/* How many complete tick periods passed while the processor
			was waiting? */
			ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;

			/* The reload value is set to whatever fraction of a single tick
			period remains. */
			portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
		}

		/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
		again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
		value.  The critical section is used to ensure the tick interrupt
		can only execute once in the case that the reload register is near
		zero. */
		portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
		portENTER_CRITICAL();
		{
			portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
			vTaskStepTick( ulCompleteTickPeriods );
			portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
		}
		portEXIT_CRITICAL();
	}
}
endif /* #if configUSETICKLESSIDLE */

/-----------------------------------------------------------/

/* * Setup the systick timer to generate the tick interrupts at the required * frequency. / attribute(( weak )) void vPortSetupTimerInterrupt( void ) { / Calculate the constants required to configure the tick interrupt. / #if configUSETICKLESSIDLE == 1 { ulTimerCountsForOneTick = ( configSYSTICKCLOCKHZ / configTICKRATEHZ ); xMaximumPossibleSuppressedTicks = portMAX24BITNUMBER / ulTimerCountsForOneTick; ulStoppedTimerCompensation = portMISSEDCOUNTSFACTOR / ( configCPUCLOCKHZ / configSYSTICKCLOCK_HZ ); } #endif / configUSETICKLESSIDLE */

/* Configure SysTick to interrupt at the requested rate. */
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );

} /-----------------------------------------------------------/

/* This is a naked function. / static void vPortEnableVFP( void ) { __asm volatile ( " ldr.w r0, =0xE000ED88 n" / The FPU enable bits are in the CPACR. / " ldr r1, [r0] n" " n" " orr r1, r1, #( 0xf << 20 ) n" / Enable CP10 and CP11 coprocessors, then save back. / " str r1, [r0] n" " bx r14 " ); } /-----------------------------------------------------------*/

if( configASSERT_DEFINED == 1 )
void vPortValidateInterruptPriority( void )
{
uint32_t ulCurrentInterrupt;
uint8_t ucCurrentPriority;

	/* Obtain the number of the currently executing interrupt. */
	__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );

	/* Is the interrupt number a user defined interrupt? */
	if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
	{
		/* Look up the interrupt's priority. */
		ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];

		/* The following assertion will fail if a service routine (ISR) for
		an interrupt that has been assigned a priority above
		configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
		function.  ISR safe FreeRTOS API functions must *only* be called
		from interrupts that have been assigned a priority at or below
		configMAX_SYSCALL_INTERRUPT_PRIORITY.

		Numerically low interrupt priority numbers represent logically high
		interrupt priorities, therefore the priority of the interrupt must
		be set to a value equal to or numerically *higher* than
		configMAX_SYSCALL_INTERRUPT_PRIORITY.

		Interrupts that	use the FreeRTOS API must not be left at their
		default priority of	zero as that is the highest possible priority,
		which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
		and	therefore also guaranteed to be invalid.

		FreeRTOS maintains separate thread and ISR API functions to ensure
		interrupt entry is as fast and simple as possible.

		The following links provide detailed information:
		http://www.freertos.org/RTOS-Cortex-M3-M4.html
		http://www.freertos.org/FAQHelp.html */
		configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
	}

	/* Priority grouping:  The interrupt controller (NVIC) allows the bits
	that define each interrupt's priority to be split between bits that
	define the interrupt's pre-emption priority bits and bits that define
	the interrupt's sub-priority.  For simplicity all bits must be defined
	to be pre-emption priority bits.  The following assertion will fail if
	this is not the case (if some bits represent a sub-priority).

	If the application only uses CMSIS libraries for interrupt
	configuration then the correct setting can be achieved on all Cortex-M
	devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
	scheduler.  Note however that some vendor specific peripheral libraries
	assume a non-zero priority group setting, in which cases using a value
	of zero will result in unpredicable behaviour. */
	configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
}
endif /* configASSERT_DEFINED */

~~~


compile doesn't get errors, But rtos task can not start.

Posted by rtel on August 23, 2017

If this is a C++ problem I would suggest re-posting with C++ in the subject. We don't use C++ ourselves, but there are experts on the forum that will answer if they know your question is related to C++.


compile doesn't get errors, But rtos task can not start.

Posted by rtel on August 23, 2017

Also, I"m not sure why you are posting source files that are in the download and available to view in the public SVN repository - unless you changed something in the FreeRTOS code? If you did change something, then that is generally a bad idea, but at least point out where the change is rathe than just post the whole file.


compile doesn't get errors, But rtos task can not start.

Posted by heinbali01 on August 23, 2017

It looks like you are using an antique version V7.1.0. In that version, the header files still did not have these C-linkage statements:

~~~~

ifdef __cplusplus

extern "C" {

endif
ifdef __cplusplus

}

endif

~~~~

Could you please first download the latest kernel sources and test with them. Also check if C++ start-up code ( calling static and global constructors ) will be included into your code.

I can confirm that FreeRTOS works perfectly in a C++ application.

One user, Richard Damon, wrote a C++ wrapper for FreeRTOS.


[ 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