+ The MPU port is not supported in this revision number.
+ The documentation for the static allocation functions in the header files has not yet been updated for this revision.

Kernel updates:
+ Simplify the static allocation of objects implementation.
+ Introduce configSUPPORT_DYNAMIC_ALLOCATION in addition to the existing configSUPPORT_STATIC_ALLOCATION so FreeRTOS can be built without providing a heap at all.

Demo application updates:
+ Update the demos to take into account the new configSUPPORT_DYNAMIC_ALLOCATION constant.
+ Add an MSVC demo that only uses static allocation, and does not include a FreeRTOS heap.
+ Update the MSVC project to use both configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION.
+ Update the MingW project to use only configSUPPORT_DYNAMIC_ALLOCATION.
This commit is contained in:
Richard Barry 2016-03-22 16:23:37 +00:00
parent 283bc18d23
commit 6568ba6eb0
50 changed files with 2350 additions and 3914 deletions

View file

@ -71,6 +71,8 @@
* Implementation of functions defined in portable.h for the ARM CM3 port.
*----------------------------------------------------------*/
#error This port is not currently supported in this V9.0.0 revision number but will be by the final release. For now use V8.2.3 instead.
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */
@ -1156,27 +1158,35 @@ BaseType_t xRunningPrivileged = prvRaisePrivilege();
}
/*-----------------------------------------------------------*/
void *MPU_pvPortMalloc( size_t xSize )
{
void *pvReturn;
BaseType_t xRunningPrivileged = prvRaisePrivilege();
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
void *MPU_pvPortMalloc( size_t xSize )
{
void *pvReturn;
BaseType_t xRunningPrivileged = prvRaisePrivilege();
pvReturn = pvPortMalloc( xSize );
pvReturn = pvPortMalloc( xSize );
portRESET_PRIVILEGE( xRunningPrivileged );
portRESET_PRIVILEGE( xRunningPrivileged );
return pvReturn;
}
return pvReturn;
}
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
/*-----------------------------------------------------------*/
void MPU_vPortFree( void *pv )
{
BaseType_t xRunningPrivileged = prvRaisePrivilege();
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
vPortFree( pv );
void MPU_vPortFree( void *pv )
{
BaseType_t xRunningPrivileged = prvRaisePrivilege();
portRESET_PRIVILEGE( xRunningPrivileged );
}
vPortFree( pv );
portRESET_PRIVILEGE( xRunningPrivileged );
}
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
/*-----------------------------------------------------------*/
void MPU_vPortInitialiseBlocks( void )

View file

@ -89,6 +89,10 @@
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be between 2 and 15
#endif
#if( ( configSUPPORT_FPU == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) )
#error configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 to use this port with an FPU
#endif
/* A critical section is exited when the critical section nesting count reaches
this value. */
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
@ -640,7 +644,7 @@ BaseType_t xPortInstallInterruptHandler( ISR_Handler_t pxHandler, uint32_t ulVec
BaseType_t xReturn;
xReturn = prvCheckValidityOfVectorNumber( ulVectorNumber );
if( xReturn != pdFAIL )
{
taskENTER_CRITICAL();

View file

@ -84,6 +84,10 @@
#include <xintc_i.h>
#include <xtmrctr.h>
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#error configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 to use this port.
#endif
/* Tasks are started with interrupts enabled. */
#define portINITIAL_MSR_STATE ( ( StackType_t ) 0x02 )
@ -99,7 +103,7 @@ to reach zero, so it is initialised to a high value. */
debugging. */
#define portISR_STACK_FILL_VALUE 0x55555555
/* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task
/* Counts the nesting depth of calls to portENTER_CRITICAL(). Each task
maintains it's own count, so this variable is saved as part of the task
context. */
volatile UBaseType_t uxCriticalNesting = portINITIAL_NESTING_VALUE;
@ -117,10 +121,10 @@ uint32_t *pulISRStack;
static void prvSetupTimerInterrupt( void );
/*-----------------------------------------------------------*/
/*
* Initialise the stack of a task to look exactly as if a call to
/*
* Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been made.
*
*
* See the header file portable.h.
*/
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
@ -129,16 +133,16 @@ extern void *_SDA2_BASE_, *_SDA_BASE_;
const uint32_t ulR2 = ( uint32_t ) &_SDA2_BASE_;
const uint32_t ulR13 = ( uint32_t ) &_SDA_BASE_;
/* Place a few bytes of known values on the bottom of the stack.
/* Place a few bytes of known values on the bottom of the stack.
This is essential for the Microblaze port and these lines must
not be omitted. The parameter value will overwrite the
not be omitted. The parameter value will overwrite the
0x22222222 value during the function prologue. */
*pxTopOfStack = ( StackType_t ) 0x11111111;
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x22222222;
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x33333333;
pxTopOfStack--;
pxTopOfStack--;
/* First stack an initial value for the critical section nesting. This
is initialised to zero as tasks are started with interrupts enabled. */
@ -261,7 +265,7 @@ void vPortEndScheduler( void )
/*-----------------------------------------------------------*/
/*
* Manual context switch called by portYIELD or taskYIELD.
* Manual context switch called by portYIELD or taskYIELD.
*/
void vPortYield( void )
{
@ -280,7 +284,7 @@ extern void VPortYieldASM( void );
/*-----------------------------------------------------------*/
/*
* Hardware initialisation to generate the RTOS tick.
* Hardware initialisation to generate the RTOS tick.
*/
static void prvSetupTimerInterrupt( void )
{
@ -295,12 +299,12 @@ UBaseType_t uxMask;
XTmrCtr_mSetLoadReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCounterValue );
XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, XTC_CSR_LOAD_MASK | XTC_CSR_INT_OCCURED_MASK );
/* Set the timer interrupt enable bit while maintaining the other bit
/* Set the timer interrupt enable bit while maintaining the other bit
states. */
uxMask = XIntc_In32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ) );
uxMask |= XPAR_OPB_TIMER_1_INTERRUPT_MASK;
XIntc_Out32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ), ( uxMask ) );
XIntc_Out32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ), ( uxMask ) );
XTmrCtr_Start( &xTimer, XPAR_OPB_TIMER_1_DEVICE_ID );
XTmrCtr_mSetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK | XTC_CSR_INT_OCCURED_MASK );
XIntc_mAckIntr( XPAR_INTC_SINGLE_BASEADDR, 1 );
@ -310,12 +314,12 @@ UBaseType_t uxMask;
/*
* The interrupt handler placed in the interrupt vector when the scheduler is
* started. The task context has already been saved when this is called.
* This handler determines the interrupt source and calls the relevant
* This handler determines the interrupt source and calls the relevant
* peripheral handler.
*/
void vTaskISRHandler( void )
{
static uint32_t ulPending;
static uint32_t ulPending;
/* Which interrupts are pending? */
ulPending = XIntc_In32( ( XPAR_INTC_SINGLE_BASEADDR + XIN_IVR_OFFSET ) );
@ -346,7 +350,7 @@ static uint32_t ulPending;
}
/*-----------------------------------------------------------*/
/*
/*
* Handler for the timer interrupt.
*/
void vTickISR( void *pvBaseAddress )
@ -360,7 +364,7 @@ uint32_t ulCSR;
}
/* Clear the timer interrupt */
ulCSR = XTmrCtr_mGetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, 0);
ulCSR = XTmrCtr_mGetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, 0);
XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCSR );
}
/*-----------------------------------------------------------*/

View file

@ -70,7 +70,6 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#include <Windows.h>
/******************************************************************************
Defines

View file

@ -87,6 +87,10 @@ task.h is included from an application file. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
#endif
/* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )

View file

@ -88,6 +88,10 @@ task.h is included from an application file. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
#endif
/* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )

View file

@ -91,6 +91,10 @@ task.h is included from an application file. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
#endif
/*-----------------------------------------------------------*/
void *pvPortMalloc( size_t xWantedSize )

View file

@ -87,6 +87,10 @@ task.h is included from an application file. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
#endif
/* Block sizes must not get too small. */
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )

View file

@ -121,6 +121,10 @@ task.h is included from an application file. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
#endif
/* Block sizes must not get too small. */
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )

View file

@ -84,13 +84,17 @@
value is for all interrupts to be enabled. */
#define portINITIAL_SR ( 0UL )
/* Dimensions the array into which the floating point context is saved.
/* Dimensions the array into which the floating point context is saved.
Allocate enough space for FPR0 to FPR15, FPUL and FPSCR, each of which is 4
bytes big. If this number is changed then the 72 in portasm.src also needs
changing. */
#define portFLOP_REGISTERS_TO_STORE ( 18 )
#define portFLOP_STORAGE_SIZE ( portFLOP_REGISTERS_TO_STORE * 4 )
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#error configSUPPORT_DYNAMIC_ALLOCATION must be 1 to use this port.
#endif
/*-----------------------------------------------------------*/
/*
@ -110,8 +114,8 @@ extern uint32_t ulPortGetGBR( void );
/*-----------------------------------------------------------*/
/*
* See header file for description.
/*
* See header file for description.
*/
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
@ -124,17 +128,17 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
pxTopOfStack--;
/* SR. */
*pxTopOfStack = portINITIAL_SR;
*pxTopOfStack = portINITIAL_SR;
pxTopOfStack--;
/* PC. */
*pxTopOfStack = ( uint32_t ) pxCode;
pxTopOfStack--;
/* PR. */
*pxTopOfStack = 15;
pxTopOfStack--;
/* 14. */
*pxTopOfStack = 14;
pxTopOfStack--;
@ -190,22 +194,22 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
/* R1. */
*pxTopOfStack = 1;
pxTopOfStack--;
/* R0 */
*pxTopOfStack = 0;
pxTopOfStack--;
/* MACL. */
*pxTopOfStack = 16;
pxTopOfStack--;
/* MACH. */
*pxTopOfStack = 17;
pxTopOfStack--;
/* GBR. */
*pxTopOfStack = ulPortGetGBR();
/* GBR = global base register.
VBR = vector base register.
TBR = jump table base register.
@ -220,7 +224,7 @@ BaseType_t xPortStartScheduler( void )
extern void vApplicationSetupTimerInterrupt( void );
/* Call an application function to set up the timer that will generate the
tick interrupt. This way the application can decide which peripheral to
tick interrupt. This way the application can decide which peripheral to
use. A demo application is provided to show a suitable example. */
vApplicationSetupTimerInterrupt();
@ -252,11 +256,11 @@ int32_t lInterruptMask;
/* taskYIELD() can only be called from a task, not an interrupt, so the
current interrupt mask can only be 0 or portKERNEL_INTERRUPT_PRIORITY and
the mask can be set without risk of accidentally lowering the mask value. */
the mask can be set without risk of accidentally lowering the mask value. */
set_imask( portKERNEL_INTERRUPT_PRIORITY );
trapa( portYIELD_TRAP_NO );
/* Restore the interrupt mask to whatever it was previously (when the
function was entered). */
set_imask( ( int ) lInterruptMask );
@ -282,26 +286,26 @@ extern void * volatile pxCurrentTCB;
/* Allocate a buffer large enough to hold all the flop registers. */
pulFlopBuffer = ( uint32_t * ) pvPortMalloc( portFLOP_STORAGE_SIZE );
if( pulFlopBuffer != NULL )
{
/* Start with the registers in a benign state. */
memset( ( void * ) pulFlopBuffer, 0x00, portFLOP_STORAGE_SIZE );
/* The first thing to get saved in the buffer is the FPSCR value -
initialise this to the current FPSCR value. */
*pulFlopBuffer = get_fpscr();
/* Use the task tag to point to the flop buffer. Pass pointer to just
/* Use the task tag to point to the flop buffer. Pass pointer to just
above the buffer because the flop save routine uses a pre-decrement. */
vTaskSetApplicationTaskTag( xTask, ( void * ) ( pulFlopBuffer + portFLOP_REGISTERS_TO_STORE ) );
vTaskSetApplicationTaskTag( xTask, ( void * ) ( pulFlopBuffer + portFLOP_REGISTERS_TO_STORE ) );
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
}
return xReturn;
}
/*-----------------------------------------------------------*/

View file

@ -70,7 +70,7 @@
/*
Changes from V3.2.1
+ CallReturn Depth increased from 8 to 10 levels to accomodate wizC/fedC V12.
Changes from V3.2.0
+ TBLPTRU is now initialised to zero during the initial stack creation of a new task. This solves
an error on devices with more than 64kB ROM.
@ -134,7 +134,7 @@ uint16_t usCalcMinStackSize = 0;
/*-----------------------------------------------------------*/
/*
* We initialise ucCriticalNesting to the middle value an
* We initialise ucCriticalNesting to the middle value an
* uint8_t can contain. This way portENTER_CRITICAL()
* and portEXIT_CRITICAL() can be called without interrupts
* being enabled before the scheduler starts.
@ -143,9 +143,9 @@ register uint8_t ucCriticalNesting = 0x7F;
/*-----------------------------------------------------------*/
/*
/*
* Initialise the stack of a new task.
* See portSAVE_CONTEXT macro for description.
* See portSAVE_CONTEXT macro for description.
*/
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
@ -161,7 +161,7 @@ uint8_t ucScratch;
ucScratch = PRODL;
/*
* Place a few bytes of known values on the bottom of the stack.
* Place a few bytes of known values on the bottom of the stack.
* This is just useful for debugging.
*/
// *pxTopOfStack-- = 0x11;
@ -210,10 +210,10 @@ uint8_t ucScratch;
{
*pxTopOfStack-- = ( StackType_t ) 0;
}
/*
* The only function return address so far is the address of the task entry.
* The order is TOSU/TOSH/TOSL. For devices > 64kB, TOSU is put on the
* The order is TOSU/TOSH/TOSL. For devices > 64kB, TOSU is put on the
* stack, too. TOSU is always written as zero here because wizC does not allow
* functionpointers to point above 64kB in ROM.
*/
@ -231,12 +231,12 @@ uint8_t ucScratch;
/*
* The code generated by wizC does not maintain separate
* stack and frame pointers. Therefore the portENTER_CRITICAL macro cannot
* stack and frame pointers. Therefore the portENTER_CRITICAL macro cannot
* use the stack as per other ports. Instead a variable is used to keep
* track of the critical section nesting. This variable has to be stored
* as part of the task context and is initially set to zero.
*/
*pxTopOfStack-- = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
*pxTopOfStack-- = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
return pxTopOfStack;
}
@ -272,7 +272,7 @@ BaseType_t xPortStartScheduler( void )
/*
* Setup a timer for the tick ISR for the preemptive scheduler.
*/
portSetupTick();
portSetupTick();
/*
* Restore the context of the first task to run.
@ -321,30 +321,39 @@ void vPortYield( void )
*/
portRESTORE_CONTEXT();
}
/*-----------------------------------------------------------*/
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
void *pvPortMalloc( uint16_t usWantedSize )
{
void *pvReturn;
vTaskSuspendAll();
{
pvReturn = malloc( ( malloc_t ) usWantedSize );
}
xTaskResumeAll();
return pvReturn;
}
#endif /* configSUPPORT_STATIC_ALLOCATION */
/*-----------------------------------------------------------*/
void *pvPortMalloc( uint16_t usWantedSize )
{
void *pvReturn;
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
vTaskSuspendAll();
void vPortFree( void *pv )
{
pvReturn = malloc( ( malloc_t ) usWantedSize );
}
xTaskResumeAll();
return pvReturn;
}
void vPortFree( void *pv )
{
if( pv )
{
vTaskSuspendAll();
if( pv )
{
free( pv );
vTaskSuspendAll();
{
free( pv );
}
xTaskResumeAll();
}
xTaskResumeAll();
}
}
#endif /* configSUPPORT_STATIC_ALLOCATION */