mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-07 05:34:59 -05:00
Style: uncrusitfy
This commit is contained in:
parent
a5dbc2b1de
commit
718178c68a
406 changed files with 108795 additions and 106323 deletions
153
croutine.c
153
croutine.c
|
|
@ -29,32 +29,32 @@
|
||||||
#include "croutine.h"
|
#include "croutine.h"
|
||||||
|
|
||||||
/* Remove the whole file is co-routines are not being used. */
|
/* Remove the whole file is co-routines are not being used. */
|
||||||
#if( configUSE_CO_ROUTINES != 0 )
|
#if ( configUSE_CO_ROUTINES != 0 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some kernel aware debuggers require data to be viewed to be global, rather
|
* Some kernel aware debuggers require data to be viewed to be global, rather
|
||||||
* than file scope.
|
* than file scope.
|
||||||
*/
|
*/
|
||||||
#ifdef portREMOVE_STATIC_QUALIFIER
|
#ifdef portREMOVE_STATIC_QUALIFIER
|
||||||
#define static
|
#define static
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Lists for ready and blocked co-routines. --------------------*/
|
/* Lists for ready and blocked co-routines. --------------------*/
|
||||||
static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
|
static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
|
||||||
static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */
|
static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */
|
||||||
static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
|
static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
|
||||||
static List_t * pxDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used. */
|
static List_t * pxDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used. */
|
||||||
static List_t * pxOverflowDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
|
static List_t * pxOverflowDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
|
||||||
static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
|
static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
|
||||||
|
|
||||||
/* Other file private variables. --------------------------------*/
|
/* Other file private variables. --------------------------------*/
|
||||||
CRCB_t * pxCurrentCoRoutine = NULL;
|
CRCB_t * pxCurrentCoRoutine = NULL;
|
||||||
static UBaseType_t uxTopCoRoutineReadyPriority = 0;
|
static UBaseType_t uxTopCoRoutineReadyPriority = 0;
|
||||||
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
||||||
|
|
||||||
/* The initial state of the co-routine when it is created. */
|
/* The initial state of the co-routine when it is created. */
|
||||||
#define corINITIAL_STATE ( 0 )
|
#define corINITIAL_STATE ( 0 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Place the co-routine represented by pxCRCB into the appropriate ready queue
|
* Place the co-routine represented by pxCRCB into the appropriate ready queue
|
||||||
|
|
@ -63,20 +63,20 @@ static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
||||||
* This macro accesses the co-routine ready lists and therefore must not be
|
* This macro accesses the co-routine ready lists and therefore must not be
|
||||||
* used from within an ISR.
|
* used from within an ISR.
|
||||||
*/
|
*/
|
||||||
#define prvAddCoRoutineToReadyQueue( pxCRCB ) \
|
#define prvAddCoRoutineToReadyQueue( pxCRCB ) \
|
||||||
{ \
|
{ \
|
||||||
if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \
|
if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \
|
||||||
{ \
|
{ \
|
||||||
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
|
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
|
||||||
} \
|
} \
|
||||||
vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
|
vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility to ready all the lists used by the scheduler. This is called
|
* Utility to ready all the lists used by the scheduler. This is called
|
||||||
* automatically upon the creation of the first co-routine.
|
* automatically upon the creation of the first co-routine.
|
||||||
*/
|
*/
|
||||||
static void prvInitialiseCoRoutineLists( void );
|
static void prvInitialiseCoRoutineLists( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Co-routines that are readied by an interrupt cannot be placed directly into
|
* Co-routines that are readied by an interrupt cannot be placed directly into
|
||||||
|
|
@ -84,7 +84,7 @@ static void prvInitialiseCoRoutineLists( void );
|
||||||
* in the pending ready list in order that they can later be moved to the ready
|
* in the pending ready list in order that they can later be moved to the ready
|
||||||
* list by the co-routine scheduler.
|
* list by the co-routine scheduler.
|
||||||
*/
|
*/
|
||||||
static void prvCheckPendingReadyList( void );
|
static void prvCheckPendingReadyList( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro that looks at the list of co-routines that are currently delayed to
|
* Macro that looks at the list of co-routines that are currently delayed to
|
||||||
|
|
@ -94,21 +94,24 @@ static void prvCheckPendingReadyList( void );
|
||||||
* meaning once one co-routine has been found whose timer has not expired
|
* meaning once one co-routine has been found whose timer has not expired
|
||||||
* we need not look any further down the list.
|
* we need not look any further down the list.
|
||||||
*/
|
*/
|
||||||
static void prvCheckDelayedList( void );
|
static void prvCheckDelayedList( void );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex )
|
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode,
|
||||||
{
|
UBaseType_t uxPriority,
|
||||||
BaseType_t xReturn;
|
UBaseType_t uxIndex )
|
||||||
CRCB_t *pxCoRoutine;
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
CRCB_t * pxCoRoutine;
|
||||||
|
|
||||||
/* Allocate the memory that will store the co-routine control block. */
|
/* Allocate the memory that will store the co-routine control block. */
|
||||||
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
|
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
|
||||||
|
|
||||||
if( pxCoRoutine )
|
if( pxCoRoutine )
|
||||||
{
|
{
|
||||||
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
||||||
be created and the co-routine data structures need initialising. */
|
* be created and the co-routine data structures need initialising. */
|
||||||
if( pxCurrentCoRoutine == NULL )
|
if( pxCurrentCoRoutine == NULL )
|
||||||
{
|
{
|
||||||
pxCurrentCoRoutine = pxCoRoutine;
|
pxCurrentCoRoutine = pxCoRoutine;
|
||||||
|
|
@ -132,8 +135,8 @@ CRCB_t *pxCoRoutine;
|
||||||
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
||||||
|
|
||||||
/* Set the co-routine control block as a link back from the ListItem_t.
|
/* Set the co-routine control block as a link back from the ListItem_t.
|
||||||
This is so we can get back to the containing CRCB from a generic item
|
* This is so we can get back to the containing CRCB from a generic item
|
||||||
in a list. */
|
* in a list. */
|
||||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
||||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
||||||
|
|
||||||
|
|
@ -141,7 +144,7 @@ CRCB_t *pxCoRoutine;
|
||||||
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
|
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
|
||||||
|
|
||||||
/* Now the co-routine has been initialised it can be added to the ready
|
/* Now the co-routine has been initialised it can be added to the ready
|
||||||
list at the correct priority. */
|
* list at the correct priority. */
|
||||||
prvAddCoRoutineToReadyQueue( pxCoRoutine );
|
prvAddCoRoutineToReadyQueue( pxCoRoutine );
|
||||||
|
|
||||||
xReturn = pdPASS;
|
xReturn = pdPASS;
|
||||||
|
|
@ -152,20 +155,21 @@ CRCB_t *pxCoRoutine;
|
||||||
}
|
}
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
|
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
|
||||||
{
|
List_t * pxEventList )
|
||||||
TickType_t xTimeToWake;
|
{
|
||||||
|
TickType_t xTimeToWake;
|
||||||
|
|
||||||
/* Calculate the time to wake - this may overflow but this is
|
/* Calculate the time to wake - this may overflow but this is
|
||||||
not a problem. */
|
* not a problem. */
|
||||||
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
|
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
|
||||||
|
|
||||||
/* We must remove ourselves from the ready list before adding
|
/* We must remove ourselves from the ready list before adding
|
||||||
ourselves to the blocked list as the same list item is used for
|
* ourselves to the blocked list as the same list item is used for
|
||||||
both lists. */
|
* both lists. */
|
||||||
( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
|
|
||||||
/* The list item will be inserted in wake time order. */
|
/* The list item will be inserted in wake time order. */
|
||||||
|
|
@ -174,38 +178,38 @@ TickType_t xTimeToWake;
|
||||||
if( xTimeToWake < xCoRoutineTickCount )
|
if( xTimeToWake < xCoRoutineTickCount )
|
||||||
{
|
{
|
||||||
/* Wake time has overflowed. Place this item in the
|
/* Wake time has overflowed. Place this item in the
|
||||||
overflow list. */
|
* overflow list. */
|
||||||
vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The wake time has not overflowed, so we can use the
|
/* The wake time has not overflowed, so we can use the
|
||||||
current block list. */
|
* current block list. */
|
||||||
vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pxEventList )
|
if( pxEventList )
|
||||||
{
|
{
|
||||||
/* Also add the co-routine to an event list. If this is done then the
|
/* Also add the co-routine to an event list. If this is done then the
|
||||||
function must be called with interrupts disabled. */
|
* function must be called with interrupts disabled. */
|
||||||
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
|
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvCheckPendingReadyList( void )
|
static void prvCheckPendingReadyList( void )
|
||||||
{
|
{
|
||||||
/* Are there any co-routines waiting to get moved to the ready list? These
|
/* Are there any co-routines waiting to get moved to the ready list? These
|
||||||
are co-routines that have been readied by an ISR. The ISR cannot access
|
* are co-routines that have been readied by an ISR. The ISR cannot access
|
||||||
the ready lists itself. */
|
* the ready lists itself. */
|
||||||
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
||||||
{
|
{
|
||||||
CRCB_t *pxUnblockedCRCB;
|
CRCB_t * pxUnblockedCRCB;
|
||||||
|
|
||||||
/* The pending ready list can be accessed by an ISR. */
|
/* The pending ready list can be accessed by an ISR. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
{
|
{
|
||||||
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
|
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyCoRoutineList ) );
|
||||||
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
}
|
}
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
@ -213,14 +217,15 @@ static void prvCheckPendingReadyList( void )
|
||||||
( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
|
( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
|
||||||
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
|
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvCheckDelayedList( void )
|
static void prvCheckDelayedList( void )
|
||||||
{
|
{
|
||||||
CRCB_t *pxCRCB;
|
CRCB_t * pxCRCB;
|
||||||
|
|
||||||
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
||||||
|
|
||||||
while( xPassedTicks )
|
while( xPassedTicks )
|
||||||
{
|
{
|
||||||
xCoRoutineTickCount++;
|
xCoRoutineTickCount++;
|
||||||
|
|
@ -232,7 +237,7 @@ CRCB_t *pxCRCB;
|
||||||
List_t * pxTemp;
|
List_t * pxTemp;
|
||||||
|
|
||||||
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
||||||
any items in pxDelayedCoRoutineList here then there is an error! */
|
* any items in pxDelayedCoRoutineList here then there is an error! */
|
||||||
pxTemp = pxDelayedCoRoutineList;
|
pxTemp = pxDelayedCoRoutineList;
|
||||||
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
|
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
|
||||||
pxOverflowDelayedCoRoutineList = pxTemp;
|
pxOverflowDelayedCoRoutineList = pxTemp;
|
||||||
|
|
@ -252,10 +257,10 @@ CRCB_t *pxCRCB;
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
{
|
{
|
||||||
/* The event could have occurred just before this critical
|
/* The event could have occurred just before this critical
|
||||||
section. If this is the case then the generic list item will
|
* section. If this is the case then the generic list item will
|
||||||
have been moved to the pending ready list and the following
|
* have been moved to the pending ready list and the following
|
||||||
line is still valid. Also the pvContainer parameter will have
|
* line is still valid. Also the pvContainer parameter will have
|
||||||
been set to NULL so the following lines are also valid. */
|
* been set to NULL so the following lines are also valid. */
|
||||||
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
|
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
|
||||||
|
|
||||||
/* Is the co-routine waiting on an event also? */
|
/* Is the co-routine waiting on an event also? */
|
||||||
|
|
@ -271,14 +276,14 @@ CRCB_t *pxCRCB;
|
||||||
}
|
}
|
||||||
|
|
||||||
xLastTickCount = xCoRoutineTickCount;
|
xLastTickCount = xCoRoutineTickCount;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vCoRoutineSchedule( void )
|
void vCoRoutineSchedule( void )
|
||||||
{
|
{
|
||||||
/* Only run a co-routine after prvInitialiseCoRoutineLists() has been
|
/* Only run a co-routine after prvInitialiseCoRoutineLists() has been
|
||||||
called. prvInitialiseCoRoutineLists() is called automatically when a
|
* called. prvInitialiseCoRoutineLists() is called automatically when a
|
||||||
co-routine is created. */
|
* co-routine is created. */
|
||||||
if( pxDelayedCoRoutineList != NULL )
|
if( pxDelayedCoRoutineList != NULL )
|
||||||
{
|
{
|
||||||
/* See if any co-routines readied by events need moving to the ready lists. */
|
/* See if any co-routines readied by events need moving to the ready lists. */
|
||||||
|
|
@ -295,24 +300,23 @@ void vCoRoutineSchedule( void )
|
||||||
/* No more co-routines to check. */
|
/* No more co-routines to check. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
--uxTopCoRoutineReadyPriority;
|
--uxTopCoRoutineReadyPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
|
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
|
||||||
of the same priority get an equal share of the processor time. */
|
* of the same priority get an equal share of the processor time. */
|
||||||
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
|
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
|
||||||
|
|
||||||
/* Call the co-routine. */
|
/* Call the co-routine. */
|
||||||
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
|
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvInitialiseCoRoutineLists( void )
|
static void prvInitialiseCoRoutineLists( void )
|
||||||
{
|
{
|
||||||
UBaseType_t uxPriority;
|
UBaseType_t uxPriority;
|
||||||
|
|
||||||
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
|
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
|
||||||
{
|
{
|
||||||
|
|
@ -324,20 +328,20 @@ UBaseType_t uxPriority;
|
||||||
vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
|
vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
|
||||||
|
|
||||||
/* Start with pxDelayedCoRoutineList using list1 and the
|
/* Start with pxDelayedCoRoutineList using list1 and the
|
||||||
pxOverflowDelayedCoRoutineList using list2. */
|
* pxOverflowDelayedCoRoutineList using list2. */
|
||||||
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
|
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
|
||||||
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
|
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList )
|
BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList )
|
||||||
{
|
{
|
||||||
CRCB_t *pxUnblockedCRCB;
|
CRCB_t * pxUnblockedCRCB;
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
/* This function is called from within an interrupt. It can only access
|
/* This function is called from within an interrupt. It can only access
|
||||||
event lists and the pending ready list. This function assumes that a
|
* event lists and the pending ready list. This function assumes that a
|
||||||
check has already been made to ensure pxEventList is not empty. */
|
* check has already been made to ensure pxEventList is not empty. */
|
||||||
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
||||||
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
|
|
@ -352,7 +356,6 @@ BaseType_t xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configUSE_CO_ROUTINES == 0 */
|
#endif /* configUSE_CO_ROUTINES == 0 */
|
||||||
|
|
||||||
|
|
|
||||||
267
event_groups.c
267
event_groups.c
|
|
@ -28,8 +28,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
/* 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
|
* all the API functions to use the MPU wrappers. That should only be done when
|
||||||
task.h is included from an application file. */
|
* task.h is included from an application file. */
|
||||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
/* FreeRTOS includes. */
|
/* FreeRTOS includes. */
|
||||||
|
|
@ -39,14 +39,14 @@ task.h is included from an application file. */
|
||||||
#include "event_groups.h"
|
#include "event_groups.h"
|
||||||
|
|
||||||
/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified
|
/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified
|
||||||
because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
|
* because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
|
||||||
for the header files above, but not in this file, in order to generate the
|
* for the header files above, but not in this file, in order to generate the
|
||||||
correct privileged Vs unprivileged linkage and placement. */
|
* correct privileged Vs unprivileged linkage and placement. */
|
||||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */
|
||||||
|
|
||||||
/* The following bit fields convey control information in a task's event list
|
/* The following bit fields convey control information in a task's event list
|
||||||
item value. It is important they don't clash with the
|
* item value. It is important they don't clash with the
|
||||||
taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
|
* taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
|
||||||
#if configUSE_16_BIT_TICKS == 1
|
#if configUSE_16_BIT_TICKS == 1
|
||||||
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
|
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
|
||||||
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
|
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
|
||||||
|
|
@ -64,11 +64,11 @@ typedef struct EventGroupDef_t
|
||||||
EventBits_t uxEventBits;
|
EventBits_t uxEventBits;
|
||||||
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
|
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
|
||||||
|
|
||||||
#if( configUSE_TRACE_FACILITY == 1 )
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
UBaseType_t uxEventGroupNumber;
|
UBaseType_t uxEventGroupNumber;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||||
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
|
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
|
||||||
#endif
|
#endif
|
||||||
} EventGroup_t;
|
} EventGroup_t;
|
||||||
|
|
@ -83,24 +83,26 @@ typedef struct EventGroupDef_t
|
||||||
* wait condition is met if any of the bits set in uxBitsToWait for are also set
|
* wait condition is met if any of the bits set in uxBitsToWait for are also set
|
||||||
* in uxCurrentEventBits.
|
* in uxCurrentEventBits.
|
||||||
*/
|
*/
|
||||||
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
|
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
|
||||||
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer )
|
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer )
|
||||||
{
|
{
|
||||||
EventGroup_t *pxEventBits;
|
EventGroup_t * pxEventBits;
|
||||||
|
|
||||||
/* A StaticEventGroup_t object must be provided. */
|
/* A StaticEventGroup_t object must be provided. */
|
||||||
configASSERT( pxEventGroupBuffer );
|
configASSERT( pxEventGroupBuffer );
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
/* Sanity check that the size of the structure used to declare a
|
/* Sanity check that the size of the structure used to declare a
|
||||||
variable of type StaticEventGroup_t equals the size of the real
|
* variable of type StaticEventGroup_t equals the size of the real
|
||||||
event group structure. */
|
* event group structure. */
|
||||||
volatile size_t xSize = sizeof( StaticEventGroup_t );
|
volatile size_t xSize = sizeof( StaticEventGroup_t );
|
||||||
configASSERT( xSize == sizeof( EventGroup_t ) );
|
configASSERT( xSize == sizeof( EventGroup_t ) );
|
||||||
} /*lint !e529 xSize is referenced if configASSERT() is defined. */
|
} /*lint !e529 xSize is referenced if configASSERT() is defined. */
|
||||||
|
|
@ -114,11 +116,11 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
||||||
pxEventBits->uxEventBits = 0;
|
pxEventBits->uxEventBits = 0;
|
||||||
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||||
|
|
||||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
{
|
{
|
||||||
/* Both static and dynamic allocation can be used, so note that
|
/* Both static and dynamic allocation can be used, so note that
|
||||||
this event group was created statically in case the event group
|
* this event group was created statically in case the event group
|
||||||
is later deleted. */
|
* is later deleted. */
|
||||||
pxEventBits->ucStaticallyAllocated = pdTRUE;
|
pxEventBits->ucStaticallyAllocated = pdTRUE;
|
||||||
}
|
}
|
||||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
|
@ -128,8 +130,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* xEventGroupCreateStatic should only ever be called with
|
/* xEventGroupCreateStatic should only ever be called with
|
||||||
pxEventGroupBuffer pointing to a pre-allocated (compile time
|
* pxEventGroupBuffer pointing to a pre-allocated (compile time
|
||||||
allocated) StaticEventGroup_t variable. */
|
* allocated) StaticEventGroup_t variable. */
|
||||||
traceEVENT_GROUP_CREATE_FAILED();
|
traceEVENT_GROUP_CREATE_FAILED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,25 +141,25 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
||||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
|
|
||||||
EventGroupHandle_t xEventGroupCreate( void )
|
EventGroupHandle_t xEventGroupCreate( void )
|
||||||
{
|
{
|
||||||
EventGroup_t *pxEventBits;
|
EventGroup_t * pxEventBits;
|
||||||
|
|
||||||
/* Allocate the event group. Justification for MISRA deviation as
|
/* Allocate the event group. Justification for MISRA deviation as
|
||||||
follows: pvPortMalloc() always ensures returned memory blocks are
|
* follows: pvPortMalloc() always ensures returned memory blocks are
|
||||||
aligned per the requirements of the MCU stack. In this case
|
* aligned per the requirements of the MCU stack. In this case
|
||||||
pvPortMalloc() must return a pointer that is guaranteed to meet the
|
* pvPortMalloc() must return a pointer that is guaranteed to meet the
|
||||||
alignment requirements of the EventGroup_t structure - which (if you
|
* alignment requirements of the EventGroup_t structure - which (if you
|
||||||
follow it through) is the alignment requirements of the TickType_t type
|
* follow it through) is the alignment requirements of the TickType_t type
|
||||||
(EventBits_t being of TickType_t itself). Therefore, whenever the
|
* (EventBits_t being of TickType_t itself). Therefore, whenever the
|
||||||
stack alignment requirements are greater than or equal to the
|
* stack alignment requirements are greater than or equal to the
|
||||||
TickType_t alignment requirements the cast is safe. In other cases,
|
* TickType_t alignment requirements the cast is safe. In other cases,
|
||||||
where the natural word size of the architecture is less than
|
* where the natural word size of the architecture is less than
|
||||||
sizeof( TickType_t ), the TickType_t variables will be accessed in two
|
* sizeof( TickType_t ), the TickType_t variables will be accessed in two
|
||||||
or more reads operations, and the alignment requirements is only that
|
* or more reads operations, and the alignment requirements is only that
|
||||||
of each individual read. */
|
* of each individual read. */
|
||||||
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */
|
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */
|
||||||
|
|
||||||
if( pxEventBits != NULL )
|
if( pxEventBits != NULL )
|
||||||
|
|
@ -165,11 +167,11 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
||||||
pxEventBits->uxEventBits = 0;
|
pxEventBits->uxEventBits = 0;
|
||||||
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||||
|
|
||||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
{
|
{
|
||||||
/* Both static and dynamic allocation can be used, so note this
|
/* Both static and dynamic allocation can be used, so note this
|
||||||
event group was allocated statically in case the event group is
|
* event group was allocated statically in case the event group is
|
||||||
later deleted. */
|
* later deleted. */
|
||||||
pxEventBits->ucStaticallyAllocated = pdFALSE;
|
pxEventBits->ucStaticallyAllocated = pdFALSE;
|
||||||
}
|
}
|
||||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
@ -187,12 +189,15 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
||||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
|
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
TickType_t xTicksToWait )
|
||||||
{
|
{
|
||||||
EventBits_t uxOriginalBitValue, uxReturn;
|
EventBits_t uxOriginalBitValue, uxReturn;
|
||||||
EventGroup_t *pxEventBits = xEventGroup;
|
EventGroup_t * pxEventBits = xEventGroup;
|
||||||
BaseType_t xAlreadyYielded;
|
BaseType_t xAlreadyYielded;
|
||||||
BaseType_t xTimeoutOccurred = pdFALSE;
|
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
|
|
||||||
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
configASSERT( uxBitsToWaitFor != 0 );
|
configASSERT( uxBitsToWaitFor != 0 );
|
||||||
|
|
@ -214,7 +219,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
uxReturn = ( uxOriginalBitValue | uxBitsToSet );
|
uxReturn = ( uxOriginalBitValue | uxBitsToSet );
|
||||||
|
|
||||||
/* Rendezvous always clear the bits. They will have been cleared
|
/* Rendezvous always clear the bits. They will have been cleared
|
||||||
already unless this is the only task in the rendezvous. */
|
* already unless this is the only task in the rendezvous. */
|
||||||
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
|
||||||
xTicksToWait = 0;
|
xTicksToWait = 0;
|
||||||
|
|
@ -226,20 +231,20 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
|
traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
|
||||||
|
|
||||||
/* Store the bits that the calling task is waiting for in the
|
/* Store the bits that the calling task is waiting for in the
|
||||||
task's event list item so the kernel knows when a match is
|
* task's event list item so the kernel knows when a match is
|
||||||
found. Then enter the blocked state. */
|
* found. Then enter the blocked state. */
|
||||||
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
|
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
|
||||||
|
|
||||||
/* This assignment is obsolete as uxReturn will get set after
|
/* This assignment is obsolete as uxReturn will get set after
|
||||||
the task unblocks, but some compilers mistakenly generate a
|
* the task unblocks, but some compilers mistakenly generate a
|
||||||
warning about uxReturn being returned without being set if the
|
* warning about uxReturn being returned without being set if the
|
||||||
assignment is omitted. */
|
* assignment is omitted. */
|
||||||
uxReturn = 0;
|
uxReturn = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The rendezvous bits were not set, but no block time was
|
/* The rendezvous bits were not set, but no block time was
|
||||||
specified - just return the current event bit value. */
|
* specified - just return the current event bit value. */
|
||||||
uxReturn = pxEventBits->uxEventBits;
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
xTimeoutOccurred = pdTRUE;
|
xTimeoutOccurred = pdTRUE;
|
||||||
}
|
}
|
||||||
|
|
@ -259,9 +264,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The task blocked to wait for its required bits to be set - at this
|
/* The task blocked to wait for its required bits to be set - at this
|
||||||
point either the required bits were set or the block time expired. If
|
* point either the required bits were set or the block time expired. If
|
||||||
the required bits were set they will have been stored in the task's
|
* the required bits were set they will have been stored in the task's
|
||||||
event list item, and they should now be retrieved then cleared. */
|
* event list item, and they should now be retrieved then cleared. */
|
||||||
uxReturn = uxTaskResetEventItemValue();
|
uxReturn = uxTaskResetEventItemValue();
|
||||||
|
|
||||||
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||||
|
|
@ -272,9 +277,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
uxReturn = pxEventBits->uxEventBits;
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
/* Although the task got here because it timed out before the
|
/* Although the task got here because it timed out before the
|
||||||
bits it was waiting for were set, it is possible that since it
|
* bits it was waiting for were set, it is possible that since it
|
||||||
unblocked another task has set the bits. If this is the case
|
* unblocked another task has set the bits. If this is the case
|
||||||
then it needs to clear the bits before exiting. */
|
* then it needs to clear the bits before exiting. */
|
||||||
if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||||
{
|
{
|
||||||
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
|
@ -294,7 +299,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Control bits might be set as the task had blocked should not be
|
/* Control bits might be set as the task had blocked should not be
|
||||||
returned. */
|
* returned. */
|
||||||
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -307,15 +312,19 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
|
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
const BaseType_t xClearOnExit,
|
||||||
|
const BaseType_t xWaitForAllBits,
|
||||||
|
TickType_t xTicksToWait )
|
||||||
{
|
{
|
||||||
EventGroup_t *pxEventBits = xEventGroup;
|
EventGroup_t * pxEventBits = xEventGroup;
|
||||||
EventBits_t uxReturn, uxControlBits = 0;
|
EventBits_t uxReturn, uxControlBits = 0;
|
||||||
BaseType_t xWaitConditionMet, xAlreadyYielded;
|
BaseType_t xWaitConditionMet, xAlreadyYielded;
|
||||||
BaseType_t xTimeoutOccurred = pdFALSE;
|
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
|
|
||||||
/* Check the user is not attempting to wait on the bits used by the kernel
|
/* Check the user is not attempting to wait on the bits used by the kernel
|
||||||
itself, and that at least one bit is being requested. */
|
* itself, and that at least one bit is being requested. */
|
||||||
configASSERT( xEventGroup );
|
configASSERT( xEventGroup );
|
||||||
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
configASSERT( uxBitsToWaitFor != 0 );
|
configASSERT( uxBitsToWaitFor != 0 );
|
||||||
|
|
@ -335,7 +344,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
if( xWaitConditionMet != pdFALSE )
|
if( xWaitConditionMet != pdFALSE )
|
||||||
{
|
{
|
||||||
/* The wait condition has already been met so there is no need to
|
/* The wait condition has already been met so there is no need to
|
||||||
block. */
|
* block. */
|
||||||
uxReturn = uxCurrentEventBits;
|
uxReturn = uxCurrentEventBits;
|
||||||
xTicksToWait = ( TickType_t ) 0;
|
xTicksToWait = ( TickType_t ) 0;
|
||||||
|
|
||||||
|
|
@ -352,16 +361,16 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
else if( xTicksToWait == ( TickType_t ) 0 )
|
else if( xTicksToWait == ( TickType_t ) 0 )
|
||||||
{
|
{
|
||||||
/* The wait condition has not been met, but no block time was
|
/* The wait condition has not been met, but no block time was
|
||||||
specified, so just return the current value. */
|
* specified, so just return the current value. */
|
||||||
uxReturn = uxCurrentEventBits;
|
uxReturn = uxCurrentEventBits;
|
||||||
xTimeoutOccurred = pdTRUE;
|
xTimeoutOccurred = pdTRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The task is going to block to wait for its required bits to be
|
/* The task is going to block to wait for its required bits to be
|
||||||
set. uxControlBits are used to remember the specified behaviour of
|
* set. uxControlBits are used to remember the specified behaviour of
|
||||||
this call to xEventGroupWaitBits() - for use when the event bits
|
* this call to xEventGroupWaitBits() - for use when the event bits
|
||||||
unblock the task. */
|
* unblock the task. */
|
||||||
if( xClearOnExit != pdFALSE )
|
if( xClearOnExit != pdFALSE )
|
||||||
{
|
{
|
||||||
uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
|
uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
|
||||||
|
|
@ -381,13 +390,13 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the bits that the calling task is waiting for in the
|
/* Store the bits that the calling task is waiting for in the
|
||||||
task's event list item so the kernel knows when a match is
|
* task's event list item so the kernel knows when a match is
|
||||||
found. Then enter the blocked state. */
|
* found. Then enter the blocked state. */
|
||||||
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
|
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
|
||||||
|
|
||||||
/* This is obsolete as it will get set after the task unblocks, but
|
/* This is obsolete as it will get set after the task unblocks, but
|
||||||
some compilers mistakenly generate a warning about the variable
|
* some compilers mistakenly generate a warning about the variable
|
||||||
being returned without being set if it is not done. */
|
* being returned without being set if it is not done. */
|
||||||
uxReturn = 0;
|
uxReturn = 0;
|
||||||
|
|
||||||
traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
|
traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
|
||||||
|
|
@ -407,9 +416,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The task blocked to wait for its required bits to be set - at this
|
/* The task blocked to wait for its required bits to be set - at this
|
||||||
point either the required bits were set or the block time expired. If
|
* point either the required bits were set or the block time expired. If
|
||||||
the required bits were set they will have been stored in the task's
|
* the required bits were set they will have been stored in the task's
|
||||||
event list item, and they should now be retrieved then cleared. */
|
* event list item, and they should now be retrieved then cleared. */
|
||||||
uxReturn = uxTaskResetEventItemValue();
|
uxReturn = uxTaskResetEventItemValue();
|
||||||
|
|
||||||
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||||
|
|
@ -420,7 +429,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
uxReturn = pxEventBits->uxEventBits;
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
/* It is possible that the event bits were updated between this
|
/* It is possible that the event bits were updated between this
|
||||||
task leaving the Blocked state and running again. */
|
* task leaving the Blocked state and running again. */
|
||||||
if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
|
if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
|
||||||
{
|
{
|
||||||
if( xClearOnExit != pdFALSE )
|
if( xClearOnExit != pdFALSE )
|
||||||
|
|
@ -436,6 +445,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
{
|
{
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
xTimeoutOccurred = pdTRUE;
|
xTimeoutOccurred = pdTRUE;
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
|
@ -448,6 +458,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
/* The task blocked so control bits may have been set. */
|
/* The task blocked so control bits may have been set. */
|
||||||
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
|
traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
|
||||||
|
|
||||||
/* Prevent compiler warnings when trace macros are not used. */
|
/* Prevent compiler warnings when trace macros are not used. */
|
||||||
|
|
@ -457,13 +468,14 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToClear )
|
||||||
{
|
{
|
||||||
EventGroup_t *pxEventBits = xEventGroup;
|
EventGroup_t * pxEventBits = xEventGroup;
|
||||||
EventBits_t uxReturn;
|
EventBits_t uxReturn;
|
||||||
|
|
||||||
/* Check the user is not attempting to clear the bits used by the kernel
|
/* Check the user is not attempting to clear the bits used by the kernel
|
||||||
itself. */
|
* itself. */
|
||||||
configASSERT( xEventGroup );
|
configASSERT( xEventGroup );
|
||||||
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
|
||||||
|
|
@ -472,7 +484,7 @@ EventBits_t uxReturn;
|
||||||
traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
|
traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
|
||||||
|
|
||||||
/* The value returned is the event group value prior to the bits being
|
/* The value returned is the event group value prior to the bits being
|
||||||
cleared. */
|
* cleared. */
|
||||||
uxReturn = pxEventBits->uxEventBits;
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
/* Clear the bits. */
|
/* Clear the bits. */
|
||||||
|
|
@ -486,7 +498,8 @@ EventBits_t uxReturn;
|
||||||
|
|
||||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
|
|
||||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToClear )
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
|
@ -496,14 +509,14 @@ EventBits_t uxReturn;
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
|
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
|
||||||
{
|
{
|
||||||
UBaseType_t uxSavedInterruptStatus;
|
UBaseType_t uxSavedInterruptStatus;
|
||||||
EventGroup_t const * const pxEventBits = xEventGroup;
|
EventGroup_t const * const pxEventBits = xEventGroup;
|
||||||
EventBits_t uxReturn;
|
EventBits_t uxReturn;
|
||||||
|
|
||||||
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
|
|
@ -515,17 +528,18 @@ EventBits_t uxReturn;
|
||||||
} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */
|
} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
|
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet )
|
||||||
{
|
{
|
||||||
ListItem_t *pxListItem, *pxNext;
|
ListItem_t * pxListItem, * pxNext;
|
||||||
ListItem_t const *pxListEnd;
|
ListItem_t const * pxListEnd;
|
||||||
List_t const * pxList;
|
List_t const * pxList;
|
||||||
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
|
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
|
||||||
EventGroup_t *pxEventBits = xEventGroup;
|
EventGroup_t * pxEventBits = xEventGroup;
|
||||||
BaseType_t xMatchFound = pdFALSE;
|
BaseType_t xMatchFound = pdFALSE;
|
||||||
|
|
||||||
/* Check the user is not attempting to set the bits used by the kernel
|
/* Check the user is not attempting to set the bits used by the kernel
|
||||||
itself. */
|
* itself. */
|
||||||
configASSERT( xEventGroup );
|
configASSERT( xEventGroup );
|
||||||
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
|
||||||
|
|
@ -586,21 +600,21 @@ BaseType_t xMatchFound = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the actual event flag value in the task's event list
|
/* Store the actual event flag value in the task's event list
|
||||||
item before removing the task from the event list. The
|
* item before removing the task from the event list. The
|
||||||
eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
|
* eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
|
||||||
that is was unblocked due to its required bits matching, rather
|
* that is was unblocked due to its required bits matching, rather
|
||||||
than because it timed out. */
|
* than because it timed out. */
|
||||||
vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
|
vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move onto the next list item. Note pxListItem->pxNext is not
|
/* Move onto the next list item. Note pxListItem->pxNext is not
|
||||||
used here as the list item may have been removed from the event list
|
* used here as the list item may have been removed from the event list
|
||||||
and inserted into the ready/pending reading list. */
|
* and inserted into the ready/pending reading list. */
|
||||||
pxListItem = pxNext;
|
pxListItem = pxNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
|
/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
|
||||||
bit was set in the control word. */
|
* bit was set in the control word. */
|
||||||
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||||
}
|
}
|
||||||
( void ) xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
|
|
@ -611,8 +625,8 @@ BaseType_t xMatchFound = pdFALSE;
|
||||||
|
|
||||||
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
||||||
{
|
{
|
||||||
EventGroup_t *pxEventBits = xEventGroup;
|
EventGroup_t * pxEventBits = xEventGroup;
|
||||||
const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
const List_t * pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||||
|
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
{
|
{
|
||||||
|
|
@ -621,21 +635,21 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||||
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
|
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
|
||||||
{
|
{
|
||||||
/* Unblock the task, returning 0 as the event list is being deleted
|
/* Unblock the task, returning 0 as the event list is being deleted
|
||||||
and cannot therefore have any bits set. */
|
* and cannot therefore have any bits set. */
|
||||||
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
||||||
vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
|
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
|
||||||
{
|
{
|
||||||
/* The event group can only have been allocated dynamically - free
|
/* The event group can only have been allocated dynamically - free
|
||||||
it again. */
|
* it again. */
|
||||||
vPortFree( pxEventBits );
|
vPortFree( pxEventBits );
|
||||||
}
|
}
|
||||||
#elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
#elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||||
{
|
{
|
||||||
/* The event group could have been allocated statically or
|
/* The event group could have been allocated statically or
|
||||||
dynamically, so check before attempting to free the memory. */
|
* dynamically, so check before attempting to free the memory. */
|
||||||
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
|
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
|
||||||
{
|
{
|
||||||
vPortFree( pxEventBits );
|
vPortFree( pxEventBits );
|
||||||
|
|
@ -652,29 +666,33 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* For internal use only - execute a 'set bits' command that was pended from
|
/* For internal use only - execute a 'set bits' command that was pended from
|
||||||
an interrupt. */
|
* an interrupt. */
|
||||||
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
|
void vEventGroupSetBitsCallback( void * pvEventGroup,
|
||||||
|
const uint32_t ulBitsToSet )
|
||||||
{
|
{
|
||||||
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
|
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* For internal use only - execute a 'clear bits' command that was pended from
|
/* For internal use only - execute a 'clear bits' command that was pended from
|
||||||
an interrupt. */
|
* an interrupt. */
|
||||||
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )
|
void vEventGroupClearBitsCallback( void * pvEventGroup,
|
||||||
|
const uint32_t ulBitsToClear )
|
||||||
{
|
{
|
||||||
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
|
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits )
|
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
const BaseType_t xWaitForAllBits )
|
||||||
{
|
{
|
||||||
BaseType_t xWaitConditionMet = pdFALSE;
|
BaseType_t xWaitConditionMet = pdFALSE;
|
||||||
|
|
||||||
if( xWaitForAllBits == pdFALSE )
|
if( xWaitForAllBits == pdFALSE )
|
||||||
{
|
{
|
||||||
/* Task only has to wait for one bit within uxBitsToWaitFor to be
|
/* Task only has to wait for one bit within uxBitsToWaitFor to be
|
||||||
set. Is one already set? */
|
* set. Is one already set? */
|
||||||
if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
|
if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
|
||||||
{
|
{
|
||||||
xWaitConditionMet = pdTRUE;
|
xWaitConditionMet = pdTRUE;
|
||||||
|
|
@ -687,7 +705,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Task has to wait for all the bits in uxBitsToWaitFor to be set.
|
/* Task has to wait for all the bits in uxBitsToWaitFor to be set.
|
||||||
Are they set already? */
|
* Are they set already? */
|
||||||
if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||||
{
|
{
|
||||||
xWaitConditionMet = pdTRUE;
|
xWaitConditionMet = pdTRUE;
|
||||||
|
|
@ -704,7 +722,9 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
||||||
|
|
||||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
|
|
||||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
|
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet,
|
||||||
|
BaseType_t * pxHigherPriorityTaskWoken )
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
|
@ -714,15 +734,15 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if (configUSE_TRACE_FACILITY == 1)
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
|
||||||
UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
|
UBaseType_t uxEventGroupGetNumber( void * xEventGroup )
|
||||||
{
|
{
|
||||||
UBaseType_t xReturn;
|
UBaseType_t xReturn;
|
||||||
EventGroup_t const *pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
|
EventGroup_t const * pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
|
||||||
|
|
||||||
if( xEventGroup == NULL )
|
if( xEventGroup == NULL )
|
||||||
{
|
{
|
||||||
|
|
@ -741,12 +761,11 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
||||||
|
|
||||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
|
||||||
void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber )
|
void vEventGroupSetNumber( void * xEventGroup,
|
||||||
|
UBaseType_t uxEventGroupNumber )
|
||||||
{
|
{
|
||||||
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
|
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configUSE_TRACE_FACILITY */
|
#endif /* configUSE_TRACE_FACILITY */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
1125
include/FreeRTOS.h
1125
include/FreeRTOS.h
File diff suppressed because it is too large
Load diff
|
|
@ -47,9 +47,9 @@
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
|
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
/* Only the current stack state is to be checked. */
|
/* Only the current stack state is to be checked. */
|
||||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
|
|
@ -62,9 +62,9 @@
|
||||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
|
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
/* Only the current stack state is to be checked. */
|
/* Only the current stack state is to be checked. */
|
||||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
\
|
\
|
||||||
|
|
@ -78,7 +78,7 @@
|
||||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
|
|
@ -97,11 +97,11 @@
|
||||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
|
int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
|
||||||
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
|
@ -129,4 +129,3 @@
|
||||||
|
|
||||||
|
|
||||||
#endif /* STACK_MACROS_H */
|
#endif /* STACK_MACROS_H */
|
||||||
|
|
||||||
|
|
|
||||||
122
include/atomic.h
122
include/atomic.h
|
|
@ -34,18 +34,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ATOMIC_H
|
#ifndef ATOMIC_H
|
||||||
#define ATOMIC_H
|
#define ATOMIC_H
|
||||||
|
|
||||||
#ifndef INC_FREERTOS_H
|
#ifndef INC_FREERTOS_H
|
||||||
#error "include FreeRTOS.h must appear in source files before include atomic.h"
|
#error "include FreeRTOS.h must appear in source files before include atomic.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Port specific definitions -- entering/exiting critical section.
|
* Port specific definitions -- entering/exiting critical section.
|
||||||
|
|
@ -55,22 +55,22 @@ extern "C" {
|
||||||
* ATOMIC_ENTER_CRITICAL().
|
* ATOMIC_ENTER_CRITICAL().
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#if defined( portSET_INTERRUPT_MASK_FROM_ISR )
|
#if defined( portSET_INTERRUPT_MASK_FROM_ISR )
|
||||||
|
|
||||||
/* Nested interrupt scheme is supported in this port. */
|
/* Nested interrupt scheme is supported in this port. */
|
||||||
#define ATOMIC_ENTER_CRITICAL() \
|
#define ATOMIC_ENTER_CRITICAL() \
|
||||||
UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()
|
UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()
|
||||||
|
|
||||||
#define ATOMIC_EXIT_CRITICAL() \
|
#define ATOMIC_EXIT_CRITICAL() \
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Nested interrupt scheme is NOT supported in this port. */
|
/* Nested interrupt scheme is NOT supported in this port. */
|
||||||
#define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
|
#define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
|
||||||
#define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL()
|
#define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL()
|
||||||
|
|
||||||
#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
|
#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Port specific definition -- "always inline".
|
* Port specific definition -- "always inline".
|
||||||
|
|
@ -79,12 +79,12 @@ extern "C" {
|
||||||
* for atomic. Thus, if portFORCE_INLINE is not provided by portmacro.h,
|
* for atomic. Thus, if portFORCE_INLINE is not provided by portmacro.h,
|
||||||
* instead of resulting error, simply define it away.
|
* instead of resulting error, simply define it away.
|
||||||
*/
|
*/
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE
|
#define portFORCE_INLINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U /**< Compare and swap succeeded, swapped. */
|
#define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U /**< Compare and swap succeeded, swapped. */
|
||||||
#define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U /**< Compare and swap failed, did not swap. */
|
#define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U /**< Compare and swap failed, did not swap. */
|
||||||
|
|
||||||
/*----------------------------- Swap && CAS ------------------------------*/
|
/*----------------------------- Swap && CAS ------------------------------*/
|
||||||
|
|
||||||
|
|
@ -103,11 +103,11 @@ extern "C" {
|
||||||
* @note This function only swaps *pulDestination with ulExchange, if previous
|
* @note This function only swaps *pulDestination with ulExchange, if previous
|
||||||
* *pulDestination value equals ulComparand.
|
* *pulDestination value equals ulComparand.
|
||||||
*/
|
*/
|
||||||
static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination,
|
static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination,
|
||||||
uint32_t ulExchange,
|
uint32_t ulExchange,
|
||||||
uint32_t ulComparand )
|
uint32_t ulComparand )
|
||||||
{
|
{
|
||||||
uint32_t ulReturnValue;
|
uint32_t ulReturnValue;
|
||||||
|
|
||||||
ATOMIC_ENTER_CRITICAL();
|
ATOMIC_ENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
|
|
@ -124,7 +124,7 @@ uint32_t ulReturnValue;
|
||||||
ATOMIC_EXIT_CRITICAL();
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
return ulReturnValue;
|
return ulReturnValue;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -139,10 +139,10 @@ uint32_t ulReturnValue;
|
||||||
*
|
*
|
||||||
* @return The initial value of *ppvDestination.
|
* @return The initial value of *ppvDestination.
|
||||||
*/
|
*/
|
||||||
static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination,
|
static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination,
|
||||||
void * pvExchange )
|
void * pvExchange )
|
||||||
{
|
{
|
||||||
void * pReturnValue;
|
void * pReturnValue;
|
||||||
|
|
||||||
ATOMIC_ENTER_CRITICAL();
|
ATOMIC_ENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
|
|
@ -152,7 +152,7 @@ void * pReturnValue;
|
||||||
ATOMIC_EXIT_CRITICAL();
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
return pReturnValue;
|
return pReturnValue;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -171,11 +171,11 @@ void * pReturnValue;
|
||||||
* @note This function only swaps *ppvDestination with pvExchange, if previous
|
* @note This function only swaps *ppvDestination with pvExchange, if previous
|
||||||
* *ppvDestination value equals pvComparand.
|
* *ppvDestination value equals pvComparand.
|
||||||
*/
|
*/
|
||||||
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination,
|
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination,
|
||||||
void * pvExchange,
|
void * pvExchange,
|
||||||
void * pvComparand )
|
void * pvComparand )
|
||||||
{
|
{
|
||||||
uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
|
uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
|
||||||
|
|
||||||
ATOMIC_ENTER_CRITICAL();
|
ATOMIC_ENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
|
|
@ -188,7 +188,7 @@ uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
|
||||||
ATOMIC_EXIT_CRITICAL();
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
return ulReturnValue;
|
return ulReturnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------- Arithmetic ------------------------------*/
|
/*----------------------------- Arithmetic ------------------------------*/
|
||||||
|
|
@ -204,9 +204,9 @@ uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
|
||||||
*
|
*
|
||||||
* @return previous *pulAddend value.
|
* @return previous *pulAddend value.
|
||||||
*/
|
*/
|
||||||
static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend,
|
static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend,
|
||||||
uint32_t ulCount )
|
uint32_t ulCount )
|
||||||
{
|
{
|
||||||
uint32_t ulCurrent;
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
ATOMIC_ENTER_CRITICAL();
|
ATOMIC_ENTER_CRITICAL();
|
||||||
|
|
@ -217,7 +217,7 @@ static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend,
|
||||||
ATOMIC_EXIT_CRITICAL();
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
return ulCurrent;
|
return ulCurrent;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -232,9 +232,9 @@ static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend,
|
||||||
*
|
*
|
||||||
* @return previous *pulAddend value.
|
* @return previous *pulAddend value.
|
||||||
*/
|
*/
|
||||||
static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend,
|
static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend,
|
||||||
uint32_t ulCount )
|
uint32_t ulCount )
|
||||||
{
|
{
|
||||||
uint32_t ulCurrent;
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
ATOMIC_ENTER_CRITICAL();
|
ATOMIC_ENTER_CRITICAL();
|
||||||
|
|
@ -245,7 +245,7 @@ static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAdd
|
||||||
ATOMIC_EXIT_CRITICAL();
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
return ulCurrent;
|
return ulCurrent;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -258,9 +258,9 @@ static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAdd
|
||||||
*
|
*
|
||||||
* @return *pulAddend value before increment.
|
* @return *pulAddend value before increment.
|
||||||
*/
|
*/
|
||||||
static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend )
|
static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend )
|
||||||
{
|
{
|
||||||
uint32_t ulCurrent;
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
ATOMIC_ENTER_CRITICAL();
|
ATOMIC_ENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
|
|
@ -270,7 +270,7 @@ uint32_t ulCurrent;
|
||||||
ATOMIC_EXIT_CRITICAL();
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
return ulCurrent;
|
return ulCurrent;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -283,9 +283,9 @@ uint32_t ulCurrent;
|
||||||
*
|
*
|
||||||
* @return *pulAddend value before decrement.
|
* @return *pulAddend value before decrement.
|
||||||
*/
|
*/
|
||||||
static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend )
|
static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend )
|
||||||
{
|
{
|
||||||
uint32_t ulCurrent;
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
ATOMIC_ENTER_CRITICAL();
|
ATOMIC_ENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
|
|
@ -295,7 +295,7 @@ uint32_t ulCurrent;
|
||||||
ATOMIC_EXIT_CRITICAL();
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
return ulCurrent;
|
return ulCurrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------- Bitwise Logical ------------------------------*/
|
/*----------------------------- Bitwise Logical ------------------------------*/
|
||||||
|
|
||||||
|
|
@ -310,10 +310,10 @@ uint32_t ulCurrent;
|
||||||
*
|
*
|
||||||
* @return The original value of *pulDestination.
|
* @return The original value of *pulDestination.
|
||||||
*/
|
*/
|
||||||
static portFORCE_INLINE uint32_t Atomic_OR_u32( uint32_t volatile * pulDestination,
|
static portFORCE_INLINE uint32_t Atomic_OR_u32( uint32_t volatile * pulDestination,
|
||||||
uint32_t ulValue )
|
uint32_t ulValue )
|
||||||
{
|
{
|
||||||
uint32_t ulCurrent;
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
ATOMIC_ENTER_CRITICAL();
|
ATOMIC_ENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
|
|
@ -323,7 +323,7 @@ uint32_t ulCurrent;
|
||||||
ATOMIC_EXIT_CRITICAL();
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
return ulCurrent;
|
return ulCurrent;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -337,10 +337,10 @@ uint32_t ulCurrent;
|
||||||
*
|
*
|
||||||
* @return The original value of *pulDestination.
|
* @return The original value of *pulDestination.
|
||||||
*/
|
*/
|
||||||
static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination,
|
static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination,
|
||||||
uint32_t ulValue )
|
uint32_t ulValue )
|
||||||
{
|
{
|
||||||
uint32_t ulCurrent;
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
ATOMIC_ENTER_CRITICAL();
|
ATOMIC_ENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
|
|
@ -350,7 +350,7 @@ uint32_t ulCurrent;
|
||||||
ATOMIC_EXIT_CRITICAL();
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
return ulCurrent;
|
return ulCurrent;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -364,10 +364,10 @@ uint32_t ulCurrent;
|
||||||
*
|
*
|
||||||
* @return The original value of *pulDestination.
|
* @return The original value of *pulDestination.
|
||||||
*/
|
*/
|
||||||
static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination,
|
static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination,
|
||||||
uint32_t ulValue )
|
uint32_t ulValue )
|
||||||
{
|
{
|
||||||
uint32_t ulCurrent;
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
ATOMIC_ENTER_CRITICAL();
|
ATOMIC_ENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
|
|
@ -377,7 +377,7 @@ uint32_t ulCurrent;
|
||||||
ATOMIC_EXIT_CRITICAL();
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
return ulCurrent;
|
return ulCurrent;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -391,10 +391,10 @@ uint32_t ulCurrent;
|
||||||
*
|
*
|
||||||
* @return The original value of *pulDestination.
|
* @return The original value of *pulDestination.
|
||||||
*/
|
*/
|
||||||
static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination,
|
static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination,
|
||||||
uint32_t ulValue )
|
uint32_t ulValue )
|
||||||
{
|
{
|
||||||
uint32_t ulCurrent;
|
uint32_t ulCurrent;
|
||||||
|
|
||||||
ATOMIC_ENTER_CRITICAL();
|
ATOMIC_ENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
|
|
@ -404,10 +404,10 @@ uint32_t ulCurrent;
|
||||||
ATOMIC_EXIT_CRITICAL();
|
ATOMIC_EXIT_CRITICAL();
|
||||||
|
|
||||||
return ulCurrent;
|
return ulCurrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* ATOMIC_H */
|
#endif /* ATOMIC_H */
|
||||||
|
|
|
||||||
|
|
@ -25,44 +25,45 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CO_ROUTINE_H
|
#ifndef CO_ROUTINE_H
|
||||||
#define CO_ROUTINE_H
|
#define CO_ROUTINE_H
|
||||||
|
|
||||||
#ifndef INC_FREERTOS_H
|
#ifndef INC_FREERTOS_H
|
||||||
#error "include FreeRTOS.h must appear in source files before include croutine.h"
|
#error "include FreeRTOS.h must appear in source files before include croutine.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Used to hide the implementation of the co-routine control block. The
|
/* Used to hide the implementation of the co-routine control block. The
|
||||||
control block structure however has to be included in the header due to
|
* control block structure however has to be included in the header due to
|
||||||
the macro implementation of the co-routine functionality. */
|
* the macro implementation of the co-routine functionality. */
|
||||||
typedef void * CoRoutineHandle_t;
|
typedef void * CoRoutineHandle_t;
|
||||||
|
|
||||||
/* Defines the prototype to which co-routine functions must conform. */
|
/* Defines the prototype to which co-routine functions must conform. */
|
||||||
typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t );
|
typedef void (* crCOROUTINE_CODE)( CoRoutineHandle_t,
|
||||||
|
UBaseType_t );
|
||||||
|
|
||||||
typedef struct corCoRoutineControlBlock
|
typedef struct corCoRoutineControlBlock
|
||||||
{
|
{
|
||||||
crCOROUTINE_CODE pxCoRoutineFunction;
|
crCOROUTINE_CODE pxCoRoutineFunction;
|
||||||
ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */
|
ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */
|
||||||
ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */
|
ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */
|
||||||
UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */
|
UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */
|
||||||
UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
|
UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
|
||||||
uint16_t uxState; /*< Used internally by the co-routine implementation. */
|
uint16_t uxState; /*< Used internally by the co-routine implementation. */
|
||||||
} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */
|
} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
*<pre>
|
*<pre>
|
||||||
BaseType_t xCoRoutineCreate(
|
* BaseType_t xCoRoutineCreate(
|
||||||
crCOROUTINE_CODE pxCoRoutineCode,
|
* crCOROUTINE_CODE pxCoRoutineCode,
|
||||||
UBaseType_t uxPriority,
|
* UBaseType_t uxPriority,
|
||||||
UBaseType_t uxIndex
|
* UBaseType_t uxIndex
|
||||||
);</pre>
|
* );</pre>
|
||||||
*
|
*
|
||||||
* Create a new co-routine and add it to the list of co-routines that are
|
* Create a new co-routine and add it to the list of co-routines that are
|
||||||
* ready to run.
|
* ready to run.
|
||||||
|
|
@ -82,58 +83,60 @@ typedef struct corCoRoutineControlBlock
|
||||||
* list, otherwise an error code defined with ProjDefs.h.
|
* list, otherwise an error code defined with ProjDefs.h.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
// Co-routine to be created.
|
* // Co-routine to be created.
|
||||||
void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
* void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
* {
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
// This may not be necessary for const variables.
|
* // This may not be necessary for const variables.
|
||||||
static const char cLedToFlash[ 2 ] = { 5, 6 };
|
* static const char cLedToFlash[ 2 ] = { 5, 6 };
|
||||||
static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
|
* static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
|
||||||
|
*
|
||||||
// Must start every co-routine with a call to crSTART();
|
* // Must start every co-routine with a call to crSTART();
|
||||||
crSTART( xHandle );
|
* crSTART( xHandle );
|
||||||
|
*
|
||||||
for( ;; )
|
* for( ;; )
|
||||||
{
|
* {
|
||||||
// This co-routine just delays for a fixed period, then toggles
|
* // This co-routine just delays for a fixed period, then toggles
|
||||||
// an LED. Two co-routines are created using this function, so
|
* // an LED. Two co-routines are created using this function, so
|
||||||
// the uxIndex parameter is used to tell the co-routine which
|
* // the uxIndex parameter is used to tell the co-routine which
|
||||||
// LED to flash and how int32_t to delay. This assumes xQueue has
|
* // LED to flash and how int32_t to delay. This assumes xQueue has
|
||||||
// already been created.
|
* // already been created.
|
||||||
vParTestToggleLED( cLedToFlash[ uxIndex ] );
|
* vParTestToggleLED( cLedToFlash[ uxIndex ] );
|
||||||
crDELAY( xHandle, uxFlashRates[ uxIndex ] );
|
* crDELAY( xHandle, uxFlashRates[ uxIndex ] );
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// Must end every co-routine with a call to crEND();
|
* // Must end every co-routine with a call to crEND();
|
||||||
crEND();
|
* crEND();
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// Function that creates two co-routines.
|
* // Function that creates two co-routines.
|
||||||
void vOtherFunction( void )
|
* void vOtherFunction( void )
|
||||||
{
|
* {
|
||||||
uint8_t ucParameterToPass;
|
* uint8_t ucParameterToPass;
|
||||||
TaskHandle_t xHandle;
|
* TaskHandle_t xHandle;
|
||||||
|
*
|
||||||
// Create two co-routines at priority 0. The first is given index 0
|
* // Create two co-routines at priority 0. The first is given index 0
|
||||||
// so (from the code above) toggles LED 5 every 200 ticks. The second
|
* // so (from the code above) toggles LED 5 every 200 ticks. The second
|
||||||
// is given index 1 so toggles LED 6 every 400 ticks.
|
* // is given index 1 so toggles LED 6 every 400 ticks.
|
||||||
for( uxIndex = 0; uxIndex < 2; uxIndex++ )
|
* for( uxIndex = 0; uxIndex < 2; uxIndex++ )
|
||||||
{
|
* {
|
||||||
xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
|
* xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xCoRoutineCreate xCoRoutineCreate
|
* \defgroup xCoRoutineCreate xCoRoutineCreate
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex );
|
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode,
|
||||||
|
UBaseType_t uxPriority,
|
||||||
|
UBaseType_t uxIndex );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
*<pre>
|
*<pre>
|
||||||
void vCoRoutineSchedule( void );</pre>
|
* void vCoRoutineSchedule( void );</pre>
|
||||||
*
|
*
|
||||||
* Run a co-routine.
|
* Run a co-routine.
|
||||||
*
|
*
|
||||||
|
|
@ -147,103 +150,109 @@ BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPri
|
||||||
* hook).
|
* hook).
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
// This idle task hook will schedule a co-routine each time it is called.
|
* // This idle task hook will schedule a co-routine each time it is called.
|
||||||
// The rest of the idle task will execute between co-routine calls.
|
* // The rest of the idle task will execute between co-routine calls.
|
||||||
void vApplicationIdleHook( void )
|
* void vApplicationIdleHook( void )
|
||||||
{
|
* {
|
||||||
vCoRoutineSchedule();
|
* vCoRoutineSchedule();
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// Alternatively, if you do not require any other part of the idle task to
|
* // Alternatively, if you do not require any other part of the idle task to
|
||||||
// execute, the idle task hook can call vCoRoutineSchedule() within an
|
* // execute, the idle task hook can call vCoRoutineSchedule() within an
|
||||||
// infinite loop.
|
* // infinite loop.
|
||||||
void vApplicationIdleHook( void )
|
* void vApplicationIdleHook( void )
|
||||||
{
|
* {
|
||||||
for( ;; )
|
* for( ;; )
|
||||||
{
|
* {
|
||||||
vCoRoutineSchedule();
|
* vCoRoutineSchedule();
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup vCoRoutineSchedule vCoRoutineSchedule
|
* \defgroup vCoRoutineSchedule vCoRoutineSchedule
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
void vCoRoutineSchedule( void );
|
void vCoRoutineSchedule( void );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
* <pre>
|
* <pre>
|
||||||
crSTART( CoRoutineHandle_t xHandle );</pre>
|
* crSTART( CoRoutineHandle_t xHandle );</pre>
|
||||||
*
|
*
|
||||||
* This macro MUST always be called at the start of a co-routine function.
|
* This macro MUST always be called at the start of a co-routine function.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
// Co-routine to be created.
|
* // Co-routine to be created.
|
||||||
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
* void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
* {
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
static int32_t ulAVariable;
|
* static int32_t ulAVariable;
|
||||||
|
*
|
||||||
// Must start every co-routine with a call to crSTART();
|
* // Must start every co-routine with a call to crSTART();
|
||||||
crSTART( xHandle );
|
* crSTART( xHandle );
|
||||||
|
*
|
||||||
for( ;; )
|
* for( ;; )
|
||||||
{
|
* {
|
||||||
// Co-routine functionality goes here.
|
* // Co-routine functionality goes here.
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// Must end every co-routine with a call to crEND();
|
* // Must end every co-routine with a call to crEND();
|
||||||
crEND();
|
* crEND();
|
||||||
}</pre>
|
* }</pre>
|
||||||
* \defgroup crSTART crSTART
|
* \defgroup crSTART crSTART
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0:
|
#define crSTART( pxCRCB ) \
|
||||||
|
switch( ( ( CRCB_t * ) ( pxCRCB ) )->uxState ) { \
|
||||||
|
case 0:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
* <pre>
|
* <pre>
|
||||||
crEND();</pre>
|
* crEND();</pre>
|
||||||
*
|
*
|
||||||
* This macro MUST always be called at the end of a co-routine function.
|
* This macro MUST always be called at the end of a co-routine function.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
// Co-routine to be created.
|
* // Co-routine to be created.
|
||||||
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
* void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
* {
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
static int32_t ulAVariable;
|
* static int32_t ulAVariable;
|
||||||
|
*
|
||||||
// Must start every co-routine with a call to crSTART();
|
* // Must start every co-routine with a call to crSTART();
|
||||||
crSTART( xHandle );
|
* crSTART( xHandle );
|
||||||
|
*
|
||||||
for( ;; )
|
* for( ;; )
|
||||||
{
|
* {
|
||||||
// Co-routine functionality goes here.
|
* // Co-routine functionality goes here.
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// Must end every co-routine with a call to crEND();
|
* // Must end every co-routine with a call to crEND();
|
||||||
crEND();
|
* crEND();
|
||||||
}</pre>
|
* }</pre>
|
||||||
* \defgroup crSTART crSTART
|
* \defgroup crSTART crSTART
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
#define crEND() }
|
#define crEND() }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These macros are intended for internal use by the co-routine implementation
|
* These macros are intended for internal use by the co-routine implementation
|
||||||
* only. The macros should not be used directly by application writers.
|
* only. The macros should not be used directly by application writers.
|
||||||
*/
|
*/
|
||||||
#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
|
#define crSET_STATE0( xHandle ) \
|
||||||
#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
|
( ( CRCB_t * ) ( xHandle ) )->uxState = ( __LINE__ * 2 ); return; \
|
||||||
|
case ( __LINE__ * 2 ):
|
||||||
|
#define crSET_STATE1( xHandle ) \
|
||||||
|
( ( CRCB_t * ) ( xHandle ) )->uxState = ( ( __LINE__ * 2 ) + 1 ); return; \
|
||||||
|
case ( ( __LINE__ * 2 ) + 1 ):
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
*<pre>
|
*<pre>
|
||||||
crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre>
|
* crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre>
|
||||||
*
|
*
|
||||||
* Delay a co-routine for a fixed period of time.
|
* Delay a co-routine for a fixed period of time.
|
||||||
*
|
*
|
||||||
|
|
@ -260,33 +269,33 @@ void vCoRoutineSchedule( void );
|
||||||
* can be used to convert ticks to milliseconds.
|
* can be used to convert ticks to milliseconds.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
// Co-routine to be created.
|
* // Co-routine to be created.
|
||||||
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
* void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
* {
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
// This may not be necessary for const variables.
|
* // This may not be necessary for const variables.
|
||||||
// We are to delay for 200ms.
|
* // We are to delay for 200ms.
|
||||||
static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
|
* static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
|
||||||
|
*
|
||||||
// Must start every co-routine with a call to crSTART();
|
* // Must start every co-routine with a call to crSTART();
|
||||||
crSTART( xHandle );
|
* crSTART( xHandle );
|
||||||
|
*
|
||||||
for( ;; )
|
* for( ;; )
|
||||||
{
|
* {
|
||||||
// Delay for 200ms.
|
* // Delay for 200ms.
|
||||||
crDELAY( xHandle, xDelayTime );
|
* crDELAY( xHandle, xDelayTime );
|
||||||
|
*
|
||||||
// Do something here.
|
* // Do something here.
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// Must end every co-routine with a call to crEND();
|
* // Must end every co-routine with a call to crEND();
|
||||||
crEND();
|
* crEND();
|
||||||
}</pre>
|
* }</pre>
|
||||||
* \defgroup crDELAY crDELAY
|
* \defgroup crDELAY crDELAY
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
#define crDELAY( xHandle, xTicksToDelay ) \
|
#define crDELAY( xHandle, xTicksToDelay ) \
|
||||||
if( ( xTicksToDelay ) > 0 ) \
|
if( ( xTicksToDelay ) > 0 ) \
|
||||||
{ \
|
{ \
|
||||||
vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \
|
vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \
|
||||||
|
|
@ -295,13 +304,13 @@ void vCoRoutineSchedule( void );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
crQUEUE_SEND(
|
* crQUEUE_SEND(
|
||||||
CoRoutineHandle_t xHandle,
|
* CoRoutineHandle_t xHandle,
|
||||||
QueueHandle_t pxQueue,
|
* QueueHandle_t pxQueue,
|
||||||
void *pvItemToQueue,
|
* void *pvItemToQueue,
|
||||||
TickType_t xTicksToWait,
|
* TickType_t xTicksToWait,
|
||||||
BaseType_t *pxResult
|
* BaseType_t *pxResult
|
||||||
)</pre>
|
* )</pre>
|
||||||
*
|
*
|
||||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||||
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||||
|
|
@ -341,44 +350,44 @@ void vCoRoutineSchedule( void );
|
||||||
* error defined within ProjDefs.h.
|
* error defined within ProjDefs.h.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
// Co-routine function that blocks for a fixed period then posts a number onto
|
* // Co-routine function that blocks for a fixed period then posts a number onto
|
||||||
// a queue.
|
* // a queue.
|
||||||
static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
* static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
* {
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
static BaseType_t xNumberToPost = 0;
|
* static BaseType_t xNumberToPost = 0;
|
||||||
static BaseType_t xResult;
|
* static BaseType_t xResult;
|
||||||
|
*
|
||||||
// Co-routines must begin with a call to crSTART().
|
* // Co-routines must begin with a call to crSTART().
|
||||||
crSTART( xHandle );
|
* crSTART( xHandle );
|
||||||
|
*
|
||||||
for( ;; )
|
* for( ;; )
|
||||||
{
|
* {
|
||||||
// This assumes the queue has already been created.
|
* // This assumes the queue has already been created.
|
||||||
crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
|
* crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
|
||||||
|
*
|
||||||
if( xResult != pdPASS )
|
* if( xResult != pdPASS )
|
||||||
{
|
* {
|
||||||
// The message was not posted!
|
* // The message was not posted!
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// Increment the number to be posted onto the queue.
|
* // Increment the number to be posted onto the queue.
|
||||||
xNumberToPost++;
|
* xNumberToPost++;
|
||||||
|
*
|
||||||
// Delay for 100 ticks.
|
* // Delay for 100 ticks.
|
||||||
crDELAY( xHandle, 100 );
|
* crDELAY( xHandle, 100 );
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// Co-routines must end with a call to crEND().
|
* // Co-routines must end with a call to crEND().
|
||||||
crEND();
|
* crEND();
|
||||||
}</pre>
|
* }</pre>
|
||||||
* \defgroup crQUEUE_SEND crQUEUE_SEND
|
* \defgroup crQUEUE_SEND crQUEUE_SEND
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \
|
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \
|
||||||
{ \
|
{ \
|
||||||
*( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \
|
*( pxResult ) = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), ( xTicksToWait ) ); \
|
||||||
if( *( pxResult ) == errQUEUE_BLOCKED ) \
|
if( *( pxResult ) == errQUEUE_BLOCKED ) \
|
||||||
{ \
|
{ \
|
||||||
crSET_STATE0( ( xHandle ) ); \
|
crSET_STATE0( ( xHandle ) ); \
|
||||||
|
|
@ -389,18 +398,18 @@ void vCoRoutineSchedule( void );
|
||||||
crSET_STATE1( ( xHandle ) ); \
|
crSET_STATE1( ( xHandle ) ); \
|
||||||
*pxResult = pdPASS; \
|
*pxResult = pdPASS; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
* <pre>
|
* <pre>
|
||||||
crQUEUE_RECEIVE(
|
* crQUEUE_RECEIVE(
|
||||||
CoRoutineHandle_t xHandle,
|
* CoRoutineHandle_t xHandle,
|
||||||
QueueHandle_t pxQueue,
|
* QueueHandle_t pxQueue,
|
||||||
void *pvBuffer,
|
* void *pvBuffer,
|
||||||
TickType_t xTicksToWait,
|
* TickType_t xTicksToWait,
|
||||||
BaseType_t *pxResult
|
* BaseType_t *pxResult
|
||||||
)</pre>
|
* )</pre>
|
||||||
*
|
*
|
||||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||||
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||||
|
|
@ -439,58 +448,58 @@ void vCoRoutineSchedule( void );
|
||||||
* an error code as defined within ProjDefs.h.
|
* an error code as defined within ProjDefs.h.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
// A co-routine receives the number of an LED to flash from a queue. It
|
* // A co-routine receives the number of an LED to flash from a queue. It
|
||||||
// blocks on the queue until the number is received.
|
* // blocks on the queue until the number is received.
|
||||||
static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
* static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
* {
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
static BaseType_t xResult;
|
* static BaseType_t xResult;
|
||||||
static UBaseType_t uxLEDToFlash;
|
* static UBaseType_t uxLEDToFlash;
|
||||||
|
*
|
||||||
// All co-routines must start with a call to crSTART().
|
* // All co-routines must start with a call to crSTART().
|
||||||
crSTART( xHandle );
|
* crSTART( xHandle );
|
||||||
|
*
|
||||||
for( ;; )
|
* for( ;; )
|
||||||
{
|
* {
|
||||||
// Wait for data to become available on the queue.
|
* // Wait for data to become available on the queue.
|
||||||
crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
* crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||||
|
*
|
||||||
if( xResult == pdPASS )
|
* if( xResult == pdPASS )
|
||||||
{
|
* {
|
||||||
// We received the LED to flash - flash it!
|
* // We received the LED to flash - flash it!
|
||||||
vParTestToggleLED( uxLEDToFlash );
|
* vParTestToggleLED( uxLEDToFlash );
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
crEND();
|
* crEND();
|
||||||
}</pre>
|
* }</pre>
|
||||||
* \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
|
* \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \
|
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \
|
||||||
{ \
|
{ \
|
||||||
*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \
|
*( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), ( xTicksToWait ) ); \
|
||||||
if( *( pxResult ) == errQUEUE_BLOCKED ) \
|
if( *( pxResult ) == errQUEUE_BLOCKED ) \
|
||||||
{ \
|
{ \
|
||||||
crSET_STATE0( ( xHandle ) ); \
|
crSET_STATE0( ( xHandle ) ); \
|
||||||
*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \
|
*( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), 0 ); \
|
||||||
} \
|
} \
|
||||||
if( *( pxResult ) == errQUEUE_YIELD ) \
|
if( *( pxResult ) == errQUEUE_YIELD ) \
|
||||||
{ \
|
{ \
|
||||||
crSET_STATE1( ( xHandle ) ); \
|
crSET_STATE1( ( xHandle ) ); \
|
||||||
*( pxResult ) = pdPASS; \
|
*( pxResult ) = pdPASS; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
* <pre>
|
* <pre>
|
||||||
crQUEUE_SEND_FROM_ISR(
|
* crQUEUE_SEND_FROM_ISR(
|
||||||
QueueHandle_t pxQueue,
|
* QueueHandle_t pxQueue,
|
||||||
void *pvItemToQueue,
|
* void *pvItemToQueue,
|
||||||
BaseType_t xCoRoutinePreviouslyWoken
|
* BaseType_t xCoRoutinePreviouslyWoken
|
||||||
)</pre>
|
* )</pre>
|
||||||
*
|
*
|
||||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||||
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||||
|
|
@ -525,69 +534,69 @@ void vCoRoutineSchedule( void );
|
||||||
* the ISR.
|
* the ISR.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
// A co-routine that blocks on a queue waiting for characters to be received.
|
* // A co-routine that blocks on a queue waiting for characters to be received.
|
||||||
static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
* static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
* {
|
||||||
char cRxedChar;
|
* char cRxedChar;
|
||||||
BaseType_t xResult;
|
* BaseType_t xResult;
|
||||||
|
*
|
||||||
// All co-routines must start with a call to crSTART().
|
* // All co-routines must start with a call to crSTART().
|
||||||
crSTART( xHandle );
|
* crSTART( xHandle );
|
||||||
|
*
|
||||||
for( ;; )
|
* for( ;; )
|
||||||
{
|
* {
|
||||||
// Wait for data to become available on the queue. This assumes the
|
* // Wait for data to become available on the queue. This assumes the
|
||||||
// queue xCommsRxQueue has already been created!
|
* // queue xCommsRxQueue has already been created!
|
||||||
crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
* crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||||
|
*
|
||||||
// Was a character received?
|
* // Was a character received?
|
||||||
if( xResult == pdPASS )
|
* if( xResult == pdPASS )
|
||||||
{
|
* {
|
||||||
// Process the character here.
|
* // Process the character here.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// All co-routines must end with a call to crEND().
|
* // All co-routines must end with a call to crEND().
|
||||||
crEND();
|
* crEND();
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// An ISR that uses a queue to send characters received on a serial port to
|
* // An ISR that uses a queue to send characters received on a serial port to
|
||||||
// a co-routine.
|
* // a co-routine.
|
||||||
void vUART_ISR( void )
|
* void vUART_ISR( void )
|
||||||
{
|
* {
|
||||||
char cRxedChar;
|
* char cRxedChar;
|
||||||
BaseType_t xCRWokenByPost = pdFALSE;
|
* BaseType_t xCRWokenByPost = pdFALSE;
|
||||||
|
*
|
||||||
// We loop around reading characters until there are none left in the UART.
|
* // We loop around reading characters until there are none left in the UART.
|
||||||
while( UART_RX_REG_NOT_EMPTY() )
|
* while( UART_RX_REG_NOT_EMPTY() )
|
||||||
{
|
* {
|
||||||
// Obtain the character from the UART.
|
* // Obtain the character from the UART.
|
||||||
cRxedChar = UART_RX_REG;
|
* cRxedChar = UART_RX_REG;
|
||||||
|
*
|
||||||
// Post the character onto a queue. xCRWokenByPost will be pdFALSE
|
* // Post the character onto a queue. xCRWokenByPost will be pdFALSE
|
||||||
// the first time around the loop. If the post causes a co-routine
|
* // the first time around the loop. If the post causes a co-routine
|
||||||
// to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
|
* // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
|
||||||
// In this manner we can ensure that if more than one co-routine is
|
* // In this manner we can ensure that if more than one co-routine is
|
||||||
// blocked on the queue only one is woken by this ISR no matter how
|
* // blocked on the queue only one is woken by this ISR no matter how
|
||||||
// many characters are posted to the queue.
|
* // many characters are posted to the queue.
|
||||||
xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
|
* xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
|
||||||
}
|
* }
|
||||||
}</pre>
|
* }</pre>
|
||||||
* \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
|
* \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )
|
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
* <pre>
|
* <pre>
|
||||||
crQUEUE_SEND_FROM_ISR(
|
* crQUEUE_SEND_FROM_ISR(
|
||||||
QueueHandle_t pxQueue,
|
* QueueHandle_t pxQueue,
|
||||||
void *pvBuffer,
|
* void *pvBuffer,
|
||||||
BaseType_t * pxCoRoutineWoken
|
* BaseType_t * pxCoRoutineWoken
|
||||||
)</pre>
|
* )</pre>
|
||||||
*
|
*
|
||||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||||
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||||
|
|
@ -622,75 +631,75 @@ void vCoRoutineSchedule( void );
|
||||||
* pdFALSE.
|
* pdFALSE.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
// A co-routine that posts a character to a queue then blocks for a fixed
|
* // A co-routine that posts a character to a queue then blocks for a fixed
|
||||||
// period. The character is incremented each time.
|
* // period. The character is incremented each time.
|
||||||
static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
* static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
* {
|
||||||
// cChar holds its value while this co-routine is blocked and must therefore
|
* // cChar holds its value while this co-routine is blocked and must therefore
|
||||||
// be declared static.
|
* // be declared static.
|
||||||
static char cCharToTx = 'a';
|
* static char cCharToTx = 'a';
|
||||||
BaseType_t xResult;
|
* BaseType_t xResult;
|
||||||
|
*
|
||||||
// All co-routines must start with a call to crSTART().
|
* // All co-routines must start with a call to crSTART().
|
||||||
crSTART( xHandle );
|
* crSTART( xHandle );
|
||||||
|
*
|
||||||
for( ;; )
|
* for( ;; )
|
||||||
{
|
* {
|
||||||
// Send the next character to the queue.
|
* // Send the next character to the queue.
|
||||||
crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
|
* crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
|
||||||
|
*
|
||||||
if( xResult == pdPASS )
|
* if( xResult == pdPASS )
|
||||||
{
|
* {
|
||||||
// The character was successfully posted to the queue.
|
* // The character was successfully posted to the queue.
|
||||||
}
|
* }
|
||||||
else
|
* else
|
||||||
{
|
* {
|
||||||
// Could not post the character to the queue.
|
* // Could not post the character to the queue.
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// Enable the UART Tx interrupt to cause an interrupt in this
|
* // Enable the UART Tx interrupt to cause an interrupt in this
|
||||||
// hypothetical UART. The interrupt will obtain the character
|
* // hypothetical UART. The interrupt will obtain the character
|
||||||
// from the queue and send it.
|
* // from the queue and send it.
|
||||||
ENABLE_RX_INTERRUPT();
|
* ENABLE_RX_INTERRUPT();
|
||||||
|
*
|
||||||
// Increment to the next character then block for a fixed period.
|
* // Increment to the next character then block for a fixed period.
|
||||||
// cCharToTx will maintain its value across the delay as it is
|
* // cCharToTx will maintain its value across the delay as it is
|
||||||
// declared static.
|
* // declared static.
|
||||||
cCharToTx++;
|
* cCharToTx++;
|
||||||
if( cCharToTx > 'x' )
|
* if( cCharToTx > 'x' )
|
||||||
{
|
* {
|
||||||
cCharToTx = 'a';
|
* cCharToTx = 'a';
|
||||||
}
|
* }
|
||||||
crDELAY( 100 );
|
* crDELAY( 100 );
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// All co-routines must end with a call to crEND().
|
* // All co-routines must end with a call to crEND().
|
||||||
crEND();
|
* crEND();
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// An ISR that uses a queue to receive characters to send on a UART.
|
* // An ISR that uses a queue to receive characters to send on a UART.
|
||||||
void vUART_ISR( void )
|
* void vUART_ISR( void )
|
||||||
{
|
* {
|
||||||
char cCharToTx;
|
* char cCharToTx;
|
||||||
BaseType_t xCRWokenByPost = pdFALSE;
|
* BaseType_t xCRWokenByPost = pdFALSE;
|
||||||
|
*
|
||||||
while( UART_TX_REG_EMPTY() )
|
* while( UART_TX_REG_EMPTY() )
|
||||||
{
|
* {
|
||||||
// Are there any characters in the queue waiting to be sent?
|
* // Are there any characters in the queue waiting to be sent?
|
||||||
// xCRWokenByPost will automatically be set to pdTRUE if a co-routine
|
* // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
|
||||||
// is woken by the post - ensuring that only a single co-routine is
|
* // is woken by the post - ensuring that only a single co-routine is
|
||||||
// woken no matter how many times we go around this loop.
|
* // woken no matter how many times we go around this loop.
|
||||||
if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
|
* if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
|
||||||
{
|
* {
|
||||||
SEND_CHARACTER( cCharToTx );
|
* SEND_CHARACTER( cCharToTx );
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
}</pre>
|
* }</pre>
|
||||||
* \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
|
* \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )
|
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is intended for internal use by the co-routine macros only.
|
* This function is intended for internal use by the co-routine macros only.
|
||||||
|
|
@ -701,7 +710,8 @@ void vCoRoutineSchedule( void );
|
||||||
* Removes the current co-routine from its ready list and places it in the
|
* Removes the current co-routine from its ready list and places it in the
|
||||||
* appropriate delayed list.
|
* appropriate delayed list.
|
||||||
*/
|
*/
|
||||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList );
|
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
|
||||||
|
List_t * pxEventList );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is intended for internal use by the queue implementation only.
|
* This function is intended for internal use by the queue implementation only.
|
||||||
|
|
@ -710,10 +720,10 @@ void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
|
||||||
* Removes the highest priority co-routine from the event list and places it in
|
* Removes the highest priority co-routine from the event list and places it in
|
||||||
* the pending ready list.
|
* the pending ready list.
|
||||||
*/
|
*/
|
||||||
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList );
|
BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* CO_ROUTINE_H */
|
#endif /* CO_ROUTINE_H */
|
||||||
|
|
|
||||||
|
|
@ -29,22 +29,22 @@
|
||||||
|
|
||||||
|
|
||||||
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||||
pre-processor definition was used to ensure the pre-processor found the correct
|
* pre-processor definition was used to ensure the pre-processor found the correct
|
||||||
portmacro.h file for the port being used. That scheme was deprecated in favour
|
* portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||||
of setting the compiler's include path such that it found the correct
|
* of setting the compiler's include path such that it found the correct
|
||||||
portmacro.h file - removing the need for the constant and allowing the
|
* portmacro.h file - removing the need for the constant and allowing the
|
||||||
portmacro.h file to be located anywhere in relation to the port being used. The
|
* portmacro.h file to be located anywhere in relation to the port being used. The
|
||||||
definitions below remain in the code for backward compatibility only. New
|
* definitions below remain in the code for backward compatibility only. New
|
||||||
projects should not use them. */
|
* projects should not use them. */
|
||||||
|
|
||||||
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
||||||
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
typedef void ( __interrupt __far * pxISR )();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
||||||
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
typedef void ( __interrupt __far * pxISR )();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GCC_MEGA_AVR
|
#ifdef GCC_MEGA_AVR
|
||||||
|
|
@ -208,19 +208,21 @@ projects should not use them. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BCC_INDUSTRIAL_PC_PORT
|
#ifdef BCC_INDUSTRIAL_PC_PORT
|
||||||
/* A short file name has to be used in place of the normal
|
|
||||||
FreeRTOSConfig.h when using the Borland compiler. */
|
/* A short file name has to be used in place of the normal
|
||||||
|
* FreeRTOSConfig.h when using the Borland compiler. */
|
||||||
#include "frconfig.h"
|
#include "frconfig.h"
|
||||||
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
typedef void ( __interrupt __far * pxISR )();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BCC_FLASH_LITE_186_PORT
|
#ifdef BCC_FLASH_LITE_186_PORT
|
||||||
/* A short file name has to be used in place of the normal
|
|
||||||
FreeRTOSConfig.h when using the Borland compiler. */
|
/* A short file name has to be used in place of the normal
|
||||||
|
* FreeRTOSConfig.h when using the Borland compiler. */
|
||||||
#include "frconfig.h"
|
#include "frconfig.h"
|
||||||
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
typedef void ( __interrupt __far * pxISR )();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
@ -275,4 +277,3 @@ projects should not use them. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* DEPRECATED_DEFINITIONS_H */
|
#endif /* DEPRECATED_DEFINITIONS_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,18 +25,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EVENT_GROUPS_H
|
#ifndef EVENT_GROUPS_H
|
||||||
#define EVENT_GROUPS_H
|
#define EVENT_GROUPS_H
|
||||||
|
|
||||||
#ifndef INC_FREERTOS_H
|
#ifndef INC_FREERTOS_H
|
||||||
#error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
|
#error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* FreeRTOS includes. */
|
/* FreeRTOS includes. */
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An event group is a collection of bits to which an application can assign a
|
* An event group is a collection of bits to which an application can assign a
|
||||||
|
|
@ -77,8 +77,8 @@ extern "C" {
|
||||||
* \defgroup EventGroupHandle_t EventGroupHandle_t
|
* \defgroup EventGroupHandle_t EventGroupHandle_t
|
||||||
* \ingroup EventGroup
|
* \ingroup EventGroup
|
||||||
*/
|
*/
|
||||||
struct EventGroupDef_t;
|
struct EventGroupDef_t;
|
||||||
typedef struct EventGroupDef_t * EventGroupHandle_t;
|
typedef struct EventGroupDef_t * EventGroupHandle_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The type that holds event bits always matches TickType_t - therefore the
|
* The type that holds event bits always matches TickType_t - therefore the
|
||||||
|
|
@ -88,13 +88,13 @@ typedef struct EventGroupDef_t * EventGroupHandle_t;
|
||||||
* \defgroup EventBits_t EventBits_t
|
* \defgroup EventBits_t EventBits_t
|
||||||
* \ingroup EventGroup
|
* \ingroup EventGroup
|
||||||
*/
|
*/
|
||||||
typedef TickType_t EventBits_t;
|
typedef TickType_t EventBits_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_groups.h
|
* event_groups.h
|
||||||
*<pre>
|
*<pre>
|
||||||
EventGroupHandle_t xEventGroupCreate( void );
|
* EventGroupHandle_t xEventGroupCreate( void );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Create a new event group.
|
* Create a new event group.
|
||||||
*
|
*
|
||||||
|
|
@ -121,36 +121,36 @@ typedef TickType_t EventBits_t;
|
||||||
* event group then NULL is returned. See http://www.freertos.org/a00111.html
|
* event group then NULL is returned. See http://www.freertos.org/a00111.html
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
// Declare a variable to hold the created event group.
|
* // Declare a variable to hold the created event group.
|
||||||
EventGroupHandle_t xCreatedEventGroup;
|
* EventGroupHandle_t xCreatedEventGroup;
|
||||||
|
*
|
||||||
// Attempt to create the event group.
|
* // Attempt to create the event group.
|
||||||
xCreatedEventGroup = xEventGroupCreate();
|
* xCreatedEventGroup = xEventGroupCreate();
|
||||||
|
*
|
||||||
// Was the event group created successfully?
|
* // Was the event group created successfully?
|
||||||
if( xCreatedEventGroup == NULL )
|
* if( xCreatedEventGroup == NULL )
|
||||||
{
|
* {
|
||||||
// The event group was not created because there was insufficient
|
* // The event group was not created because there was insufficient
|
||||||
// FreeRTOS heap available.
|
* // FreeRTOS heap available.
|
||||||
}
|
* }
|
||||||
else
|
* else
|
||||||
{
|
* {
|
||||||
// The event group was created.
|
* // The event group was created.
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xEventGroupCreate xEventGroupCreate
|
* \defgroup xEventGroupCreate xEventGroupCreate
|
||||||
* \ingroup EventGroup
|
* \ingroup EventGroup
|
||||||
*/
|
*/
|
||||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
|
EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_groups.h
|
* event_groups.h
|
||||||
*<pre>
|
*<pre>
|
||||||
EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
|
* EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Create a new event group.
|
* Create a new event group.
|
||||||
*
|
*
|
||||||
|
|
@ -180,34 +180,34 @@ typedef TickType_t EventBits_t;
|
||||||
* returned. If pxEventGroupBuffer was NULL then NULL is returned.
|
* returned. If pxEventGroupBuffer was NULL then NULL is returned.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
// StaticEventGroup_t is a publicly accessible structure that has the same
|
* // StaticEventGroup_t is a publicly accessible structure that has the same
|
||||||
// size and alignment requirements as the real event group structure. It is
|
* // size and alignment requirements as the real event group structure. It is
|
||||||
// provided as a mechanism for applications to know the size of the event
|
* // provided as a mechanism for applications to know the size of the event
|
||||||
// group (which is dependent on the architecture and configuration file
|
* // group (which is dependent on the architecture and configuration file
|
||||||
// settings) without breaking the strict data hiding policy by exposing the
|
* // settings) without breaking the strict data hiding policy by exposing the
|
||||||
// real event group internals. This StaticEventGroup_t variable is passed
|
* // real event group internals. This StaticEventGroup_t variable is passed
|
||||||
// into the xSemaphoreCreateEventGroupStatic() function and is used to store
|
* // into the xSemaphoreCreateEventGroupStatic() function and is used to store
|
||||||
// the event group's data structures
|
* // the event group's data structures
|
||||||
StaticEventGroup_t xEventGroupBuffer;
|
* StaticEventGroup_t xEventGroupBuffer;
|
||||||
|
*
|
||||||
// Create the event group without dynamically allocating any memory.
|
* // Create the event group without dynamically allocating any memory.
|
||||||
xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
|
* xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
|
||||||
</pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
|
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_groups.h
|
* event_groups.h
|
||||||
*<pre>
|
*<pre>
|
||||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
* EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||||
const EventBits_t uxBitsToWaitFor,
|
* const EventBits_t uxBitsToWaitFor,
|
||||||
const BaseType_t xClearOnExit,
|
* const BaseType_t xClearOnExit,
|
||||||
const BaseType_t xWaitForAllBits,
|
* const BaseType_t xWaitForAllBits,
|
||||||
const TickType_t xTicksToWait );
|
* const TickType_t xTicksToWait );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* [Potentially] block to wait for one or more bits to be set within a
|
* [Potentially] block to wait for one or more bits to be set within a
|
||||||
* previously created event group.
|
* previously created event group.
|
||||||
|
|
@ -251,53 +251,57 @@ typedef TickType_t EventBits_t;
|
||||||
* pdTRUE.
|
* pdTRUE.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
#define BIT_0 ( 1 << 0 )
|
#define BIT_0 ( 1 << 0 )
|
||||||
#define BIT_4 ( 1 << 4 )
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
*
|
||||||
void aFunction( EventGroupHandle_t xEventGroup )
|
* void aFunction( EventGroupHandle_t xEventGroup )
|
||||||
{
|
* {
|
||||||
EventBits_t uxBits;
|
* EventBits_t uxBits;
|
||||||
const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
* const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
||||||
|
*
|
||||||
// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
|
* // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
|
||||||
// the event group. Clear the bits before exiting.
|
* // the event group. Clear the bits before exiting.
|
||||||
uxBits = xEventGroupWaitBits(
|
* uxBits = xEventGroupWaitBits(
|
||||||
xEventGroup, // The event group being tested.
|
* xEventGroup, // The event group being tested.
|
||||||
BIT_0 | BIT_4, // The bits within the event group to wait for.
|
* BIT_0 | BIT_4, // The bits within the event group to wait for.
|
||||||
pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
|
* pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
|
||||||
pdFALSE, // Don't wait for both bits, either bit will do.
|
* pdFALSE, // Don't wait for both bits, either bit will do.
|
||||||
xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
|
* xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
|
||||||
|
*
|
||||||
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
* if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||||
{
|
* {
|
||||||
// xEventGroupWaitBits() returned because both bits were set.
|
* // xEventGroupWaitBits() returned because both bits were set.
|
||||||
}
|
* }
|
||||||
else if( ( uxBits & BIT_0 ) != 0 )
|
* else if( ( uxBits & BIT_0 ) != 0 )
|
||||||
{
|
* {
|
||||||
// xEventGroupWaitBits() returned because just BIT_0 was set.
|
* // xEventGroupWaitBits() returned because just BIT_0 was set.
|
||||||
}
|
* }
|
||||||
else if( ( uxBits & BIT_4 ) != 0 )
|
* else if( ( uxBits & BIT_4 ) != 0 )
|
||||||
{
|
* {
|
||||||
// xEventGroupWaitBits() returned because just BIT_4 was set.
|
* // xEventGroupWaitBits() returned because just BIT_4 was set.
|
||||||
}
|
* }
|
||||||
else
|
* else
|
||||||
{
|
* {
|
||||||
// xEventGroupWaitBits() returned because xTicksToWait ticks passed
|
* // xEventGroupWaitBits() returned because xTicksToWait ticks passed
|
||||||
// without either BIT_0 or BIT_4 becoming set.
|
* // without either BIT_0 or BIT_4 becoming set.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xEventGroupWaitBits xEventGroupWaitBits
|
* \defgroup xEventGroupWaitBits xEventGroupWaitBits
|
||||||
* \ingroup EventGroup
|
* \ingroup EventGroup
|
||||||
*/
|
*/
|
||||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
const BaseType_t xClearOnExit,
|
||||||
|
const BaseType_t xWaitForAllBits,
|
||||||
|
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_groups.h
|
* event_groups.h
|
||||||
*<pre>
|
*<pre>
|
||||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
|
* EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Clear bits within an event group. This function cannot be called from an
|
* Clear bits within an event group. This function cannot be called from an
|
||||||
* interrupt.
|
* interrupt.
|
||||||
|
|
@ -311,50 +315,51 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits
|
||||||
* @return The value of the event group before the specified bits were cleared.
|
* @return The value of the event group before the specified bits were cleared.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
#define BIT_0 ( 1 << 0 )
|
#define BIT_0 ( 1 << 0 )
|
||||||
#define BIT_4 ( 1 << 4 )
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
*
|
||||||
void aFunction( EventGroupHandle_t xEventGroup )
|
* void aFunction( EventGroupHandle_t xEventGroup )
|
||||||
{
|
* {
|
||||||
EventBits_t uxBits;
|
* EventBits_t uxBits;
|
||||||
|
*
|
||||||
// Clear bit 0 and bit 4 in xEventGroup.
|
* // Clear bit 0 and bit 4 in xEventGroup.
|
||||||
uxBits = xEventGroupClearBits(
|
* uxBits = xEventGroupClearBits(
|
||||||
xEventGroup, // The event group being updated.
|
* xEventGroup, // The event group being updated.
|
||||||
BIT_0 | BIT_4 );// The bits being cleared.
|
* BIT_0 | BIT_4 );// The bits being cleared.
|
||||||
|
*
|
||||||
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
* if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||||
{
|
* {
|
||||||
// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
|
* // Both bit 0 and bit 4 were set before xEventGroupClearBits() was
|
||||||
// called. Both will now be clear (not set).
|
* // called. Both will now be clear (not set).
|
||||||
}
|
* }
|
||||||
else if( ( uxBits & BIT_0 ) != 0 )
|
* else if( ( uxBits & BIT_0 ) != 0 )
|
||||||
{
|
* {
|
||||||
// Bit 0 was set before xEventGroupClearBits() was called. It will
|
* // Bit 0 was set before xEventGroupClearBits() was called. It will
|
||||||
// now be clear.
|
* // now be clear.
|
||||||
}
|
* }
|
||||||
else if( ( uxBits & BIT_4 ) != 0 )
|
* else if( ( uxBits & BIT_4 ) != 0 )
|
||||||
{
|
* {
|
||||||
// Bit 4 was set before xEventGroupClearBits() was called. It will
|
* // Bit 4 was set before xEventGroupClearBits() was called. It will
|
||||||
// now be clear.
|
* // now be clear.
|
||||||
}
|
* }
|
||||||
else
|
* else
|
||||||
{
|
* {
|
||||||
// Neither bit 0 nor bit 4 were set in the first place.
|
* // Neither bit 0 nor bit 4 were set in the first place.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xEventGroupClearBits xEventGroupClearBits
|
* \defgroup xEventGroupClearBits xEventGroupClearBits
|
||||||
* \ingroup EventGroup
|
* \ingroup EventGroup
|
||||||
*/
|
*/
|
||||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_groups.h
|
* event_groups.h
|
||||||
*<pre>
|
*<pre>
|
||||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
* BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* A version of xEventGroupClearBits() that can be called from an interrupt.
|
* A version of xEventGroupClearBits() that can be called from an interrupt.
|
||||||
*
|
*
|
||||||
|
|
@ -379,41 +384,42 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
|
||||||
* if the timer service queue was full.
|
* if the timer service queue was full.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
#define BIT_0 ( 1 << 0 )
|
#define BIT_0 ( 1 << 0 )
|
||||||
#define BIT_4 ( 1 << 4 )
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
*
|
||||||
// An event group which it is assumed has already been created by a call to
|
* // An event group which it is assumed has already been created by a call to
|
||||||
// xEventGroupCreate().
|
* // xEventGroupCreate().
|
||||||
EventGroupHandle_t xEventGroup;
|
* EventGroupHandle_t xEventGroup;
|
||||||
|
*
|
||||||
void anInterruptHandler( void )
|
* void anInterruptHandler( void )
|
||||||
{
|
* {
|
||||||
// Clear bit 0 and bit 4 in xEventGroup.
|
* // Clear bit 0 and bit 4 in xEventGroup.
|
||||||
xResult = xEventGroupClearBitsFromISR(
|
* xResult = xEventGroupClearBitsFromISR(
|
||||||
xEventGroup, // The event group being updated.
|
* xEventGroup, // The event group being updated.
|
||||||
BIT_0 | BIT_4 ); // The bits being set.
|
* BIT_0 | BIT_4 ); // The bits being set.
|
||||||
|
*
|
||||||
if( xResult == pdPASS )
|
* if( xResult == pdPASS )
|
||||||
{
|
* {
|
||||||
// The message was posted successfully.
|
* // The message was posted successfully.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
|
* \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
|
||||||
* \ingroup EventGroup
|
* \ingroup EventGroup
|
||||||
*/
|
*/
|
||||||
#if( configUSE_TRACE_FACILITY == 1 )
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
#else
|
const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
||||||
|
#else
|
||||||
#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
|
#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_groups.h
|
* event_groups.h
|
||||||
*<pre>
|
*<pre>
|
||||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
* EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Set bits within an event group.
|
* Set bits within an event group.
|
||||||
* This function cannot be called from an interrupt. xEventGroupSetBitsFromISR()
|
* This function cannot be called from an interrupt. xEventGroupSetBitsFromISR()
|
||||||
|
|
@ -439,55 +445,56 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
|
||||||
* event group value before the call to xEventGroupSetBits() returns.
|
* event group value before the call to xEventGroupSetBits() returns.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
#define BIT_0 ( 1 << 0 )
|
#define BIT_0 ( 1 << 0 )
|
||||||
#define BIT_4 ( 1 << 4 )
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
*
|
||||||
void aFunction( EventGroupHandle_t xEventGroup )
|
* void aFunction( EventGroupHandle_t xEventGroup )
|
||||||
{
|
* {
|
||||||
EventBits_t uxBits;
|
* EventBits_t uxBits;
|
||||||
|
*
|
||||||
// Set bit 0 and bit 4 in xEventGroup.
|
* // Set bit 0 and bit 4 in xEventGroup.
|
||||||
uxBits = xEventGroupSetBits(
|
* uxBits = xEventGroupSetBits(
|
||||||
xEventGroup, // The event group being updated.
|
* xEventGroup, // The event group being updated.
|
||||||
BIT_0 | BIT_4 );// The bits being set.
|
* BIT_0 | BIT_4 );// The bits being set.
|
||||||
|
*
|
||||||
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
* if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||||
{
|
* {
|
||||||
// Both bit 0 and bit 4 remained set when the function returned.
|
* // Both bit 0 and bit 4 remained set when the function returned.
|
||||||
}
|
* }
|
||||||
else if( ( uxBits & BIT_0 ) != 0 )
|
* else if( ( uxBits & BIT_0 ) != 0 )
|
||||||
{
|
* {
|
||||||
// Bit 0 remained set when the function returned, but bit 4 was
|
* // Bit 0 remained set when the function returned, but bit 4 was
|
||||||
// cleared. It might be that bit 4 was cleared automatically as a
|
* // cleared. It might be that bit 4 was cleared automatically as a
|
||||||
// task that was waiting for bit 4 was removed from the Blocked
|
* // task that was waiting for bit 4 was removed from the Blocked
|
||||||
// state.
|
* // state.
|
||||||
}
|
* }
|
||||||
else if( ( uxBits & BIT_4 ) != 0 )
|
* else if( ( uxBits & BIT_4 ) != 0 )
|
||||||
{
|
* {
|
||||||
// Bit 4 remained set when the function returned, but bit 0 was
|
* // Bit 4 remained set when the function returned, but bit 0 was
|
||||||
// cleared. It might be that bit 0 was cleared automatically as a
|
* // cleared. It might be that bit 0 was cleared automatically as a
|
||||||
// task that was waiting for bit 0 was removed from the Blocked
|
* // task that was waiting for bit 0 was removed from the Blocked
|
||||||
// state.
|
* // state.
|
||||||
}
|
* }
|
||||||
else
|
* else
|
||||||
{
|
* {
|
||||||
// Neither bit 0 nor bit 4 remained set. It might be that a task
|
* // Neither bit 0 nor bit 4 remained set. It might be that a task
|
||||||
// was waiting for both of the bits to be set, and the bits were
|
* // was waiting for both of the bits to be set, and the bits were
|
||||||
// cleared as the task left the Blocked state.
|
* // cleared as the task left the Blocked state.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xEventGroupSetBits xEventGroupSetBits
|
* \defgroup xEventGroupSetBits xEventGroupSetBits
|
||||||
* \ingroup EventGroup
|
* \ingroup EventGroup
|
||||||
*/
|
*/
|
||||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
|
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_groups.h
|
* event_groups.h
|
||||||
*<pre>
|
*<pre>
|
||||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
|
* BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* A version of xEventGroupSetBits() that can be called from an interrupt.
|
* A version of xEventGroupSetBits() that can be called from an interrupt.
|
||||||
*
|
*
|
||||||
|
|
@ -520,55 +527,57 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
|
||||||
* if the timer service queue was full.
|
* if the timer service queue was full.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
#define BIT_0 ( 1 << 0 )
|
#define BIT_0 ( 1 << 0 )
|
||||||
#define BIT_4 ( 1 << 4 )
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
*
|
||||||
// An event group which it is assumed has already been created by a call to
|
* // An event group which it is assumed has already been created by a call to
|
||||||
// xEventGroupCreate().
|
* // xEventGroupCreate().
|
||||||
EventGroupHandle_t xEventGroup;
|
* EventGroupHandle_t xEventGroup;
|
||||||
|
*
|
||||||
void anInterruptHandler( void )
|
* void anInterruptHandler( void )
|
||||||
{
|
* {
|
||||||
BaseType_t xHigherPriorityTaskWoken, xResult;
|
* BaseType_t xHigherPriorityTaskWoken, xResult;
|
||||||
|
*
|
||||||
// xHigherPriorityTaskWoken must be initialised to pdFALSE.
|
* // xHigherPriorityTaskWoken must be initialised to pdFALSE.
|
||||||
xHigherPriorityTaskWoken = pdFALSE;
|
* xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
*
|
||||||
// Set bit 0 and bit 4 in xEventGroup.
|
* // Set bit 0 and bit 4 in xEventGroup.
|
||||||
xResult = xEventGroupSetBitsFromISR(
|
* xResult = xEventGroupSetBitsFromISR(
|
||||||
xEventGroup, // The event group being updated.
|
* xEventGroup, // The event group being updated.
|
||||||
BIT_0 | BIT_4 // The bits being set.
|
* BIT_0 | BIT_4 // The bits being set.
|
||||||
&xHigherPriorityTaskWoken );
|
* &xHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
// Was the message posted successfully?
|
* // Was the message posted successfully?
|
||||||
if( xResult == pdPASS )
|
* if( xResult == pdPASS )
|
||||||
{
|
* {
|
||||||
// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
|
* // If xHigherPriorityTaskWoken is now set to pdTRUE then a context
|
||||||
// switch should be requested. The macro used is port specific and
|
* // switch should be requested. The macro used is port specific and
|
||||||
// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
|
* // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
|
||||||
// refer to the documentation page for the port being used.
|
* // refer to the documentation page for the port being used.
|
||||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
|
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
|
||||||
* \ingroup EventGroup
|
* \ingroup EventGroup
|
||||||
*/
|
*/
|
||||||
#if( configUSE_TRACE_FACILITY == 1 )
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||||
#else
|
const EventBits_t uxBitsToSet,
|
||||||
|
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
#else
|
||||||
#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
|
#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_groups.h
|
* event_groups.h
|
||||||
*<pre>
|
*<pre>
|
||||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
* EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||||
const EventBits_t uxBitsToSet,
|
* const EventBits_t uxBitsToSet,
|
||||||
const EventBits_t uxBitsToWaitFor,
|
* const EventBits_t uxBitsToWaitFor,
|
||||||
TickType_t xTicksToWait );
|
* TickType_t xTicksToWait );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Atomically set bits within an event group, then wait for a combination of
|
* Atomically set bits within an event group, then wait for a combination of
|
||||||
* bits to be set within the same event group. This functionality is typically
|
* bits to be set within the same event group. This functionality is typically
|
||||||
|
|
@ -607,92 +616,95 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
|
||||||
* automatically cleared.
|
* automatically cleared.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
// Bits used by the three tasks.
|
* // Bits used by the three tasks.
|
||||||
#define TASK_0_BIT ( 1 << 0 )
|
#define TASK_0_BIT ( 1 << 0 )
|
||||||
#define TASK_1_BIT ( 1 << 1 )
|
#define TASK_1_BIT ( 1 << 1 )
|
||||||
#define TASK_2_BIT ( 1 << 2 )
|
#define TASK_2_BIT ( 1 << 2 )
|
||||||
|
*
|
||||||
#define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
|
#define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
|
||||||
|
*
|
||||||
// Use an event group to synchronise three tasks. It is assumed this event
|
* // Use an event group to synchronise three tasks. It is assumed this event
|
||||||
// group has already been created elsewhere.
|
* // group has already been created elsewhere.
|
||||||
EventGroupHandle_t xEventBits;
|
* EventGroupHandle_t xEventBits;
|
||||||
|
*
|
||||||
void vTask0( void *pvParameters )
|
* void vTask0( void *pvParameters )
|
||||||
{
|
* {
|
||||||
EventBits_t uxReturn;
|
* EventBits_t uxReturn;
|
||||||
TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
* TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
||||||
|
*
|
||||||
for( ;; )
|
* for( ;; )
|
||||||
{
|
* {
|
||||||
// Perform task functionality here.
|
* // Perform task functionality here.
|
||||||
|
*
|
||||||
// Set bit 0 in the event flag to note this task has reached the
|
* // Set bit 0 in the event flag to note this task has reached the
|
||||||
// sync point. The other two tasks will set the other two bits defined
|
* // sync point. The other two tasks will set the other two bits defined
|
||||||
// by ALL_SYNC_BITS. All three tasks have reached the synchronisation
|
* // by ALL_SYNC_BITS. All three tasks have reached the synchronisation
|
||||||
// point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms
|
* // point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms
|
||||||
// for this to happen.
|
* // for this to happen.
|
||||||
uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
|
* uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
|
||||||
|
*
|
||||||
if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
|
* if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
|
||||||
{
|
* {
|
||||||
// All three tasks reached the synchronisation point before the call
|
* // All three tasks reached the synchronisation point before the call
|
||||||
// to xEventGroupSync() timed out.
|
* // to xEventGroupSync() timed out.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
void vTask1( void *pvParameters )
|
* void vTask1( void *pvParameters )
|
||||||
{
|
* {
|
||||||
for( ;; )
|
* for( ;; )
|
||||||
{
|
* {
|
||||||
// Perform task functionality here.
|
* // Perform task functionality here.
|
||||||
|
*
|
||||||
// Set bit 1 in the event flag to note this task has reached the
|
* // Set bit 1 in the event flag to note this task has reached the
|
||||||
// synchronisation point. The other two tasks will set the other two
|
* // synchronisation point. The other two tasks will set the other two
|
||||||
// bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
* // bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
||||||
// synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
* // synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
||||||
// indefinitely for this to happen.
|
* // indefinitely for this to happen.
|
||||||
xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
* xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
||||||
|
*
|
||||||
// xEventGroupSync() was called with an indefinite block time, so
|
* // xEventGroupSync() was called with an indefinite block time, so
|
||||||
// this task will only reach here if the syncrhonisation was made by all
|
* // this task will only reach here if the syncrhonisation was made by all
|
||||||
// three tasks, so there is no need to test the return value.
|
* // three tasks, so there is no need to test the return value.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
void vTask2( void *pvParameters )
|
* void vTask2( void *pvParameters )
|
||||||
{
|
* {
|
||||||
for( ;; )
|
* for( ;; )
|
||||||
{
|
* {
|
||||||
// Perform task functionality here.
|
* // Perform task functionality here.
|
||||||
|
*
|
||||||
// Set bit 2 in the event flag to note this task has reached the
|
* // Set bit 2 in the event flag to note this task has reached the
|
||||||
// synchronisation point. The other two tasks will set the other two
|
* // synchronisation point. The other two tasks will set the other two
|
||||||
// bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
* // bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
||||||
// synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
* // synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
||||||
// indefinitely for this to happen.
|
* // indefinitely for this to happen.
|
||||||
xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
* xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
||||||
|
*
|
||||||
// xEventGroupSync() was called with an indefinite block time, so
|
* // xEventGroupSync() was called with an indefinite block time, so
|
||||||
// this task will only reach here if the syncrhonisation was made by all
|
* // this task will only reach here if the syncrhonisation was made by all
|
||||||
// three tasks, so there is no need to test the return value.
|
* // three tasks, so there is no need to test the return value.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xEventGroupSync xEventGroupSync
|
* \defgroup xEventGroupSync xEventGroupSync
|
||||||
* \ingroup EventGroup
|
* \ingroup EventGroup
|
||||||
*/
|
*/
|
||||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_groups.h
|
* event_groups.h
|
||||||
*<pre>
|
*<pre>
|
||||||
EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
|
* EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Returns the current value of the bits in an event group. This function
|
* Returns the current value of the bits in an event group. This function
|
||||||
* cannot be used from an interrupt.
|
* cannot be used from an interrupt.
|
||||||
|
|
@ -704,13 +716,13 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t u
|
||||||
* \defgroup xEventGroupGetBits xEventGroupGetBits
|
* \defgroup xEventGroupGetBits xEventGroupGetBits
|
||||||
* \ingroup EventGroup
|
* \ingroup EventGroup
|
||||||
*/
|
*/
|
||||||
#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )
|
#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_groups.h
|
* event_groups.h
|
||||||
*<pre>
|
*<pre>
|
||||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
|
* EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* A version of xEventGroupGetBits() that can be called from an ISR.
|
* A version of xEventGroupGetBits() that can be called from an ISR.
|
||||||
*
|
*
|
||||||
|
|
@ -721,13 +733,13 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t u
|
||||||
* \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR
|
* \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR
|
||||||
* \ingroup EventGroup
|
* \ingroup EventGroup
|
||||||
*/
|
*/
|
||||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_groups.h
|
* event_groups.h
|
||||||
*<pre>
|
*<pre>
|
||||||
void xEventGroupDelete( EventGroupHandle_t xEventGroup );
|
* void xEventGroupDelete( EventGroupHandle_t xEventGroup );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Delete an event group that was previously created by a call to
|
* Delete an event group that was previously created by a call to
|
||||||
* xEventGroupCreate(). Tasks that are blocked on the event group will be
|
* xEventGroupCreate(). Tasks that are blocked on the event group will be
|
||||||
|
|
@ -735,22 +747,23 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG
|
||||||
*
|
*
|
||||||
* @param xEventGroup The event group being deleted.
|
* @param xEventGroup The event group being deleted.
|
||||||
*/
|
*/
|
||||||
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/* For internal use only. */
|
/* For internal use only. */
|
||||||
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
|
void vEventGroupSetBitsCallback( void * pvEventGroup,
|
||||||
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
|
const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
|
||||||
|
void vEventGroupClearBitsCallback( void * pvEventGroup,
|
||||||
|
const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
|
||||||
#if (configUSE_TRACE_FACILITY == 1)
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION;
|
UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) PRIVILEGED_FUNCTION;
|
||||||
void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
|
void vEventGroupSetNumber( void * xEventGroup,
|
||||||
#endif
|
UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* EVENT_GROUPS_H */
|
#endif /* EVENT_GROUPS_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
113
include/list.h
113
include/list.h
|
|
@ -57,7 +57,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LIST_H
|
#ifndef LIST_H
|
||||||
#define LIST_H
|
#define LIST_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The list structure members are modified from within interrupts, and therefore
|
* The list structure members are modified from within interrupts, and therefore
|
||||||
|
|
@ -87,20 +87,20 @@
|
||||||
* FreeRTOSConfig.h (without the quotes):
|
* FreeRTOSConfig.h (without the quotes):
|
||||||
* "#define configLIST_VOLATILE volatile"
|
* "#define configLIST_VOLATILE volatile"
|
||||||
*/
|
*/
|
||||||
#ifndef configLIST_VOLATILE
|
#ifndef configLIST_VOLATILE
|
||||||
#define configLIST_VOLATILE
|
#define configLIST_VOLATILE
|
||||||
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
|
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Macros that can be used to place known values within the list structures,
|
/* Macros that can be used to place known values within the list structures,
|
||||||
then check that the known values do not get corrupted during the execution of
|
* then check that the known values do not get corrupted during the execution of
|
||||||
the application. These may catch the list data structures being overwritten in
|
* the application. These may catch the list data structures being overwritten in
|
||||||
memory. They will not catch data errors caused by incorrect configuration or
|
* memory. They will not catch data errors caused by incorrect configuration or
|
||||||
use of FreeRTOS.*/
|
* use of FreeRTOS.*/
|
||||||
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
|
#if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
|
||||||
/* Define the macros to do nothing. */
|
/* Define the macros to do nothing. */
|
||||||
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
||||||
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
||||||
|
|
@ -112,32 +112,32 @@ use of FreeRTOS.*/
|
||||||
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
|
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
|
||||||
#define listTEST_LIST_ITEM_INTEGRITY( pxItem )
|
#define listTEST_LIST_ITEM_INTEGRITY( pxItem )
|
||||||
#define listTEST_LIST_INTEGRITY( pxList )
|
#define listTEST_LIST_INTEGRITY( pxList )
|
||||||
#else
|
#else /* if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) */
|
||||||
/* Define macros that add new members into the list structures. */
|
/* Define macros that add new members into the list structures. */
|
||||||
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
|
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
|
||||||
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
|
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
|
||||||
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1;
|
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1;
|
||||||
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2;
|
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2;
|
||||||
|
|
||||||
/* Define macros that set the new structure members to known values. */
|
/* Define macros that set the new structure members to known values. */
|
||||||
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
||||||
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
||||||
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
||||||
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
||||||
|
|
||||||
/* Define macros that will assert if one of the structure members does not
|
/* Define macros that will assert if one of the structure members does not
|
||||||
contain its expected value. */
|
* contain its expected value. */
|
||||||
#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
||||||
#define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
#define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
||||||
#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
|
#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definition of the only type of object that a list can contain.
|
* Definition of the only type of object that a list can contain.
|
||||||
*/
|
*/
|
||||||
struct xLIST;
|
struct xLIST;
|
||||||
struct xLIST_ITEM
|
struct xLIST_ITEM
|
||||||
{
|
{
|
||||||
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */
|
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */
|
||||||
|
|
@ -145,29 +145,29 @@ struct xLIST_ITEM
|
||||||
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
||||||
struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
||||||
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
};
|
};
|
||||||
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
|
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
|
||||||
|
|
||||||
struct xMINI_LIST_ITEM
|
struct xMINI_LIST_ITEM
|
||||||
{
|
{
|
||||||
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
configLIST_VOLATILE TickType_t xItemValue;
|
configLIST_VOLATILE TickType_t xItemValue;
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
|
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
|
||||||
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
|
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
|
||||||
};
|
};
|
||||||
typedef struct xMINI_LIST_ITEM MiniListItem_t;
|
typedef struct xMINI_LIST_ITEM MiniListItem_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definition of the type of queue used by the scheduler.
|
* Definition of the type of queue used by the scheduler.
|
||||||
*/
|
*/
|
||||||
typedef struct xLIST
|
typedef struct xLIST
|
||||||
{
|
{
|
||||||
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
volatile UBaseType_t uxNumberOfItems;
|
volatile UBaseType_t uxNumberOfItems;
|
||||||
ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
|
ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
|
||||||
MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
||||||
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
} List_t;
|
} List_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to set the owner of a list item. The owner of a list item
|
* Access macro to set the owner of a list item. The owner of a list item
|
||||||
|
|
@ -176,7 +176,7 @@ typedef struct xLIST
|
||||||
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
|
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to get the owner of a list item. The owner of a list item
|
* Access macro to get the owner of a list item. The owner of a list item
|
||||||
|
|
@ -185,7 +185,7 @@ typedef struct xLIST
|
||||||
* \page listGET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
* \page listGET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner )
|
#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to set the value of the list item. In most cases the value is
|
* Access macro to set the value of the list item. In most cases the value is
|
||||||
|
|
@ -194,7 +194,7 @@ typedef struct xLIST
|
||||||
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) )
|
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to retrieve the value of the list item. The value can
|
* Access macro to retrieve the value of the list item. The value can
|
||||||
|
|
@ -204,7 +204,7 @@ typedef struct xLIST
|
||||||
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
|
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to retrieve the value of the list item at the head of a given
|
* Access macro to retrieve the value of the list item at the head of a given
|
||||||
|
|
@ -213,7 +213,7 @@ typedef struct xLIST
|
||||||
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue )
|
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the list item at the head of the list.
|
* Return the list item at the head of the list.
|
||||||
|
|
@ -221,7 +221,7 @@ typedef struct xLIST
|
||||||
* \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY
|
* \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext )
|
#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the next list item.
|
* Return the next list item.
|
||||||
|
|
@ -229,7 +229,7 @@ typedef struct xLIST
|
||||||
* \page listGET_NEXT listGET_NEXT
|
* \page listGET_NEXT listGET_NEXT
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext )
|
#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the list item that marks the end of the list
|
* Return the list item that marks the end of the list
|
||||||
|
|
@ -237,7 +237,7 @@ typedef struct xLIST
|
||||||
* \page listGET_END_MARKER listGET_END_MARKER
|
* \page listGET_END_MARKER listGET_END_MARKER
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
|
#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to determine if a list contains any items. The macro will
|
* Access macro to determine if a list contains any items. The macro will
|
||||||
|
|
@ -246,12 +246,12 @@ typedef struct xLIST
|
||||||
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
|
#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to return the number of items in the list.
|
* Access macro to return the number of items in the list.
|
||||||
*/
|
*/
|
||||||
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
|
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access function to obtain the owner of the next entry in a list.
|
* Access function to obtain the owner of the next entry in a list.
|
||||||
|
|
@ -273,9 +273,9 @@ typedef struct xLIST
|
||||||
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
||||||
{ \
|
{ \
|
||||||
List_t * const pxConstList = ( pxList ); \
|
List_t * const pxConstList = ( pxList ); \
|
||||||
/* Increment the index to the next item and return the item, ensuring */ \
|
/* Increment the index to the next item and return the item, ensuring */ \
|
||||||
/* we don't return the marker used at the end of the list. */ \
|
/* we don't return the marker used at the end of the list. */ \
|
||||||
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||||
|
|
@ -284,7 +284,7 @@ List_t * const pxConstList = ( pxList ); \
|
||||||
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||||
} \
|
} \
|
||||||
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
|
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -303,7 +303,7 @@ List_t * const pxConstList = ( pxList ); \
|
||||||
* \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
|
* \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )
|
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( ( &( ( pxList )->xListEnd ) )->pxNext->pvOwner )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check to see if a list item is within a list. The list item maintains a
|
* Check to see if a list item is within a list. The list item maintains a
|
||||||
|
|
@ -314,7 +314,7 @@ List_t * const pxConstList = ( pxList ); \
|
||||||
* @param pxListItem The list item we want to know if is in the list.
|
* @param pxListItem The list item we want to know if is in the list.
|
||||||
* @return pdTRUE if the list item is in the list, otherwise pdFALSE.
|
* @return pdTRUE if the list item is in the list, otherwise pdFALSE.
|
||||||
*/
|
*/
|
||||||
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) )
|
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the list a list item is contained within (referenced from).
|
* Return the list a list item is contained within (referenced from).
|
||||||
|
|
@ -322,14 +322,14 @@ List_t * const pxConstList = ( pxList ); \
|
||||||
* @param pxListItem The list item being queried.
|
* @param pxListItem The list item being queried.
|
||||||
* @return A pointer to the List_t object that references the pxListItem
|
* @return A pointer to the List_t object that references the pxListItem
|
||||||
*/
|
*/
|
||||||
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer )
|
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This provides a crude means of knowing if a list has been initialised, as
|
* This provides a crude means of knowing if a list has been initialised, as
|
||||||
* pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()
|
* pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()
|
||||||
* function.
|
* function.
|
||||||
*/
|
*/
|
||||||
#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )
|
#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Must be called before a list is used! This initialises all the members
|
* Must be called before a list is used! This initialises all the members
|
||||||
|
|
@ -341,7 +341,7 @@ List_t * const pxConstList = ( pxList ); \
|
||||||
* \page vListInitialise vListInitialise
|
* \page vListInitialise vListInitialise
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION;
|
void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Must be called before a list item is used. This sets the list container to
|
* Must be called before a list item is used. This sets the list container to
|
||||||
|
|
@ -352,7 +352,7 @@ void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION;
|
||||||
* \page vListInitialiseItem vListInitialiseItem
|
* \page vListInitialiseItem vListInitialiseItem
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
|
void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a list item into a list. The item will be inserted into the list in
|
* Insert a list item into a list. The item will be inserted into the list in
|
||||||
|
|
@ -365,7 +365,8 @@ void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
|
||||||
* \page vListInsert vListInsert
|
* \page vListInsert vListInsert
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
void vListInsert( List_t * const pxList,
|
||||||
|
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a list item into a list. The item will be inserted in a position
|
* Insert a list item into a list. The item will be inserted in a position
|
||||||
|
|
@ -386,7 +387,8 @@ void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIV
|
||||||
* \page vListInsertEnd vListInsertEnd
|
* \page vListInsertEnd vListInsertEnd
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
void vListInsertEnd( List_t * const pxList,
|
||||||
|
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove an item from a list. The list item has a pointer to the list that
|
* Remove an item from a list. The list item has a pointer to the list that
|
||||||
|
|
@ -401,11 +403,10 @@ void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) P
|
||||||
* \page uxListRemove uxListRemove
|
* \page uxListRemove uxListRemove
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;
|
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif /* ifndef LIST_H */
|
||||||
|
|
|
||||||
|
|
@ -59,18 +59,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FREERTOS_MESSAGE_BUFFER_H
|
#ifndef FREERTOS_MESSAGE_BUFFER_H
|
||||||
#define FREERTOS_MESSAGE_BUFFER_H
|
#define FREERTOS_MESSAGE_BUFFER_H
|
||||||
|
|
||||||
#ifndef INC_FREERTOS_H
|
#ifndef INC_FREERTOS_H
|
||||||
#error "include FreeRTOS.h must appear in source files before include message_buffer.h"
|
#error "include FreeRTOS.h must appear in source files before include message_buffer.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Message buffers are built onto of stream buffers. */
|
/* Message buffers are built onto of stream buffers. */
|
||||||
#include "stream_buffer.h"
|
#include "stream_buffer.h"
|
||||||
|
|
||||||
#if defined( __cplusplus )
|
#if defined( __cplusplus )
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type by which message buffers are referenced. For example, a call to
|
* Type by which message buffers are referenced. For example, a call to
|
||||||
|
|
@ -78,16 +78,16 @@ extern "C" {
|
||||||
* then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(),
|
* then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(),
|
||||||
* etc.
|
* etc.
|
||||||
*/
|
*/
|
||||||
typedef void * MessageBufferHandle_t;
|
typedef void * MessageBufferHandle_t;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
|
* MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Creates a new message buffer using dynamically allocated memory. See
|
* Creates a new message buffer using dynamically allocated memory. See
|
||||||
* xMessageBufferCreateStatic() for a version that uses statically allocated
|
* xMessageBufferCreateStatic() for a version that uses statically allocated
|
||||||
|
|
@ -111,43 +111,43 @@ MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
|
||||||
* buffer.
|
* buffer.
|
||||||
*
|
*
|
||||||
* Example use:
|
* Example use:
|
||||||
<pre>
|
* <pre>
|
||||||
|
*
|
||||||
void vAFunction( void )
|
* void vAFunction( void )
|
||||||
{
|
* {
|
||||||
MessageBufferHandle_t xMessageBuffer;
|
* MessageBufferHandle_t xMessageBuffer;
|
||||||
const size_t xMessageBufferSizeBytes = 100;
|
* const size_t xMessageBufferSizeBytes = 100;
|
||||||
|
*
|
||||||
// Create a message buffer that can hold 100 bytes. The memory used to hold
|
* // Create a message buffer that can hold 100 bytes. The memory used to hold
|
||||||
// both the message buffer structure and the messages themselves is allocated
|
* // both the message buffer structure and the messages themselves is allocated
|
||||||
// dynamically. Each message added to the buffer consumes an additional 4
|
* // dynamically. Each message added to the buffer consumes an additional 4
|
||||||
// bytes which are used to hold the lengh of the message.
|
* // bytes which are used to hold the lengh of the message.
|
||||||
xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
|
* xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
|
||||||
|
*
|
||||||
if( xMessageBuffer == NULL )
|
* if( xMessageBuffer == NULL )
|
||||||
{
|
* {
|
||||||
// There was not enough heap memory space available to create the
|
* // There was not enough heap memory space available to create the
|
||||||
// message buffer.
|
* // message buffer.
|
||||||
}
|
* }
|
||||||
else
|
* else
|
||||||
{
|
* {
|
||||||
// The message buffer was created successfully and can now be used.
|
* // The message buffer was created successfully and can now be used.
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xMessageBufferCreate xMessageBufferCreate
|
* \defgroup xMessageBufferCreate xMessageBufferCreate
|
||||||
* \ingroup MessageBufferManagement
|
* \ingroup MessageBufferManagement
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferCreate( xBufferSizeBytes ) ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE )
|
#define xMessageBufferCreate( xBufferSizeBytes ) ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
|
* MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
|
||||||
uint8_t *pucMessageBufferStorageArea,
|
* uint8_t *pucMessageBufferStorageArea,
|
||||||
StaticMessageBuffer_t *pxStaticMessageBuffer );
|
* StaticMessageBuffer_t *pxStaticMessageBuffer );
|
||||||
</pre>
|
* </pre>
|
||||||
* Creates a new message buffer using statically allocated memory. See
|
* Creates a new message buffer using statically allocated memory. See
|
||||||
* xMessageBufferCreate() for a version that uses dynamically allocated memory.
|
* xMessageBufferCreate() for a version that uses dynamically allocated memory.
|
||||||
*
|
*
|
||||||
|
|
@ -172,49 +172,49 @@ MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
|
||||||
* pxStaticmessageBuffer are NULL then NULL is returned.
|
* pxStaticmessageBuffer are NULL then NULL is returned.
|
||||||
*
|
*
|
||||||
* Example use:
|
* Example use:
|
||||||
<pre>
|
* <pre>
|
||||||
|
*
|
||||||
// Used to dimension the array used to hold the messages. The available space
|
* // Used to dimension the array used to hold the messages. The available space
|
||||||
// will actually be one less than this, so 999.
|
* // will actually be one less than this, so 999.
|
||||||
#define STORAGE_SIZE_BYTES 1000
|
#define STORAGE_SIZE_BYTES 1000
|
||||||
|
*
|
||||||
// Defines the memory that will actually hold the messages within the message
|
* // Defines the memory that will actually hold the messages within the message
|
||||||
// buffer.
|
* // buffer.
|
||||||
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
|
* static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
|
||||||
|
*
|
||||||
// The variable used to hold the message buffer structure.
|
* // The variable used to hold the message buffer structure.
|
||||||
StaticMessageBuffer_t xMessageBufferStruct;
|
* StaticMessageBuffer_t xMessageBufferStruct;
|
||||||
|
*
|
||||||
void MyFunction( void )
|
* void MyFunction( void )
|
||||||
{
|
* {
|
||||||
MessageBufferHandle_t xMessageBuffer;
|
* MessageBufferHandle_t xMessageBuffer;
|
||||||
|
*
|
||||||
xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ),
|
* xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ),
|
||||||
ucBufferStorage,
|
* ucBufferStorage,
|
||||||
&xMessageBufferStruct );
|
* &xMessageBufferStruct );
|
||||||
|
*
|
||||||
// As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
|
* // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
|
||||||
// parameters were NULL, xMessageBuffer will not be NULL, and can be used to
|
* // parameters were NULL, xMessageBuffer will not be NULL, and can be used to
|
||||||
// reference the created message buffer in other message buffer API calls.
|
* // reference the created message buffer in other message buffer API calls.
|
||||||
|
*
|
||||||
// Other code that uses the message buffer can go here.
|
* // Other code that uses the message buffer can go here.
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic
|
* \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic
|
||||||
* \ingroup MessageBufferManagement
|
* \ingroup MessageBufferManagement
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer )
|
#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
|
* size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
|
||||||
const void *pvTxData,
|
* const void *pvTxData,
|
||||||
size_t xDataLengthBytes,
|
* size_t xDataLengthBytes,
|
||||||
TickType_t xTicksToWait );
|
* TickType_t xTicksToWait );
|
||||||
<pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
* Sends a discrete message to the message buffer. The message can be any
|
* Sends a discrete message to the message buffer. The message can be any
|
||||||
* length that fits within the buffer's free space, and is copied into the
|
* length that fits within the buffer's free space, and is copied into the
|
||||||
|
|
@ -271,49 +271,49 @@ size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
|
||||||
* time out then xDataLengthBytes is returned.
|
* time out then xDataLengthBytes is returned.
|
||||||
*
|
*
|
||||||
* Example use:
|
* Example use:
|
||||||
<pre>
|
* <pre>
|
||||||
void vAFunction( MessageBufferHandle_t xMessageBuffer )
|
* void vAFunction( MessageBufferHandle_t xMessageBuffer )
|
||||||
{
|
* {
|
||||||
size_t xBytesSent;
|
* size_t xBytesSent;
|
||||||
uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
|
* uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
|
||||||
char *pcStringToSend = "String to send";
|
* char *pcStringToSend = "String to send";
|
||||||
const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
* const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
||||||
|
*
|
||||||
// Send an array to the message buffer, blocking for a maximum of 100ms to
|
* // Send an array to the message buffer, blocking for a maximum of 100ms to
|
||||||
// wait for enough space to be available in the message buffer.
|
* // wait for enough space to be available in the message buffer.
|
||||||
xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
|
* xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
|
||||||
|
*
|
||||||
if( xBytesSent != sizeof( ucArrayToSend ) )
|
* if( xBytesSent != sizeof( ucArrayToSend ) )
|
||||||
{
|
* {
|
||||||
// The call to xMessageBufferSend() times out before there was enough
|
* // The call to xMessageBufferSend() times out before there was enough
|
||||||
// space in the buffer for the data to be written.
|
* // space in the buffer for the data to be written.
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// Send the string to the message buffer. Return immediately if there is
|
* // Send the string to the message buffer. Return immediately if there is
|
||||||
// not enough space in the buffer.
|
* // not enough space in the buffer.
|
||||||
xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
|
* xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
|
||||||
|
*
|
||||||
if( xBytesSent != strlen( pcStringToSend ) )
|
* if( xBytesSent != strlen( pcStringToSend ) )
|
||||||
{
|
* {
|
||||||
// The string could not be added to the message buffer because there was
|
* // The string could not be added to the message buffer because there was
|
||||||
// not enough free space in the buffer.
|
* // not enough free space in the buffer.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xMessageBufferSend xMessageBufferSend
|
* \defgroup xMessageBufferSend xMessageBufferSend
|
||||||
* \ingroup MessageBufferManagement
|
* \ingroup MessageBufferManagement
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait )
|
#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
|
* size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||||
const void *pvTxData,
|
* const void *pvTxData,
|
||||||
size_t xDataLengthBytes,
|
* size_t xDataLengthBytes,
|
||||||
BaseType_t *pxHigherPriorityTaskWoken );
|
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
<pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
* Interrupt safe version of the API function that sends a discrete message to
|
* Interrupt safe version of the API function that sends a discrete message to
|
||||||
* the message buffer. The message can be any length that fits within the
|
* the message buffer. The message can be any length that fits within the
|
||||||
|
|
@ -371,53 +371,53 @@ size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||||
* then 0 is returned, otherwise xDataLengthBytes is returned.
|
* then 0 is returned, otherwise xDataLengthBytes is returned.
|
||||||
*
|
*
|
||||||
* Example use:
|
* Example use:
|
||||||
<pre>
|
* <pre>
|
||||||
// A message buffer that has already been created.
|
* // A message buffer that has already been created.
|
||||||
MessageBufferHandle_t xMessageBuffer;
|
* MessageBufferHandle_t xMessageBuffer;
|
||||||
|
*
|
||||||
void vAnInterruptServiceRoutine( void )
|
* void vAnInterruptServiceRoutine( void )
|
||||||
{
|
* {
|
||||||
size_t xBytesSent;
|
* size_t xBytesSent;
|
||||||
char *pcStringToSend = "String to send";
|
* char *pcStringToSend = "String to send";
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
* BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||||
|
*
|
||||||
// Attempt to send the string to the message buffer.
|
* // Attempt to send the string to the message buffer.
|
||||||
xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
|
* xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
|
||||||
( void * ) pcStringToSend,
|
* ( void * ) pcStringToSend,
|
||||||
strlen( pcStringToSend ),
|
* strlen( pcStringToSend ),
|
||||||
&xHigherPriorityTaskWoken );
|
* &xHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
if( xBytesSent != strlen( pcStringToSend ) )
|
* if( xBytesSent != strlen( pcStringToSend ) )
|
||||||
{
|
* {
|
||||||
// The string could not be added to the message buffer because there was
|
* // The string could not be added to the message buffer because there was
|
||||||
// not enough free space in the buffer.
|
* // not enough free space in the buffer.
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
* // If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||||
// xMessageBufferSendFromISR() then a task that has a priority above the
|
* // xMessageBufferSendFromISR() then a task that has a priority above the
|
||||||
// priority of the currently executing task was unblocked and a context
|
* // priority of the currently executing task was unblocked and a context
|
||||||
// switch should be performed to ensure the ISR returns to the unblocked
|
* // switch should be performed to ensure the ISR returns to the unblocked
|
||||||
// task. In most FreeRTOS ports this is done by simply passing
|
* // task. In most FreeRTOS ports this is done by simply passing
|
||||||
// xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
|
* // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
|
||||||
// variables value, and perform the context switch if necessary. Check the
|
* // variables value, and perform the context switch if necessary. Check the
|
||||||
// documentation for the port in use for port specific instructions.
|
* // documentation for the port in use for port specific instructions.
|
||||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR
|
* \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR
|
||||||
* \ingroup MessageBufferManagement
|
* \ingroup MessageBufferManagement
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken )
|
#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
|
* size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
|
||||||
void *pvRxData,
|
* void *pvRxData,
|
||||||
size_t xBufferLengthBytes,
|
* size_t xBufferLengthBytes,
|
||||||
TickType_t xTicksToWait );
|
* TickType_t xTicksToWait );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Receives a discrete message from a message buffer. Messages can be of
|
* Receives a discrete message from a message buffer. Messages can be of
|
||||||
* variable length and are copied out of the buffer.
|
* variable length and are copied out of the buffer.
|
||||||
|
|
@ -470,43 +470,43 @@ size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
|
||||||
* zero is returned.
|
* zero is returned.
|
||||||
*
|
*
|
||||||
* Example use:
|
* Example use:
|
||||||
<pre>
|
* <pre>
|
||||||
void vAFunction( MessageBuffer_t xMessageBuffer )
|
* void vAFunction( MessageBuffer_t xMessageBuffer )
|
||||||
{
|
* {
|
||||||
uint8_t ucRxData[ 20 ];
|
* uint8_t ucRxData[ 20 ];
|
||||||
size_t xReceivedBytes;
|
* size_t xReceivedBytes;
|
||||||
const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
* const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
||||||
|
*
|
||||||
// Receive the next message from the message buffer. Wait in the Blocked
|
* // Receive the next message from the message buffer. Wait in the Blocked
|
||||||
// state (so not using any CPU processing time) for a maximum of 100ms for
|
* // state (so not using any CPU processing time) for a maximum of 100ms for
|
||||||
// a message to become available.
|
* // a message to become available.
|
||||||
xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
|
* xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
|
||||||
( void * ) ucRxData,
|
* ( void * ) ucRxData,
|
||||||
sizeof( ucRxData ),
|
* sizeof( ucRxData ),
|
||||||
xBlockTime );
|
* xBlockTime );
|
||||||
|
*
|
||||||
if( xReceivedBytes > 0 )
|
* if( xReceivedBytes > 0 )
|
||||||
{
|
* {
|
||||||
// A ucRxData contains a message that is xReceivedBytes long. Process
|
* // A ucRxData contains a message that is xReceivedBytes long. Process
|
||||||
// the message here....
|
* // the message here....
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xMessageBufferReceive xMessageBufferReceive
|
* \defgroup xMessageBufferReceive xMessageBufferReceive
|
||||||
* \ingroup MessageBufferManagement
|
* \ingroup MessageBufferManagement
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) xStreamBufferReceive( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait )
|
#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) xStreamBufferReceive( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait )
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
|
* size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||||
void *pvRxData,
|
* void *pvRxData,
|
||||||
size_t xBufferLengthBytes,
|
* size_t xBufferLengthBytes,
|
||||||
BaseType_t *pxHigherPriorityTaskWoken );
|
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* An interrupt safe version of the API function that receives a discrete
|
* An interrupt safe version of the API function that receives a discrete
|
||||||
* message from a message buffer. Messages can be of variable length and are
|
* message from a message buffer. Messages can be of variable length and are
|
||||||
|
|
@ -560,50 +560,50 @@ size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||||
* any.
|
* any.
|
||||||
*
|
*
|
||||||
* Example use:
|
* Example use:
|
||||||
<pre>
|
* <pre>
|
||||||
// A message buffer that has already been created.
|
* // A message buffer that has already been created.
|
||||||
MessageBuffer_t xMessageBuffer;
|
* MessageBuffer_t xMessageBuffer;
|
||||||
|
*
|
||||||
void vAnInterruptServiceRoutine( void )
|
* void vAnInterruptServiceRoutine( void )
|
||||||
{
|
* {
|
||||||
uint8_t ucRxData[ 20 ];
|
* uint8_t ucRxData[ 20 ];
|
||||||
size_t xReceivedBytes;
|
* size_t xReceivedBytes;
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
* BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||||
|
*
|
||||||
// Receive the next message from the message buffer.
|
* // Receive the next message from the message buffer.
|
||||||
xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
|
* xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
|
||||||
( void * ) ucRxData,
|
* ( void * ) ucRxData,
|
||||||
sizeof( ucRxData ),
|
* sizeof( ucRxData ),
|
||||||
&xHigherPriorityTaskWoken );
|
* &xHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
if( xReceivedBytes > 0 )
|
* if( xReceivedBytes > 0 )
|
||||||
{
|
* {
|
||||||
// A ucRxData contains a message that is xReceivedBytes long. Process
|
* // A ucRxData contains a message that is xReceivedBytes long. Process
|
||||||
// the message here....
|
* // the message here....
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
* // If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||||
// xMessageBufferReceiveFromISR() then a task that has a priority above the
|
* // xMessageBufferReceiveFromISR() then a task that has a priority above the
|
||||||
// priority of the currently executing task was unblocked and a context
|
* // priority of the currently executing task was unblocked and a context
|
||||||
// switch should be performed to ensure the ISR returns to the unblocked
|
* // switch should be performed to ensure the ISR returns to the unblocked
|
||||||
// task. In most FreeRTOS ports this is done by simply passing
|
* // task. In most FreeRTOS ports this is done by simply passing
|
||||||
// xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
|
* // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
|
||||||
// variables value, and perform the context switch if necessary. Check the
|
* // variables value, and perform the context switch if necessary. Check the
|
||||||
// documentation for the port in use for port specific instructions.
|
* // documentation for the port in use for port specific instructions.
|
||||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR
|
* \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR
|
||||||
* \ingroup MessageBufferManagement
|
* \ingroup MessageBufferManagement
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken )
|
#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
|
* void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Deletes a message buffer that was previously created using a call to
|
* Deletes a message buffer that was previously created using a call to
|
||||||
* xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message
|
* xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message
|
||||||
|
|
@ -616,13 +616,13 @@ void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
|
||||||
* @param xMessageBuffer The handle of the message buffer to be deleted.
|
* @param xMessageBuffer The handle of the message buffer to be deleted.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define vMessageBufferDelete( xMessageBuffer ) vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer )
|
#define vMessageBufferDelete( xMessageBuffer ) vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
<pre>
|
* <pre>
|
||||||
BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
|
* BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Tests to see if a message buffer is full. A message buffer is full if it
|
* Tests to see if a message buffer is full. A message buffer is full if it
|
||||||
* cannot accept any more messages, of any size, until space is made available
|
* cannot accept any more messages, of any size, until space is made available
|
||||||
|
|
@ -633,13 +633,13 @@ BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
|
||||||
* @return If the message buffer referenced by xMessageBuffer is full then
|
* @return If the message buffer referenced by xMessageBuffer is full then
|
||||||
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferIsFull( xMessageBuffer ) xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer )
|
#define xMessageBufferIsFull( xMessageBuffer ) xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
<pre>
|
* <pre>
|
||||||
BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
|
* BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Tests to see if a message buffer is empty (does not contain any messages).
|
* Tests to see if a message buffer is empty (does not contain any messages).
|
||||||
*
|
*
|
||||||
|
|
@ -649,13 +649,13 @@ BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
|
||||||
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferIsEmpty( xMessageBuffer ) xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer )
|
#define xMessageBufferIsEmpty( xMessageBuffer ) xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
<pre>
|
* <pre>
|
||||||
BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
|
* BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Resets a message buffer to its initial empty state, discarding any message it
|
* Resets a message buffer to its initial empty state, discarding any message it
|
||||||
* contained.
|
* contained.
|
||||||
|
|
@ -672,14 +672,14 @@ BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
|
||||||
* \defgroup xMessageBufferReset xMessageBufferReset
|
* \defgroup xMessageBufferReset xMessageBufferReset
|
||||||
* \ingroup MessageBufferManagement
|
* \ingroup MessageBufferManagement
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferReset( xMessageBuffer ) xStreamBufferReset( ( StreamBufferHandle_t ) xMessageBuffer )
|
#define xMessageBufferReset( xMessageBuffer ) xStreamBufferReset( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
<pre>
|
* <pre>
|
||||||
size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
|
* size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
|
||||||
</pre>
|
* </pre>
|
||||||
* Returns the number of bytes of free space in the message buffer.
|
* Returns the number of bytes of free space in the message buffer.
|
||||||
*
|
*
|
||||||
* @param xMessageBuffer The handle of the message buffer being queried.
|
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||||
|
|
@ -694,14 +694,14 @@ size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
|
||||||
* \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable
|
* \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable
|
||||||
* \ingroup MessageBufferManagement
|
* \ingroup MessageBufferManagement
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer )
|
#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||||
#define xMessageBufferSpacesAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) /* Corrects typo in original macro name. */
|
#define xMessageBufferSpacesAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) /* Corrects typo in original macro name. */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
<pre>
|
* <pre>
|
||||||
size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) );
|
* size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) );
|
||||||
</pre>
|
* </pre>
|
||||||
* Returns the length (in bytes) of the next message in a message buffer.
|
* Returns the length (in bytes) of the next message in a message buffer.
|
||||||
* Useful if xMessageBufferReceive() returned 0 because the size of the buffer
|
* Useful if xMessageBufferReceive() returned 0 because the size of the buffer
|
||||||
* passed into xMessageBufferReceive() was too small to hold the next message.
|
* passed into xMessageBufferReceive() was too small to hold the next message.
|
||||||
|
|
@ -714,14 +714,14 @@ size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
|
||||||
* \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes
|
* \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes
|
||||||
* \ingroup MessageBufferManagement
|
* \ingroup MessageBufferManagement
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION;
|
#define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
* BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* For advanced users only.
|
* For advanced users only.
|
||||||
*
|
*
|
||||||
|
|
@ -753,14 +753,14 @@ BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuff
|
||||||
* \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR
|
* \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken )
|
#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
* BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* For advanced users only.
|
* For advanced users only.
|
||||||
*
|
*
|
||||||
|
|
@ -793,10 +793,10 @@ BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamB
|
||||||
* \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR
|
* \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferReceiveCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken )
|
#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferReceiveCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken )
|
||||||
|
|
||||||
#if defined( __cplusplus )
|
#if defined( __cplusplus )
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */
|
#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */
|
||||||
|
|
|
||||||
|
|
@ -37,19 +37,38 @@
|
||||||
#define MPU_PROTOTYPES_H
|
#define MPU_PROTOTYPES_H
|
||||||
|
|
||||||
/* MPU versions of tasks.h API functions. */
|
/* MPU versions of tasks.h API functions. */
|
||||||
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode,
|
||||||
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL;
|
const char * const pcName,
|
||||||
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL;
|
const uint16_t usStackDepth,
|
||||||
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL;
|
void * const pvParameters,
|
||||||
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) FREERTOS_SYSTEM_CALL;
|
UBaseType_t uxPriority,
|
||||||
|
TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL;
|
||||||
|
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode,
|
||||||
|
const char * const pcName,
|
||||||
|
const uint32_t ulStackDepth,
|
||||||
|
void * const pvParameters,
|
||||||
|
UBaseType_t uxPriority,
|
||||||
|
StackType_t * const puxStackBuffer,
|
||||||
|
StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition,
|
||||||
|
TaskHandle_t * pxCreatedTask ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition,
|
||||||
|
TaskHandle_t * pxCreatedTask ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask,
|
||||||
|
const MemoryRegion_t * const pxRegions ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
|
||||||
|
const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTaskGetInfo( TaskHandle_t xTask,
|
||||||
void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL;
|
TaskStatus_t * pxTaskStatus,
|
||||||
|
BaseType_t xGetFreeStackSpace,
|
||||||
|
eTaskState eState ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vTaskPrioritySet( TaskHandle_t xTask,
|
||||||
|
UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
@ -58,90 +77,169 @@ BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL;
|
||||||
TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL;
|
TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL;
|
||||||
UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL;
|
UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL;
|
||||||
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL;
|
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL;
|
||||||
TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) FREERTOS_SYSTEM_CALL;
|
TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) FREERTOS_SYSTEM_CALL;
|
||||||
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask,
|
||||||
|
TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL;
|
||||||
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
|
||||||
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) FREERTOS_SYSTEM_CALL;
|
BaseType_t xIndex,
|
||||||
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) FREERTOS_SYSTEM_CALL;
|
void * pvValue ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
|
||||||
|
BaseType_t xIndex ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask,
|
||||||
|
void * pvParameter ) FREERTOS_SYSTEM_CALL;
|
||||||
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||||
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL;
|
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
|
||||||
|
const UBaseType_t uxArraySize,
|
||||||
|
uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL;
|
||||||
uint32_t MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL;
|
uint32_t MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTaskGetRunTimeStats( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify,
|
||||||
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
UBaseType_t uxIndexToNotify,
|
||||||
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
uint32_t ulValue,
|
||||||
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL;
|
eNotifyAction eAction,
|
||||||
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL;
|
uint32_t * pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn,
|
||||||
|
uint32_t ulBitsToClearOnEntry,
|
||||||
|
uint32_t ulBitsToClearOnExit,
|
||||||
|
uint32_t * pulNotificationValue,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn,
|
||||||
|
BaseType_t xClearCountOnExit,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask,
|
||||||
|
UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL;
|
||||||
|
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask,
|
||||||
|
UBaseType_t uxIndexToClear,
|
||||||
|
uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL;
|
||||||
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
|
||||||
|
TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
/* MPU versions of queue.h API functions. */
|
/* MPU versions of queue.h API functions. */
|
||||||
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue,
|
||||||
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
const void * const pvItemToQueue,
|
||||||
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
TickType_t xTicksToWait,
|
||||||
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue,
|
||||||
|
void * const pvBuffer,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue,
|
||||||
|
void * const pvBuffer,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
||||||
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL;
|
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType,
|
||||||
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL;
|
StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL;
|
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount,
|
||||||
|
const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL;
|
||||||
|
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount,
|
||||||
|
const UBaseType_t uxInitialCount,
|
||||||
|
StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL;
|
TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) FREERTOS_SYSTEM_CALL;
|
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue,
|
||||||
|
const char * pcName ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength,
|
||||||
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
const UBaseType_t uxItemSize,
|
||||||
|
const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
||||||
|
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength,
|
||||||
|
const UBaseType_t uxItemSize,
|
||||||
|
uint8_t * pucQueueStorage,
|
||||||
|
StaticQueue_t * pxStaticQueue,
|
||||||
|
const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
||||||
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL;
|
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||||
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
|
QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
|
||||||
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||||
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL;
|
QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL;
|
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
|
||||||
|
const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,
|
||||||
|
BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
|
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue,
|
||||||
|
UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL;
|
||||||
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
/* MPU versions of timers.h API functions. */
|
/* MPU versions of timers.h API functions. */
|
||||||
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL;
|
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName,
|
||||||
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) FREERTOS_SYSTEM_CALL;
|
const TickType_t xTimerPeriodInTicks,
|
||||||
|
const UBaseType_t uxAutoReload,
|
||||||
|
void * const pvTimerID,
|
||||||
|
TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL;
|
||||||
|
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName,
|
||||||
|
const TickType_t xTimerPeriodInTicks,
|
||||||
|
const UBaseType_t uxAutoReload,
|
||||||
|
void * const pvTimerID,
|
||||||
|
TimerCallbackFunction_t pxCallbackFunction,
|
||||||
|
StaticTimer_t * pxTimerBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTimerSetTimerID( TimerHandle_t xTimer,
|
||||||
|
void * pvNewID ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||||
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
||||||
|
void * pvParameter1,
|
||||||
|
uint32_t ulParameter2,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL;
|
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer,
|
||||||
|
const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL;
|
||||||
UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||||
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||||
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer,
|
||||||
|
const BaseType_t xCommandID,
|
||||||
|
const TickType_t xOptionalValue,
|
||||||
|
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||||
|
const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
/* MPU versions of event_group.h API functions. */
|
/* MPU versions of event_group.h API functions. */
|
||||||
EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL;
|
EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL;
|
||||||
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL;
|
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||||
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL;
|
const EventBits_t uxBitsToWaitFor,
|
||||||
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL;
|
const BaseType_t xClearOnExit,
|
||||||
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
const BaseType_t xWaitForAllBits,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL;
|
||||||
|
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL;
|
||||||
|
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL;
|
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL;
|
||||||
UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ) FREERTOS_SYSTEM_CALL;
|
UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
/* MPU versions of message/stream_buffer.h API functions. */
|
/* MPU versions of message/stream_buffer.h API functions. */
|
||||||
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||||
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
const void * pvTxData,
|
||||||
|
size_t xDataLengthBytes,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
|
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
void * pvRxData,
|
||||||
|
size_t xBufferLengthBytes,
|
||||||
|
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||||
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
@ -149,11 +247,17 @@ BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERT
|
||||||
BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL;
|
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
|
||||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL;
|
size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL;
|
||||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
||||||
|
size_t xTriggerLevelBytes,
|
||||||
|
BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||||
|
size_t xTriggerLevelBytes,
|
||||||
|
BaseType_t xIsMessageBuffer,
|
||||||
|
uint8_t * const pucStreamBufferStorageArea,
|
||||||
|
StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* MPU_PROTOTYPES_H */
|
#endif /* MPU_PROTOTYPES_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,15 +28,15 @@
|
||||||
#define MPU_WRAPPERS_H
|
#define MPU_WRAPPERS_H
|
||||||
|
|
||||||
/* This file redefines API functions to be called through a wrapper macro, but
|
/* This file redefines API functions to be called through a wrapper macro, but
|
||||||
only for ports that are using the MPU. */
|
* only for ports that are using the MPU. */
|
||||||
#ifdef portUSING_MPU_WRAPPERS
|
#ifdef portUSING_MPU_WRAPPERS
|
||||||
|
|
||||||
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
|
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
|
||||||
included from queue.c or task.c to prevent it from having an effect within
|
* included from queue.c or task.c to prevent it from having an effect within
|
||||||
those files. */
|
* those files. */
|
||||||
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map standard (non MPU) API functions to equivalents that start
|
* Map standard (non MPU) API functions to equivalents that start
|
||||||
* "MPU_". This will cause the application code to call the MPU_
|
* "MPU_". This will cause the application code to call the MPU_
|
||||||
* version, which wraps the non-MPU version with privilege promoting
|
* version, which wraps the non-MPU version with privilege promoting
|
||||||
|
|
@ -44,7 +44,7 @@ only for ports that are using the MPU. */
|
||||||
* privileges.
|
* privileges.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Map standard tasks.h API functions to the MPU equivalents. */
|
/* Map standard tasks.h API functions to the MPU equivalents. */
|
||||||
#define xTaskCreate MPU_xTaskCreate
|
#define xTaskCreate MPU_xTaskCreate
|
||||||
#define xTaskCreateStatic MPU_xTaskCreateStatic
|
#define xTaskCreateStatic MPU_xTaskCreateStatic
|
||||||
#define xTaskCreateRestricted MPU_xTaskCreateRestricted
|
#define xTaskCreateRestricted MPU_xTaskCreateRestricted
|
||||||
|
|
@ -89,7 +89,7 @@ only for ports that are using the MPU. */
|
||||||
#define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut
|
#define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut
|
||||||
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
||||||
|
|
||||||
/* Map standard queue.h API functions to the MPU equivalents. */
|
/* Map standard queue.h API functions to the MPU equivalents. */
|
||||||
#define xQueueGenericSend MPU_xQueueGenericSend
|
#define xQueueGenericSend MPU_xQueueGenericSend
|
||||||
#define xQueueReceive MPU_xQueueReceive
|
#define xQueueReceive MPU_xQueueReceive
|
||||||
#define xQueuePeek MPU_xQueuePeek
|
#define xQueuePeek MPU_xQueuePeek
|
||||||
|
|
@ -112,13 +112,13 @@ only for ports that are using the MPU. */
|
||||||
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
|
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
|
||||||
#define xQueueGenericReset MPU_xQueueGenericReset
|
#define xQueueGenericReset MPU_xQueueGenericReset
|
||||||
|
|
||||||
#if( configQUEUE_REGISTRY_SIZE > 0 )
|
#if ( configQUEUE_REGISTRY_SIZE > 0 )
|
||||||
#define vQueueAddToRegistry MPU_vQueueAddToRegistry
|
#define vQueueAddToRegistry MPU_vQueueAddToRegistry
|
||||||
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
|
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
|
||||||
#define pcQueueGetName MPU_pcQueueGetName
|
#define pcQueueGetName MPU_pcQueueGetName
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Map standard timer.h API functions to the MPU equivalents. */
|
/* Map standard timer.h API functions to the MPU equivalents. */
|
||||||
#define xTimerCreate MPU_xTimerCreate
|
#define xTimerCreate MPU_xTimerCreate
|
||||||
#define xTimerCreateStatic MPU_xTimerCreateStatic
|
#define xTimerCreateStatic MPU_xTimerCreateStatic
|
||||||
#define pvTimerGetTimerID MPU_pvTimerGetTimerID
|
#define pvTimerGetTimerID MPU_pvTimerGetTimerID
|
||||||
|
|
@ -133,7 +133,7 @@ only for ports that are using the MPU. */
|
||||||
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
|
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
|
||||||
#define xTimerGenericCommand MPU_xTimerGenericCommand
|
#define xTimerGenericCommand MPU_xTimerGenericCommand
|
||||||
|
|
||||||
/* Map standard event_group.h API functions to the MPU equivalents. */
|
/* Map standard event_group.h API functions to the MPU equivalents. */
|
||||||
#define xEventGroupCreate MPU_xEventGroupCreate
|
#define xEventGroupCreate MPU_xEventGroupCreate
|
||||||
#define xEventGroupCreateStatic MPU_xEventGroupCreateStatic
|
#define xEventGroupCreateStatic MPU_xEventGroupCreateStatic
|
||||||
#define xEventGroupWaitBits MPU_xEventGroupWaitBits
|
#define xEventGroupWaitBits MPU_xEventGroupWaitBits
|
||||||
|
|
@ -142,8 +142,8 @@ only for ports that are using the MPU. */
|
||||||
#define xEventGroupSync MPU_xEventGroupSync
|
#define xEventGroupSync MPU_xEventGroupSync
|
||||||
#define vEventGroupDelete MPU_vEventGroupDelete
|
#define vEventGroupDelete MPU_vEventGroupDelete
|
||||||
|
|
||||||
/* Map standard message/stream_buffer.h API functions to the MPU
|
/* Map standard message/stream_buffer.h API functions to the MPU
|
||||||
equivalents. */
|
* equivalents. */
|
||||||
#define xStreamBufferSend MPU_xStreamBufferSend
|
#define xStreamBufferSend MPU_xStreamBufferSend
|
||||||
#define xStreamBufferReceive MPU_xStreamBufferReceive
|
#define xStreamBufferReceive MPU_xStreamBufferReceive
|
||||||
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
|
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
|
||||||
|
|
@ -158,19 +158,19 @@ only for ports that are using the MPU. */
|
||||||
#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic
|
#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic
|
||||||
|
|
||||||
|
|
||||||
/* Remove the privileged function macro, but keep the PRIVILEGED_DATA
|
/* Remove the privileged function macro, but keep the PRIVILEGED_DATA
|
||||||
macro so applications can place data in privileged access sections
|
* macro so applications can place data in privileged access sections
|
||||||
(useful when using statically allocated objects). */
|
* (useful when using statically allocated objects). */
|
||||||
#define PRIVILEGED_FUNCTION
|
#define PRIVILEGED_FUNCTION
|
||||||
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
|
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
|
||||||
#define FREERTOS_SYSTEM_CALL
|
#define FREERTOS_SYSTEM_CALL
|
||||||
|
|
||||||
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||||
|
|
||||||
/* Ensure API functions go in the privileged execution section. */
|
/* Ensure API functions go in the privileged execution section. */
|
||||||
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
|
#define PRIVILEGED_FUNCTION __attribute__( ( section( "privileged_functions" ) ) )
|
||||||
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
|
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
|
||||||
#define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls")))
|
#define FREERTOS_SYSTEM_CALL __attribute__( ( section( "freertos_system_calls" ) ) )
|
||||||
|
|
||||||
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||||
|
|
||||||
|
|
@ -185,4 +185,3 @@ only for ports that are using the MPU. */
|
||||||
|
|
||||||
|
|
||||||
#endif /* MPU_WRAPPERS_H */
|
#endif /* MPU_WRAPPERS_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,77 +25,77 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Portable layer API. Each function must be defined for each port.
|
* Portable layer API. Each function must be defined for each port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef PORTABLE_H
|
#ifndef PORTABLE_H
|
||||||
#define PORTABLE_H
|
#define PORTABLE_H
|
||||||
|
|
||||||
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||||
pre-processor definition was used to ensure the pre-processor found the correct
|
* pre-processor definition was used to ensure the pre-processor found the correct
|
||||||
portmacro.h file for the port being used. That scheme was deprecated in favour
|
* portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||||
of setting the compiler's include path such that it found the correct
|
* of setting the compiler's include path such that it found the correct
|
||||||
portmacro.h file - removing the need for the constant and allowing the
|
* portmacro.h file - removing the need for the constant and allowing the
|
||||||
portmacro.h file to be located anywhere in relation to the port being used.
|
* portmacro.h file to be located anywhere in relation to the port being used.
|
||||||
Purely for reasons of backward compatibility the old method is still valid, but
|
* Purely for reasons of backward compatibility the old method is still valid, but
|
||||||
to make it clear that new projects should not use it, support for the port
|
* to make it clear that new projects should not use it, support for the port
|
||||||
specific constants has been moved into the deprecated_definitions.h header
|
* specific constants has been moved into the deprecated_definitions.h header
|
||||||
file. */
|
* file. */
|
||||||
#include "deprecated_definitions.h"
|
#include "deprecated_definitions.h"
|
||||||
|
|
||||||
/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
|
/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
|
||||||
did not result in a portmacro.h header file being included - and it should be
|
* did not result in a portmacro.h header file being included - and it should be
|
||||||
included here. In this case the path to the correct portmacro.h header file
|
* included here. In this case the path to the correct portmacro.h header file
|
||||||
must be set in the compiler's include path. */
|
* must be set in the compiler's include path. */
|
||||||
#ifndef portENTER_CRITICAL
|
#ifndef portENTER_CRITICAL
|
||||||
#include "portmacro.h"
|
#include "portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if portBYTE_ALIGNMENT == 32
|
#if portBYTE_ALIGNMENT == 32
|
||||||
#define portBYTE_ALIGNMENT_MASK ( 0x001f )
|
#define portBYTE_ALIGNMENT_MASK ( 0x001f )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if portBYTE_ALIGNMENT == 16
|
#if portBYTE_ALIGNMENT == 16
|
||||||
#define portBYTE_ALIGNMENT_MASK ( 0x000f )
|
#define portBYTE_ALIGNMENT_MASK ( 0x000f )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if portBYTE_ALIGNMENT == 8
|
#if portBYTE_ALIGNMENT == 8
|
||||||
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
|
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if portBYTE_ALIGNMENT == 4
|
#if portBYTE_ALIGNMENT == 4
|
||||||
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
|
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if portBYTE_ALIGNMENT == 2
|
#if portBYTE_ALIGNMENT == 2
|
||||||
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
|
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if portBYTE_ALIGNMENT == 1
|
#if portBYTE_ALIGNMENT == 1
|
||||||
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
|
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef portBYTE_ALIGNMENT_MASK
|
#ifndef portBYTE_ALIGNMENT_MASK
|
||||||
#error "Invalid portBYTE_ALIGNMENT definition"
|
#error "Invalid portBYTE_ALIGNMENT definition"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef portNUM_CONFIGURABLE_REGIONS
|
#ifndef portNUM_CONFIGURABLE_REGIONS
|
||||||
#define portNUM_CONFIGURABLE_REGIONS 1
|
#define portNUM_CONFIGURABLE_REGIONS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef portHAS_STACK_OVERFLOW_CHECKING
|
#ifndef portHAS_STACK_OVERFLOW_CHECKING
|
||||||
#define portHAS_STACK_OVERFLOW_CHECKING 0
|
#define portHAS_STACK_OVERFLOW_CHECKING 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef portARCH_NAME
|
#ifndef portARCH_NAME
|
||||||
#define portARCH_NAME NULL
|
#define portARCH_NAME NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mpu_wrappers.h"
|
#include "mpu_wrappers.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the stack of a new task so it is ready to be placed under the
|
* Setup the stack of a new task so it is ready to be placed under the
|
||||||
|
|
@ -103,31 +103,43 @@ extern "C" {
|
||||||
* the order that the port expects to find them.
|
* the order that the port expects to find them.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||||
#if( portHAS_STACK_OVERFLOW_CHECKING == 1 )
|
#if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
StackType_t * pxEndOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters,
|
||||||
|
BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||||
#else
|
#else
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters,
|
||||||
|
BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else /* if ( portUSING_MPU_WRAPPERS == 1 ) */
|
||||||
#if( portHAS_STACK_OVERFLOW_CHECKING == 1 )
|
#if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
StackType_t * pxEndOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters ) PRIVILEGED_FUNCTION;
|
||||||
#else
|
#else
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif /* if ( portUSING_MPU_WRAPPERS == 1 ) */
|
||||||
|
|
||||||
/* Used by heap_5.c to define the start address and size of each memory region
|
/* Used by heap_5.c to define the start address and size of each memory region
|
||||||
that together comprise the total FreeRTOS heap space. */
|
* that together comprise the total FreeRTOS heap space. */
|
||||||
typedef struct HeapRegion
|
typedef struct HeapRegion
|
||||||
{
|
{
|
||||||
uint8_t *pucStartAddress;
|
uint8_t * pucStartAddress;
|
||||||
size_t xSizeInBytes;
|
size_t xSizeInBytes;
|
||||||
} HeapRegion_t;
|
} HeapRegion_t;
|
||||||
|
|
||||||
/* Used to pass information about the heap out of vPortGetHeapStats(). */
|
/* Used to pass information about the heap out of vPortGetHeapStats(). */
|
||||||
typedef struct xHeapStats
|
typedef struct xHeapStats
|
||||||
{
|
{
|
||||||
size_t xAvailableHeapSpaceInBytes; /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */
|
size_t xAvailableHeapSpaceInBytes; /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */
|
||||||
size_t xSizeOfLargestFreeBlockInBytes; /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
|
size_t xSizeOfLargestFreeBlockInBytes; /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
|
||||||
size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
|
size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
|
||||||
|
|
@ -135,7 +147,7 @@ typedef struct xHeapStats
|
||||||
size_t xMinimumEverFreeBytesRemaining; /* The minimum amount of total free memory (sum of all free blocks) there has been in the heap since the system booted. */
|
size_t xMinimumEverFreeBytesRemaining; /* The minimum amount of total free memory (sum of all free blocks) there has been in the heap since the system booted. */
|
||||||
size_t xNumberOfSuccessfulAllocations; /* The number of calls to pvPortMalloc() that have returned a valid memory block. */
|
size_t xNumberOfSuccessfulAllocations; /* The number of calls to pvPortMalloc() that have returned a valid memory block. */
|
||||||
size_t xNumberOfSuccessfulFrees; /* The number of calls to vPortFree() that has successfully freed a block of memory. */
|
size_t xNumberOfSuccessfulFrees; /* The number of calls to vPortFree() that has successfully freed a block of memory. */
|
||||||
} HeapStats_t;
|
} HeapStats_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to define multiple heap regions for use by heap_5.c. This function
|
* Used to define multiple heap regions for use by heap_5.c. This function
|
||||||
|
|
@ -148,35 +160,35 @@ typedef struct xHeapStats
|
||||||
* terminated by a HeapRegions_t structure that has a size of 0. The region
|
* terminated by a HeapRegions_t structure that has a size of 0. The region
|
||||||
* with the lowest start address must appear first in the array.
|
* with the lowest start address must appear first in the array.
|
||||||
*/
|
*/
|
||||||
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION;
|
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns a HeapStats_t structure filled with information about the current
|
* Returns a HeapStats_t structure filled with information about the current
|
||||||
* heap state.
|
* heap state.
|
||||||
*/
|
*/
|
||||||
void vPortGetHeapStats( HeapStats_t *pxHeapStats );
|
void vPortGetHeapStats( HeapStats_t * pxHeapStats );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map to the memory management routines required for the port.
|
* Map to the memory management routines required for the port.
|
||||||
*/
|
*/
|
||||||
void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
|
void * pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
|
||||||
void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
|
void vPortFree( void * pv ) PRIVILEGED_FUNCTION;
|
||||||
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
|
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
|
||||||
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||||
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the hardware ready for the scheduler to take control. This generally
|
* Setup the hardware ready for the scheduler to take control. This generally
|
||||||
* sets up a tick interrupt and sets timers for the correct tick frequency.
|
* sets up a tick interrupt and sets timers for the correct tick frequency.
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
|
BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
|
* Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
|
||||||
* the hardware is left in its original condition after the scheduler stops
|
* the hardware is left in its original condition after the scheduler stops
|
||||||
* executing.
|
* executing.
|
||||||
*/
|
*/
|
||||||
void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The structures and methods of manipulating the MPU are contained within the
|
* The structures and methods of manipulating the MPU are contained within the
|
||||||
|
|
@ -185,14 +197,16 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
||||||
* Fills the xMPUSettings structure with the memory region information
|
* Fills the xMPUSettings structure with the memory region information
|
||||||
* contained in xRegions.
|
* contained in xRegions.
|
||||||
*/
|
*/
|
||||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||||
struct xMEMORY_REGION;
|
struct xMEMORY_REGION;
|
||||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION;
|
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||||
#endif
|
const struct xMEMORY_REGION * const xRegions,
|
||||||
|
StackType_t * pxBottomOfStack,
|
||||||
|
uint32_t ulStackDepth ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTABLE_H */
|
#endif /* PORTABLE_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,11 @@
|
||||||
* Defines the prototype to which task functions must conform. Defined in this
|
* Defines the prototype to which task functions must conform. Defined in this
|
||||||
* file to ensure the type is known before portable.h is included.
|
* file to ensure the type is known before portable.h is included.
|
||||||
*/
|
*/
|
||||||
typedef void (*TaskFunction_t)( void * );
|
typedef void (* TaskFunction_t)( void * );
|
||||||
|
|
||||||
/* Converts a time in milliseconds to a time in ticks. This macro can be
|
/* Converts a time in milliseconds to a time in ticks. This macro can be
|
||||||
overridden by a macro of the same name defined in FreeRTOSConfig.h in case the
|
* overridden by a macro of the same name defined in FreeRTOSConfig.h in case the
|
||||||
definition here is not suitable for your application. */
|
* definition here is not suitable for your application. */
|
||||||
#ifndef pdMS_TO_TICKS
|
#ifndef pdMS_TO_TICKS
|
||||||
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )
|
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -58,14 +58,14 @@ definition here is not suitable for your application. */
|
||||||
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0
|
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
#define pdINTEGRITY_CHECK_VALUE 0x5a5a
|
#define pdINTEGRITY_CHECK_VALUE 0x5a5a
|
||||||
#else
|
#else
|
||||||
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL
|
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
|
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
|
||||||
itself. */
|
* itself. */
|
||||||
#define pdFREERTOS_ERRNO_NONE 0 /* No errors */
|
#define pdFREERTOS_ERRNO_NONE 0 /* No errors */
|
||||||
#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
|
#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
|
||||||
#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */
|
#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */
|
||||||
|
|
@ -108,7 +108,7 @@ itself. */
|
||||||
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
|
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
|
||||||
|
|
||||||
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS
|
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS
|
||||||
itself. */
|
* itself. */
|
||||||
#define pdFREERTOS_LITTLE_ENDIAN 0
|
#define pdFREERTOS_LITTLE_ENDIAN 0
|
||||||
#define pdFREERTOS_BIG_ENDIAN 1
|
#define pdFREERTOS_BIG_ENDIAN 1
|
||||||
|
|
||||||
|
|
@ -118,6 +118,3 @@ itself. */
|
||||||
|
|
||||||
|
|
||||||
#endif /* PROJDEFS_H */
|
#endif /* PROJDEFS_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
1571
include/queue.h
1571
include/queue.h
File diff suppressed because it is too large
Load diff
812
include/semphr.h
812
include/semphr.h
|
|
@ -70,26 +70,26 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t.
|
* @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
SemaphoreHandle_t xSemaphore = NULL;
|
* SemaphoreHandle_t xSemaphore = NULL;
|
||||||
|
*
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
|
* // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
|
||||||
// This is a macro so pass the variable in directly.
|
* // This is a macro so pass the variable in directly.
|
||||||
vSemaphoreCreateBinary( xSemaphore );
|
* vSemaphoreCreateBinary( xSemaphore );
|
||||||
|
*
|
||||||
if( xSemaphore != NULL )
|
* if( xSemaphore != NULL )
|
||||||
{
|
* {
|
||||||
// The semaphore was created successfully.
|
* // The semaphore was created successfully.
|
||||||
// The semaphore can now be used.
|
* // The semaphore can now be used.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
|
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
#define vSemaphoreCreateBinary( xSemaphore ) \
|
#define vSemaphoreCreateBinary( xSemaphore ) \
|
||||||
{ \
|
{ \
|
||||||
( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
|
( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
|
||||||
|
|
@ -138,26 +138,26 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* hold the semaphore's data structures could not be allocated.
|
* hold the semaphore's data structures could not be allocated.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
SemaphoreHandle_t xSemaphore = NULL;
|
* SemaphoreHandle_t xSemaphore = NULL;
|
||||||
|
*
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// Semaphore cannot be used before a call to xSemaphoreCreateBinary().
|
* // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
|
||||||
// This is a macro so pass the variable in directly.
|
* // This is a macro so pass the variable in directly.
|
||||||
xSemaphore = xSemaphoreCreateBinary();
|
* xSemaphore = xSemaphoreCreateBinary();
|
||||||
|
*
|
||||||
if( xSemaphore != NULL )
|
* if( xSemaphore != NULL )
|
||||||
{
|
* {
|
||||||
// The semaphore was created successfully.
|
* // The semaphore was created successfully.
|
||||||
// The semaphore can now be used.
|
* // The semaphore can now be used.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary
|
* \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
|
#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -196,27 +196,27 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* returned. If pxSemaphoreBuffer is NULL then NULL is returned.
|
* returned. If pxSemaphoreBuffer is NULL then NULL is returned.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
SemaphoreHandle_t xSemaphore = NULL;
|
* SemaphoreHandle_t xSemaphore = NULL;
|
||||||
StaticSemaphore_t xSemaphoreBuffer;
|
* StaticSemaphore_t xSemaphoreBuffer;
|
||||||
|
*
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// Semaphore cannot be used before a call to xSemaphoreCreateBinary().
|
* // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
|
||||||
// The semaphore's data structures will be placed in the xSemaphoreBuffer
|
* // The semaphore's data structures will be placed in the xSemaphoreBuffer
|
||||||
// variable, the address of which is passed into the function. The
|
* // variable, the address of which is passed into the function. The
|
||||||
// function's parameter is not NULL, so the function will not attempt any
|
* // function's parameter is not NULL, so the function will not attempt any
|
||||||
// dynamic memory allocation, and therefore the function will not return
|
* // dynamic memory allocation, and therefore the function will not return
|
||||||
// return NULL.
|
* // return NULL.
|
||||||
xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
|
* xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
|
||||||
|
*
|
||||||
// Rest of task code goes here.
|
* // Rest of task code goes here.
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic
|
* \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
#define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE )
|
#define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE )
|
||||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
|
@ -244,44 +244,44 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* if xBlockTime expired without the semaphore becoming available.
|
* if xBlockTime expired without the semaphore becoming available.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
SemaphoreHandle_t xSemaphore = NULL;
|
* SemaphoreHandle_t xSemaphore = NULL;
|
||||||
|
*
|
||||||
// A task that creates a semaphore.
|
* // A task that creates a semaphore.
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// Create the semaphore to guard a shared resource.
|
* // Create the semaphore to guard a shared resource.
|
||||||
xSemaphore = xSemaphoreCreateBinary();
|
* xSemaphore = xSemaphoreCreateBinary();
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// A task that uses the semaphore.
|
* // A task that uses the semaphore.
|
||||||
void vAnotherTask( void * pvParameters )
|
* void vAnotherTask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// ... Do other things.
|
* // ... Do other things.
|
||||||
|
*
|
||||||
if( xSemaphore != NULL )
|
* if( xSemaphore != NULL )
|
||||||
{
|
* {
|
||||||
// See if we can obtain the semaphore. If the semaphore is not available
|
* // See if we can obtain the semaphore. If the semaphore is not available
|
||||||
// wait 10 ticks to see if it becomes free.
|
* // wait 10 ticks to see if it becomes free.
|
||||||
if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
|
* if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
|
||||||
{
|
* {
|
||||||
// We were able to obtain the semaphore and can now access the
|
* // We were able to obtain the semaphore and can now access the
|
||||||
// shared resource.
|
* // shared resource.
|
||||||
|
*
|
||||||
// ...
|
* // ...
|
||||||
|
*
|
||||||
// We have finished accessing the shared resource. Release the
|
* // We have finished accessing the shared resource. Release the
|
||||||
// semaphore.
|
* // semaphore.
|
||||||
xSemaphoreGive( xSemaphore );
|
* xSemaphoreGive( xSemaphore );
|
||||||
}
|
* }
|
||||||
else
|
* else
|
||||||
{
|
* {
|
||||||
// We could not obtain the semaphore and can therefore not access
|
* // We could not obtain the semaphore and can therefore not access
|
||||||
// the shared resource safely.
|
* // the shared resource safely.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xSemaphoreTake xSemaphoreTake
|
* \defgroup xSemaphoreTake xSemaphoreTake
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
|
|
@ -323,62 +323,62 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* expired without the semaphore becoming available.
|
* expired without the semaphore becoming available.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
SemaphoreHandle_t xMutex = NULL;
|
* SemaphoreHandle_t xMutex = NULL;
|
||||||
|
*
|
||||||
// A task that creates a mutex.
|
* // A task that creates a mutex.
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// Create the mutex to guard a shared resource.
|
* // Create the mutex to guard a shared resource.
|
||||||
xMutex = xSemaphoreCreateRecursiveMutex();
|
* xMutex = xSemaphoreCreateRecursiveMutex();
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// A task that uses the mutex.
|
* // A task that uses the mutex.
|
||||||
void vAnotherTask( void * pvParameters )
|
* void vAnotherTask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// ... Do other things.
|
* // ... Do other things.
|
||||||
|
*
|
||||||
if( xMutex != NULL )
|
* if( xMutex != NULL )
|
||||||
{
|
* {
|
||||||
// See if we can obtain the mutex. If the mutex is not available
|
* // See if we can obtain the mutex. If the mutex is not available
|
||||||
// wait 10 ticks to see if it becomes free.
|
* // wait 10 ticks to see if it becomes free.
|
||||||
if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
|
* if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
|
||||||
{
|
* {
|
||||||
// We were able to obtain the mutex and can now access the
|
* // We were able to obtain the mutex and can now access the
|
||||||
// shared resource.
|
* // shared resource.
|
||||||
|
*
|
||||||
// ...
|
* // ...
|
||||||
// For some reason due to the nature of the code further calls to
|
* // For some reason due to the nature of the code further calls to
|
||||||
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
* // xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||||
// code these would not be just sequential calls as this would make
|
* // code these would not be just sequential calls as this would make
|
||||||
// no sense. Instead the calls are likely to be buried inside
|
* // no sense. Instead the calls are likely to be buried inside
|
||||||
// a more complex call structure.
|
* // a more complex call structure.
|
||||||
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
* xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||||
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
* xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||||
|
*
|
||||||
// The mutex has now been 'taken' three times, so will not be
|
* // The mutex has now been 'taken' three times, so will not be
|
||||||
// available to another task until it has also been given back
|
* // available to another task until it has also been given back
|
||||||
// three times. Again it is unlikely that real code would have
|
* // three times. Again it is unlikely that real code would have
|
||||||
// these calls sequentially, but instead buried in a more complex
|
* // these calls sequentially, but instead buried in a more complex
|
||||||
// call structure. This is just for illustrative purposes.
|
* // call structure. This is just for illustrative purposes.
|
||||||
xSemaphoreGiveRecursive( xMutex );
|
* xSemaphoreGiveRecursive( xMutex );
|
||||||
xSemaphoreGiveRecursive( xMutex );
|
* xSemaphoreGiveRecursive( xMutex );
|
||||||
xSemaphoreGiveRecursive( xMutex );
|
* xSemaphoreGiveRecursive( xMutex );
|
||||||
|
*
|
||||||
// Now the mutex can be taken by other tasks.
|
* // Now the mutex can be taken by other tasks.
|
||||||
}
|
* }
|
||||||
else
|
* else
|
||||||
{
|
* {
|
||||||
// We could not obtain the mutex and can therefore not access
|
* // We could not obtain the mutex and can therefore not access
|
||||||
// the shared resource safely.
|
* // the shared resource safely.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
|
* \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#if( configUSE_RECURSIVE_MUTEXES == 1 )
|
#if ( configUSE_RECURSIVE_MUTEXES == 1 )
|
||||||
#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
|
#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -405,41 +405,41 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* semaphore was not first obtained correctly.
|
* semaphore was not first obtained correctly.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
SemaphoreHandle_t xSemaphore = NULL;
|
* SemaphoreHandle_t xSemaphore = NULL;
|
||||||
|
*
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// Create the semaphore to guard a shared resource.
|
* // Create the semaphore to guard a shared resource.
|
||||||
xSemaphore = vSemaphoreCreateBinary();
|
* xSemaphore = vSemaphoreCreateBinary();
|
||||||
|
*
|
||||||
if( xSemaphore != NULL )
|
* if( xSemaphore != NULL )
|
||||||
{
|
* {
|
||||||
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
* if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
||||||
{
|
* {
|
||||||
// We would expect this call to fail because we cannot give
|
* // We would expect this call to fail because we cannot give
|
||||||
// a semaphore without first "taking" it!
|
* // a semaphore without first "taking" it!
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// Obtain the semaphore - don't block if the semaphore is not
|
* // Obtain the semaphore - don't block if the semaphore is not
|
||||||
// immediately available.
|
* // immediately available.
|
||||||
if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
|
* if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
|
||||||
{
|
* {
|
||||||
// We now have the semaphore and can access the shared resource.
|
* // We now have the semaphore and can access the shared resource.
|
||||||
|
*
|
||||||
// ...
|
* // ...
|
||||||
|
*
|
||||||
// We have finished accessing the shared resource so can free the
|
* // We have finished accessing the shared resource so can free the
|
||||||
// semaphore.
|
* // semaphore.
|
||||||
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
* if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
||||||
{
|
* {
|
||||||
// We would not expect this call to fail because we must have
|
* // We would not expect this call to fail because we must have
|
||||||
// obtained the semaphore to get here.
|
* // obtained the semaphore to get here.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xSemaphoreGive xSemaphoreGive
|
* \defgroup xSemaphoreGive xSemaphoreGive
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
|
|
@ -471,73 +471,73 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* @return pdTRUE if the semaphore was given.
|
* @return pdTRUE if the semaphore was given.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
SemaphoreHandle_t xMutex = NULL;
|
* SemaphoreHandle_t xMutex = NULL;
|
||||||
|
*
|
||||||
// A task that creates a mutex.
|
* // A task that creates a mutex.
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// Create the mutex to guard a shared resource.
|
* // Create the mutex to guard a shared resource.
|
||||||
xMutex = xSemaphoreCreateRecursiveMutex();
|
* xMutex = xSemaphoreCreateRecursiveMutex();
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// A task that uses the mutex.
|
* // A task that uses the mutex.
|
||||||
void vAnotherTask( void * pvParameters )
|
* void vAnotherTask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// ... Do other things.
|
* // ... Do other things.
|
||||||
|
*
|
||||||
if( xMutex != NULL )
|
* if( xMutex != NULL )
|
||||||
{
|
* {
|
||||||
// See if we can obtain the mutex. If the mutex is not available
|
* // See if we can obtain the mutex. If the mutex is not available
|
||||||
// wait 10 ticks to see if it becomes free.
|
* // wait 10 ticks to see if it becomes free.
|
||||||
if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
|
* if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
|
||||||
{
|
* {
|
||||||
// We were able to obtain the mutex and can now access the
|
* // We were able to obtain the mutex and can now access the
|
||||||
// shared resource.
|
* // shared resource.
|
||||||
|
*
|
||||||
// ...
|
* // ...
|
||||||
// For some reason due to the nature of the code further calls to
|
* // For some reason due to the nature of the code further calls to
|
||||||
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
* // xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||||
// code these would not be just sequential calls as this would make
|
* // code these would not be just sequential calls as this would make
|
||||||
// no sense. Instead the calls are likely to be buried inside
|
* // no sense. Instead the calls are likely to be buried inside
|
||||||
// a more complex call structure.
|
* // a more complex call structure.
|
||||||
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
* xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||||
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
* xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||||
|
*
|
||||||
// The mutex has now been 'taken' three times, so will not be
|
* // The mutex has now been 'taken' three times, so will not be
|
||||||
// available to another task until it has also been given back
|
* // available to another task until it has also been given back
|
||||||
// three times. Again it is unlikely that real code would have
|
* // three times. Again it is unlikely that real code would have
|
||||||
// these calls sequentially, it would be more likely that the calls
|
* // these calls sequentially, it would be more likely that the calls
|
||||||
// to xSemaphoreGiveRecursive() would be called as a call stack
|
* // to xSemaphoreGiveRecursive() would be called as a call stack
|
||||||
// unwound. This is just for demonstrative purposes.
|
* // unwound. This is just for demonstrative purposes.
|
||||||
xSemaphoreGiveRecursive( xMutex );
|
* xSemaphoreGiveRecursive( xMutex );
|
||||||
xSemaphoreGiveRecursive( xMutex );
|
* xSemaphoreGiveRecursive( xMutex );
|
||||||
xSemaphoreGiveRecursive( xMutex );
|
* xSemaphoreGiveRecursive( xMutex );
|
||||||
|
*
|
||||||
// Now the mutex can be taken by other tasks.
|
* // Now the mutex can be taken by other tasks.
|
||||||
}
|
* }
|
||||||
else
|
* else
|
||||||
{
|
* {
|
||||||
// We could not obtain the mutex and can therefore not access
|
* // We could not obtain the mutex and can therefore not access
|
||||||
// the shared resource safely.
|
* // the shared resource safely.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
|
* \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#if( configUSE_RECURSIVE_MUTEXES == 1 )
|
#if ( configUSE_RECURSIVE_MUTEXES == 1 )
|
||||||
#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )
|
#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* <pre>
|
* <pre>
|
||||||
xSemaphoreGiveFromISR(
|
* xSemaphoreGiveFromISR(
|
||||||
SemaphoreHandle_t xSemaphore,
|
* SemaphoreHandle_t xSemaphore,
|
||||||
BaseType_t *pxHigherPriorityTaskWoken
|
* BaseType_t *pxHigherPriorityTaskWoken
|
||||||
)</pre>
|
* )</pre>
|
||||||
*
|
*
|
||||||
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
|
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
|
||||||
* created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting().
|
* created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting().
|
||||||
|
|
@ -559,64 +559,64 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
|
* @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
\#define LONG_TIME 0xffff
|
\#define LONG_TIME 0xffff
|
||||||
\#define TICKS_TO_WAIT 10
|
\#define TICKS_TO_WAIT 10
|
||||||
SemaphoreHandle_t xSemaphore = NULL;
|
* SemaphoreHandle_t xSemaphore = NULL;
|
||||||
|
*
|
||||||
// Repetitive task.
|
* // Repetitive task.
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
for( ;; )
|
* for( ;; )
|
||||||
{
|
* {
|
||||||
// We want this task to run every 10 ticks of a timer. The semaphore
|
* // We want this task to run every 10 ticks of a timer. The semaphore
|
||||||
// was created before this task was started.
|
* // was created before this task was started.
|
||||||
|
*
|
||||||
// Block waiting for the semaphore to become available.
|
* // Block waiting for the semaphore to become available.
|
||||||
if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
|
* if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
|
||||||
{
|
* {
|
||||||
// It is time to execute.
|
* // It is time to execute.
|
||||||
|
*
|
||||||
// ...
|
* // ...
|
||||||
|
*
|
||||||
// We have finished our task. Return to the top of the loop where
|
* // We have finished our task. Return to the top of the loop where
|
||||||
// we will block on the semaphore until it is time to execute
|
* // we will block on the semaphore until it is time to execute
|
||||||
// again. Note when using the semaphore for synchronisation with an
|
* // again. Note when using the semaphore for synchronisation with an
|
||||||
// ISR in this manner there is no need to 'give' the semaphore back.
|
* // ISR in this manner there is no need to 'give' the semaphore back.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// Timer ISR
|
* // Timer ISR
|
||||||
void vTimerISR( void * pvParameters )
|
* void vTimerISR( void * pvParameters )
|
||||||
{
|
* {
|
||||||
static uint8_t ucLocalTickCount = 0;
|
* static uint8_t ucLocalTickCount = 0;
|
||||||
static BaseType_t xHigherPriorityTaskWoken;
|
* static BaseType_t xHigherPriorityTaskWoken;
|
||||||
|
*
|
||||||
// A timer tick has occurred.
|
* // A timer tick has occurred.
|
||||||
|
*
|
||||||
// ... Do other time functions.
|
* // ... Do other time functions.
|
||||||
|
*
|
||||||
// Is it time for vATask () to run?
|
* // Is it time for vATask () to run?
|
||||||
xHigherPriorityTaskWoken = pdFALSE;
|
* xHigherPriorityTaskWoken = pdFALSE;
|
||||||
ucLocalTickCount++;
|
* ucLocalTickCount++;
|
||||||
if( ucLocalTickCount >= TICKS_TO_WAIT )
|
* if( ucLocalTickCount >= TICKS_TO_WAIT )
|
||||||
{
|
* {
|
||||||
// Unblock the task by releasing the semaphore.
|
* // Unblock the task by releasing the semaphore.
|
||||||
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
|
* xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
// Reset the count so we release the semaphore again in 10 ticks time.
|
* // Reset the count so we release the semaphore again in 10 ticks time.
|
||||||
ucLocalTickCount = 0;
|
* ucLocalTickCount = 0;
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
if( xHigherPriorityTaskWoken != pdFALSE )
|
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
{
|
* {
|
||||||
// We can force a context switch here. Context switching from an
|
* // We can force a context switch here. Context switching from an
|
||||||
// ISR uses port specific syntax. Check the demo task for your port
|
* // ISR uses port specific syntax. Check the demo task for your port
|
||||||
// to find the syntax required.
|
* // to find the syntax required.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
|
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
|
|
@ -625,10 +625,10 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
/**
|
/**
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* <pre>
|
* <pre>
|
||||||
xSemaphoreTakeFromISR(
|
* xSemaphoreTakeFromISR(
|
||||||
SemaphoreHandle_t xSemaphore,
|
* SemaphoreHandle_t xSemaphore,
|
||||||
BaseType_t *pxHigherPriorityTaskWoken
|
* BaseType_t *pxHigherPriorityTaskWoken
|
||||||
)</pre>
|
* )</pre>
|
||||||
*
|
*
|
||||||
* <i>Macro</i> to take a semaphore from an ISR. The semaphore must have
|
* <i>Macro</i> to take a semaphore from an ISR. The semaphore must have
|
||||||
* previously been created with a call to xSemaphoreCreateBinary() or
|
* previously been created with a call to xSemaphoreCreateBinary() or
|
||||||
|
|
@ -692,26 +692,26 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* data structures then NULL is returned.
|
* data structures then NULL is returned.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
SemaphoreHandle_t xSemaphore;
|
* SemaphoreHandle_t xSemaphore;
|
||||||
|
*
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
|
* // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
|
||||||
// This is a macro so pass the variable in directly.
|
* // This is a macro so pass the variable in directly.
|
||||||
xSemaphore = xSemaphoreCreateMutex();
|
* xSemaphore = xSemaphoreCreateMutex();
|
||||||
|
*
|
||||||
if( xSemaphore != NULL )
|
* if( xSemaphore != NULL )
|
||||||
{
|
* {
|
||||||
// The semaphore was created successfully.
|
* // The semaphore was created successfully.
|
||||||
// The semaphore can now be used.
|
* // The semaphore can now be used.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex
|
* \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
|
#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -754,25 +754,25 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* mutex is returned. If pxMutexBuffer was NULL then NULL is returned.
|
* mutex is returned. If pxMutexBuffer was NULL then NULL is returned.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
SemaphoreHandle_t xSemaphore;
|
* SemaphoreHandle_t xSemaphore;
|
||||||
StaticSemaphore_t xMutexBuffer;
|
* StaticSemaphore_t xMutexBuffer;
|
||||||
|
*
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// A mutex cannot be used before it has been created. xMutexBuffer is
|
* // A mutex cannot be used before it has been created. xMutexBuffer is
|
||||||
// into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
|
* // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
|
||||||
// attempted.
|
* // attempted.
|
||||||
xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
|
* xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
|
||||||
|
*
|
||||||
// As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
|
* // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
|
||||||
// so there is no need to check it.
|
* // so there is no need to check it.
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic
|
* \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
#define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) )
|
#define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) )
|
||||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
|
@ -821,26 +821,26 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* SemaphoreHandle_t.
|
* SemaphoreHandle_t.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
SemaphoreHandle_t xSemaphore;
|
* SemaphoreHandle_t xSemaphore;
|
||||||
|
*
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
|
* // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
|
||||||
// This is a macro so pass the variable in directly.
|
* // This is a macro so pass the variable in directly.
|
||||||
xSemaphore = xSemaphoreCreateRecursiveMutex();
|
* xSemaphore = xSemaphoreCreateRecursiveMutex();
|
||||||
|
*
|
||||||
if( xSemaphore != NULL )
|
* if( xSemaphore != NULL )
|
||||||
{
|
* {
|
||||||
// The semaphore was created successfully.
|
* // The semaphore was created successfully.
|
||||||
// The semaphore can now be used.
|
* // The semaphore can now be used.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex
|
* \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
|
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
|
||||||
#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
|
#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -893,27 +893,27 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* returned.
|
* returned.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
SemaphoreHandle_t xSemaphore;
|
* SemaphoreHandle_t xSemaphore;
|
||||||
StaticSemaphore_t xMutexBuffer;
|
* StaticSemaphore_t xMutexBuffer;
|
||||||
|
*
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
// A recursive semaphore cannot be used before it is created. Here a
|
* // A recursive semaphore cannot be used before it is created. Here a
|
||||||
// recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
|
* // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
|
||||||
// The address of xMutexBuffer is passed into the function, and will hold
|
* // The address of xMutexBuffer is passed into the function, and will hold
|
||||||
// the mutexes data structures - so no dynamic memory allocation will be
|
* // the mutexes data structures - so no dynamic memory allocation will be
|
||||||
// attempted.
|
* // attempted.
|
||||||
xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
|
* xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
|
||||||
|
*
|
||||||
// As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
|
* // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
|
||||||
// so there is no need to check it.
|
* // so there is no need to check it.
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic
|
* \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
|
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
|
||||||
#define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore )
|
#define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore )
|
||||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
|
@ -971,29 +971,29 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* created.
|
* created.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
SemaphoreHandle_t xSemaphore;
|
* SemaphoreHandle_t xSemaphore;
|
||||||
|
*
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
SemaphoreHandle_t xSemaphore = NULL;
|
* SemaphoreHandle_t xSemaphore = NULL;
|
||||||
|
*
|
||||||
// Semaphore cannot be used before a call to xSemaphoreCreateCounting().
|
* // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
|
||||||
// The max value to which the semaphore can count should be 10, and the
|
* // The max value to which the semaphore can count should be 10, and the
|
||||||
// initial value assigned to the count should be 0.
|
* // initial value assigned to the count should be 0.
|
||||||
xSemaphore = xSemaphoreCreateCounting( 10, 0 );
|
* xSemaphore = xSemaphoreCreateCounting( 10, 0 );
|
||||||
|
*
|
||||||
if( xSemaphore != NULL )
|
* if( xSemaphore != NULL )
|
||||||
{
|
* {
|
||||||
// The semaphore was created successfully.
|
* // The semaphore was created successfully.
|
||||||
// The semaphore can now be used.
|
* // The semaphore can now be used.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
|
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
|
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -1055,30 +1055,30 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* then NULL is returned.
|
* then NULL is returned.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
* <pre>
|
||||||
SemaphoreHandle_t xSemaphore;
|
* SemaphoreHandle_t xSemaphore;
|
||||||
StaticSemaphore_t xSemaphoreBuffer;
|
* StaticSemaphore_t xSemaphoreBuffer;
|
||||||
|
*
|
||||||
void vATask( void * pvParameters )
|
* void vATask( void * pvParameters )
|
||||||
{
|
* {
|
||||||
SemaphoreHandle_t xSemaphore = NULL;
|
* SemaphoreHandle_t xSemaphore = NULL;
|
||||||
|
*
|
||||||
// Counting semaphore cannot be used before they have been created. Create
|
* // Counting semaphore cannot be used before they have been created. Create
|
||||||
// a counting semaphore using xSemaphoreCreateCountingStatic(). The max
|
* // a counting semaphore using xSemaphoreCreateCountingStatic(). The max
|
||||||
// value to which the semaphore can count is 10, and the initial value
|
* // value to which the semaphore can count is 10, and the initial value
|
||||||
// assigned to the count will be 0. The address of xSemaphoreBuffer is
|
* // assigned to the count will be 0. The address of xSemaphoreBuffer is
|
||||||
// passed in and will be used to hold the semaphore structure, so no dynamic
|
* // passed in and will be used to hold the semaphore structure, so no dynamic
|
||||||
// memory allocation will be used.
|
* // memory allocation will be used.
|
||||||
xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
|
* xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
|
||||||
|
*
|
||||||
// No memory allocation was attempted so xSemaphore cannot be NULL, so there
|
* // No memory allocation was attempted so xSemaphore cannot be NULL, so there
|
||||||
// is no need to check its value.
|
* // is no need to check its value.
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic
|
* \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
#define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) )
|
#define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) )
|
||||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
|
@ -1135,5 +1135,3 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
|
#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
|
||||||
|
|
||||||
#endif /* SEMAPHORE_H */
|
#endif /* SEMAPHORE_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,9 @@
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
|
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
/* Only the current stack state is to be checked. */
|
/* Only the current stack state is to be checked. */
|
||||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
|
|
@ -58,9 +58,9 @@
|
||||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
|
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
/* Only the current stack state is to be checked. */
|
/* Only the current stack state is to be checked. */
|
||||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
\
|
\
|
||||||
|
|
@ -74,7 +74,7 @@
|
||||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
|
|
@ -93,11 +93,11 @@
|
||||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
|
int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
|
||||||
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
|
@ -125,4 +125,3 @@
|
||||||
|
|
||||||
|
|
||||||
#endif /* STACK_MACROS_H */
|
#endif /* STACK_MACROS_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,15 +48,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef STREAM_BUFFER_H
|
#ifndef STREAM_BUFFER_H
|
||||||
#define STREAM_BUFFER_H
|
#define STREAM_BUFFER_H
|
||||||
|
|
||||||
#ifndef INC_FREERTOS_H
|
#ifndef INC_FREERTOS_H
|
||||||
#error "include FreeRTOS.h must appear in source files before include stream_buffer.h"
|
#error "include FreeRTOS.h must appear in source files before include stream_buffer.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined( __cplusplus )
|
#if defined( __cplusplus )
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type by which stream buffers are referenced. For example, a call to
|
* Type by which stream buffers are referenced. For example, a call to
|
||||||
|
|
@ -64,16 +64,16 @@ extern "C" {
|
||||||
* then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(),
|
* then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(),
|
||||||
* etc.
|
* etc.
|
||||||
*/
|
*/
|
||||||
struct StreamBufferDef_t;
|
struct StreamBufferDef_t;
|
||||||
typedef struct StreamBufferDef_t * StreamBufferHandle_t;
|
typedef struct StreamBufferDef_t * StreamBufferHandle_t;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
|
* StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Creates a new stream buffer using dynamically allocated memory. See
|
* Creates a new stream buffer using dynamically allocated memory. See
|
||||||
* xStreamBufferCreateStatic() for a version that uses statically allocated
|
* xStreamBufferCreateStatic() for a version that uses statically allocated
|
||||||
|
|
@ -107,43 +107,43 @@ StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTrigg
|
||||||
* buffer.
|
* buffer.
|
||||||
*
|
*
|
||||||
* Example use:
|
* Example use:
|
||||||
<pre>
|
* <pre>
|
||||||
|
*
|
||||||
void vAFunction( void )
|
* void vAFunction( void )
|
||||||
{
|
* {
|
||||||
StreamBufferHandle_t xStreamBuffer;
|
* StreamBufferHandle_t xStreamBuffer;
|
||||||
const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
|
* const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
|
||||||
|
*
|
||||||
// Create a stream buffer that can hold 100 bytes. The memory used to hold
|
* // Create a stream buffer that can hold 100 bytes. The memory used to hold
|
||||||
// both the stream buffer structure and the data in the stream buffer is
|
* // both the stream buffer structure and the data in the stream buffer is
|
||||||
// allocated dynamically.
|
* // allocated dynamically.
|
||||||
xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
|
* xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
|
||||||
|
*
|
||||||
if( xStreamBuffer == NULL )
|
* if( xStreamBuffer == NULL )
|
||||||
{
|
* {
|
||||||
// There was not enough heap memory space available to create the
|
* // There was not enough heap memory space available to create the
|
||||||
// stream buffer.
|
* // stream buffer.
|
||||||
}
|
* }
|
||||||
else
|
* else
|
||||||
{
|
* {
|
||||||
// The stream buffer was created successfully and can now be used.
|
* // The stream buffer was created successfully and can now be used.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xStreamBufferCreate xStreamBufferCreate
|
* \defgroup xStreamBufferCreate xStreamBufferCreate
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE )
|
#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
|
* StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
|
||||||
size_t xTriggerLevelBytes,
|
* size_t xTriggerLevelBytes,
|
||||||
uint8_t *pucStreamBufferStorageArea,
|
* uint8_t *pucStreamBufferStorageArea,
|
||||||
StaticStreamBuffer_t *pxStaticStreamBuffer );
|
* StaticStreamBuffer_t *pxStaticStreamBuffer );
|
||||||
</pre>
|
* </pre>
|
||||||
* Creates a new stream buffer using statically allocated memory. See
|
* Creates a new stream buffer using statically allocated memory. See
|
||||||
* xStreamBufferCreate() for a version that uses dynamically allocated memory.
|
* xStreamBufferCreate() for a version that uses dynamically allocated memory.
|
||||||
*
|
*
|
||||||
|
|
@ -180,51 +180,51 @@ StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
|
||||||
* pxStaticstreamBuffer are NULL then NULL is returned.
|
* pxStaticstreamBuffer are NULL then NULL is returned.
|
||||||
*
|
*
|
||||||
* Example use:
|
* Example use:
|
||||||
<pre>
|
* <pre>
|
||||||
|
*
|
||||||
// Used to dimension the array used to hold the streams. The available space
|
* // Used to dimension the array used to hold the streams. The available space
|
||||||
// will actually be one less than this, so 999.
|
* // will actually be one less than this, so 999.
|
||||||
#define STORAGE_SIZE_BYTES 1000
|
#define STORAGE_SIZE_BYTES 1000
|
||||||
|
*
|
||||||
// Defines the memory that will actually hold the streams within the stream
|
* // Defines the memory that will actually hold the streams within the stream
|
||||||
// buffer.
|
* // buffer.
|
||||||
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
|
* static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
|
||||||
|
*
|
||||||
// The variable used to hold the stream buffer structure.
|
* // The variable used to hold the stream buffer structure.
|
||||||
StaticStreamBuffer_t xStreamBufferStruct;
|
* StaticStreamBuffer_t xStreamBufferStruct;
|
||||||
|
*
|
||||||
void MyFunction( void )
|
* void MyFunction( void )
|
||||||
{
|
* {
|
||||||
StreamBufferHandle_t xStreamBuffer;
|
* StreamBufferHandle_t xStreamBuffer;
|
||||||
const size_t xTriggerLevel = 1;
|
* const size_t xTriggerLevel = 1;
|
||||||
|
*
|
||||||
xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ),
|
* xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ),
|
||||||
xTriggerLevel,
|
* xTriggerLevel,
|
||||||
ucBufferStorage,
|
* ucBufferStorage,
|
||||||
&xStreamBufferStruct );
|
* &xStreamBufferStruct );
|
||||||
|
*
|
||||||
// As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
|
* // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
|
||||||
// parameters were NULL, xStreamBuffer will not be NULL, and can be used to
|
* // parameters were NULL, xStreamBuffer will not be NULL, and can be used to
|
||||||
// reference the created stream buffer in other stream buffer API calls.
|
* // reference the created stream buffer in other stream buffer API calls.
|
||||||
|
*
|
||||||
// Other code that uses the stream buffer can go here.
|
* // Other code that uses the stream buffer can go here.
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic
|
* \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer )
|
#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
* size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||||
const void *pvTxData,
|
* const void *pvTxData,
|
||||||
size_t xDataLengthBytes,
|
* size_t xDataLengthBytes,
|
||||||
TickType_t xTicksToWait );
|
* TickType_t xTicksToWait );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Sends bytes to a stream buffer. The bytes are copied into the stream buffer.
|
* Sends bytes to a stream buffer. The bytes are copied into the stream buffer.
|
||||||
*
|
*
|
||||||
|
|
@ -274,54 +274,54 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||||
* write as many bytes as possible.
|
* write as many bytes as possible.
|
||||||
*
|
*
|
||||||
* Example use:
|
* Example use:
|
||||||
<pre>
|
* <pre>
|
||||||
void vAFunction( StreamBufferHandle_t xStreamBuffer )
|
* void vAFunction( StreamBufferHandle_t xStreamBuffer )
|
||||||
{
|
* {
|
||||||
size_t xBytesSent;
|
* size_t xBytesSent;
|
||||||
uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
|
* uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
|
||||||
char *pcStringToSend = "String to send";
|
* char *pcStringToSend = "String to send";
|
||||||
const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
* const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
||||||
|
*
|
||||||
// Send an array to the stream buffer, blocking for a maximum of 100ms to
|
* // Send an array to the stream buffer, blocking for a maximum of 100ms to
|
||||||
// wait for enough space to be available in the stream buffer.
|
* // wait for enough space to be available in the stream buffer.
|
||||||
xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
|
* xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
|
||||||
|
*
|
||||||
if( xBytesSent != sizeof( ucArrayToSend ) )
|
* if( xBytesSent != sizeof( ucArrayToSend ) )
|
||||||
{
|
* {
|
||||||
// The call to xStreamBufferSend() times out before there was enough
|
* // The call to xStreamBufferSend() times out before there was enough
|
||||||
// space in the buffer for the data to be written, but it did
|
* // space in the buffer for the data to be written, but it did
|
||||||
// successfully write xBytesSent bytes.
|
* // successfully write xBytesSent bytes.
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// Send the string to the stream buffer. Return immediately if there is not
|
* // Send the string to the stream buffer. Return immediately if there is not
|
||||||
// enough space in the buffer.
|
* // enough space in the buffer.
|
||||||
xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
|
* xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
|
||||||
|
*
|
||||||
if( xBytesSent != strlen( pcStringToSend ) )
|
* if( xBytesSent != strlen( pcStringToSend ) )
|
||||||
{
|
* {
|
||||||
// The entire string could not be added to the stream buffer because
|
* // The entire string could not be added to the stream buffer because
|
||||||
// there was not enough free space in the buffer, but xBytesSent bytes
|
* // there was not enough free space in the buffer, but xBytesSent bytes
|
||||||
// were sent. Could try again to send the remaining bytes.
|
* // were sent. Could try again to send the remaining bytes.
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xStreamBufferSend xStreamBufferSend
|
* \defgroup xStreamBufferSend xStreamBufferSend
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||||
const void *pvTxData,
|
const void * pvTxData,
|
||||||
size_t xDataLengthBytes,
|
size_t xDataLengthBytes,
|
||||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
* size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
const void *pvTxData,
|
* const void *pvTxData,
|
||||||
size_t xDataLengthBytes,
|
* size_t xDataLengthBytes,
|
||||||
BaseType_t *pxHigherPriorityTaskWoken );
|
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Interrupt safe version of the API function that sends a stream of bytes to
|
* Interrupt safe version of the API function that sends a stream of bytes to
|
||||||
* the stream buffer.
|
* the stream buffer.
|
||||||
|
|
@ -373,56 +373,56 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
* space for all the bytes to be written.
|
* space for all the bytes to be written.
|
||||||
*
|
*
|
||||||
* Example use:
|
* Example use:
|
||||||
<pre>
|
* <pre>
|
||||||
// A stream buffer that has already been created.
|
* // A stream buffer that has already been created.
|
||||||
StreamBufferHandle_t xStreamBuffer;
|
* StreamBufferHandle_t xStreamBuffer;
|
||||||
|
*
|
||||||
void vAnInterruptServiceRoutine( void )
|
* void vAnInterruptServiceRoutine( void )
|
||||||
{
|
* {
|
||||||
size_t xBytesSent;
|
* size_t xBytesSent;
|
||||||
char *pcStringToSend = "String to send";
|
* char *pcStringToSend = "String to send";
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
* BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||||
|
*
|
||||||
// Attempt to send the string to the stream buffer.
|
* // Attempt to send the string to the stream buffer.
|
||||||
xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
|
* xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
|
||||||
( void * ) pcStringToSend,
|
* ( void * ) pcStringToSend,
|
||||||
strlen( pcStringToSend ),
|
* strlen( pcStringToSend ),
|
||||||
&xHigherPriorityTaskWoken );
|
* &xHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
if( xBytesSent != strlen( pcStringToSend ) )
|
* if( xBytesSent != strlen( pcStringToSend ) )
|
||||||
{
|
* {
|
||||||
// There was not enough free space in the stream buffer for the entire
|
* // There was not enough free space in the stream buffer for the entire
|
||||||
// string to be written, ut xBytesSent bytes were written.
|
* // string to be written, ut xBytesSent bytes were written.
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
* // If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||||
// xStreamBufferSendFromISR() then a task that has a priority above the
|
* // xStreamBufferSendFromISR() then a task that has a priority above the
|
||||||
// priority of the currently executing task was unblocked and a context
|
* // priority of the currently executing task was unblocked and a context
|
||||||
// switch should be performed to ensure the ISR returns to the unblocked
|
* // switch should be performed to ensure the ISR returns to the unblocked
|
||||||
// task. In most FreeRTOS ports this is done by simply passing
|
* // task. In most FreeRTOS ports this is done by simply passing
|
||||||
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
* // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||||
// variables value, and perform the context switch if necessary. Check the
|
* // variables value, and perform the context switch if necessary. Check the
|
||||||
// documentation for the port in use for port specific instructions.
|
* // documentation for the port in use for port specific instructions.
|
||||||
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
* taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR
|
* \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
const void *pvTxData,
|
const void * pvTxData,
|
||||||
size_t xDataLengthBytes,
|
size_t xDataLengthBytes,
|
||||||
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
* size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||||
void *pvRxData,
|
* void *pvRxData,
|
||||||
size_t xBufferLengthBytes,
|
* size_t xBufferLengthBytes,
|
||||||
TickType_t xTicksToWait );
|
* TickType_t xTicksToWait );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Receives bytes from a stream buffer.
|
* Receives bytes from a stream buffer.
|
||||||
*
|
*
|
||||||
|
|
@ -472,46 +472,46 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||||
* out before xBufferLengthBytes were available.
|
* out before xBufferLengthBytes were available.
|
||||||
*
|
*
|
||||||
* Example use:
|
* Example use:
|
||||||
<pre>
|
* <pre>
|
||||||
void vAFunction( StreamBuffer_t xStreamBuffer )
|
* void vAFunction( StreamBuffer_t xStreamBuffer )
|
||||||
{
|
* {
|
||||||
uint8_t ucRxData[ 20 ];
|
* uint8_t ucRxData[ 20 ];
|
||||||
size_t xReceivedBytes;
|
* size_t xReceivedBytes;
|
||||||
const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
* const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
||||||
|
*
|
||||||
// Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
|
* // Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
|
||||||
// Wait in the Blocked state (so not using any CPU processing time) for a
|
* // Wait in the Blocked state (so not using any CPU processing time) for a
|
||||||
// maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
|
* // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
|
||||||
// available.
|
* // available.
|
||||||
xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
|
* xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
|
||||||
( void * ) ucRxData,
|
* ( void * ) ucRxData,
|
||||||
sizeof( ucRxData ),
|
* sizeof( ucRxData ),
|
||||||
xBlockTime );
|
* xBlockTime );
|
||||||
|
*
|
||||||
if( xReceivedBytes > 0 )
|
* if( xReceivedBytes > 0 )
|
||||||
{
|
* {
|
||||||
// A ucRxData contains another xRecievedBytes bytes of data, which can
|
* // A ucRxData contains another xRecievedBytes bytes of data, which can
|
||||||
// be processed here....
|
* // be processed here....
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xStreamBufferReceive xStreamBufferReceive
|
* \defgroup xStreamBufferReceive xStreamBufferReceive
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||||
void *pvRxData,
|
void * pvRxData,
|
||||||
size_t xBufferLengthBytes,
|
size_t xBufferLengthBytes,
|
||||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
* size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
void *pvRxData,
|
* void *pvRxData,
|
||||||
size_t xBufferLengthBytes,
|
* size_t xBufferLengthBytes,
|
||||||
BaseType_t *pxHigherPriorityTaskWoken );
|
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* An interrupt safe version of the API function that receives bytes from a
|
* An interrupt safe version of the API function that receives bytes from a
|
||||||
* stream buffer.
|
* stream buffer.
|
||||||
|
|
@ -548,53 +548,53 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
* @return The number of bytes read from the stream buffer, if any.
|
* @return The number of bytes read from the stream buffer, if any.
|
||||||
*
|
*
|
||||||
* Example use:
|
* Example use:
|
||||||
<pre>
|
* <pre>
|
||||||
// A stream buffer that has already been created.
|
* // A stream buffer that has already been created.
|
||||||
StreamBuffer_t xStreamBuffer;
|
* StreamBuffer_t xStreamBuffer;
|
||||||
|
*
|
||||||
void vAnInterruptServiceRoutine( void )
|
* void vAnInterruptServiceRoutine( void )
|
||||||
{
|
* {
|
||||||
uint8_t ucRxData[ 20 ];
|
* uint8_t ucRxData[ 20 ];
|
||||||
size_t xReceivedBytes;
|
* size_t xReceivedBytes;
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
* BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||||
|
*
|
||||||
// Receive the next stream from the stream buffer.
|
* // Receive the next stream from the stream buffer.
|
||||||
xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
|
* xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
|
||||||
( void * ) ucRxData,
|
* ( void * ) ucRxData,
|
||||||
sizeof( ucRxData ),
|
* sizeof( ucRxData ),
|
||||||
&xHigherPriorityTaskWoken );
|
* &xHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
if( xReceivedBytes > 0 )
|
* if( xReceivedBytes > 0 )
|
||||||
{
|
* {
|
||||||
// ucRxData contains xReceivedBytes read from the stream buffer.
|
* // ucRxData contains xReceivedBytes read from the stream buffer.
|
||||||
// Process the stream here....
|
* // Process the stream here....
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
* // If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||||
// xStreamBufferReceiveFromISR() then a task that has a priority above the
|
* // xStreamBufferReceiveFromISR() then a task that has a priority above the
|
||||||
// priority of the currently executing task was unblocked and a context
|
* // priority of the currently executing task was unblocked and a context
|
||||||
// switch should be performed to ensure the ISR returns to the unblocked
|
* // switch should be performed to ensure the ISR returns to the unblocked
|
||||||
// task. In most FreeRTOS ports this is done by simply passing
|
* // task. In most FreeRTOS ports this is done by simply passing
|
||||||
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
* // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||||
// variables value, and perform the context switch if necessary. Check the
|
* // variables value, and perform the context switch if necessary. Check the
|
||||||
// documentation for the port in use for port specific instructions.
|
* // documentation for the port in use for port specific instructions.
|
||||||
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
* taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
}
|
* }
|
||||||
</pre>
|
* </pre>
|
||||||
* \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR
|
* \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
void *pvRxData,
|
void * pvRxData,
|
||||||
size_t xBufferLengthBytes,
|
size_t xBufferLengthBytes,
|
||||||
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
|
* void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Deletes a stream buffer that was previously created using a call to
|
* Deletes a stream buffer that was previously created using a call to
|
||||||
* xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream
|
* xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream
|
||||||
|
|
@ -609,14 +609,14 @@ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
|
||||||
* \defgroup vStreamBufferDelete vStreamBufferDelete
|
* \defgroup vStreamBufferDelete vStreamBufferDelete
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
|
* BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Queries a stream buffer to see if it is full. A stream buffer is full if it
|
* Queries a stream buffer to see if it is full. A stream buffer is full if it
|
||||||
* does not have any free space, and therefore cannot accept any more data.
|
* does not have any free space, and therefore cannot accept any more data.
|
||||||
|
|
@ -629,14 +629,14 @@ BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
|
||||||
* \defgroup xStreamBufferIsFull xStreamBufferIsFull
|
* \defgroup xStreamBufferIsFull xStreamBufferIsFull
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
|
* BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Queries a stream buffer to see if it is empty. A stream buffer is empty if
|
* Queries a stream buffer to see if it is empty. A stream buffer is empty if
|
||||||
* it does not contain any data.
|
* it does not contain any data.
|
||||||
|
|
@ -649,14 +649,14 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
|
||||||
* \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty
|
* \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
|
* BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Resets a stream buffer to its initial, empty, state. Any data that was in
|
* Resets a stream buffer to its initial, empty, state. Any data that was in
|
||||||
* the stream buffer is discarded. A stream buffer can only be reset if there
|
* the stream buffer is discarded. A stream buffer can only be reset if there
|
||||||
|
|
@ -672,14 +672,14 @@ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
|
||||||
* \defgroup xStreamBufferReset xStreamBufferReset
|
* \defgroup xStreamBufferReset xStreamBufferReset
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
|
* size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Queries a stream buffer to see how much free space it contains, which is
|
* Queries a stream buffer to see how much free space it contains, which is
|
||||||
* equal to the amount of data that can be sent to the stream buffer before it
|
* equal to the amount of data that can be sent to the stream buffer before it
|
||||||
|
|
@ -693,14 +693,14 @@ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||||
* \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable
|
* \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
|
* size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Queries a stream buffer to see how much data it contains, which is equal to
|
* Queries a stream buffer to see how much data it contains, which is equal to
|
||||||
* the number of bytes that can be read from the stream buffer before the stream
|
* the number of bytes that can be read from the stream buffer before the stream
|
||||||
|
|
@ -714,14 +714,14 @@ size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||||
* \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable
|
* \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
|
* BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* A stream buffer's trigger level is the number of bytes that must be in the
|
* A stream buffer's trigger level is the number of bytes that must be in the
|
||||||
* stream buffer before a task that is blocked on the stream buffer to
|
* stream buffer before a task that is blocked on the stream buffer to
|
||||||
|
|
@ -751,14 +751,15 @@ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, siz
|
||||||
* \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel
|
* \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION;
|
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
size_t xTriggerLevel ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
* BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* For advanced users only.
|
* For advanced users only.
|
||||||
*
|
*
|
||||||
|
|
@ -790,14 +791,15 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer
|
||||||
* \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR
|
* \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stream_buffer.h
|
* stream_buffer.h
|
||||||
*
|
*
|
||||||
<pre>
|
* <pre>
|
||||||
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
* BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
</pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* For advanced users only.
|
* For advanced users only.
|
||||||
*
|
*
|
||||||
|
|
@ -830,29 +832,31 @@ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuf
|
||||||
* \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR
|
* \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR
|
||||||
* \ingroup StreamBufferManagement
|
* \ingroup StreamBufferManagement
|
||||||
*/
|
*/
|
||||||
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/* Functions below here are not part of the public API. */
|
/* Functions below here are not part of the public API. */
|
||||||
StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
||||||
size_t xTriggerLevelBytes,
|
size_t xTriggerLevelBytes,
|
||||||
BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION;
|
BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||||
size_t xTriggerLevelBytes,
|
size_t xTriggerLevelBytes,
|
||||||
BaseType_t xIsMessageBuffer,
|
BaseType_t xIsMessageBuffer,
|
||||||
uint8_t * const pucStreamBufferStorageArea,
|
uint8_t * const pucStreamBufferStorageArea,
|
||||||
StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
|
StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
#if( configUSE_TRACE_FACILITY == 1 )
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
|
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer,
|
||||||
|
UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
|
||||||
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined( __cplusplus )
|
#if defined( __cplusplus )
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* !defined( STREAM_BUFFER_H ) */
|
#endif /* !defined( STREAM_BUFFER_H ) */
|
||||||
|
|
|
||||||
1669
include/task.h
1669
include/task.h
File diff suppressed because it is too large
Load diff
191
include/timers.h
191
include/timers.h
|
|
@ -26,44 +26,44 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef TIMERS_H
|
#ifndef TIMERS_H
|
||||||
#define TIMERS_H
|
#define TIMERS_H
|
||||||
|
|
||||||
#ifndef INC_FREERTOS_H
|
#ifndef INC_FREERTOS_H
|
||||||
#error "include FreeRTOS.h must appear in source files before include timers.h"
|
#error "include FreeRTOS.h must appear in source files before include timers.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*lint -save -e537 This headers are only multiply included if the application code
|
/*lint -save -e537 This headers are only multiply included if the application code
|
||||||
happens to also be including task.h. */
|
* happens to also be including task.h. */
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
/*lint -restore */
|
/*lint -restore */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* MACROS AND DEFINITIONS
|
* MACROS AND DEFINITIONS
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* IDs for commands that can be sent/received on the timer queue. These are to
|
/* IDs for commands that can be sent/received on the timer queue. These are to
|
||||||
be used solely through the macros that make up the public software timer API,
|
* be used solely through the macros that make up the public software timer API,
|
||||||
as defined below. The commands that are sent from interrupts must use the
|
* as defined below. The commands that are sent from interrupts must use the
|
||||||
highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task
|
* highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task
|
||||||
or interrupt version of the queue send function should be used. */
|
* or interrupt version of the queue send function should be used. */
|
||||||
#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 )
|
#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 )
|
||||||
#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 )
|
#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 )
|
||||||
#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 )
|
#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 )
|
||||||
#define tmrCOMMAND_START ( ( BaseType_t ) 1 )
|
#define tmrCOMMAND_START ( ( BaseType_t ) 1 )
|
||||||
#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 )
|
#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 )
|
||||||
#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 )
|
#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 )
|
||||||
#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 )
|
#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 )
|
||||||
#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 )
|
#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 )
|
||||||
|
|
||||||
#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 )
|
#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 )
|
||||||
#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 )
|
#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 )
|
||||||
#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 )
|
#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 )
|
||||||
#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 )
|
#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 )
|
||||||
#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 )
|
#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 )
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -72,19 +72,20 @@ or interrupt version of the queue send function should be used. */
|
||||||
* reference the subject timer in calls to other software timer API functions
|
* reference the subject timer in calls to other software timer API functions
|
||||||
* (for example, xTimerStart(), xTimerReset(), etc.).
|
* (for example, xTimerStart(), xTimerReset(), etc.).
|
||||||
*/
|
*/
|
||||||
struct tmrTimerControl; /* The old naming convention is used to prevent breaking kernel aware debuggers. */
|
struct tmrTimerControl; /* The old naming convention is used to prevent breaking kernel aware debuggers. */
|
||||||
typedef struct tmrTimerControl * TimerHandle_t;
|
typedef struct tmrTimerControl * TimerHandle_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defines the prototype to which timer callback functions must conform.
|
* Defines the prototype to which timer callback functions must conform.
|
||||||
*/
|
*/
|
||||||
typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer );
|
typedef void (* TimerCallbackFunction_t)( TimerHandle_t xTimer );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defines the prototype to which functions used with the
|
* Defines the prototype to which functions used with the
|
||||||
* xTimerPendFunctionCallFromISR() function must conform.
|
* xTimerPendFunctionCallFromISR() function must conform.
|
||||||
*/
|
*/
|
||||||
typedef void (*PendedFunction_t)( void *, uint32_t );
|
typedef void (* PendedFunction_t)( void *,
|
||||||
|
uint32_t );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TimerHandle_t xTimerCreate( const char * const pcTimerName,
|
* TimerHandle_t xTimerCreate( const char * const pcTimerName,
|
||||||
|
|
@ -223,13 +224,13 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
const TickType_t xTimerPeriodInTicks,
|
const TickType_t xTimerPeriodInTicks,
|
||||||
const UBaseType_t uxAutoReload,
|
const UBaseType_t uxAutoReload,
|
||||||
void * const pvTimerID,
|
void * const pvTimerID,
|
||||||
TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION;
|
TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TimerHandle_t xTimerCreateStatic(const char * const pcTimerName,
|
* TimerHandle_t xTimerCreateStatic(const char * const pcTimerName,
|
||||||
|
|
@ -353,14 +354,14 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
const TickType_t xTimerPeriodInTicks,
|
const TickType_t xTimerPeriodInTicks,
|
||||||
const UBaseType_t uxAutoReload,
|
const UBaseType_t uxAutoReload,
|
||||||
void * const pvTimerID,
|
void * const pvTimerID,
|
||||||
TimerCallbackFunction_t pxCallbackFunction,
|
TimerCallbackFunction_t pxCallbackFunction,
|
||||||
StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION;
|
StaticTimer_t * pxTimerBuffer ) PRIVILEGED_FUNCTION;
|
||||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* void *pvTimerGetTimerID( TimerHandle_t xTimer );
|
* void *pvTimerGetTimerID( TimerHandle_t xTimer );
|
||||||
|
|
@ -382,7 +383,7 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
||||||
*
|
*
|
||||||
* See the xTimerCreate() API function example usage scenario.
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
*/
|
*/
|
||||||
void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
void * pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );
|
* void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );
|
||||||
|
|
@ -403,7 +404,8 @@ void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
*
|
*
|
||||||
* See the xTimerCreate() API function example usage scenario.
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
*/
|
*/
|
||||||
void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION;
|
void vTimerSetTimerID( TimerHandle_t xTimer,
|
||||||
|
void * pvNewID ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );
|
* BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );
|
||||||
|
|
@ -440,7 +442,7 @@ void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );
|
* TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );
|
||||||
|
|
@ -448,7 +450,7 @@ BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
* Simply returns the handle of the timer service/daemon task. It it not valid
|
* Simply returns the handle of the timer service/daemon task. It it not valid
|
||||||
* to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started.
|
* to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started.
|
||||||
*/
|
*/
|
||||||
TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
* BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
||||||
|
|
@ -500,7 +502,7 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* See the xTimerCreate() API function example usage scenario.
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
|
#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
* BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
||||||
|
|
@ -542,7 +544,7 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* See the xTimerCreate() API function example usage scenario.
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) )
|
#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
|
* BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
|
||||||
|
|
@ -660,7 +662,7 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
*
|
*
|
||||||
* See the xTimerChangePeriod() API function example usage scenario.
|
* See the xTimerChangePeriod() API function example usage scenario.
|
||||||
*/
|
*/
|
||||||
#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) )
|
#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
* BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
||||||
|
|
@ -784,7 +786,7 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
|
#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,
|
* BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,
|
||||||
|
|
@ -870,7 +872,7 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerStopFromISR( TimerHandle_t xTimer,
|
* BaseType_t xTimerStopFromISR( TimerHandle_t xTimer,
|
||||||
|
|
@ -933,7 +935,7 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U )
|
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer,
|
* BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer,
|
||||||
|
|
@ -1006,7 +1008,7 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )
|
#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerResetFromISR( TimerHandle_t xTimer,
|
* BaseType_t xTimerResetFromISR( TimerHandle_t xTimer,
|
||||||
|
|
@ -1092,7 +1094,7 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1183,9 +1185,12 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||||
* }
|
* }
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend,
|
||||||
|
void * pvParameter1,
|
||||||
|
uint32_t ulParameter2,
|
||||||
|
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
* BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
||||||
* void *pvParameter1,
|
* void *pvParameter1,
|
||||||
* uint32_t ulParameter2,
|
* uint32_t ulParameter2,
|
||||||
|
|
@ -1217,7 +1222,10 @@ BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void
|
||||||
* timer daemon task, otherwise pdFALSE is returned.
|
* timer daemon task, otherwise pdFALSE is returned.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
||||||
|
void * pvParameter1,
|
||||||
|
uint32_t ulParameter2,
|
||||||
|
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* const char * const pcTimerGetName( TimerHandle_t xTimer );
|
* const char * const pcTimerGetName( TimerHandle_t xTimer );
|
||||||
|
|
@ -1228,7 +1236,7 @@ BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvPar
|
||||||
*
|
*
|
||||||
* @return The name assigned to the timer specified by the xTimer parameter.
|
* @return The name assigned to the timer specified by the xTimer parameter.
|
||||||
*/
|
*/
|
||||||
const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload );
|
* void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload );
|
||||||
|
|
@ -1245,21 +1253,22 @@ const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint
|
||||||
* uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
|
* uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
|
||||||
* enter the dormant state after it expires.
|
* enter the dormant state after it expires.
|
||||||
*/
|
*/
|
||||||
void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION;
|
void vTimerSetReloadMode( TimerHandle_t xTimer,
|
||||||
|
const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer );
|
* UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer );
|
||||||
*
|
*
|
||||||
* Queries a timer to determine if it is an auto-reload timer, in which case the timer
|
* Queries a timer to determine if it is an auto-reload timer, in which case the timer
|
||||||
* automatically resets itself each time it expires, or a one-shot timer, in
|
* automatically resets itself each time it expires, or a one-shot timer, in
|
||||||
* which case the timer will only expire once unless it is manually restarted.
|
* which case the timer will only expire once unless it is manually restarted.
|
||||||
*
|
*
|
||||||
* @param xTimer The handle of the timer being queried.
|
* @param xTimer The handle of the timer being queried.
|
||||||
*
|
*
|
||||||
* @return If the timer is an auto-reload timer then pdTRUE is returned, otherwise
|
* @return If the timer is an auto-reload timer then pdTRUE is returned, otherwise
|
||||||
* pdFALSE is returned.
|
* pdFALSE is returned.
|
||||||
*/
|
*/
|
||||||
UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TickType_t xTimerGetPeriod( TimerHandle_t xTimer );
|
* TickType_t xTimerGetPeriod( TimerHandle_t xTimer );
|
||||||
|
|
@ -1270,39 +1279,41 @@ UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
*
|
*
|
||||||
* @return The period of the timer in ticks.
|
* @return The period of the timer in ticks.
|
||||||
*/
|
*/
|
||||||
TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer );
|
* TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer );
|
||||||
*
|
*
|
||||||
* Returns the time in ticks at which the timer will expire. If this is less
|
* Returns the time in ticks at which the timer will expire. If this is less
|
||||||
* than the current tick count then the expiry time has overflowed from the
|
* than the current tick count then the expiry time has overflowed from the
|
||||||
* current time.
|
* current time.
|
||||||
*
|
*
|
||||||
* @param xTimer The handle of the timer being queried.
|
* @param xTimer The handle of the timer being queried.
|
||||||
*
|
*
|
||||||
* @return If the timer is running then the time in ticks at which the timer
|
* @return If the timer is running then the time in ticks at which the timer
|
||||||
* will next expire is returned. If the timer is not running then the return
|
* will next expire is returned. If the timer is not running then the return
|
||||||
* value is undefined.
|
* value is undefined.
|
||||||
*/
|
*/
|
||||||
TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions beyond this part are not part of the public API and are intended
|
* Functions beyond this part are not part of the public API and are intended
|
||||||
* for use by the kernel only.
|
* for use by the kernel only.
|
||||||
*/
|
*/
|
||||||
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
|
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
|
||||||
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer,
|
||||||
|
const BaseType_t xCommandID,
|
||||||
|
const TickType_t xOptionalValue,
|
||||||
|
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||||
|
const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
#if( configUSE_TRACE_FACILITY == 1 )
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION;
|
void vTimerSetTimerNumber( TimerHandle_t xTimer,
|
||||||
|
UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION;
|
||||||
UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* TIMERS_H */
|
#endif /* TIMERS_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
103
list.c
103
list.c
|
|
@ -30,29 +30,29 @@
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* PUBLIC LIST API documented in list.h
|
* PUBLIC LIST API documented in list.h
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInitialise( List_t * const pxList )
|
void vListInitialise( List_t * const pxList )
|
||||||
{
|
{
|
||||||
/* The list structure contains a list item which is used to mark the
|
/* The list structure contains a list item which is used to mark the
|
||||||
end of the list. To initialise the list the list end is inserted
|
* end of the list. To initialise the list the list end is inserted
|
||||||
as the only list entry. */
|
* as the only list entry. */
|
||||||
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
|
|
||||||
/* The list end value is the highest possible value in the list to
|
/* The list end value is the highest possible value in the list to
|
||||||
ensure it remains at the end of the list. */
|
* ensure it remains at the end of the list. */
|
||||||
pxList->xListEnd.xItemValue = portMAX_DELAY;
|
pxList->xListEnd.xItemValue = portMAX_DELAY;
|
||||||
|
|
||||||
/* The list end next and previous pointers point to itself so we know
|
/* The list end next and previous pointers point to itself so we know
|
||||||
when the list is empty. */
|
* when the list is empty. */
|
||||||
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
|
|
||||||
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
|
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
|
||||||
|
|
||||||
/* Write known values into the list if
|
/* Write known values into the list if
|
||||||
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
|
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
|
||||||
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
|
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
|
||||||
}
|
}
|
||||||
|
|
@ -64,25 +64,26 @@ void vListInitialiseItem( ListItem_t * const pxItem )
|
||||||
pxItem->pxContainer = NULL;
|
pxItem->pxContainer = NULL;
|
||||||
|
|
||||||
/* Write known values into the list item if
|
/* Write known values into the list item if
|
||||||
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
||||||
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
|
void vListInsertEnd( List_t * const pxList,
|
||||||
|
ListItem_t * const pxNewListItem )
|
||||||
{
|
{
|
||||||
ListItem_t * const pxIndex = pxList->pxIndex;
|
ListItem_t * const pxIndex = pxList->pxIndex;
|
||||||
|
|
||||||
/* Only effective when configASSERT() is also defined, these tests may catch
|
/* Only effective when configASSERT() is also defined, these tests may catch
|
||||||
the list data structures being overwritten in memory. They will not catch
|
* the list data structures being overwritten in memory. They will not catch
|
||||||
data errors caused by incorrect configuration or use of FreeRTOS. */
|
* data errors caused by incorrect configuration or use of FreeRTOS. */
|
||||||
listTEST_LIST_INTEGRITY( pxList );
|
listTEST_LIST_INTEGRITY( pxList );
|
||||||
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
||||||
|
|
||||||
/* Insert a new list item into pxList, but rather than sort the list,
|
/* Insert a new list item into pxList, but rather than sort the list,
|
||||||
makes the new list item the last item to be removed by a call to
|
* makes the new list item the last item to be removed by a call to
|
||||||
listGET_OWNER_OF_NEXT_ENTRY(). */
|
* listGET_OWNER_OF_NEXT_ENTRY(). */
|
||||||
pxNewListItem->pxNext = pxIndex;
|
pxNewListItem->pxNext = pxIndex;
|
||||||
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
||||||
|
|
||||||
|
|
@ -99,25 +100,26 @@ ListItem_t * const pxIndex = pxList->pxIndex;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
|
void vListInsert( List_t * const pxList,
|
||||||
|
ListItem_t * const pxNewListItem )
|
||||||
{
|
{
|
||||||
ListItem_t *pxIterator;
|
ListItem_t * pxIterator;
|
||||||
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
|
|
||||||
/* Only effective when configASSERT() is also defined, these tests may catch
|
/* Only effective when configASSERT() is also defined, these tests may catch
|
||||||
the list data structures being overwritten in memory. They will not catch
|
* the list data structures being overwritten in memory. They will not catch
|
||||||
data errors caused by incorrect configuration or use of FreeRTOS. */
|
* data errors caused by incorrect configuration or use of FreeRTOS. */
|
||||||
listTEST_LIST_INTEGRITY( pxList );
|
listTEST_LIST_INTEGRITY( pxList );
|
||||||
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
||||||
|
|
||||||
/* Insert the new list item into the list, sorted in xItemValue order.
|
/* Insert the new list item into the list, sorted in xItemValue order.
|
||||||
|
*
|
||||||
If the list already contains a list item with the same item value then the
|
* If the list already contains a list item with the same item value then the
|
||||||
new list item should be placed after it. This ensures that TCBs which are
|
* new list item should be placed after it. This ensures that TCBs which are
|
||||||
stored in ready lists (all of which have the same xItemValue value) get a
|
* stored in ready lists (all of which have the same xItemValue value) get a
|
||||||
share of the CPU. However, if the xItemValue is the same as the back marker
|
* share of the CPU. However, if the xItemValue is the same as the back marker
|
||||||
the iteration loop below will not end. Therefore the value is checked
|
* the iteration loop below will not end. Therefore the value is checked
|
||||||
first, and the algorithm slightly modified if necessary. */
|
* first, and the algorithm slightly modified if necessary. */
|
||||||
if( xValueOfInsertion == portMAX_DELAY )
|
if( xValueOfInsertion == portMAX_DELAY )
|
||||||
{
|
{
|
||||||
pxIterator = pxList->xListEnd.pxPrevious;
|
pxIterator = pxList->xListEnd.pxPrevious;
|
||||||
|
|
@ -125,31 +127,31 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* *** NOTE ***********************************************************
|
/* *** NOTE ***********************************************************
|
||||||
If you find your application is crashing here then likely causes are
|
* If you find your application is crashing here then likely causes are
|
||||||
listed below. In addition see https://www.freertos.org/FAQHelp.html for
|
* listed below. In addition see https://www.freertos.org/FAQHelp.html for
|
||||||
more tips, and ensure configASSERT() is defined!
|
* more tips, and ensure configASSERT() is defined!
|
||||||
https://www.freertos.org/a00110.html#configASSERT
|
* https://www.freertos.org/a00110.html#configASSERT
|
||||||
|
*
|
||||||
1) Stack overflow -
|
* 1) Stack overflow -
|
||||||
see https://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
* see https://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
||||||
2) Incorrect interrupt priority assignment, especially on Cortex-M
|
* 2) Incorrect interrupt priority assignment, especially on Cortex-M
|
||||||
parts where numerically high priority values denote low actual
|
* parts where numerically high priority values denote low actual
|
||||||
interrupt priorities, which can seem counter intuitive. See
|
* interrupt priorities, which can seem counter intuitive. See
|
||||||
https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
|
* https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
|
||||||
of configMAX_SYSCALL_INTERRUPT_PRIORITY on
|
* of configMAX_SYSCALL_INTERRUPT_PRIORITY on
|
||||||
https://www.freertos.org/a00110.html
|
* https://www.freertos.org/a00110.html
|
||||||
3) Calling an API function from within a critical section or when
|
* 3) Calling an API function from within a critical section or when
|
||||||
the scheduler is suspended, or calling an API function that does
|
* the scheduler is suspended, or calling an API function that does
|
||||||
not end in "FromISR" from an interrupt.
|
* not end in "FromISR" from an interrupt.
|
||||||
4) Using a queue or semaphore before it has been initialised or
|
* 4) Using a queue or semaphore before it has been initialised or
|
||||||
before the scheduler has been started (are interrupts firing
|
* before the scheduler has been started (are interrupts firing
|
||||||
before vTaskStartScheduler() has been called?).
|
* before vTaskStartScheduler() has been called?).
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
|
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
|
||||||
{
|
{
|
||||||
/* There is nothing to do here, just iterating to the wanted
|
/* There is nothing to do here, just iterating to the wanted
|
||||||
insertion position. */
|
* insertion position. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,7 +161,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
pxIterator->pxNext = pxNewListItem;
|
pxIterator->pxNext = pxNewListItem;
|
||||||
|
|
||||||
/* Remember which list the item is in. This allows fast removal of the
|
/* Remember which list the item is in. This allows fast removal of the
|
||||||
item later. */
|
* item later. */
|
||||||
pxNewListItem->pxContainer = pxList;
|
pxNewListItem->pxContainer = pxList;
|
||||||
|
|
||||||
( pxList->uxNumberOfItems )++;
|
( pxList->uxNumberOfItems )++;
|
||||||
|
|
@ -169,8 +171,8 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
||||||
{
|
{
|
||||||
/* The list item knows which list it is in. Obtain the list from the list
|
/* The list item knows which list it is in. Obtain the list from the list
|
||||||
item. */
|
* item. */
|
||||||
List_t * const pxList = pxItemToRemove->pxContainer;
|
List_t * const pxList = pxItemToRemove->pxContainer;
|
||||||
|
|
||||||
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
||||||
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
||||||
|
|
@ -194,4 +196,3 @@ List_t * const pxList = pxItemToRemove->pxContainer;
|
||||||
return pxList->uxNumberOfItems;
|
return pxList->uxNumberOfItems;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
/* Portasm includes. */
|
/* Portasm includes. */
|
||||||
#include "portasm.h"
|
#include "portasm.h"
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/* Secure components includes. */
|
/* Secure components includes. */
|
||||||
#include "secure_context.h"
|
#include "secure_context.h"
|
||||||
#include "secure_init.h"
|
#include "secure_init.h"
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
* 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support:
|
* 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support:
|
||||||
* configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0
|
* configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0
|
||||||
*/
|
*/
|
||||||
#if( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) )
|
#if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) )
|
||||||
#error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side.
|
#error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -70,10 +70,10 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
|
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||||
#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) )
|
#define portNVIC_SYSPRI2_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||||
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||||
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
||||||
|
|
@ -85,7 +85,8 @@
|
||||||
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
#else
|
#else
|
||||||
/* The way the SysTick is clocked is not modified in case it is not the
|
|
||||||
|
/* The way the SysTick is clocked is not modified in case it is not the
|
||||||
* same a the core. */
|
* same a the core. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -94,7 +95,7 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( * ( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -117,24 +118,24 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the MPU.
|
* @brief Constants required to manipulate the MPU.
|
||||||
*/
|
*/
|
||||||
#define portMPU_TYPE_REG ( * ( ( volatile uint32_t * ) 0xe000ed90 ) )
|
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
|
||||||
#define portMPU_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed94 ) )
|
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
|
||||||
#define portMPU_RNR_REG ( * ( ( volatile uint32_t * ) 0xe000ed98 ) )
|
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_REG ( * ( ( volatile uint32_t * ) 0xe000ed9c ) )
|
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
|
||||||
#define portMPU_RLAR_REG ( * ( ( volatile uint32_t * ) 0xe000eda0 ) )
|
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_A1_REG ( * ( ( volatile uint32_t * ) 0xe000eda4 ) )
|
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
|
||||||
#define portMPU_RLAR_A1_REG ( * ( ( volatile uint32_t * ) 0xe000eda8 ) )
|
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_A2_REG ( * ( ( volatile uint32_t * ) 0xe000edac ) )
|
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
|
||||||
#define portMPU_RLAR_A2_REG ( * ( ( volatile uint32_t * ) 0xe000edb0 ) )
|
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_A3_REG ( * ( ( volatile uint32_t * ) 0xe000edb4 ) )
|
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
|
||||||
#define portMPU_RLAR_A3_REG ( * ( ( volatile uint32_t * ) 0xe000edb8 ) )
|
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
|
||||||
|
|
||||||
#define portMPU_MAIR0_REG ( * ( ( volatile uint32_t * ) 0xe000edc0 ) )
|
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
|
||||||
#define portMPU_MAIR1_REG ( * ( ( volatile uint32_t * ) 0xe000edc4 ) )
|
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
||||||
#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
||||||
|
|
@ -204,8 +205,9 @@
|
||||||
*/
|
*/
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
|
|
||||||
#if( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -221,7 +223,8 @@
|
||||||
*/
|
*/
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -284,15 +287,17 @@
|
||||||
*/
|
*/
|
||||||
static void prvTaskExitError( void );
|
static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -337,7 +342,7 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION;
|
||||||
/**
|
/**
|
||||||
* @brief C part of SVC handler.
|
* @brief C part of SVC handler.
|
||||||
*/
|
*/
|
||||||
portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVILEGED_FUNCTION;
|
portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -346,27 +351,29 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVI
|
||||||
*/
|
*/
|
||||||
static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT;
|
portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief The number of SysTick increments that make up one tick period.
|
* @brief The number of SysTick increments that make up one tick period.
|
||||||
*/
|
*/
|
||||||
static uint32_t ulTimerCountsForOneTick = 0;
|
static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -374,8 +381,8 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
__attribute__(( weak )) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
__attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
||||||
TickType_t xModifiableIdleTime;
|
TickType_t xModifiableIdleTime;
|
||||||
|
|
@ -396,6 +403,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
* tick periods. -1 is used because this code will execute part way
|
* tick periods. -1 is used because this code will execute part way
|
||||||
* through one of the tick periods. */
|
* through one of the tick periods. */
|
||||||
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
||||||
|
|
||||||
if( ulReloadValue > ulStoppedTimerCompensation )
|
if( ulReloadValue > ulStoppedTimerCompensation )
|
||||||
{
|
{
|
||||||
ulReloadValue -= ulStoppedTimerCompensation;
|
ulReloadValue -= ulStoppedTimerCompensation;
|
||||||
|
|
@ -403,9 +411,9 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||||
* method as that will mask interrupts that should exit sleep mode. */
|
* method as that will mask interrupts that should exit sleep mode. */
|
||||||
__asm volatile( "cpsid i" ::: "memory" );
|
__asm volatile ( "cpsid i" ::: "memory" );
|
||||||
__asm volatile( "dsb" );
|
__asm volatile ( "dsb" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
|
|
||||||
/* If a context switch is pending or a task is waiting for the scheduler
|
/* If a context switch is pending or a task is waiting for the scheduler
|
||||||
* to be un-suspended then abandon the low power entry. */
|
* to be un-suspended then abandon the low power entry. */
|
||||||
|
|
@ -424,7 +432,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
* above. */
|
* above. */
|
||||||
__asm volatile( "cpsie i" ::: "memory" );
|
__asm volatile ( "cpsie i" ::: "memory" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -446,28 +454,30 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
* so a copy is taken. */
|
* so a copy is taken. */
|
||||||
xModifiableIdleTime = xExpectedIdleTime;
|
xModifiableIdleTime = xExpectedIdleTime;
|
||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||||
|
|
||||||
if( xModifiableIdleTime > 0 )
|
if( xModifiableIdleTime > 0 )
|
||||||
{
|
{
|
||||||
__asm volatile( "dsb" ::: "memory" );
|
__asm volatile ( "dsb" ::: "memory" );
|
||||||
__asm volatile( "wfi" );
|
__asm volatile ( "wfi" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
}
|
}
|
||||||
|
|
||||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
|
||||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||||
* out of sleep mode to execute immediately. See comments above
|
* out of sleep mode to execute immediately. See comments above
|
||||||
* the cpsid instruction above. */
|
* the cpsid instruction above. */
|
||||||
__asm volatile( "cpsie i" ::: "memory" );
|
__asm volatile ( "cpsie i" ::: "memory" );
|
||||||
__asm volatile( "dsb" );
|
__asm volatile ( "dsb" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
|
|
||||||
/* Disable interrupts again because the clock is about to be stopped
|
/* Disable interrupts again because the clock is about to be stopped
|
||||||
* and interrupts that execute while the clock is stopped will
|
* and interrupts that execute while the clock is stopped will
|
||||||
* increase any slippage between the time maintained by the RTOS and
|
* increase any slippage between the time maintained by the RTOS and
|
||||||
* calendar time. */
|
* calendar time. */
|
||||||
__asm volatile( "cpsid i" ::: "memory" );
|
__asm volatile ( "cpsid i" ::: "memory" );
|
||||||
__asm volatile( "dsb" );
|
__asm volatile ( "dsb" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
|
|
||||||
/* Disable the SysTick clock without reading the
|
/* Disable the SysTick clock without reading the
|
||||||
* portNVIC_SYSTICK_CTRL_REG register to ensure the
|
* portNVIC_SYSTICK_CTRL_REG register to ensure the
|
||||||
|
|
@ -534,16 +544,16 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
|
|
||||||
/* Exit with interrupts enabled. */
|
/* Exit with interrupts enabled. */
|
||||||
__asm volatile( "cpsie i" ::: "memory" );
|
__asm volatile ( "cpsie i" ::: "memory" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
|
__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
/* Calculate the constants required to configure the tick interrupt. */
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
{
|
{
|
||||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||||
|
|
@ -563,7 +573,7 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNC
|
||||||
|
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulDummy = 0UL;
|
volatile uint32_t ulDummy = 0UL;
|
||||||
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* 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
|
* its caller as there is nothing to return to. If a task wants to exit it
|
||||||
|
|
@ -586,10 +596,11 @@ volatile uint32_t ulDummy = 0UL;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */
|
static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* Declaration when these variable are defined in code instead of being
|
||||||
* exported from linker scripts. */
|
* exported from linker scripts. */
|
||||||
extern uint32_t * __privileged_functions_start__;
|
extern uint32_t * __privileged_functions_start__;
|
||||||
|
|
@ -600,7 +611,7 @@ volatile uint32_t ulDummy = 0UL;
|
||||||
extern uint32_t * __unprivileged_flash_end__;
|
extern uint32_t * __unprivileged_flash_end__;
|
||||||
extern uint32_t * __privileged_sram_start__;
|
extern uint32_t * __privileged_sram_start__;
|
||||||
extern uint32_t * __privileged_sram_end__;
|
extern uint32_t * __privileged_sram_end__;
|
||||||
#else
|
#else /* if defined( __ARMCC_VERSION ) */
|
||||||
/* Declaration when these variable are exported from linker scripts. */
|
/* Declaration when these variable are exported from linker scripts. */
|
||||||
extern uint32_t __privileged_functions_start__[];
|
extern uint32_t __privileged_functions_start__[];
|
||||||
extern uint32_t __privileged_functions_end__[];
|
extern uint32_t __privileged_functions_end__[];
|
||||||
|
|
@ -671,10 +682,10 @@ volatile uint32_t ulDummy = 0UL;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */
|
static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
{
|
{
|
||||||
/* Enable non-secure access to the FPU. */
|
/* Enable non-secure access to the FPU. */
|
||||||
SecureInit_EnableNSFPUAccess();
|
SecureInit_EnableNSFPUAccess();
|
||||||
|
|
@ -703,8 +714,8 @@ void vPortYield( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is
|
/* Barriers are normally not required but do ensure the code is
|
||||||
* completely within the specified behaviour for the architecture. */
|
* completely within the specified behaviour for the architecture. */
|
||||||
__asm volatile( "dsb" ::: "memory" );
|
__asm volatile ( "dsb" ::: "memory" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -715,8 +726,8 @@ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is
|
/* Barriers are normally not required but do ensure the code is
|
||||||
* completely within the specified behaviour for the architecture. */
|
* completely within the specified behaviour for the architecture. */
|
||||||
__asm volatile( "dsb" ::: "memory" );
|
__asm volatile ( "dsb" ::: "memory" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -734,7 +745,7 @@ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
|
void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
uint32_t ulPreviousMask;
|
uint32_t ulPreviousMask;
|
||||||
|
|
||||||
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
|
|
@ -749,10 +760,11 @@ uint32_t ulPreviousMask;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */
|
void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */
|
||||||
{
|
{
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* Declaration when these variable are defined in code instead of being
|
||||||
* exported from linker scripts. */
|
* exported from linker scripts. */
|
||||||
extern uint32_t * __syscalls_flash_start__;
|
extern uint32_t * __syscalls_flash_start__;
|
||||||
|
|
@ -762,33 +774,33 @@ void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION
|
||||||
extern uint32_t __syscalls_flash_start__[];
|
extern uint32_t __syscalls_flash_start__[];
|
||||||
extern uint32_t __syscalls_flash_end__[];
|
extern uint32_t __syscalls_flash_end__[];
|
||||||
#endif /* defined( __ARMCC_VERSION ) */
|
#endif /* defined( __ARMCC_VERSION ) */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
uint32_t ulPC;
|
uint32_t ulPC;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
uint32_t ulR0;
|
uint32_t ulR0;
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
uint32_t ulControl, ulIsTaskPrivileged;
|
uint32_t ulControl, ulIsTaskPrivileged;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
uint8_t ucSVCNumber;
|
uint8_t ucSVCNumber;
|
||||||
|
|
||||||
/* Register are stored on the stack in the following order - R0, R1, R2, R3,
|
/* Register are stored on the stack in the following order - R0, R1, R2, R3,
|
||||||
* R12, LR, PC, xPSR. */
|
* R12, LR, PC, xPSR. */
|
||||||
ulPC = pulCallerStackAddress[ 6 ];
|
ulPC = pulCallerStackAddress[ 6 ];
|
||||||
ucSVCNumber = ( ( uint8_t *) ulPC )[ -2 ];
|
ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ];
|
||||||
|
|
||||||
switch( ucSVCNumber )
|
switch( ucSVCNumber )
|
||||||
{
|
{
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
case portSVC_ALLOCATE_SECURE_CONTEXT:
|
case portSVC_ALLOCATE_SECURE_CONTEXT:
|
||||||
{
|
|
||||||
/* R0 contains the stack size passed as parameter to the
|
/* R0 contains the stack size passed as parameter to the
|
||||||
* vPortAllocateSecureContext function. */
|
* vPortAllocateSecureContext function. */
|
||||||
ulR0 = pulCallerStackAddress[ 0 ];
|
ulR0 = pulCallerStackAddress[ 0 ];
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
/* Read the CONTROL register value. */
|
/* Read the CONTROL register value. */
|
||||||
__asm volatile ( "mrs %0, control" : "=r" ( ulControl ) );
|
__asm volatile ( "mrs %0, control" : "=r" ( ulControl ) );
|
||||||
|
|
@ -800,7 +812,7 @@ uint8_t ucSVCNumber;
|
||||||
/* Allocate and load a context for the secure task. */
|
/* Allocate and load a context for the secure task. */
|
||||||
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
|
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
|
||||||
}
|
}
|
||||||
#else
|
#else /* if ( configENABLE_MPU == 1 ) */
|
||||||
{
|
{
|
||||||
/* Allocate and load a context for the secure task. */
|
/* Allocate and load a context for the secure task. */
|
||||||
xSecureContext = SecureContext_AllocateContext( ulR0 );
|
xSecureContext = SecureContext_AllocateContext( ulR0 );
|
||||||
|
|
@ -809,23 +821,19 @@ uint8_t ucSVCNumber;
|
||||||
|
|
||||||
configASSERT( xSecureContext != NULL );
|
configASSERT( xSecureContext != NULL );
|
||||||
SecureContext_LoadContext( xSecureContext );
|
SecureContext_LoadContext( xSecureContext );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case portSVC_FREE_SECURE_CONTEXT:
|
case portSVC_FREE_SECURE_CONTEXT:
|
||||||
{
|
|
||||||
/* R0 contains the secure context handle to be freed. */
|
/* R0 contains the secure context handle to be freed. */
|
||||||
ulR0 = pulCallerStackAddress[ 0 ];
|
ulR0 = pulCallerStackAddress[ 0 ];
|
||||||
|
|
||||||
/* Free the secure context. */
|
/* Free the secure context. */
|
||||||
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 );
|
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
case portSVC_START_SCHEDULER:
|
case portSVC_START_SCHEDULER:
|
||||||
{
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
|
||||||
{
|
{
|
||||||
/* De-prioritize the non-secure exceptions so that the
|
/* De-prioritize the non-secure exceptions so that the
|
||||||
* non-secure pendSV runs at the lowest priority. */
|
* non-secure pendSV runs at the lowest priority. */
|
||||||
|
|
@ -836,7 +844,7 @@ uint8_t ucSVCNumber;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
{
|
{
|
||||||
/* Setup the Floating Point Unit (FPU). */
|
/* Setup the Floating Point Unit (FPU). */
|
||||||
prvSetupFPU();
|
prvSetupFPU();
|
||||||
|
|
@ -846,41 +854,44 @@ uint8_t ucSVCNumber;
|
||||||
/* Setup the context of the first task so that the first task starts
|
/* Setup the context of the first task so that the first task starts
|
||||||
* executing. */
|
* executing. */
|
||||||
vRestoreContextOfFirstTask();
|
vRestoreContextOfFirstTask();
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
case portSVC_RAISE_PRIVILEGE:
|
case portSVC_RAISE_PRIVILEGE:
|
||||||
{
|
|
||||||
/* Only raise the privilege, if the svc was raised from any of
|
/* Only raise the privilege, if the svc was raised from any of
|
||||||
* the system calls. */
|
* the system calls. */
|
||||||
if( ulPC >= ( uint32_t ) __syscalls_flash_start__ &&
|
if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) &&
|
||||||
ulPC <= ( uint32_t ) __syscalls_flash_end__ )
|
( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) )
|
||||||
{
|
{
|
||||||
vRaisePrivilege();
|
vRaisePrivilege();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
|
||||||
/* Incorrect SVC call. */
|
/* Incorrect SVC call. */
|
||||||
configASSERT( pdFALSE );
|
configASSERT( pdFALSE );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
StackType_t * pxEndOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters,
|
||||||
|
BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */
|
||||||
#else
|
#else
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) /* PRIVILEGED_FUNCTION */
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
StackType_t * pxEndOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters ) /* PRIVILEGED_FUNCTION */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
{
|
{
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
* interrupt. */
|
* interrupt. */
|
||||||
#if( portPRELOAD_REGISTERS == 0 )
|
#if ( portPRELOAD_REGISTERS == 0 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||||
|
|
@ -893,9 +904,10 @@ uint8_t ucSVCNumber;
|
||||||
pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */
|
pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */
|
||||||
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
if( xRunPrivileged == pdTRUE )
|
if( xRunPrivileged == pdTRUE )
|
||||||
{
|
{
|
||||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||||
|
|
@ -910,7 +922,7 @@ uint8_t ucSVCNumber;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
||||||
|
|
@ -954,9 +966,10 @@ uint8_t ucSVCNumber;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */
|
*pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
if( xRunPrivileged == pdTRUE )
|
if( xRunPrivileged == pdTRUE )
|
||||||
{
|
{
|
||||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||||
|
|
@ -971,7 +984,7 @@ uint8_t ucSVCNumber;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
||||||
|
|
@ -990,7 +1003,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
/* Setup the Memory Protection Unit (MPU). */
|
/* Setup the Memory Protection Unit (MPU). */
|
||||||
prvSetupMPU();
|
prvSetupMPU();
|
||||||
|
|
@ -1029,8 +1042,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )
|
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||||
|
const struct xMEMORY_REGION * const xRegions,
|
||||||
|
StackType_t * pxBottomOfStack,
|
||||||
|
uint32_t ulStackDepth )
|
||||||
{
|
{
|
||||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||||
int32_t lIndex = 0;
|
int32_t lIndex = 0;
|
||||||
|
|
@ -1126,13 +1142,13 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
BaseType_t xPortIsInsideInterrupt( void )
|
BaseType_t xPortIsInsideInterrupt( void )
|
||||||
{
|
{
|
||||||
uint32_t ulCurrentInterrupt;
|
uint32_t ulCurrentInterrupt;
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
/* Obtain the number of the currently executing interrupt. Interrupt Program
|
/* Obtain the number of the currently executing interrupt. Interrupt Program
|
||||||
* Status Register (IPSR) holds the exception number of the currently-executing
|
* Status Register (IPSR) holds the exception number of the currently-executing
|
||||||
* exception or zero for Thread mode.*/
|
* exception or zero for Thread mode.*/
|
||||||
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
|
||||||
|
|
||||||
if( ulCurrentInterrupt == 0 )
|
if( ulCurrentInterrupt == 0 )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
* header files. */
|
* header files. */
|
||||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -48,80 +48,80 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r3, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n"/* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r5, #1 \n" /* r5 = 1. */
|
" movs r5, #1 \n"/* r5 = 1. */
|
||||||
" bics r4, r5 \n" /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
|
" bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Disable MPU. */
|
" str r4, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
||||||
" ldr r4, [r3] \n" /* r4 = *r3 i.e. r4 = MAIR0. */
|
" ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r4, [r2] \n" /* Program MAIR0. */
|
" str r4, [r2] \n"/* Program MAIR0. */
|
||||||
" ldr r2, xRNRConst2 \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
" ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */
|
||||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||||
" movs r5, #4 \n" /* r5 = 4. */
|
" movs r5, #4 \n"/* r5 = 4. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 4. */
|
" str r5, [r2] \n"/* Program RNR = 4. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read first set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst2 \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write first set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */
|
||||||
" movs r5, #5 \n" /* r5 = 5. */
|
" movs r5, #5 \n"/* r5 = 5. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 5. */
|
" str r5, [r2] \n"/* Program RNR = 5. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read second set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst2 \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write second set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */
|
||||||
" movs r5, #6 \n" /* r5 = 6. */
|
" movs r5, #6 \n"/* r5 = 6. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 6. */
|
" str r5, [r2] \n"/* Program RNR = 6. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read third set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst2 \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write third set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */
|
||||||
" movs r5, #7 \n" /* r5 = 7. */
|
" movs r5, #7 \n"/* r5 = 7. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 7. */
|
" str r5, [r2] \n"/* Program RNR = 7. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read fourth set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst2 \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write fourth set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r5, #1 \n" /* r5 = 1. */
|
" movs r5, #1 \n"/* r5 = 1. */
|
||||||
" orrs r4, r5 \n" /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
|
" orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Enable MPU. */
|
" str r4, [r2] \n"/* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n"/* Force memory writes before continuing. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" ldm r0!, {r1-r4} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */
|
" ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */
|
||||||
" ldr r5, xSecureContextConst2 \n"
|
" ldr r5, xSecureContextConst2 \n"
|
||||||
" str r1, [r5] \n" /* Set xSecureContext to this task's value for the same. */
|
" str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */
|
||||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
" msr psplim, r2 \n"/* Set this task's PSPLIM value. */
|
||||||
" msr control, r3 \n" /* Set this task's CONTROL value. */
|
" msr control, r3 \n"/* Set this task's CONTROL value. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r4 \n" /* Finally, branch to EXC_RETURN. */
|
" bx r4 \n"/* Finally, branch to EXC_RETURN. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
" ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||||
" ldr r4, xSecureContextConst2 \n"
|
" ldr r4, xSecureContextConst2 \n"
|
||||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
" str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */
|
||||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
" msr psplim, r2 \n"/* Set this task's PSPLIM value. */
|
||||||
" movs r1, #2 \n" /* r1 = 2. */
|
" movs r1, #2 \n"/* r1 = 2. */
|
||||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
" msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
" bx r3 \n"/* Finally, branch to EXC_RETURN. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
"xSecureContextConst2: .word xSecureContext \n"
|
"xSecureContextConst2: .word xSecureContext \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||||
"xMAIR0Const2: .word 0xe000edc0 \n"
|
"xMAIR0Const2: .word 0xe000edc0 \n"
|
||||||
"xRNRConst2: .word 0xe000ed98 \n"
|
"xRNRConst2: .word 0xe000ed98 \n"
|
||||||
|
|
@ -135,15 +135,15 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||||
" movs r1, #1 \n" /* r1 = 1. */
|
" movs r1, #1 \n"/* r1 = 1. */
|
||||||
" tst r0, r1 \n" /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
" tst r0, r1 \n"/* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
||||||
" beq running_privileged \n" /* If the result of previous AND operation was 0, branch. */
|
" beq running_privileged \n"/* If the result of previous AND operation was 0, branch. */
|
||||||
" movs r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
" movs r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
" running_privileged: \n"
|
" running_privileged: \n"
|
||||||
" movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
" movs r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
|
|
@ -155,11 +155,11 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||||
" movs r1, #1 \n" /* r1 = 1. */
|
" movs r1, #1 \n"/* r1 = 1. */
|
||||||
" bics r0, r1 \n" /* Clear the bit 0. */
|
" bics r0, r1 \n"/* Clear the bit 0. */
|
||||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||||
" bx lr \n" /* Return to the caller. */
|
" bx lr \n"/* Return to the caller. */
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -169,12 +169,12 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||||
" movs r1, #1 \n" /* r1 = 1. */
|
" movs r1, #1 \n"/* r1 = 1. */
|
||||||
" orrs r0, r1 \n" /* r0 = r0 | r1. */
|
" orrs r0, r1 \n"/* r0 = r0 | r1. */
|
||||||
" msr control, r0 \n" /* CONTROL = r0. */
|
" msr control, r0 \n"/* CONTROL = r0. */
|
||||||
" bx lr \n" /* Return to the caller. */
|
" bx lr \n"/* Return to the caller. */
|
||||||
:::"r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -183,19 +183,19 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||||
" cpsie i \n" /* Globally enable interrupts. */
|
" cpsie i \n"/* Globally enable interrupts. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" svc %0 \n" /* System call to start the first task. */
|
" svc %0 \n"/* System call to start the first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"xVTORConst: .word 0xe000ed08 \n"
|
"xVTORConst: .word 0xe000ed08 \n"
|
||||||
:: "i" ( portSVC_START_SCHEDULER ) : "memory"
|
::"i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -231,64 +231,64 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
" .extern SecureContext_SaveContext \n"
|
" .extern SecureContext_SaveContext \n"
|
||||||
" .extern SecureContext_LoadContext \n"
|
" .extern SecureContext_LoadContext \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r1, psp \n" /* Read PSP in r1. */
|
" mrs r1, psp \n"/* Read PSP in r1. */
|
||||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" ldr r0, [r2] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
" ldr r0, [r2] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||||
" \n"
|
" \n"
|
||||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
" cbz r0, save_ns_context \n"/* No secure context to save. */
|
||||||
" push {r0-r2, r14} \n"
|
" push {r0-r2, r14} \n"
|
||||||
" bl SecureContext_SaveContext \n"
|
" bl SecureContext_SaveContext \n"
|
||||||
" pop {r0-r3} \n" /* LR is now in r3. */
|
" pop {r0-r3} \n"/* LR is now in r3. */
|
||||||
" mov lr, r3 \n" /* LR = r3. */
|
" mov lr, r3 \n"/* LR = r3. */
|
||||||
" lsls r2, r3, #25 \n" /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
" lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
" bpl save_ns_context \n" /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
" bpl save_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r2, [r3] \n" /* Read pxCurrentTCB. */
|
" ldr r2, [r3] \n"/* Read pxCurrentTCB. */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" subs r1, r1, #16 \n" /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
" subs r1, r1, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||||
" str r1, [r2] \n" /* Save the new top of stack in TCB. */
|
" str r1, [r2] \n"/* Save the new top of stack in TCB. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mrs r3, control \n" /* r3 = CONTROL. */
|
" mrs r3, control \n"/* r3 = CONTROL. */
|
||||||
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
|
" mov r4, lr \n"/* r4 = LR/EXC_RETURN. */
|
||||||
" stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
" stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" subs r1, r1, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
" subs r1, r1, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
||||||
" str r1, [r2] \n" /* Save the new top of stack in TCB. */
|
" str r1, [r2] \n"/* Save the new top of stack in TCB. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||||
" stmia r1!, {r0, r2-r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
" stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" b select_next_task \n"
|
" b select_next_task \n"
|
||||||
" \n"
|
" \n"
|
||||||
" save_ns_context: \n"
|
" save_ns_context: \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r2, [r3] \n" /* Read pxCurrentTCB. */
|
" ldr r2, [r3] \n"/* Read pxCurrentTCB. */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" subs r1, r1, #48 \n" /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
|
" subs r1, r1, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
|
||||||
" str r1, [r2] \n" /* Save the new top of stack in TCB. */
|
" str r1, [r2] \n"/* Save the new top of stack in TCB. */
|
||||||
" adds r1, r1, #16 \n" /* r1 = r1 + 16. */
|
" adds r1, r1, #16 \n"/* r1 = r1 + 16. */
|
||||||
" stmia r1!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */
|
" stmia r1!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */
|
||||||
" mov r4, r8 \n" /* r4 = r8. */
|
" mov r4, r8 \n"/* r4 = r8. */
|
||||||
" mov r5, r9 \n" /* r5 = r9. */
|
" mov r5, r9 \n"/* r5 = r9. */
|
||||||
" mov r6, r10 \n" /* r6 = r10. */
|
" mov r6, r10 \n"/* r6 = r10. */
|
||||||
" mov r7, r11 \n" /* r7 = r11. */
|
" mov r7, r11 \n"/* r7 = r11. */
|
||||||
" stmia r1!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
" stmia r1!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mrs r3, control \n" /* r3 = CONTROL. */
|
" mrs r3, control \n"/* r3 = CONTROL. */
|
||||||
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
|
" mov r4, lr \n"/* r4 = LR/EXC_RETURN. */
|
||||||
" subs r1, r1, #48 \n" /* r1 = r1 - 48. */
|
" subs r1, r1, #48 \n"/* r1 = r1 - 48. */
|
||||||
" stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
" stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" subs r1, r1, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
" subs r1, r1, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
||||||
" str r1, [r2] \n" /* Save the new top of stack in TCB. */
|
" str r1, [r2] \n"/* Save the new top of stack in TCB. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||||
" stmia r1!, {r0, r2-r7} \n" /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */
|
" stmia r1!, {r0, r2-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */
|
||||||
" mov r4, r8 \n" /* r4 = r8. */
|
" mov r4, r8 \n"/* r4 = r8. */
|
||||||
" mov r5, r9 \n" /* r5 = r9. */
|
" mov r5, r9 \n"/* r5 = r9. */
|
||||||
" mov r6, r10 \n" /* r6 = r10. */
|
" mov r6, r10 \n"/* r6 = r10. */
|
||||||
" mov r7, r11 \n" /* r7 = r11. */
|
" mov r7, r11 \n"/* r7 = r11. */
|
||||||
" stmia r1!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
" stmia r1!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" select_next_task: \n"
|
" select_next_task: \n"
|
||||||
|
|
@ -296,102 +296,102 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" cpsie i \n"
|
" cpsie i \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r3, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
" ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */
|
" ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n"/* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r5, #1 \n" /* r5 = 1. */
|
" movs r5, #1 \n"/* r5 = 1. */
|
||||||
" bics r4, r5 \n" /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
|
" bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Disable MPU. */
|
" str r4, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
||||||
" ldr r4, [r3] \n" /* r4 = *r3 i.e. r4 = MAIR0. */
|
" ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r4, [r2] \n" /* Program MAIR0. */
|
" str r4, [r2] \n"/* Program MAIR0. */
|
||||||
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
" ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */
|
||||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||||
" movs r5, #4 \n" /* r5 = 4. */
|
" movs r5, #4 \n"/* r5 = 4. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 4. */
|
" str r5, [r2] \n"/* Program RNR = 4. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read first set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write first set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */
|
||||||
" movs r5, #5 \n" /* r5 = 5. */
|
" movs r5, #5 \n"/* r5 = 5. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 5. */
|
" str r5, [r2] \n"/* Program RNR = 5. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read second set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write second set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */
|
||||||
" movs r5, #6 \n" /* r5 = 6. */
|
" movs r5, #6 \n"/* r5 = 6. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 6. */
|
" str r5, [r2] \n"/* Program RNR = 6. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read third set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write third set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */
|
||||||
" movs r5, #7 \n" /* r5 = 7. */
|
" movs r5, #7 \n"/* r5 = 7. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 7. */
|
" str r5, [r2] \n"/* Program RNR = 7. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read fourth set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write fourth set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r5, #1 \n" /* r5 = 1. */
|
" movs r5, #1 \n"/* r5 = 1. */
|
||||||
" orrs r4, r5 \n" /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
|
" orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Enable MPU. */
|
" str r4, [r2] \n"/* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n"/* Force memory writes before continuing. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" ldmia r1!, {r0, r2-r4} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */
|
" ldmia r1!, {r0, r2-r4} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */
|
||||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
||||||
" msr control, r3 \n" /* Restore the CONTROL register value for the task. */
|
" msr control, r3 \n"/* Restore the CONTROL register value for the task. */
|
||||||
" mov lr, r4 \n" /* LR = r4. */
|
" mov lr, r4 \n"/* LR = r4. */
|
||||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" str r0, [r2] \n" /* Restore the task's xSecureContext. */
|
" str r0, [r2] \n"/* Restore the task's xSecureContext. */
|
||||||
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
|
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
|
||||||
" push {r1,r4} \n"
|
" push {r1,r4} \n"
|
||||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. */
|
" bl SecureContext_LoadContext \n"/* Restore the secure context. */
|
||||||
" pop {r1,r4} \n"
|
" pop {r1,r4} \n"
|
||||||
" mov lr, r4 \n" /* LR = r4. */
|
" mov lr, r4 \n"/* LR = r4. */
|
||||||
" lsls r2, r4, #25 \n" /* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
" lsls r2, r4, #25 \n"/* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
" bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||||
" msr psp, r1 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r1 \n"/* Remember the new top of stack for the task. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" ldmia r1!, {r0, r2-r3} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */
|
" ldmia r1!, {r0, r2-r3} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */
|
||||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
||||||
" mov lr, r3 \n" /* LR = r3. */
|
" mov lr, r3 \n"/* LR = r3. */
|
||||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" str r0, [r2] \n" /* Restore the task's xSecureContext. */
|
" str r0, [r2] \n"/* Restore the task's xSecureContext. */
|
||||||
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
|
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
|
||||||
" push {r1,r3} \n"
|
" push {r1,r3} \n"
|
||||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. */
|
" bl SecureContext_LoadContext \n"/* Restore the secure context. */
|
||||||
" pop {r1,r3} \n"
|
" pop {r1,r3} \n"
|
||||||
" mov lr, r3 \n" /* LR = r3. */
|
" mov lr, r3 \n"/* LR = r3. */
|
||||||
" lsls r2, r3, #25 \n" /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
" lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
" bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||||
" msr psp, r1 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r1 \n"/* Remember the new top of stack for the task. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_ns_context: \n"
|
" restore_ns_context: \n"
|
||||||
" adds r1, r1, #16 \n" /* Move to the high registers. */
|
" adds r1, r1, #16 \n"/* Move to the high registers. */
|
||||||
" ldmia r1!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
|
" ldmia r1!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */
|
||||||
" mov r8, r4 \n" /* r8 = r4. */
|
" mov r8, r4 \n"/* r8 = r4. */
|
||||||
" mov r9, r5 \n" /* r9 = r5. */
|
" mov r9, r5 \n"/* r9 = r5. */
|
||||||
" mov r10, r6 \n" /* r10 = r6. */
|
" mov r10, r6 \n"/* r10 = r6. */
|
||||||
" mov r11, r7 \n" /* r11 = r7. */
|
" mov r11, r7 \n"/* r11 = r7. */
|
||||||
" msr psp, r1 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r1 \n"/* Remember the new top of stack for the task. */
|
||||||
" subs r1, r1, #32 \n" /* Go back to the low registers. */
|
" subs r1, r1, #32 \n"/* Go back to the low registers. */
|
||||||
" ldmia r1!, {r4-r7} \n" /* Restore the low registers that are not automatically restored. */
|
" ldmia r1!, {r4-r7} \n"/* Restore the low registers that are not automatically restored. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
"xSecureContextConst: .word xSecureContext \n"
|
"xSecureContextConst: .word xSecureContext \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||||
"xMAIR0Const: .word 0xe000edc0 \n"
|
"xMAIR0Const: .word 0xe000edc0 \n"
|
||||||
"xRNRConst: .word 0xe000ed98 \n"
|
"xRNRConst: .word 0xe000ed98 \n"
|
||||||
|
|
@ -427,26 +427,26 @@ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
|
" svc %0 \n"/* Secure context is allocated in the supervisor call. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
:: "i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" ldr r1, [r0] \n" /* The first item in the TCB is the top of the stack. */
|
" ldr r1, [r0] \n"/* The first item in the TCB is the top of the stack. */
|
||||||
" ldr r0, [r1] \n" /* The first item on the stack is the task's xSecureContext. */
|
" ldr r0, [r1] \n"/* The first item on the stack is the task's xSecureContext. */
|
||||||
" cmp r0, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
|
" cmp r0, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */
|
||||||
" beq free_secure_context \n"
|
" beq free_secure_context \n"
|
||||||
" bx lr \n" /* There is no secure context (xSecureContext is NULL). */
|
" bx lr \n"/* There is no secure context (xSecureContext is NULL). */
|
||||||
" free_secure_context: \n"
|
" free_secure_context: \n"
|
||||||
" svc %0 \n" /* Secure context is freed in the supervisor call. */
|
" svc %0 \n"/* Secure context is freed in the supervisor call. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
:: "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -41,109 +41,109 @@ extern "C" {
|
||||||
*------------------------------------------------------------------------------
|
*------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef configENABLE_FPU
|
#ifndef configENABLE_FPU
|
||||||
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
#ifndef configENABLE_MPU
|
#ifndef configENABLE_MPU
|
||||||
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
#ifndef configENABLE_TRUSTZONE
|
#ifndef configENABLE_TRUSTZONE
|
||||||
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type definitions.
|
* @brief Type definitions.
|
||||||
*/
|
*/
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
* not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M23"
|
#define portARCH_NAME "Cortex-M23"
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
#endif
|
#endif
|
||||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
#define portDONT_DISCARD __attribute__(( used ))
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extern declarations.
|
* @brief Extern declarations.
|
||||||
*/
|
*/
|
||||||
extern BaseType_t xPortIsInsideInterrupt( void );
|
extern BaseType_t xPortIsInsideInterrupt( void );
|
||||||
|
|
||||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU specific constants.
|
* @brief MPU specific constants.
|
||||||
*/
|
*/
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
#define portUSING_MPU_WRAPPERS 1
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
#else
|
#else
|
||||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
|
||||||
/* MPU regions. */
|
/* MPU regions. */
|
||||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
#define portSTACK_REGION ( 4UL )
|
#define portSTACK_REGION ( 4UL )
|
||||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||||
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
/* Device memory attributes used in MPU_MAIR registers.
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
*
|
*
|
||||||
|
|
@ -155,95 +155,96 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
* 11 --> Device-GRE
|
* 11 --> Device-GRE
|
||||||
* Bit[1:0] - 00, Reserved.
|
* Bit[1:0] - 00, Reserved.
|
||||||
*/
|
*/
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
/* Attributes used in MPU_RBAR registers. */
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Settings to define an MPU region.
|
* @brief Settings to define an MPU region.
|
||||||
*/
|
*/
|
||||||
typedef struct MPURegionSettings
|
typedef struct MPURegionSettings
|
||||||
{
|
{
|
||||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
} MPURegionSettings_t;
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU settings as stored in the TCB.
|
* @brief MPU settings as stored in the TCB.
|
||||||
*/
|
*/
|
||||||
typedef struct MPU_SETTINGS
|
typedef struct MPU_SETTINGS
|
||||||
{
|
{
|
||||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
} xMPU_SETTINGS;
|
} xMPU_SETTINGS;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SVC numbers.
|
* @brief SVC numbers.
|
||||||
*/
|
*/
|
||||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||||
#define portSVC_START_SCHEDULER 2
|
#define portSVC_START_SCHEDULER 2
|
||||||
#define portSVC_RAISE_PRIVILEGE 3
|
#define portSVC_RAISE_PRIVILEGE 3
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Scheduler utilities.
|
* @brief Scheduler utilities.
|
||||||
*/
|
*/
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tickless idle/low power functionality.
|
* @brief Tickless idle/low power functionality.
|
||||||
*/
|
*/
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||||
*/
|
*/
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Allocate a secure context for the task.
|
* @brief Allocate a secure context for the task.
|
||||||
*
|
*
|
||||||
* Tasks are not created with a secure context. Any task that is going to call
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
|
@ -254,56 +255,57 @@ typedef struct MPU_SETTINGS
|
||||||
*/
|
*/
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a task is deleted to delete the task's secure context,
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
* if it has one.
|
* if it has one.
|
||||||
*
|
*
|
||||||
* @param[in] pxTCB The TCB of the task being deleted.
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
*/
|
*/
|
||||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
#else
|
#else
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||||
#define portCLEAN_UP_TCB( pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB )
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raise an SVC request to raise privilege.
|
* @brief Raise an SVC request to raise privilege.
|
||||||
*
|
*
|
||||||
* The SVC handler checks that the SVC was raised from a system call and only
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
* then it raises the privilege. If this is called from any other place,
|
* then it raises the privilege. If this is called from any other place,
|
||||||
* the privilege is not raised.
|
* the privilege is not raised.
|
||||||
*/
|
*/
|
||||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
#else
|
#else
|
||||||
#define portIS_PRIVILEGED()
|
#define portIS_PRIVILEGED()
|
||||||
#define portRAISE_PRIVILEGE()
|
#define portRAISE_PRIVILEGE()
|
||||||
#define portRESET_PRIVILEGE()
|
#define portRESET_PRIVILEGE()
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Barriers.
|
* @brief Barriers.
|
||||||
*/
|
*/
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
* header files. */
|
* header files. */
|
||||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -48,75 +48,75 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n"/* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r4, #1 \n" /* r4 = 1. */
|
" movs r4, #1 \n"/* r4 = 1. */
|
||||||
" bics r3, r4 \n" /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
|
" bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
|
||||||
" str r3, [r2] \n" /* Disable MPU. */
|
" str r3, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
||||||
" ldr r4, [r1] \n" /* r4 = *r1 i.e. r4 = MAIR0. */
|
" ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r4, [r2] \n" /* Program MAIR0. */
|
" str r4, [r2] \n"/* Program MAIR0. */
|
||||||
" ldr r2, xRNRConst2 \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
" ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */
|
||||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||||
" movs r4, #4 \n" /* r4 = 4. */
|
" movs r4, #4 \n"/* r4 = 4. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 4. */
|
" str r4, [r2] \n"/* Program RNR = 4. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read first set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst2 \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write first set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */
|
||||||
" movs r4, #5 \n" /* r4 = 5. */
|
" movs r4, #5 \n"/* r4 = 5. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 5. */
|
" str r4, [r2] \n"/* Program RNR = 5. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read second set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst2 \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write second set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */
|
||||||
" movs r4, #6 \n" /* r4 = 6. */
|
" movs r4, #6 \n"/* r4 = 6. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 6. */
|
" str r4, [r2] \n"/* Program RNR = 6. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read third set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst2 \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write third set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */
|
||||||
" movs r4, #7 \n" /* r4 = 7. */
|
" movs r4, #7 \n"/* r4 = 7. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 7. */
|
" str r4, [r2] \n"/* Program RNR = 7. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read fourth set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst2 \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write fourth set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r4, #1 \n" /* r4 = 1. */
|
" movs r4, #1 \n"/* r4 = 1. */
|
||||||
" orrs r3, r4 \n" /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
|
" orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
|
||||||
" str r3, [r2] \n" /* Enable MPU. */
|
" str r3, [r2] \n"/* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n"/* Force memory writes before continuing. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */
|
" ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */
|
||||||
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
" msr psplim, r1 \n"/* Set this task's PSPLIM value. */
|
||||||
" msr control, r2 \n" /* Set this task's CONTROL value. */
|
" msr control, r2 \n"/* Set this task's CONTROL value. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
" bx r3 \n"/* Finally, branch to EXC_RETURN. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
" ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||||
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
" msr psplim, r1 \n"/* Set this task's PSPLIM value. */
|
||||||
" movs r1, #2 \n" /* r1 = 2. */
|
" movs r1, #2 \n"/* r1 = 2. */
|
||||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
" msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r2 \n" /* Finally, branch to EXC_RETURN. */
|
" bx r2 \n"/* Finally, branch to EXC_RETURN. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||||
"xMAIR0Const2: .word 0xe000edc0 \n"
|
"xMAIR0Const2: .word 0xe000edc0 \n"
|
||||||
"xRNRConst2: .word 0xe000ed98 \n"
|
"xRNRConst2: .word 0xe000ed98 \n"
|
||||||
|
|
@ -130,15 +130,15 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||||
" movs r1, #1 \n" /* r1 = 1. */
|
" movs r1, #1 \n"/* r1 = 1. */
|
||||||
" tst r0, r1 \n" /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
" tst r0, r1 \n"/* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
||||||
" beq running_privileged \n" /* If the result of previous AND operation was 0, branch. */
|
" beq running_privileged \n"/* If the result of previous AND operation was 0, branch. */
|
||||||
" movs r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
" movs r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
" running_privileged: \n"
|
" running_privileged: \n"
|
||||||
" movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
" movs r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
|
|
@ -150,11 +150,11 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||||
" movs r1, #1 \n" /* r1 = 1. */
|
" movs r1, #1 \n"/* r1 = 1. */
|
||||||
" bics r0, r1 \n" /* Clear the bit 0. */
|
" bics r0, r1 \n"/* Clear the bit 0. */
|
||||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||||
" bx lr \n" /* Return to the caller. */
|
" bx lr \n"/* Return to the caller. */
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -164,12 +164,12 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||||
" movs r1, #1 \n" /* r1 = 1. */
|
" movs r1, #1 \n"/* r1 = 1. */
|
||||||
" orrs r0, r1 \n" /* r0 = r0 | r1. */
|
" orrs r0, r1 \n"/* r0 = r0 | r1. */
|
||||||
" msr control, r0 \n" /* CONTROL = r0. */
|
" msr control, r0 \n"/* CONTROL = r0. */
|
||||||
" bx lr \n" /* Return to the caller. */
|
" bx lr \n"/* Return to the caller. */
|
||||||
:::"r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -178,19 +178,19 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||||
" cpsie i \n" /* Globally enable interrupts. */
|
" cpsie i \n"/* Globally enable interrupts. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" svc %0 \n" /* System call to start the first task. */
|
" svc %0 \n"/* System call to start the first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"xVTORConst: .word 0xe000ed08 \n"
|
"xVTORConst: .word 0xe000ed08 \n"
|
||||||
:: "i" ( portSVC_START_SCHEDULER ) : "memory"
|
::"i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -224,115 +224,115 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, psp \n" /* Read PSP in r0. */
|
" mrs r0, psp \n"/* Read PSP in r0. */
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" subs r0, r0, #44 \n" /* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */
|
" subs r0, r0, #44 \n"/* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */
|
||||||
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
" str r0, [r1] \n"/* Save the new top of stack in TCB. */
|
||||||
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
" mrs r1, psplim \n"/* r1 = PSPLIM. */
|
||||||
" mrs r2, control \n" /* r2 = CONTROL. */
|
" mrs r2, control \n"/* r2 = CONTROL. */
|
||||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||||
" stmia r0!, {r1-r7} \n" /* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */
|
" stmia r0!, {r1-r7} \n"/* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */
|
||||||
" mov r4, r8 \n" /* r4 = r8. */
|
" mov r4, r8 \n"/* r4 = r8. */
|
||||||
" mov r5, r9 \n" /* r5 = r9. */
|
" mov r5, r9 \n"/* r5 = r9. */
|
||||||
" mov r6, r10 \n" /* r6 = r10. */
|
" mov r6, r10 \n"/* r6 = r10. */
|
||||||
" mov r7, r11 \n" /* r7 = r11. */
|
" mov r7, r11 \n"/* r7 = r11. */
|
||||||
" stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
" stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" subs r0, r0, #40 \n" /* Make space for PSPLIM, LR and the remaining registers on the stack. */
|
" subs r0, r0, #40 \n"/* Make space for PSPLIM, LR and the remaining registers on the stack. */
|
||||||
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
" str r0, [r1] \n"/* Save the new top of stack in TCB. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||||
" stmia r0!, {r2-r7} \n" /* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
|
" stmia r0!, {r2-r7} \n"/* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
|
||||||
" mov r4, r8 \n" /* r4 = r8. */
|
" mov r4, r8 \n"/* r4 = r8. */
|
||||||
" mov r5, r9 \n" /* r5 = r9. */
|
" mov r5, r9 \n"/* r5 = r9. */
|
||||||
" mov r6, r10 \n" /* r6 = r10. */
|
" mov r6, r10 \n"/* r6 = r10. */
|
||||||
" mov r7, r11 \n" /* r7 = r11. */
|
" mov r7, r11 \n"/* r7 = r11. */
|
||||||
" stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
" stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" cpsid i \n"
|
" cpsid i \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" cpsie i \n"
|
" cpsie i \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n"/* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r4, #1 \n" /* r4 = 1. */
|
" movs r4, #1 \n"/* r4 = 1. */
|
||||||
" bics r3, r4 \n" /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
|
" bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
|
||||||
" str r3, [r2] \n" /* Disable MPU. */
|
" str r3, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
||||||
" ldr r4, [r1] \n" /* r4 = *r1 i.e. r4 = MAIR0. */
|
" ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r4, [r2] \n" /* Program MAIR0. */
|
" str r4, [r2] \n"/* Program MAIR0. */
|
||||||
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
" ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */
|
||||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||||
" movs r4, #4 \n" /* r4 = 4. */
|
" movs r4, #4 \n"/* r4 = 4. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 4. */
|
" str r4, [r2] \n"/* Program RNR = 4. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read first set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write first set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */
|
||||||
" movs r4, #5 \n" /* r4 = 5. */
|
" movs r4, #5 \n"/* r4 = 5. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 5. */
|
" str r4, [r2] \n"/* Program RNR = 5. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read second set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write second set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */
|
||||||
" movs r4, #6 \n" /* r4 = 6. */
|
" movs r4, #6 \n"/* r4 = 6. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 6. */
|
" str r4, [r2] \n"/* Program RNR = 6. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read third set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write third set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */
|
||||||
" movs r4, #7 \n" /* r4 = 7. */
|
" movs r4, #7 \n"/* r4 = 7. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 7. */
|
" str r4, [r2] \n"/* Program RNR = 7. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read fourth set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write fourth set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r4, #1 \n" /* r4 = 1. */
|
" movs r4, #1 \n"/* r4 = 1. */
|
||||||
" orrs r3, r4 \n" /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
|
" orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
|
||||||
" str r3, [r2] \n" /* Enable MPU. */
|
" str r3, [r2] \n"/* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n"/* Force memory writes before continuing. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" adds r0, r0, #28 \n" /* Move to the high registers. */
|
" adds r0, r0, #28 \n"/* Move to the high registers. */
|
||||||
" ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
|
" ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */
|
||||||
" mov r8, r4 \n" /* r8 = r4. */
|
" mov r8, r4 \n"/* r8 = r4. */
|
||||||
" mov r9, r5 \n" /* r9 = r5. */
|
" mov r9, r5 \n"/* r9 = r5. */
|
||||||
" mov r10, r6 \n" /* r10 = r6. */
|
" mov r10, r6 \n"/* r10 = r6. */
|
||||||
" mov r11, r7 \n" /* r11 = r7. */
|
" mov r11, r7 \n"/* r11 = r7. */
|
||||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
||||||
" subs r0, r0, #44 \n" /* Move to the starting of the saved context. */
|
" subs r0, r0, #44 \n"/* Move to the starting of the saved context. */
|
||||||
" ldmia r0!, {r1-r7} \n" /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */
|
" ldmia r0!, {r1-r7} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */
|
||||||
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */
|
" msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */
|
||||||
" msr control, r2 \n" /* Restore the CONTROL register value for the task. */
|
" msr control, r2 \n"/* Restore the CONTROL register value for the task. */
|
||||||
" bx r3 \n"
|
" bx r3 \n"
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" adds r0, r0, #24 \n" /* Move to the high registers. */
|
" adds r0, r0, #24 \n"/* Move to the high registers. */
|
||||||
" ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
|
" ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */
|
||||||
" mov r8, r4 \n" /* r8 = r4. */
|
" mov r8, r4 \n"/* r8 = r4. */
|
||||||
" mov r9, r5 \n" /* r9 = r5. */
|
" mov r9, r5 \n"/* r9 = r5. */
|
||||||
" mov r10, r6 \n" /* r10 = r6. */
|
" mov r10, r6 \n"/* r10 = r6. */
|
||||||
" mov r11, r7 \n" /* r11 = r7. */
|
" mov r11, r7 \n"/* r11 = r7. */
|
||||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
||||||
" subs r0, r0, #40 \n" /* Move to the starting of the saved context. */
|
" subs r0, r0, #40 \n"/* Move to the starting of the saved context. */
|
||||||
" ldmia r0!, {r2-r7} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
|
" ldmia r0!, {r2-r7} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
|
||||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
||||||
" bx r3 \n"
|
" bx r3 \n"
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||||
"xMAIR0Const: .word 0xe000edc0 \n"
|
"xMAIR0Const: .word 0xe000edc0 \n"
|
||||||
"xRNRConst: .word 0xe000ed98 \n"
|
"xRNRConst: .word 0xe000ed98 \n"
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -41,109 +41,109 @@ extern "C" {
|
||||||
*------------------------------------------------------------------------------
|
*------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef configENABLE_FPU
|
#ifndef configENABLE_FPU
|
||||||
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
#ifndef configENABLE_MPU
|
#ifndef configENABLE_MPU
|
||||||
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
#ifndef configENABLE_TRUSTZONE
|
#ifndef configENABLE_TRUSTZONE
|
||||||
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type definitions.
|
* @brief Type definitions.
|
||||||
*/
|
*/
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
* not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M23"
|
#define portARCH_NAME "Cortex-M23"
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
#endif
|
#endif
|
||||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
#define portDONT_DISCARD __attribute__(( used ))
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extern declarations.
|
* @brief Extern declarations.
|
||||||
*/
|
*/
|
||||||
extern BaseType_t xPortIsInsideInterrupt( void );
|
extern BaseType_t xPortIsInsideInterrupt( void );
|
||||||
|
|
||||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU specific constants.
|
* @brief MPU specific constants.
|
||||||
*/
|
*/
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
#define portUSING_MPU_WRAPPERS 1
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
#else
|
#else
|
||||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
|
||||||
/* MPU regions. */
|
/* MPU regions. */
|
||||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
#define portSTACK_REGION ( 4UL )
|
#define portSTACK_REGION ( 4UL )
|
||||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||||
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
/* Device memory attributes used in MPU_MAIR registers.
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
*
|
*
|
||||||
|
|
@ -155,95 +155,96 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
* 11 --> Device-GRE
|
* 11 --> Device-GRE
|
||||||
* Bit[1:0] - 00, Reserved.
|
* Bit[1:0] - 00, Reserved.
|
||||||
*/
|
*/
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
/* Attributes used in MPU_RBAR registers. */
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Settings to define an MPU region.
|
* @brief Settings to define an MPU region.
|
||||||
*/
|
*/
|
||||||
typedef struct MPURegionSettings
|
typedef struct MPURegionSettings
|
||||||
{
|
{
|
||||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
} MPURegionSettings_t;
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU settings as stored in the TCB.
|
* @brief MPU settings as stored in the TCB.
|
||||||
*/
|
*/
|
||||||
typedef struct MPU_SETTINGS
|
typedef struct MPU_SETTINGS
|
||||||
{
|
{
|
||||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
} xMPU_SETTINGS;
|
} xMPU_SETTINGS;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SVC numbers.
|
* @brief SVC numbers.
|
||||||
*/
|
*/
|
||||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||||
#define portSVC_START_SCHEDULER 2
|
#define portSVC_START_SCHEDULER 2
|
||||||
#define portSVC_RAISE_PRIVILEGE 3
|
#define portSVC_RAISE_PRIVILEGE 3
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Scheduler utilities.
|
* @brief Scheduler utilities.
|
||||||
*/
|
*/
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tickless idle/low power functionality.
|
* @brief Tickless idle/low power functionality.
|
||||||
*/
|
*/
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||||
*/
|
*/
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Allocate a secure context for the task.
|
* @brief Allocate a secure context for the task.
|
||||||
*
|
*
|
||||||
* Tasks are not created with a secure context. Any task that is going to call
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
|
@ -254,56 +255,57 @@ typedef struct MPU_SETTINGS
|
||||||
*/
|
*/
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a task is deleted to delete the task's secure context,
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
* if it has one.
|
* if it has one.
|
||||||
*
|
*
|
||||||
* @param[in] pxTCB The TCB of the task being deleted.
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
*/
|
*/
|
||||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
#else
|
#else
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||||
#define portCLEAN_UP_TCB( pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB )
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raise an SVC request to raise privilege.
|
* @brief Raise an SVC request to raise privilege.
|
||||||
*
|
*
|
||||||
* The SVC handler checks that the SVC was raised from a system call and only
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
* then it raises the privilege. If this is called from any other place,
|
* then it raises the privilege. If this is called from any other place,
|
||||||
* the privilege is not raised.
|
* the privilege is not raised.
|
||||||
*/
|
*/
|
||||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
#else
|
#else
|
||||||
#define portIS_PRIVILEGED()
|
#define portIS_PRIVILEGED()
|
||||||
#define portRAISE_PRIVILEGE()
|
#define portRAISE_PRIVILEGE()
|
||||||
#define portRESET_PRIVILEGE()
|
#define portRESET_PRIVILEGE()
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Barriers.
|
* @brief Barriers.
|
||||||
*/
|
*/
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
||||||
|
|
@ -44,63 +44,63 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r3, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n"/* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" bic r4, #1 \n" /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
|
" bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Disable MPU. */
|
" str r4, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
||||||
" ldr r4, [r3] \n" /* r4 = *r3 i.e. r4 = MAIR0. */
|
" ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r4, [r2] \n" /* Program MAIR0. */
|
" str r4, [r2] \n"/* Program MAIR0. */
|
||||||
" ldr r2, xRNRConst2 \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
" ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */
|
||||||
" movs r4, #4 \n" /* r4 = 4. */
|
" movs r4, #4 \n"/* r4 = 4. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 4. */
|
" str r4, [r2] \n"/* Program RNR = 4. */
|
||||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" ldmia r3!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
" ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2!, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" orr r4, #1 \n" /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
|
" orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Enable MPU. */
|
" str r4, [r2] \n"/* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n"/* Force memory writes before continuing. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" ldm r0!, {r1-r4} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */
|
" ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */
|
||||||
" ldr r5, xSecureContextConst2 \n"
|
" ldr r5, xSecureContextConst2 \n"
|
||||||
" str r1, [r5] \n" /* Set xSecureContext to this task's value for the same. */
|
" str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */
|
||||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
" msr psplim, r2 \n"/* Set this task's PSPLIM value. */
|
||||||
" msr control, r3 \n" /* Set this task's CONTROL value. */
|
" msr control, r3 \n"/* Set this task's CONTROL value. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r4 \n" /* Finally, branch to EXC_RETURN. */
|
" bx r4 \n"/* Finally, branch to EXC_RETURN. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
" ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||||
" ldr r4, xSecureContextConst2 \n"
|
" ldr r4, xSecureContextConst2 \n"
|
||||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
" str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */
|
||||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
" msr psplim, r2 \n"/* Set this task's PSPLIM value. */
|
||||||
" movs r1, #2 \n" /* r1 = 2. */
|
" movs r1, #2 \n"/* r1 = 2. */
|
||||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
" msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
" bx r3 \n"/* Finally, branch to EXC_RETURN. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
"xSecureContextConst2: .word xSecureContext \n"
|
"xSecureContextConst2: .word xSecureContext \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||||
"xMAIR0Const2: .word 0xe000edc0 \n"
|
"xMAIR0Const2: .word 0xe000edc0 \n"
|
||||||
"xRNRConst2: .word 0xe000ed98 \n"
|
"xRNRConst2: .word 0xe000ed98 \n"
|
||||||
|
|
@ -114,12 +114,12 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||||
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
" tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||||
" ite ne \n"
|
" ite ne \n"
|
||||||
" movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
" movne r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
" moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
" moveq r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
::: "r0", "memory"
|
::: "r0", "memory"
|
||||||
|
|
@ -131,10 +131,10 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||||
" bic r0, #1 \n" /* Clear the bit 0. */
|
" bic r0, #1 \n"/* Clear the bit 0. */
|
||||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||||
" bx lr \n" /* Return to the caller. */
|
" bx lr \n"/* Return to the caller. */
|
||||||
::: "r0", "memory"
|
::: "r0", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -144,11 +144,11 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||||
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
" orr r0, #1 \n"/* r0 = r0 | 1. */
|
||||||
" msr control, r0 \n" /* CONTROL = r0. */
|
" msr control, r0 \n"/* CONTROL = r0. */
|
||||||
" bx lr \n" /* Return to the caller. */
|
" bx lr \n"/* Return to the caller. */
|
||||||
:::"r0", "memory"
|
::: "r0", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -157,20 +157,20 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||||
" cpsie i \n" /* Globally enable interrupts. */
|
" cpsie i \n"/* Globally enable interrupts. */
|
||||||
" cpsie f \n"
|
" cpsie f \n"
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" svc %0 \n" /* System call to start the first task. */
|
" svc %0 \n"/* System call to start the first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"xVTORConst: .word 0xe000ed08 \n"
|
"xVTORConst: .word 0xe000ed08 \n"
|
||||||
:: "i" ( portSVC_START_SCHEDULER ) : "memory"
|
::"i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -179,13 +179,13 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
|
" mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */
|
||||||
" mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
:: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -194,10 +194,10 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" msr basepri, r0 \n" /* basepri = ulMask. */
|
" msr basepri, r0 \n"/* basepri = ulMask. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
::: "memory"
|
::: "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -211,156 +211,156 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
" .extern SecureContext_SaveContext \n"
|
" .extern SecureContext_SaveContext \n"
|
||||||
" .extern SecureContext_LoadContext \n"
|
" .extern SecureContext_LoadContext \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r1, psp \n" /* Read PSP in r1. */
|
" mrs r1, psp \n"/* Read PSP in r1. */
|
||||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" ldr r0, [r2] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
" ldr r0, [r2] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||||
" \n"
|
" \n"
|
||||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
" cbz r0, save_ns_context \n"/* No secure context to save. */
|
||||||
" push {r0-r2, r14} \n"
|
" push {r0-r2, r14} \n"
|
||||||
" bl SecureContext_SaveContext \n"
|
" bl SecureContext_SaveContext \n"
|
||||||
" pop {r0-r3} \n" /* LR is now in r3. */
|
" pop {r0-r3} \n"/* LR is now in r3. */
|
||||||
" mov lr, r3 \n" /* LR = r3. */
|
" mov lr, r3 \n"/* LR = r3. */
|
||||||
" lsls r2, r3, #25 \n" /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
" lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
" bpl save_ns_context \n" /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
" bpl save_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r2, [r3] \n" /* Read pxCurrentTCB. */
|
" ldr r2, [r3] \n"/* Read pxCurrentTCB. */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" subs r1, r1, #16 \n" /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
" subs r1, r1, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||||
" str r1, [r2] \n" /* Save the new top of stack in TCB. */
|
" str r1, [r2] \n"/* Save the new top of stack in TCB. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mrs r3, control \n" /* r3 = CONTROL. */
|
" mrs r3, control \n"/* r3 = CONTROL. */
|
||||||
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
|
" mov r4, lr \n"/* r4 = LR/EXC_RETURN. */
|
||||||
" stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
" stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" subs r1, r1, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
" subs r1, r1, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
||||||
" str r1, [r2] \n" /* Save the new top of stack in TCB. */
|
" str r1, [r2] \n"/* Save the new top of stack in TCB. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||||
" stmia r1!, {r0, r2-r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
" stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" b select_next_task \n"
|
" b select_next_task \n"
|
||||||
" \n"
|
" \n"
|
||||||
" save_ns_context: \n"
|
" save_ns_context: \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r2, [r3] \n" /* Read pxCurrentTCB. */
|
" ldr r2, [r3] \n"/* Read pxCurrentTCB. */
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
||||||
" it eq \n"
|
" it eq \n"
|
||||||
" vstmdbeq r1!, {s16-s31} \n" /* Store the FPU registers which are not saved automatically. */
|
" vstmdbeq r1!, {s16-s31} \n"/* Store the FPU registers which are not saved automatically. */
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" subs r1, r1, #48 \n" /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
|
" subs r1, r1, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
|
||||||
" str r1, [r2] \n" /* Save the new top of stack in TCB. */
|
" str r1, [r2] \n"/* Save the new top of stack in TCB. */
|
||||||
" adds r1, r1, #16 \n" /* r1 = r1 + 16. */
|
" adds r1, r1, #16 \n"/* r1 = r1 + 16. */
|
||||||
" stm r1, {r4-r11} \n" /* Store the registers that are not saved automatically. */
|
" stm r1, {r4-r11} \n"/* Store the registers that are not saved automatically. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mrs r3, control \n" /* r3 = CONTROL. */
|
" mrs r3, control \n"/* r3 = CONTROL. */
|
||||||
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
|
" mov r4, lr \n"/* r4 = LR/EXC_RETURN. */
|
||||||
" subs r1, r1, #16 \n" /* r1 = r1 - 16. */
|
" subs r1, r1, #16 \n"/* r1 = r1 - 16. */
|
||||||
" stm r1, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
" stm r1, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" subs r1, r1, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
" subs r1, r1, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
||||||
" str r1, [r2] \n" /* Save the new top of stack in TCB. */
|
" str r1, [r2] \n"/* Save the new top of stack in TCB. */
|
||||||
" adds r1, r1, #12 \n" /* r1 = r1 + 12. */
|
" adds r1, r1, #12 \n"/* r1 = r1 + 12. */
|
||||||
" stm r1, {r4-r11} \n" /* Store the registers that are not saved automatically. */
|
" stm r1, {r4-r11} \n"/* Store the registers that are not saved automatically. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||||
" subs r1, r1, #12 \n" /* r1 = r1 - 12. */
|
" subs r1, r1, #12 \n"/* r1 = r1 - 12. */
|
||||||
" stmia r1!, {r0, r2-r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
" stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" select_next_task: \n"
|
" select_next_task: \n"
|
||||||
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
" mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||||
" msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" mov r0, #0 \n" /* r0 = 0. */
|
" mov r0, #0 \n"/* r0 = 0. */
|
||||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
" msr basepri, r0 \n"/* Enable interrupts. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r3, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
" ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */
|
" ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n"/* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" bic r4, #1 \n" /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
|
" bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Disable MPU. */
|
" str r4, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
||||||
" ldr r4, [r3] \n" /* r4 = *r3 i.e. r4 = MAIR0. */
|
" ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r4, [r2] \n" /* Program MAIR0. */
|
" str r4, [r2] \n"/* Program MAIR0. */
|
||||||
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
" ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */
|
||||||
" movs r4, #4 \n" /* r4 = 4. */
|
" movs r4, #4 \n"/* r4 = 4. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 4. */
|
" str r4, [r2] \n"/* Program RNR = 4. */
|
||||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" ldmia r3!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
" ldmia r3!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2!, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" orr r4, #1 \n" /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
|
" orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Enable MPU. */
|
" str r4, [r2] \n"/* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n"/* Force memory writes before continuing. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" ldmia r1!, {r0, r2-r4} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */
|
" ldmia r1!, {r0, r2-r4} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */
|
||||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
||||||
" msr control, r3 \n" /* Restore the CONTROL register value for the task. */
|
" msr control, r3 \n"/* Restore the CONTROL register value for the task. */
|
||||||
" mov lr, r4 \n" /* LR = r4. */
|
" mov lr, r4 \n"/* LR = r4. */
|
||||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" str r0, [r2] \n" /* Restore the task's xSecureContext. */
|
" str r0, [r2] \n"/* Restore the task's xSecureContext. */
|
||||||
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
|
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
|
||||||
" push {r1,r4} \n"
|
" push {r1,r4} \n"
|
||||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. */
|
" bl SecureContext_LoadContext \n"/* Restore the secure context. */
|
||||||
" pop {r1,r4} \n"
|
" pop {r1,r4} \n"
|
||||||
" mov lr, r4 \n" /* LR = r4. */
|
" mov lr, r4 \n"/* LR = r4. */
|
||||||
" lsls r2, r4, #25 \n" /* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
" lsls r2, r4, #25 \n"/* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
" bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||||
" msr psp, r1 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r1 \n"/* Remember the new top of stack for the task. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" ldmia r1!, {r0, r2-r3} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */
|
" ldmia r1!, {r0, r2-r3} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */
|
||||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
||||||
" mov lr, r3 \n" /* LR = r3. */
|
" mov lr, r3 \n"/* LR = r3. */
|
||||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" str r0, [r2] \n" /* Restore the task's xSecureContext. */
|
" str r0, [r2] \n"/* Restore the task's xSecureContext. */
|
||||||
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
|
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
|
||||||
" push {r1,r3} \n"
|
" push {r1,r3} \n"
|
||||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. */
|
" bl SecureContext_LoadContext \n"/* Restore the secure context. */
|
||||||
" pop {r1,r3} \n"
|
" pop {r1,r3} \n"
|
||||||
" mov lr, r3 \n" /* LR = r3. */
|
" mov lr, r3 \n"/* LR = r3. */
|
||||||
" lsls r2, r3, #25 \n" /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
" lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
" bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||||
" msr psp, r1 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r1 \n"/* Remember the new top of stack for the task. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_ns_context: \n"
|
" restore_ns_context: \n"
|
||||||
" ldmia r1!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */
|
" ldmia r1!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
||||||
" it eq \n"
|
" it eq \n"
|
||||||
" vldmiaeq r1!, {s16-s31} \n" /* Restore the FPU registers which are not restored automatically. */
|
" vldmiaeq r1!, {s16-s31} \n"/* Restore the FPU registers which are not restored automatically. */
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
" msr psp, r1 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r1 \n"/* Remember the new top of stack for the task. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
"xSecureContextConst: .word xSecureContext \n"
|
"xSecureContextConst: .word xSecureContext \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||||
"xMAIR0Const: .word 0xe000edc0 \n"
|
"xMAIR0Const: .word 0xe000edc0 \n"
|
||||||
"xRNRConst: .word 0xe000ed98 \n"
|
"xRNRConst: .word 0xe000ed98 \n"
|
||||||
"xRBARConst: .word 0xe000ed9c \n"
|
"xRBARConst: .word 0xe000ed9c \n"
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
:: "i"( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -386,24 +386,24 @@ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
|
" svc %0 \n"/* Secure context is allocated in the supervisor call. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
:: "i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" ldr r1, [r0] \n" /* The first item in the TCB is the top of the stack. */
|
" ldr r1, [r0] \n"/* The first item in the TCB is the top of the stack. */
|
||||||
" ldr r0, [r1] \n" /* The first item on the stack is the task's xSecureContext. */
|
" ldr r0, [r1] \n"/* The first item on the stack is the task's xSecureContext. */
|
||||||
" cmp r0, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
|
" cmp r0, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */
|
||||||
" it ne \n"
|
" it ne \n"
|
||||||
" svcne %0 \n" /* Secure context is freed in the supervisor call. */
|
" svcne %0 \n"/* Secure context is freed in the supervisor call. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
:: "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -41,109 +41,109 @@ extern "C" {
|
||||||
*------------------------------------------------------------------------------
|
*------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef configENABLE_FPU
|
#ifndef configENABLE_FPU
|
||||||
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
#ifndef configENABLE_MPU
|
#ifndef configENABLE_MPU
|
||||||
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
#ifndef configENABLE_TRUSTZONE
|
#ifndef configENABLE_TRUSTZONE
|
||||||
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type definitions.
|
* @brief Type definitions.
|
||||||
*/
|
*/
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
* not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M33"
|
#define portARCH_NAME "Cortex-M33"
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
#endif
|
#endif
|
||||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
#define portDONT_DISCARD __attribute__(( used ))
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extern declarations.
|
* @brief Extern declarations.
|
||||||
*/
|
*/
|
||||||
extern BaseType_t xPortIsInsideInterrupt( void );
|
extern BaseType_t xPortIsInsideInterrupt( void );
|
||||||
|
|
||||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU specific constants.
|
* @brief MPU specific constants.
|
||||||
*/
|
*/
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
#define portUSING_MPU_WRAPPERS 1
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
#else
|
#else
|
||||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
|
||||||
/* MPU regions. */
|
/* MPU regions. */
|
||||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
#define portSTACK_REGION ( 4UL )
|
#define portSTACK_REGION ( 4UL )
|
||||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||||
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
/* Device memory attributes used in MPU_MAIR registers.
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
*
|
*
|
||||||
|
|
@ -155,95 +155,96 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
* 11 --> Device-GRE
|
* 11 --> Device-GRE
|
||||||
* Bit[1:0] - 00, Reserved.
|
* Bit[1:0] - 00, Reserved.
|
||||||
*/
|
*/
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
/* Attributes used in MPU_RBAR registers. */
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Settings to define an MPU region.
|
* @brief Settings to define an MPU region.
|
||||||
*/
|
*/
|
||||||
typedef struct MPURegionSettings
|
typedef struct MPURegionSettings
|
||||||
{
|
{
|
||||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
} MPURegionSettings_t;
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU settings as stored in the TCB.
|
* @brief MPU settings as stored in the TCB.
|
||||||
*/
|
*/
|
||||||
typedef struct MPU_SETTINGS
|
typedef struct MPU_SETTINGS
|
||||||
{
|
{
|
||||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
} xMPU_SETTINGS;
|
} xMPU_SETTINGS;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SVC numbers.
|
* @brief SVC numbers.
|
||||||
*/
|
*/
|
||||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||||
#define portSVC_START_SCHEDULER 2
|
#define portSVC_START_SCHEDULER 2
|
||||||
#define portSVC_RAISE_PRIVILEGE 3
|
#define portSVC_RAISE_PRIVILEGE 3
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Scheduler utilities.
|
* @brief Scheduler utilities.
|
||||||
*/
|
*/
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tickless idle/low power functionality.
|
* @brief Tickless idle/low power functionality.
|
||||||
*/
|
*/
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||||
*/
|
*/
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Allocate a secure context for the task.
|
* @brief Allocate a secure context for the task.
|
||||||
*
|
*
|
||||||
* Tasks are not created with a secure context. Any task that is going to call
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
|
@ -254,56 +255,57 @@ typedef struct MPU_SETTINGS
|
||||||
*/
|
*/
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a task is deleted to delete the task's secure context,
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
* if it has one.
|
* if it has one.
|
||||||
*
|
*
|
||||||
* @param[in] pxTCB The TCB of the task being deleted.
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
*/
|
*/
|
||||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
#else
|
#else
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||||
#define portCLEAN_UP_TCB( pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB )
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raise an SVC request to raise privilege.
|
* @brief Raise an SVC request to raise privilege.
|
||||||
*
|
*
|
||||||
* The SVC handler checks that the SVC was raised from a system call and only
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
* then it raises the privilege. If this is called from any other place,
|
* then it raises the privilege. If this is called from any other place,
|
||||||
* the privilege is not raised.
|
* the privilege is not raised.
|
||||||
*/
|
*/
|
||||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
#else
|
#else
|
||||||
#define portIS_PRIVILEGED()
|
#define portIS_PRIVILEGED()
|
||||||
#define portRAISE_PRIVILEGE()
|
#define portRAISE_PRIVILEGE()
|
||||||
#define portRESET_PRIVILEGE()
|
#define portRESET_PRIVILEGE()
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Barriers.
|
* @brief Barriers.
|
||||||
*/
|
*/
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
||||||
|
|
@ -44,58 +44,58 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n"/* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" bic r4, #1 \n" /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
|
" bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Disable MPU. */
|
" str r4, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
||||||
" ldr r3, [r1] \n" /* r3 = *r1 i.e. r3 = MAIR0. */
|
" ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r3, [r2] \n" /* Program MAIR0. */
|
" str r3, [r2] \n"/* Program MAIR0. */
|
||||||
" ldr r2, xRNRConst2 \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
" ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */
|
||||||
" movs r3, #4 \n" /* r3 = 4. */
|
" movs r3, #4 \n"/* r3 = 4. */
|
||||||
" str r3, [r2] \n" /* Program RNR = 4. */
|
" str r3, [r2] \n"/* Program RNR = 4. */
|
||||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" ldmia r1!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
" ldmia r1!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2!, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" orr r4, #1 \n" /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
|
" orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Enable MPU. */
|
" str r4, [r2] \n"/* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n"/* Force memory writes before continuing. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */
|
" ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */
|
||||||
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
" msr psplim, r1 \n"/* Set this task's PSPLIM value. */
|
||||||
" msr control, r2 \n" /* Set this task's CONTROL value. */
|
" msr control, r2 \n"/* Set this task's CONTROL value. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
" bx r3 \n"/* Finally, branch to EXC_RETURN. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
" ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||||
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
" msr psplim, r1 \n"/* Set this task's PSPLIM value. */
|
||||||
" movs r1, #2 \n" /* r1 = 2. */
|
" movs r1, #2 \n"/* r1 = 2. */
|
||||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
" msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r2 \n" /* Finally, branch to EXC_RETURN. */
|
" bx r2 \n"/* Finally, branch to EXC_RETURN. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||||
"xMAIR0Const2: .word 0xe000edc0 \n"
|
"xMAIR0Const2: .word 0xe000edc0 \n"
|
||||||
"xRNRConst2: .word 0xe000ed98 \n"
|
"xRNRConst2: .word 0xe000ed98 \n"
|
||||||
|
|
@ -109,12 +109,12 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||||
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
" tst r0, #1 \n"/* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||||
" ite ne \n"
|
" ite ne \n"
|
||||||
" movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
" movne r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
" moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
" moveq r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
::: "r0", "memory"
|
::: "r0", "memory"
|
||||||
|
|
@ -126,10 +126,10 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||||
" bic r0, #1 \n" /* Clear the bit 0. */
|
" bic r0, #1 \n"/* Clear the bit 0. */
|
||||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||||
" bx lr \n" /* Return to the caller. */
|
" bx lr \n"/* Return to the caller. */
|
||||||
::: "r0", "memory"
|
::: "r0", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -139,11 +139,11 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||||
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
" orr r0, #1 \n"/* r0 = r0 | 1. */
|
||||||
" msr control, r0 \n" /* CONTROL = r0. */
|
" msr control, r0 \n"/* CONTROL = r0. */
|
||||||
" bx lr \n" /* Return to the caller. */
|
" bx lr \n"/* Return to the caller. */
|
||||||
:::"r0", "memory"
|
::: "r0", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -152,20 +152,20 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||||
" cpsie i \n" /* Globally enable interrupts. */
|
" cpsie i \n"/* Globally enable interrupts. */
|
||||||
" cpsie f \n"
|
" cpsie f \n"
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" svc %0 \n" /* System call to start the first task. */
|
" svc %0 \n"/* System call to start the first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"xVTORConst: .word 0xe000ed08 \n"
|
"xVTORConst: .word 0xe000ed08 \n"
|
||||||
:: "i" ( portSVC_START_SCHEDULER ) : "memory"
|
::"i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -174,13 +174,13 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
|
" mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */
|
||||||
" mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
:: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -189,10 +189,10 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" msr basepri, r0 \n" /* basepri = ulMask. */
|
" msr basepri, r0 \n"/* basepri = ulMask. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
::: "memory"
|
::: "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -204,95 +204,95 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, psp \n" /* Read PSP in r0. */
|
" mrs r0, psp \n"/* Read PSP in r0. */
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
||||||
" it eq \n"
|
" it eq \n"
|
||||||
" vstmdbeq r0!, {s16-s31} \n" /* Store the FPU registers which are not saved automatically. */
|
" vstmdbeq r0!, {s16-s31} \n"/* Store the FPU registers which are not saved automatically. */
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
" mrs r1, psplim \n"/* r1 = PSPLIM. */
|
||||||
" mrs r2, control \n" /* r2 = CONTROL. */
|
" mrs r2, control \n"/* r2 = CONTROL. */
|
||||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||||
" stmdb r0!, {r1-r11} \n" /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */
|
" stmdb r0!, {r1-r11} \n"/* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||||
" stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
|
" stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
" str r0, [r1] \n"/* Save the new top of stack in TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
" mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||||
" msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
" msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" mov r0, #0 \n" /* r0 = 0. */
|
" mov r0, #0 \n"/* r0 = 0. */
|
||||||
" msr basepri, r0 \n" /* Enable interrupts. */
|
" msr basepri, r0 \n"/* Enable interrupts. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n"/* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" bic r4, #1 \n" /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
|
" bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Disable MPU. */
|
" str r4, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
||||||
" ldr r3, [r1] \n" /* r3 = *r1 i.e. r3 = MAIR0. */
|
" ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r3, [r2] \n" /* Program MAIR0. */
|
" str r3, [r2] \n"/* Program MAIR0. */
|
||||||
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
" ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */
|
||||||
" movs r3, #4 \n" /* r3 = 4. */
|
" movs r3, #4 \n"/* r3 = 4. */
|
||||||
" str r3, [r2] \n" /* Program RNR = 4. */
|
" str r3, [r2] \n"/* Program RNR = 4. */
|
||||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" ldmia r1!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
" ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
" stmia r2!, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
" stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" orr r4, #1 \n" /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
|
" orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Enable MPU. */
|
" str r4, [r2] \n"/* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n"/* Force memory writes before continuing. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" ldmia r0!, {r1-r11} \n" /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */
|
" ldmia r0!, {r1-r11} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
" ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
" tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
" tst r3, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
||||||
" it eq \n"
|
" it eq \n"
|
||||||
" vldmiaeq r0!, {s16-s31} \n" /* Restore the FPU registers which are not restored automatically. */
|
" vldmiaeq r0!, {s16-s31} \n"/* Restore the FPU registers which are not restored automatically. */
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */
|
" msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */
|
||||||
" msr control, r2 \n" /* Restore the CONTROL register value for the task. */
|
" msr control, r2 \n"/* Restore the CONTROL register value for the task. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
||||||
" bx r3 \n"
|
" bx r3 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||||
"xMAIR0Const: .word 0xe000edc0 \n"
|
"xMAIR0Const: .word 0xe000edc0 \n"
|
||||||
"xRNRConst: .word 0xe000ed98 \n"
|
"xRNRConst: .word 0xe000ed98 \n"
|
||||||
"xRBARConst: .word 0xe000ed9c \n"
|
"xRBARConst: .word 0xe000ed9c \n"
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
:: "i"( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -41,109 +41,109 @@ extern "C" {
|
||||||
*------------------------------------------------------------------------------
|
*------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef configENABLE_FPU
|
#ifndef configENABLE_FPU
|
||||||
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
#ifndef configENABLE_MPU
|
#ifndef configENABLE_MPU
|
||||||
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
#ifndef configENABLE_TRUSTZONE
|
#ifndef configENABLE_TRUSTZONE
|
||||||
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type definitions.
|
* @brief Type definitions.
|
||||||
*/
|
*/
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
* not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M33"
|
#define portARCH_NAME "Cortex-M33"
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
#endif
|
#endif
|
||||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
#define portDONT_DISCARD __attribute__(( used ))
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extern declarations.
|
* @brief Extern declarations.
|
||||||
*/
|
*/
|
||||||
extern BaseType_t xPortIsInsideInterrupt( void );
|
extern BaseType_t xPortIsInsideInterrupt( void );
|
||||||
|
|
||||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU specific constants.
|
* @brief MPU specific constants.
|
||||||
*/
|
*/
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
#define portUSING_MPU_WRAPPERS 1
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
#else
|
#else
|
||||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
|
||||||
/* MPU regions. */
|
/* MPU regions. */
|
||||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
#define portSTACK_REGION ( 4UL )
|
#define portSTACK_REGION ( 4UL )
|
||||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||||
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
/* Device memory attributes used in MPU_MAIR registers.
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
*
|
*
|
||||||
|
|
@ -155,95 +155,96 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
* 11 --> Device-GRE
|
* 11 --> Device-GRE
|
||||||
* Bit[1:0] - 00, Reserved.
|
* Bit[1:0] - 00, Reserved.
|
||||||
*/
|
*/
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
/* Attributes used in MPU_RBAR registers. */
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Settings to define an MPU region.
|
* @brief Settings to define an MPU region.
|
||||||
*/
|
*/
|
||||||
typedef struct MPURegionSettings
|
typedef struct MPURegionSettings
|
||||||
{
|
{
|
||||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
} MPURegionSettings_t;
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU settings as stored in the TCB.
|
* @brief MPU settings as stored in the TCB.
|
||||||
*/
|
*/
|
||||||
typedef struct MPU_SETTINGS
|
typedef struct MPU_SETTINGS
|
||||||
{
|
{
|
||||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
} xMPU_SETTINGS;
|
} xMPU_SETTINGS;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SVC numbers.
|
* @brief SVC numbers.
|
||||||
*/
|
*/
|
||||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||||
#define portSVC_START_SCHEDULER 2
|
#define portSVC_START_SCHEDULER 2
|
||||||
#define portSVC_RAISE_PRIVILEGE 3
|
#define portSVC_RAISE_PRIVILEGE 3
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Scheduler utilities.
|
* @brief Scheduler utilities.
|
||||||
*/
|
*/
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tickless idle/low power functionality.
|
* @brief Tickless idle/low power functionality.
|
||||||
*/
|
*/
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||||
*/
|
*/
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Allocate a secure context for the task.
|
* @brief Allocate a secure context for the task.
|
||||||
*
|
*
|
||||||
* Tasks are not created with a secure context. Any task that is going to call
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
|
@ -254,56 +255,57 @@ typedef struct MPU_SETTINGS
|
||||||
*/
|
*/
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a task is deleted to delete the task's secure context,
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
* if it has one.
|
* if it has one.
|
||||||
*
|
*
|
||||||
* @param[in] pxTCB The TCB of the task being deleted.
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
*/
|
*/
|
||||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
#else
|
#else
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||||
#define portCLEAN_UP_TCB( pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB )
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raise an SVC request to raise privilege.
|
* @brief Raise an SVC request to raise privilege.
|
||||||
*
|
*
|
||||||
* The SVC handler checks that the SVC was raised from a system call and only
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
* then it raises the privilege. If this is called from any other place,
|
* then it raises the privilege. If this is called from any other place,
|
||||||
* the privilege is not raised.
|
* the privilege is not raised.
|
||||||
*/
|
*/
|
||||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
#else
|
#else
|
||||||
#define portIS_PRIVILEGED()
|
#define portIS_PRIVILEGED()
|
||||||
#define portRAISE_PRIVILEGE()
|
#define portRAISE_PRIVILEGE()
|
||||||
#define portRESET_PRIVILEGE()
|
#define portRESET_PRIVILEGE()
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Barriers.
|
* @brief Barriers.
|
||||||
*/
|
*/
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -41,109 +41,109 @@ extern "C" {
|
||||||
*------------------------------------------------------------------------------
|
*------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef configENABLE_FPU
|
#ifndef configENABLE_FPU
|
||||||
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
#ifndef configENABLE_MPU
|
#ifndef configENABLE_MPU
|
||||||
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
#ifndef configENABLE_TRUSTZONE
|
#ifndef configENABLE_TRUSTZONE
|
||||||
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type definitions.
|
* @brief Type definitions.
|
||||||
*/
|
*/
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
* not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M23"
|
#define portARCH_NAME "Cortex-M23"
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
#endif
|
#endif
|
||||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
#define portDONT_DISCARD __root
|
#define portDONT_DISCARD __root
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extern declarations.
|
* @brief Extern declarations.
|
||||||
*/
|
*/
|
||||||
extern BaseType_t xPortIsInsideInterrupt( void );
|
extern BaseType_t xPortIsInsideInterrupt( void );
|
||||||
|
|
||||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU specific constants.
|
* @brief MPU specific constants.
|
||||||
*/
|
*/
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
#define portUSING_MPU_WRAPPERS 1
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
#else
|
#else
|
||||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
|
||||||
/* MPU regions. */
|
/* MPU regions. */
|
||||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
#define portSTACK_REGION ( 4UL )
|
#define portSTACK_REGION ( 4UL )
|
||||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||||
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
/* Device memory attributes used in MPU_MAIR registers.
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
*
|
*
|
||||||
|
|
@ -155,95 +155,96 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
* 11 --> Device-GRE
|
* 11 --> Device-GRE
|
||||||
* Bit[1:0] - 00, Reserved.
|
* Bit[1:0] - 00, Reserved.
|
||||||
*/
|
*/
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
/* Attributes used in MPU_RBAR registers. */
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Settings to define an MPU region.
|
* @brief Settings to define an MPU region.
|
||||||
*/
|
*/
|
||||||
typedef struct MPURegionSettings
|
typedef struct MPURegionSettings
|
||||||
{
|
{
|
||||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
} MPURegionSettings_t;
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU settings as stored in the TCB.
|
* @brief MPU settings as stored in the TCB.
|
||||||
*/
|
*/
|
||||||
typedef struct MPU_SETTINGS
|
typedef struct MPU_SETTINGS
|
||||||
{
|
{
|
||||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
} xMPU_SETTINGS;
|
} xMPU_SETTINGS;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SVC numbers.
|
* @brief SVC numbers.
|
||||||
*/
|
*/
|
||||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||||
#define portSVC_START_SCHEDULER 2
|
#define portSVC_START_SCHEDULER 2
|
||||||
#define portSVC_RAISE_PRIVILEGE 3
|
#define portSVC_RAISE_PRIVILEGE 3
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Scheduler utilities.
|
* @brief Scheduler utilities.
|
||||||
*/
|
*/
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tickless idle/low power functionality.
|
* @brief Tickless idle/low power functionality.
|
||||||
*/
|
*/
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||||
*/
|
*/
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Allocate a secure context for the task.
|
* @brief Allocate a secure context for the task.
|
||||||
*
|
*
|
||||||
* Tasks are not created with a secure context. Any task that is going to call
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
|
@ -254,63 +255,64 @@ typedef struct MPU_SETTINGS
|
||||||
*/
|
*/
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a task is deleted to delete the task's secure context,
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
* if it has one.
|
* if it has one.
|
||||||
*
|
*
|
||||||
* @param[in] pxTCB The TCB of the task being deleted.
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
*/
|
*/
|
||||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
#else
|
#else
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||||
#define portCLEAN_UP_TCB( pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB )
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raise an SVC request to raise privilege.
|
* @brief Raise an SVC request to raise privilege.
|
||||||
*
|
*
|
||||||
* The SVC handler checks that the SVC was raised from a system call and only
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
* then it raises the privilege. If this is called from any other place,
|
* then it raises the privilege. If this is called from any other place,
|
||||||
* the privilege is not raised.
|
* the privilege is not raised.
|
||||||
*/
|
*/
|
||||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
#else
|
#else
|
||||||
#define portIS_PRIVILEGED()
|
#define portIS_PRIVILEGED()
|
||||||
#define portRAISE_PRIVILEGE()
|
#define portRAISE_PRIVILEGE()
|
||||||
#define portRESET_PRIVILEGE()
|
#define portRESET_PRIVILEGE()
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Barriers.
|
* @brief Barriers.
|
||||||
*/
|
*/
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
* the source code because to do so would cause other compilers to generate
|
* the source code because to do so would cause other compilers to generate
|
||||||
* warnings. */
|
* warnings. */
|
||||||
#pragma diag_suppress=Be006
|
#pragma diag_suppress=Be006
|
||||||
#pragma diag_suppress=Pa082
|
#pragma diag_suppress=Pa082
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -41,109 +41,109 @@ extern "C" {
|
||||||
*------------------------------------------------------------------------------
|
*------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef configENABLE_FPU
|
#ifndef configENABLE_FPU
|
||||||
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
#ifndef configENABLE_MPU
|
#ifndef configENABLE_MPU
|
||||||
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
#ifndef configENABLE_TRUSTZONE
|
#ifndef configENABLE_TRUSTZONE
|
||||||
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type definitions.
|
* @brief Type definitions.
|
||||||
*/
|
*/
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
* not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M23"
|
#define portARCH_NAME "Cortex-M23"
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
#endif
|
#endif
|
||||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
#define portDONT_DISCARD __root
|
#define portDONT_DISCARD __root
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extern declarations.
|
* @brief Extern declarations.
|
||||||
*/
|
*/
|
||||||
extern BaseType_t xPortIsInsideInterrupt( void );
|
extern BaseType_t xPortIsInsideInterrupt( void );
|
||||||
|
|
||||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU specific constants.
|
* @brief MPU specific constants.
|
||||||
*/
|
*/
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
#define portUSING_MPU_WRAPPERS 1
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
#else
|
#else
|
||||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
|
||||||
/* MPU regions. */
|
/* MPU regions. */
|
||||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
#define portSTACK_REGION ( 4UL )
|
#define portSTACK_REGION ( 4UL )
|
||||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||||
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
/* Device memory attributes used in MPU_MAIR registers.
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
*
|
*
|
||||||
|
|
@ -155,95 +155,96 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
* 11 --> Device-GRE
|
* 11 --> Device-GRE
|
||||||
* Bit[1:0] - 00, Reserved.
|
* Bit[1:0] - 00, Reserved.
|
||||||
*/
|
*/
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
/* Attributes used in MPU_RBAR registers. */
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Settings to define an MPU region.
|
* @brief Settings to define an MPU region.
|
||||||
*/
|
*/
|
||||||
typedef struct MPURegionSettings
|
typedef struct MPURegionSettings
|
||||||
{
|
{
|
||||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
} MPURegionSettings_t;
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU settings as stored in the TCB.
|
* @brief MPU settings as stored in the TCB.
|
||||||
*/
|
*/
|
||||||
typedef struct MPU_SETTINGS
|
typedef struct MPU_SETTINGS
|
||||||
{
|
{
|
||||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
} xMPU_SETTINGS;
|
} xMPU_SETTINGS;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SVC numbers.
|
* @brief SVC numbers.
|
||||||
*/
|
*/
|
||||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||||
#define portSVC_START_SCHEDULER 2
|
#define portSVC_START_SCHEDULER 2
|
||||||
#define portSVC_RAISE_PRIVILEGE 3
|
#define portSVC_RAISE_PRIVILEGE 3
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Scheduler utilities.
|
* @brief Scheduler utilities.
|
||||||
*/
|
*/
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tickless idle/low power functionality.
|
* @brief Tickless idle/low power functionality.
|
||||||
*/
|
*/
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||||
*/
|
*/
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Allocate a secure context for the task.
|
* @brief Allocate a secure context for the task.
|
||||||
*
|
*
|
||||||
* Tasks are not created with a secure context. Any task that is going to call
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
|
@ -254,63 +255,64 @@ typedef struct MPU_SETTINGS
|
||||||
*/
|
*/
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a task is deleted to delete the task's secure context,
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
* if it has one.
|
* if it has one.
|
||||||
*
|
*
|
||||||
* @param[in] pxTCB The TCB of the task being deleted.
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
*/
|
*/
|
||||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
#else
|
#else
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||||
#define portCLEAN_UP_TCB( pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB )
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raise an SVC request to raise privilege.
|
* @brief Raise an SVC request to raise privilege.
|
||||||
*
|
*
|
||||||
* The SVC handler checks that the SVC was raised from a system call and only
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
* then it raises the privilege. If this is called from any other place,
|
* then it raises the privilege. If this is called from any other place,
|
||||||
* the privilege is not raised.
|
* the privilege is not raised.
|
||||||
*/
|
*/
|
||||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
#else
|
#else
|
||||||
#define portIS_PRIVILEGED()
|
#define portIS_PRIVILEGED()
|
||||||
#define portRAISE_PRIVILEGE()
|
#define portRAISE_PRIVILEGE()
|
||||||
#define portRESET_PRIVILEGE()
|
#define portRESET_PRIVILEGE()
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Barriers.
|
* @brief Barriers.
|
||||||
*/
|
*/
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
* the source code because to do so would cause other compilers to generate
|
* the source code because to do so would cause other compilers to generate
|
||||||
* warnings. */
|
* warnings. */
|
||||||
#pragma diag_suppress=Be006
|
#pragma diag_suppress=Be006
|
||||||
#pragma diag_suppress=Pa082
|
#pragma diag_suppress=Pa082
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -41,109 +41,109 @@ extern "C" {
|
||||||
*------------------------------------------------------------------------------
|
*------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef configENABLE_FPU
|
#ifndef configENABLE_FPU
|
||||||
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
#ifndef configENABLE_MPU
|
#ifndef configENABLE_MPU
|
||||||
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
#ifndef configENABLE_TRUSTZONE
|
#ifndef configENABLE_TRUSTZONE
|
||||||
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type definitions.
|
* @brief Type definitions.
|
||||||
*/
|
*/
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
* not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M33"
|
#define portARCH_NAME "Cortex-M33"
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
#endif
|
#endif
|
||||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
#define portDONT_DISCARD __root
|
#define portDONT_DISCARD __root
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extern declarations.
|
* @brief Extern declarations.
|
||||||
*/
|
*/
|
||||||
extern BaseType_t xPortIsInsideInterrupt( void );
|
extern BaseType_t xPortIsInsideInterrupt( void );
|
||||||
|
|
||||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU specific constants.
|
* @brief MPU specific constants.
|
||||||
*/
|
*/
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
#define portUSING_MPU_WRAPPERS 1
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
#else
|
#else
|
||||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
|
||||||
/* MPU regions. */
|
/* MPU regions. */
|
||||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
#define portSTACK_REGION ( 4UL )
|
#define portSTACK_REGION ( 4UL )
|
||||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||||
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
/* Device memory attributes used in MPU_MAIR registers.
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
*
|
*
|
||||||
|
|
@ -155,95 +155,96 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
* 11 --> Device-GRE
|
* 11 --> Device-GRE
|
||||||
* Bit[1:0] - 00, Reserved.
|
* Bit[1:0] - 00, Reserved.
|
||||||
*/
|
*/
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
/* Attributes used in MPU_RBAR registers. */
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Settings to define an MPU region.
|
* @brief Settings to define an MPU region.
|
||||||
*/
|
*/
|
||||||
typedef struct MPURegionSettings
|
typedef struct MPURegionSettings
|
||||||
{
|
{
|
||||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
} MPURegionSettings_t;
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU settings as stored in the TCB.
|
* @brief MPU settings as stored in the TCB.
|
||||||
*/
|
*/
|
||||||
typedef struct MPU_SETTINGS
|
typedef struct MPU_SETTINGS
|
||||||
{
|
{
|
||||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
} xMPU_SETTINGS;
|
} xMPU_SETTINGS;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SVC numbers.
|
* @brief SVC numbers.
|
||||||
*/
|
*/
|
||||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||||
#define portSVC_START_SCHEDULER 2
|
#define portSVC_START_SCHEDULER 2
|
||||||
#define portSVC_RAISE_PRIVILEGE 3
|
#define portSVC_RAISE_PRIVILEGE 3
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Scheduler utilities.
|
* @brief Scheduler utilities.
|
||||||
*/
|
*/
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tickless idle/low power functionality.
|
* @brief Tickless idle/low power functionality.
|
||||||
*/
|
*/
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||||
*/
|
*/
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Allocate a secure context for the task.
|
* @brief Allocate a secure context for the task.
|
||||||
*
|
*
|
||||||
* Tasks are not created with a secure context. Any task that is going to call
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
|
@ -254,63 +255,64 @@ typedef struct MPU_SETTINGS
|
||||||
*/
|
*/
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a task is deleted to delete the task's secure context,
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
* if it has one.
|
* if it has one.
|
||||||
*
|
*
|
||||||
* @param[in] pxTCB The TCB of the task being deleted.
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
*/
|
*/
|
||||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
#else
|
#else
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||||
#define portCLEAN_UP_TCB( pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB )
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raise an SVC request to raise privilege.
|
* @brief Raise an SVC request to raise privilege.
|
||||||
*
|
*
|
||||||
* The SVC handler checks that the SVC was raised from a system call and only
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
* then it raises the privilege. If this is called from any other place,
|
* then it raises the privilege. If this is called from any other place,
|
||||||
* the privilege is not raised.
|
* the privilege is not raised.
|
||||||
*/
|
*/
|
||||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
#else
|
#else
|
||||||
#define portIS_PRIVILEGED()
|
#define portIS_PRIVILEGED()
|
||||||
#define portRAISE_PRIVILEGE()
|
#define portRAISE_PRIVILEGE()
|
||||||
#define portRESET_PRIVILEGE()
|
#define portRESET_PRIVILEGE()
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Barriers.
|
* @brief Barriers.
|
||||||
*/
|
*/
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
* the source code because to do so would cause other compilers to generate
|
* the source code because to do so would cause other compilers to generate
|
||||||
* warnings. */
|
* warnings. */
|
||||||
#pragma diag_suppress=Be006
|
#pragma diag_suppress=Be006
|
||||||
#pragma diag_suppress=Pa082
|
#pragma diag_suppress=Pa082
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -41,109 +41,109 @@ extern "C" {
|
||||||
*------------------------------------------------------------------------------
|
*------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef configENABLE_FPU
|
#ifndef configENABLE_FPU
|
||||||
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
#ifndef configENABLE_MPU
|
#ifndef configENABLE_MPU
|
||||||
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
#ifndef configENABLE_TRUSTZONE
|
#ifndef configENABLE_TRUSTZONE
|
||||||
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type definitions.
|
* @brief Type definitions.
|
||||||
*/
|
*/
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
* not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M33"
|
#define portARCH_NAME "Cortex-M33"
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
#endif
|
#endif
|
||||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
#define portDONT_DISCARD __root
|
#define portDONT_DISCARD __root
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extern declarations.
|
* @brief Extern declarations.
|
||||||
*/
|
*/
|
||||||
extern BaseType_t xPortIsInsideInterrupt( void );
|
extern BaseType_t xPortIsInsideInterrupt( void );
|
||||||
|
|
||||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU specific constants.
|
* @brief MPU specific constants.
|
||||||
*/
|
*/
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
#define portUSING_MPU_WRAPPERS 1
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
#else
|
#else
|
||||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
|
||||||
/* MPU regions. */
|
/* MPU regions. */
|
||||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
#define portSTACK_REGION ( 4UL )
|
#define portSTACK_REGION ( 4UL )
|
||||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||||
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
/* Device memory attributes used in MPU_MAIR registers.
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
*
|
*
|
||||||
|
|
@ -155,95 +155,96 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
* 11 --> Device-GRE
|
* 11 --> Device-GRE
|
||||||
* Bit[1:0] - 00, Reserved.
|
* Bit[1:0] - 00, Reserved.
|
||||||
*/
|
*/
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
/* Attributes used in MPU_RBAR registers. */
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Settings to define an MPU region.
|
* @brief Settings to define an MPU region.
|
||||||
*/
|
*/
|
||||||
typedef struct MPURegionSettings
|
typedef struct MPURegionSettings
|
||||||
{
|
{
|
||||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
} MPURegionSettings_t;
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU settings as stored in the TCB.
|
* @brief MPU settings as stored in the TCB.
|
||||||
*/
|
*/
|
||||||
typedef struct MPU_SETTINGS
|
typedef struct MPU_SETTINGS
|
||||||
{
|
{
|
||||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
} xMPU_SETTINGS;
|
} xMPU_SETTINGS;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SVC numbers.
|
* @brief SVC numbers.
|
||||||
*/
|
*/
|
||||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||||
#define portSVC_START_SCHEDULER 2
|
#define portSVC_START_SCHEDULER 2
|
||||||
#define portSVC_RAISE_PRIVILEGE 3
|
#define portSVC_RAISE_PRIVILEGE 3
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Scheduler utilities.
|
* @brief Scheduler utilities.
|
||||||
*/
|
*/
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tickless idle/low power functionality.
|
* @brief Tickless idle/low power functionality.
|
||||||
*/
|
*/
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||||
*/
|
*/
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Allocate a secure context for the task.
|
* @brief Allocate a secure context for the task.
|
||||||
*
|
*
|
||||||
* Tasks are not created with a secure context. Any task that is going to call
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
|
@ -254,63 +255,64 @@ typedef struct MPU_SETTINGS
|
||||||
*/
|
*/
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a task is deleted to delete the task's secure context,
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
* if it has one.
|
* if it has one.
|
||||||
*
|
*
|
||||||
* @param[in] pxTCB The TCB of the task being deleted.
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
*/
|
*/
|
||||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
#else
|
#else
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||||
#define portCLEAN_UP_TCB( pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB )
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raise an SVC request to raise privilege.
|
* @brief Raise an SVC request to raise privilege.
|
||||||
*
|
*
|
||||||
* The SVC handler checks that the SVC was raised from a system call and only
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
* then it raises the privilege. If this is called from any other place,
|
* then it raises the privilege. If this is called from any other place,
|
||||||
* the privilege is not raised.
|
* the privilege is not raised.
|
||||||
*/
|
*/
|
||||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
#else
|
#else
|
||||||
#define portIS_PRIVILEGED()
|
#define portIS_PRIVILEGED()
|
||||||
#define portRAISE_PRIVILEGE()
|
#define portRAISE_PRIVILEGE()
|
||||||
#define portRESET_PRIVILEGE()
|
#define portRESET_PRIVILEGE()
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Barriers.
|
* @brief Barriers.
|
||||||
*/
|
*/
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
* the source code because to do so would cause other compilers to generate
|
* the source code because to do so would cause other compilers to generate
|
||||||
* warnings. */
|
* warnings. */
|
||||||
#pragma diag_suppress=Be006
|
#pragma diag_suppress=Be006
|
||||||
#pragma diag_suppress=Pa082
|
#pragma diag_suppress=Pa082
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
||||||
|
|
@ -37,14 +37,14 @@
|
||||||
* @brief Restore the context of the first task so that the first task starts
|
* @brief Restore the context of the first task so that the first task starts
|
||||||
* executing.
|
* executing.
|
||||||
*/
|
*/
|
||||||
void vRestoreContextOfFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
BaseType_t xIsPrivileged( void ) __attribute__ (( naked ));
|
BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raises the privilege level by clearing the bit 0 of the CONTROL
|
* @brief Raises the privilege level by clearing the bit 0 of the CONTROL
|
||||||
|
|
@ -57,7 +57,7 @@ BaseType_t xIsPrivileged( void ) __attribute__ (( naked ));
|
||||||
* Bit[0] = 0 --> The processor is running privileged
|
* Bit[0] = 0 --> The processor is running privileged
|
||||||
* Bit[0] = 1 --> The processor is running unprivileged.
|
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||||
*/
|
*/
|
||||||
void vRaisePrivilege( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
|
|
@ -67,32 +67,32 @@ void vRaisePrivilege( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
||||||
* Bit[0] = 0 --> The processor is running privileged
|
* Bit[0] = 0 --> The processor is running privileged
|
||||||
* Bit[0] = 1 --> The processor is running unprivileged.
|
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||||
*/
|
*/
|
||||||
void vResetPrivilege( void ) __attribute__ (( naked ));
|
void vResetPrivilege( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Starts the first task.
|
* @brief Starts the first task.
|
||||||
*/
|
*/
|
||||||
void vStartFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disables interrupts.
|
* @brief Disables interrupts.
|
||||||
*/
|
*/
|
||||||
uint32_t ulSetInterruptMask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
|
uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables interrupts.
|
* @brief Enables interrupts.
|
||||||
*/
|
*/
|
||||||
void vClearInterruptMask( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
|
void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief PendSV Exception handler.
|
* @brief PendSV Exception handler.
|
||||||
*/
|
*/
|
||||||
void PendSV_Handler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SVC Handler.
|
* @brief SVC Handler.
|
||||||
*/
|
*/
|
||||||
void SVC_Handler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocate a Secure context for the calling task.
|
* @brief Allocate a Secure context for the calling task.
|
||||||
|
|
@ -100,13 +100,13 @@ void SVC_Handler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
||||||
* @param[in] ulSecureStackSize The size of the stack to be allocated on the
|
* @param[in] ulSecureStackSize The size of the stack to be allocated on the
|
||||||
* secure side for the calling task.
|
* secure side for the calling task.
|
||||||
*/
|
*/
|
||||||
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__ (( naked ));
|
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Free the task's secure context.
|
* @brief Free the task's secure context.
|
||||||
*
|
*
|
||||||
* @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task.
|
* @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task.
|
||||||
*/
|
*/
|
||||||
void vPortFreeSecureContext( uint32_t *pulTCB ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
#endif /* __PORT_ASM_H__ */
|
#endif /* __PORT_ASM_H__ */
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
/* Secure port macros. */
|
/* Secure port macros. */
|
||||||
#include "secure_port_macros.h"
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -41,20 +41,20 @@ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandl
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
" mrs r1, ipsr \n"/* r1 = IPSR. */
|
||||||
" cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
" cbz r1, load_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
|
||||||
" ldmia r0!, {r1, r2} \n" /* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
|
" ldmia r0!, {r1, r2} \n"/* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
" ldmia r1!, {r3} \n"/* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
||||||
" msr control, r3 \n" /* CONTROL = r3. */
|
" msr control, r3 \n"/* CONTROL = r3. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" msr psplim, r2 \n" /* PSPLIM = r2. */
|
" msr psplim, r2 \n"/* PSPLIM = r2. */
|
||||||
" msr psp, r1 \n" /* PSP = r1. */
|
" msr psp, r1 \n"/* PSP = r1. */
|
||||||
" \n"
|
" \n"
|
||||||
" load_ctx_therad_mode: \n"
|
" load_ctx_therad_mode: \n"
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
:::"r0", "r1", "r2"
|
::: "r0", "r1", "r2"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -66,25 +66,25 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
" mrs r1, ipsr \n"/* r1 = IPSR. */
|
||||||
" cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
" cbz r1, save_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
|
||||||
" mrs r1, psp \n" /* r1 = PSP. */
|
" mrs r1, psp \n"/* r1 = PSP. */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" mrs r2, control \n" /* r2 = CONTROL. */
|
" mrs r2, control \n"/* r2 = CONTROL. */
|
||||||
" subs r1, r1, #4 \n" /* Make space for the CONTROL value on the stack. */
|
" subs r1, r1, #4 \n"/* Make space for the CONTROL value on the stack. */
|
||||||
" str r1, [r0] \n" /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
" str r1, [r0] \n"/* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
||||||
" stmia r1!, {r2} \n" /* Store CONTROL value on the stack. */
|
" stmia r1!, {r2} \n"/* Store CONTROL value on the stack. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" str r1, [r0] \n" /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
" str r1, [r0] \n"/* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" movs r1, %0 \n" /* r1 = securecontextNO_STACK. */
|
" movs r1, %0 \n"/* r1 = securecontextNO_STACK. */
|
||||||
" msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */
|
" msr psplim, r1 \n"/* PSPLIM = securecontextNO_STACK. */
|
||||||
" msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
|
" msr psp, r1 \n"/* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
|
||||||
" \n"
|
" \n"
|
||||||
" save_ctx_therad_mode: \n"
|
" save_ctx_therad_mode: \n"
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
:: "i" ( securecontextNO_STACK ) : "r1", "memory"
|
::"i" ( securecontextNO_STACK ) : "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
||||||
|
|
@ -37,20 +37,20 @@ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandl
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
" mrs r1, ipsr \n"/* r1 = IPSR. */
|
||||||
" cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
" cbz r1, load_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
|
||||||
" ldmia r0!, {r1, r2} \n" /* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
|
" ldmia r0!, {r1, r2} \n"/* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
" ldmia r1!, {r3} \n"/* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
||||||
" msr control, r3 \n" /* CONTROL = r3. */
|
" msr control, r3 \n"/* CONTROL = r3. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" msr psplim, r2 \n" /* PSPLIM = r2. */
|
" msr psplim, r2 \n"/* PSPLIM = r2. */
|
||||||
" msr psp, r1 \n" /* PSP = r1. */
|
" msr psp, r1 \n"/* PSP = r1. */
|
||||||
" \n"
|
" \n"
|
||||||
" load_ctx_therad_mode: \n"
|
" load_ctx_therad_mode: \n"
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
:::"r0", "r1", "r2"
|
::: "r0", "r1", "r2"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -62,26 +62,26 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
" mrs r1, ipsr \n"/* r1 = IPSR. */
|
||||||
" cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
" cbz r1, save_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
|
||||||
" mrs r1, psp \n" /* r1 = PSP. */
|
" mrs r1, psp \n"/* r1 = PSP. */
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
" vstmdb r1!, {s0} \n" /* Trigger the defferred stacking of FPU registers. */
|
" vstmdb r1!, {s0} \n"/* Trigger the defferred stacking of FPU registers. */
|
||||||
" vldmia r1!, {s0} \n" /* Nullify the effect of the pervious statement. */
|
" vldmia r1!, {s0} \n"/* Nullify the effect of the pervious statement. */
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" mrs r2, control \n" /* r2 = CONTROL. */
|
" mrs r2, control \n"/* r2 = CONTROL. */
|
||||||
" stmdb r1!, {r2} \n" /* Store CONTROL value on the stack. */
|
" stmdb r1!, {r2} \n"/* Store CONTROL value on the stack. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" str r1, [r0] \n" /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
" str r1, [r0] \n"/* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
||||||
" movs r1, %0 \n" /* r1 = securecontextNO_STACK. */
|
" movs r1, %0 \n"/* r1 = securecontextNO_STACK. */
|
||||||
" msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */
|
" msr psplim, r1 \n"/* PSPLIM = securecontextNO_STACK. */
|
||||||
" msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
|
" msr psp, r1 \n"/* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
|
||||||
" \n"
|
" \n"
|
||||||
" save_ctx_therad_mode: \n"
|
" save_ctx_therad_mode: \n"
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
:: "i" ( securecontextNO_STACK ) : "r1", "memory"
|
::"i" ( securecontextNO_STACK ) : "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
||||||
|
|
@ -58,9 +58,9 @@
|
||||||
*/
|
*/
|
||||||
typedef struct SecureContext
|
typedef struct SecureContext
|
||||||
{
|
{
|
||||||
uint8_t *pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
|
uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
|
||||||
uint8_t *pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
|
uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
|
||||||
uint8_t *pucStackStart; /**< First location of the stack memory. */
|
uint8_t * pucStackStart; /**< First location of the stack memory. */
|
||||||
} SecureContext_t;
|
} SecureContext_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -79,7 +79,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
secureportSET_PSPLIM( securecontextNO_STACK );
|
secureportSET_PSPLIM( securecontextNO_STACK );
|
||||||
secureportSET_PSP( securecontextNO_STACK );
|
secureportSET_PSP( securecontextNO_STACK );
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||||
|
|
@ -94,17 +94,19 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged )
|
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
uint32_t ulIsTaskPrivileged )
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
|
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
{
|
{
|
||||||
uint8_t *pucStackMemory = NULL;
|
uint8_t * pucStackMemory = NULL;
|
||||||
uint32_t ulIPSR;
|
uint32_t ulIPSR;
|
||||||
SecureContextHandle_t xSecureContextHandle = NULL;
|
SecureContextHandle_t xSecureContextHandle = NULL;
|
||||||
#if( configENABLE_MPU == 1 )
|
|
||||||
uint32_t *pulCurrentStackPointer = NULL;
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
uint32_t * pulCurrentStackPointer = NULL;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
/* Read the Interrupt Program Status Register (IPSR) value. */
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
|
@ -136,13 +138,14 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
* programmed in the PSPLIM register on context switch.*/
|
* programmed in the PSPLIM register on context switch.*/
|
||||||
xSecureContextHandle->pucStackLimit = pucStackMemory;
|
xSecureContextHandle->pucStackLimit = pucStackMemory;
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
/* Store the correct CONTROL value for the task on the stack.
|
/* Store the correct CONTROL value for the task on the stack.
|
||||||
* This value is programmed in the CONTROL register on
|
* This value is programmed in the CONTROL register on
|
||||||
* context switch. */
|
* context switch. */
|
||||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
|
pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
|
||||||
pulCurrentStackPointer--;
|
pulCurrentStackPointer--;
|
||||||
|
|
||||||
if( ulIsTaskPrivileged )
|
if( ulIsTaskPrivileged )
|
||||||
{
|
{
|
||||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||||
|
|
@ -161,7 +164,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
/* Current SP is set to the starting of the stack. This
|
/* Current SP is set to the starting of the stack. This
|
||||||
* value programmed in the PSP register on context switch. */
|
* value programmed in the PSP register on context switch. */
|
||||||
xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
|
xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
* @brief Opaque handle.
|
* @brief Opaque handle.
|
||||||
*/
|
*/
|
||||||
struct SecureContext;
|
struct SecureContext;
|
||||||
typedef struct SecureContext* SecureContextHandle_t;
|
typedef struct SecureContext * SecureContextHandle_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -68,8 +68,9 @@ void SecureContext_Init( void );
|
||||||
* @return Opaque context handle if context is successfully allocated, NULL
|
* @return Opaque context handle if context is successfully allocated, NULL
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged );
|
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
uint32_t ulIsTaskPrivileged );
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
|
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,10 @@
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Allocate the memory for the heap. */
|
/* Allocate the memory for the heap. */
|
||||||
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
|
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
|
||||||
/* The application writer has already defined the array used for the RTOS
|
|
||||||
* heap - probably so it can be placed in a special segment or address. */
|
/* The application writer has already defined the array used for the RTOS
|
||||||
|
* heap - probably so it can be placed in a special segment or address. */
|
||||||
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||||
#else /* configAPPLICATION_ALLOCATED_HEAP */
|
#else /* configAPPLICATION_ALLOCATED_HEAP */
|
||||||
static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||||
|
|
@ -76,7 +77,7 @@
|
||||||
*/
|
*/
|
||||||
typedef struct A_BLOCK_LINK
|
typedef struct A_BLOCK_LINK
|
||||||
{
|
{
|
||||||
struct A_BLOCK_LINK *pxNextFreeBlock; /**< The next free block in the list. */
|
struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */
|
||||||
size_t xBlockSize; /**< The size of the free block. */
|
size_t xBlockSize; /**< The size of the free block. */
|
||||||
} BlockLink_t;
|
} BlockLink_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -96,7 +97,7 @@ static void prvHeapInit( void );
|
||||||
*
|
*
|
||||||
* @param[in] pxBlockToInsert The block being freed.
|
* @param[in] pxBlockToInsert The block being freed.
|
||||||
*/
|
*/
|
||||||
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert );
|
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -108,7 +109,7 @@ static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( s
|
||||||
/**
|
/**
|
||||||
* @brief Create a couple of list links to mark the start and end of the list.
|
* @brief Create a couple of list links to mark the start and end of the list.
|
||||||
*/
|
*/
|
||||||
static BlockLink_t xStart, *pxEnd = NULL;
|
static BlockLink_t xStart, * pxEnd = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Keeps track of the number of free bytes remaining, but says nothing
|
* @brief Keeps track of the number of free bytes remaining, but says nothing
|
||||||
|
|
@ -129,10 +130,10 @@ static size_t xBlockAllocatedBit = 0;
|
||||||
|
|
||||||
static void prvHeapInit( void )
|
static void prvHeapInit( void )
|
||||||
{
|
{
|
||||||
BlockLink_t *pxFirstFreeBlock;
|
BlockLink_t * pxFirstFreeBlock;
|
||||||
uint8_t *pucAlignedHeap;
|
uint8_t * pucAlignedHeap;
|
||||||
size_t uxAddress;
|
size_t uxAddress;
|
||||||
size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE;
|
size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE;
|
||||||
|
|
||||||
/* Ensure the heap starts on a correctly aligned boundary. */
|
/* Ensure the heap starts on a correctly aligned boundary. */
|
||||||
uxAddress = ( size_t ) ucHeap;
|
uxAddress = ( size_t ) ucHeap;
|
||||||
|
|
@ -175,10 +176,10 @@ size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert )
|
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert )
|
||||||
{
|
{
|
||||||
BlockLink_t *pxIterator;
|
BlockLink_t * pxIterator;
|
||||||
uint8_t *puc;
|
uint8_t * puc;
|
||||||
|
|
||||||
/* Iterate through the list until a block is found that has a higher address
|
/* Iterate through the list until a block is found that has a higher address
|
||||||
* than the block being inserted. */
|
* than the block being inserted. */
|
||||||
|
|
@ -190,6 +191,7 @@ uint8_t *puc;
|
||||||
/* Do the block being inserted, and the block it is being inserted after
|
/* Do the block being inserted, and the block it is being inserted after
|
||||||
* make a contiguous block of memory? */
|
* make a contiguous block of memory? */
|
||||||
puc = ( uint8_t * ) pxIterator;
|
puc = ( uint8_t * ) pxIterator;
|
||||||
|
|
||||||
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
|
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
|
||||||
{
|
{
|
||||||
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
|
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
|
||||||
|
|
@ -203,6 +205,7 @@ uint8_t *puc;
|
||||||
/* Do the block being inserted, and the block it is being inserted before
|
/* Do the block being inserted, and the block it is being inserted before
|
||||||
* make a contiguous block of memory? */
|
* make a contiguous block of memory? */
|
||||||
puc = ( uint8_t * ) pxBlockToInsert;
|
puc = ( uint8_t * ) pxBlockToInsert;
|
||||||
|
|
||||||
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
|
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
|
||||||
{
|
{
|
||||||
if( pxIterator->pxNextFreeBlock != pxEnd )
|
if( pxIterator->pxNextFreeBlock != pxEnd )
|
||||||
|
|
@ -236,10 +239,10 @@ uint8_t *puc;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void *pvPortMalloc( size_t xWantedSize )
|
void * pvPortMalloc( size_t xWantedSize )
|
||||||
{
|
{
|
||||||
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
|
BlockLink_t * pxBlock, * pxPreviousBlock, * pxNewBlockLink;
|
||||||
void *pvReturn = NULL;
|
void * pvReturn = NULL;
|
||||||
|
|
||||||
/* If this is the first call to malloc then the heap will require
|
/* If this is the first call to malloc then the heap will require
|
||||||
* initialisation to setup the list of free blocks. */
|
* initialisation to setup the list of free blocks. */
|
||||||
|
|
@ -288,6 +291,7 @@ void *pvReturn = NULL;
|
||||||
* one of adequate size is found. */
|
* one of adequate size is found. */
|
||||||
pxPreviousBlock = &xStart;
|
pxPreviousBlock = &xStart;
|
||||||
pxBlock = xStart.pxNextFreeBlock;
|
pxBlock = xStart.pxNextFreeBlock;
|
||||||
|
|
||||||
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
|
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
|
||||||
{
|
{
|
||||||
pxPreviousBlock = pxBlock;
|
pxPreviousBlock = pxBlock;
|
||||||
|
|
@ -363,7 +367,7 @@ void *pvReturn = NULL;
|
||||||
|
|
||||||
traceMALLOC( pvReturn, xWantedSize );
|
traceMALLOC( pvReturn, xWantedSize );
|
||||||
|
|
||||||
#if( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||||
{
|
{
|
||||||
if( pvReturn == NULL )
|
if( pvReturn == NULL )
|
||||||
{
|
{
|
||||||
|
|
@ -375,17 +379,17 @@ void *pvReturn = NULL;
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||||
|
|
||||||
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
return pvReturn;
|
return pvReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortFree( void *pv )
|
void vPortFree( void * pv )
|
||||||
{
|
{
|
||||||
uint8_t *puc = ( uint8_t * ) pv;
|
uint8_t * puc = ( uint8_t * ) pv;
|
||||||
BlockLink_t *pxLink;
|
BlockLink_t * pxLink;
|
||||||
|
|
||||||
if( pv != NULL )
|
if( pv != NULL )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,13 @@
|
||||||
* @return Pointer to the memory region if the allocation is successful, NULL
|
* @return Pointer to the memory region if the allocation is successful, NULL
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
void *pvPortMalloc( size_t xWantedSize );
|
void * pvPortMalloc( size_t xWantedSize );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Frees the previously allocated memory.
|
* @brief Frees the previously allocated memory.
|
||||||
*
|
*
|
||||||
* @param[in] pv Pointer to the memory to be freed.
|
* @param[in] pv Pointer to the memory to be freed.
|
||||||
*/
|
*/
|
||||||
void vPortFree( void *pv );
|
void vPortFree( void * pv );
|
||||||
|
|
||||||
#endif /* __SECURE_HEAP_H__ */
|
#endif /* __SECURE_HEAP_H__ */
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
|
||||||
|
|
||||||
/* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures
|
/* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures
|
||||||
* that we can enable/disable lazy stacking in port.c file. */
|
* that we can enable/disable lazy stacking in port.c file. */
|
||||||
*( secureinitFPCCR ) &= ~ ( secureinitFPCCR_LSPENS_MASK );
|
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
||||||
|
|
||||||
/* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP
|
/* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP
|
||||||
* registers (S16-S31) are also pushed to stack on exception entry and
|
* registers (S16-S31) are also pushed to stack on exception entry and
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
#if defined( __IAR_SYSTEMS_ICC__ )
|
#if defined( __IAR_SYSTEMS_ICC__ )
|
||||||
#define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root
|
#define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root
|
||||||
#else
|
#else
|
||||||
#define secureportNON_SECURE_CALLABLE __attribute__((cmse_nonsecure_entry)) __attribute__((used))
|
#define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -126,7 +126,7 @@
|
||||||
{ \
|
{ \
|
||||||
secureportDISABLE_SECURE_INTERRUPTS(); \
|
secureportDISABLE_SECURE_INTERRUPTS(); \
|
||||||
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
|
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
|
||||||
for( ;; ); \
|
for( ; ; ) {; } \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __SECURE_PORT_MACROS_H__ */
|
#endif /* __SECURE_PORT_MACROS_H__ */
|
||||||
|
|
|
||||||
|
|
@ -25,22 +25,22 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V1.00:
|
* Changes from V1.00:
|
||||||
|
*
|
||||||
+ Call to taskYIELD() from within tick ISR has been replaced by the more
|
+ Call to taskYIELD() from within tick ISR has been replaced by the more
|
||||||
efficient portSWITCH_CONTEXT().
|
+ efficient portSWITCH_CONTEXT().
|
||||||
+ ISR function definitions renamed to include the prv prefix.
|
+ ISR function definitions renamed to include the prv prefix.
|
||||||
|
+
|
||||||
Changes from V2.6.1
|
+ Changes from V2.6.1
|
||||||
|
+
|
||||||
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
||||||
macro to be consistent with the later ports.
|
+ macro to be consistent with the later ports.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the Flashlite 186
|
* Implementation of functions defined in portable.h for the Flashlite 186
|
||||||
* port.
|
* port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -67,14 +67,16 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz );
|
||||||
static void prvExitFunction( void );
|
static void prvExitFunction( void );
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||||
is being used. */
|
* is being used. */
|
||||||
#if( configUSE_PREEMPTION == 1 )
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
|
||||||
being used. */
|
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||||
|
* being used. */
|
||||||
static void __interrupt __far prvPreemptiveTick( void );
|
static void __interrupt __far prvPreemptiveTick( void );
|
||||||
#else
|
#else
|
||||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
|
||||||
being used. */
|
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||||
|
* being used. */
|
||||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -87,9 +89,9 @@ static void __interrupt __far prvYieldProcessor( void );
|
||||||
static BaseType_t xSchedulerRunning = pdFALSE;
|
static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
||||||
/* Points to the original routine installed on the vector we use for manual
|
/* Points to the original routine installed on the vector we use for manual
|
||||||
context switches. This is then used to restore the original routine during
|
* context switches. This is then used to restore the original routine during
|
||||||
prvExitFunction(). */
|
* prvExitFunction(). */
|
||||||
static void ( __interrupt __far *pxOldSwitchISR )();
|
static void( __interrupt __far * pxOldSwitchISR )();
|
||||||
|
|
||||||
/* Used to restore the original DOS context when the scheduler is ended. */
|
/* Used to restore the original DOS context when the scheduler is ended. */
|
||||||
static jmp_buf xJumpBuf;
|
static jmp_buf xJumpBuf;
|
||||||
|
|
@ -102,14 +104,14 @@ BaseType_t xPortStartScheduler( void )
|
||||||
/* This is called with interrupts already disabled. */
|
/* This is called with interrupts already disabled. */
|
||||||
|
|
||||||
/* Remember what was on the interrupts we are going to use
|
/* Remember what was on the interrupts we are going to use
|
||||||
so we can put them back later if required. */
|
* so we can put them back later if required. */
|
||||||
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
||||||
|
|
||||||
/* Put our manual switch (yield) function on a known
|
/* Put our manual switch (yield) function on a known
|
||||||
vector. */
|
* vector. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||||
|
|
||||||
#if( configUSE_PREEMPTION == 1 )
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
{
|
{
|
||||||
/* Put our tick switch function on the timer interrupt. */
|
/* Put our tick switch function on the timer interrupt. */
|
||||||
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
||||||
|
|
@ -142,8 +144,8 @@ BaseType_t xPortStartScheduler( void )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||||
is being used. */
|
* is being used. */
|
||||||
#if( configUSE_PREEMPTION == 1 )
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
static void __interrupt __far prvPreemptiveTick( void )
|
static void __interrupt __far prvPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Get the scheduler to update the task states following the tick. */
|
/* Get the scheduler to update the task states following the tick. */
|
||||||
|
|
@ -156,15 +158,15 @@ is being used. */
|
||||||
/* Reset the PIC ready for the next time. */
|
/* Reset the PIC ready for the next time. */
|
||||||
portRESET_PIC();
|
portRESET_PIC();
|
||||||
}
|
}
|
||||||
#else
|
#else /* if ( configUSE_PREEMPTION == 1 ) */
|
||||||
static void __interrupt __far prvNonPreemptiveTick( void )
|
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Same as preemptive tick, but the cooperative scheduler is being used
|
/* Same as preemptive tick, but the cooperative scheduler is being used
|
||||||
so we don't have to switch in the context of the next task. */
|
* so we don't have to switch in the context of the next task. */
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
portRESET_PIC();
|
portRESET_PIC();
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void __interrupt __far prvYieldProcessor( void )
|
static void __interrupt __far prvYieldProcessor( void )
|
||||||
|
|
@ -177,30 +179,31 @@ static void __interrupt __far prvYieldProcessor( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Jump back to the processor state prior to starting the
|
/* Jump back to the processor state prior to starting the
|
||||||
scheduler. This means we are not going to be using a
|
* scheduler. This means we are not going to be using a
|
||||||
task stack frame so the task can be deleted. */
|
* task stack frame so the task can be deleted. */
|
||||||
longjmp( xJumpBuf, 1 );
|
longjmp( xJumpBuf, 1 );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvExitFunction( void )
|
static void prvExitFunction( void )
|
||||||
{
|
{
|
||||||
const uint16_t usTimerDisable = 0x0000;
|
const uint16_t usTimerDisable = 0x0000;
|
||||||
uint16_t usTimer0Control;
|
uint16_t usTimer0Control;
|
||||||
|
|
||||||
/* Interrupts should be disabled here anyway - but no
|
/* Interrupts should be disabled here anyway - but no
|
||||||
harm in making sure. */
|
* harm in making sure. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( xSchedulerRunning == pdTRUE )
|
if( xSchedulerRunning == pdTRUE )
|
||||||
{
|
{
|
||||||
/* Put back the switch interrupt routines that was in place
|
/* Put back the switch interrupt routines that was in place
|
||||||
before the scheduler started. */
|
* before the scheduler started. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable the timer used for the tick to ensure the scheduler is
|
/* Disable the timer used for the tick to ensure the scheduler is
|
||||||
not called before restoring interrupts. There was previously nothing
|
* not called before restoring interrupts. There was previously nothing
|
||||||
on this timer so there is no old ISR to restore. */
|
* on this timer so there is no old ISR to restore. */
|
||||||
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerDisable );
|
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerDisable );
|
||||||
|
|
||||||
/* Restart the DOS tick. */
|
/* Restart the DOS tick. */
|
||||||
|
|
@ -215,18 +218,18 @@ uint16_t usTimer0Control;
|
||||||
|
|
||||||
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
||||||
{
|
{
|
||||||
const uint16_t usMaxCountRegister = 0xff5a;
|
const uint16_t usMaxCountRegister = 0xff5a;
|
||||||
const uint16_t usTimerPriorityRegister = 0xff32;
|
const uint16_t usTimerPriorityRegister = 0xff32;
|
||||||
const uint16_t usTimerEnable = 0xC000;
|
const uint16_t usTimerEnable = 0xC000;
|
||||||
const uint16_t usRetrigger = 0x0001;
|
const uint16_t usRetrigger = 0x0001;
|
||||||
const uint16_t usTimerHighPriority = 0x0000;
|
const uint16_t usTimerHighPriority = 0x0000;
|
||||||
uint16_t usTimer0Control;
|
uint16_t usTimer0Control;
|
||||||
|
|
||||||
/* ( CPU frequency / 4 ) / clock 2 max count [inpw( 0xff62 ) = 7] */
|
/* ( CPU frequency / 4 ) / clock 2 max count [inpw( 0xff62 ) = 7] */
|
||||||
|
|
||||||
const uint32_t ulClockFrequency = ( uint32_t ) 0x7f31a0UL;
|
const uint32_t ulClockFrequency = ( uint32_t ) 0x7f31a0UL;
|
||||||
|
|
||||||
uint32_t ulTimerCount = ulClockFrequency / ulTickRateHz;
|
uint32_t ulTimerCount = ulClockFrequency / ulTickRateHz;
|
||||||
|
|
||||||
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerEnable | portTIMER_INTERRUPT_ENABLE | usRetrigger );
|
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerEnable | portTIMER_INTERRUPT_ENABLE | usRetrigger );
|
||||||
portOUTPUT_WORD( usMaxCountRegister, ( uint16_t ) ulTimerCount );
|
portOUTPUT_WORD( usMaxCountRegister, ( uint16_t ) ulTimerCount );
|
||||||
|
|
@ -240,4 +243,3 @@ uint32_t ulTimerCount = ulClockFrequency / ulTickRateHz;
|
||||||
|
|
||||||
|
|
||||||
/*lint +e950 */
|
/*lint +e950 */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ typedef portSTACK_TYPE StackType_t;
|
||||||
typedef short BaseType_t;
|
typedef short BaseType_t;
|
||||||
typedef unsigned short UBaseType_t;
|
typedef unsigned short UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
|
|
@ -60,7 +60,8 @@ typedef unsigned short UBaseType_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section handling. */
|
/* Critical section handling. */
|
||||||
#define portENTER_CRITICAL() __asm{ pushf } \
|
#define portENTER_CRITICAL() \
|
||||||
|
__asm{ pushf } \
|
||||||
__asm{ cli } \
|
__asm{ cli } \
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() __asm{ popf }
|
#define portEXIT_CRITICAL() __asm{ popf }
|
||||||
|
|
@ -89,8 +90,7 @@ typedef unsigned short UBaseType_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,16 +25,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V2.6.1
|
* Changes from V2.6.1
|
||||||
|
*
|
||||||
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
||||||
macro to be consistent with the later ports.
|
+ macro to be consistent with the later ports.
|
||||||
|
+
|
||||||
Changes from V4.0.1
|
+ Changes from V4.0.1
|
||||||
|
+
|
||||||
+ Add function prvSetTickFrequencyDefault() to set the DOS tick back to
|
+ Add function prvSetTickFrequencyDefault() to set the DOS tick back to
|
||||||
its proper value when the scheduler exits.
|
+ its proper value when the scheduler exits.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
|
|
@ -45,9 +45,9 @@ Changes from V4.0.1
|
||||||
#include "portasm.h"
|
#include "portasm.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the industrial
|
* Implementation of functions defined in portable.h for the industrial
|
||||||
* PC port.
|
* PC port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/*lint -e950 Non ANSI reserved words okay in this file only. */
|
/*lint -e950 Non ANSI reserved words okay in this file only. */
|
||||||
|
|
||||||
|
|
@ -60,19 +60,21 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz );
|
||||||
static void prvExitFunction( void );
|
static void prvExitFunction( void );
|
||||||
|
|
||||||
/* Either chain to the DOS tick (which itself clears the PIC) or clear the PIC
|
/* Either chain to the DOS tick (which itself clears the PIC) or clear the PIC
|
||||||
directly. We chain to the DOS tick as close as possible to the standard DOS
|
* directly. We chain to the DOS tick as close as possible to the standard DOS
|
||||||
tick rate. */
|
* tick rate. */
|
||||||
static void prvPortResetPIC( void );
|
static void prvPortResetPIC( void );
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative
|
/* The ISR used depends on whether the preemptive or cooperative
|
||||||
scheduler is being used. */
|
* scheduler is being used. */
|
||||||
#if( configUSE_PREEMPTION == 1 )
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
|
||||||
being used. */
|
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||||
|
* being used. */
|
||||||
static void __interrupt __far prvPreemptiveTick( void );
|
static void __interrupt __far prvPreemptiveTick( void );
|
||||||
#else
|
#else
|
||||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
|
||||||
being used. */
|
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||||
|
* being used. */
|
||||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -80,7 +82,7 @@ scheduler is being used. */
|
||||||
static void __interrupt __far prvYieldProcessor( void );
|
static void __interrupt __far prvYieldProcessor( void );
|
||||||
|
|
||||||
/* Set the tick frequency back so the floppy drive works correctly when the
|
/* Set the tick frequency back so the floppy drive works correctly when the
|
||||||
scheduler exits. */
|
* scheduler exits. */
|
||||||
static void prvSetTickFrequencyDefault( void );
|
static void prvSetTickFrequencyDefault( void );
|
||||||
|
|
||||||
/*lint -e956 File scopes necessary here. */
|
/*lint -e956 File scopes necessary here. */
|
||||||
|
|
@ -92,10 +94,10 @@ static int16_t sDOSTickCounter;
|
||||||
static BaseType_t xSchedulerRunning = pdFALSE;
|
static BaseType_t xSchedulerRunning = pdFALSE;
|
||||||
|
|
||||||
/* Points to the original routine installed on the vector we use for manual context switches. This is then used to restore the original routine during prvExitFunction(). */
|
/* Points to the original routine installed on the vector we use for manual context switches. This is then used to restore the original routine during prvExitFunction(). */
|
||||||
static void ( __interrupt __far *pxOldSwitchISR )();
|
static void( __interrupt __far * pxOldSwitchISR )();
|
||||||
|
|
||||||
/* Points to the original routine installed on the vector we use to chain to the DOS tick. This is then used to restore the original routine during prvExitFunction(). */
|
/* Points to the original routine installed on the vector we use to chain to the DOS tick. This is then used to restore the original routine during prvExitFunction(). */
|
||||||
static void ( __interrupt __far *pxOldSwitchISRPlus1 )();
|
static void( __interrupt __far * pxOldSwitchISRPlus1 )();
|
||||||
|
|
||||||
/* Used to restore the original DOS context when the scheduler is ended. */
|
/* Used to restore the original DOS context when the scheduler is ended. */
|
||||||
static jmp_buf xJumpBuf;
|
static jmp_buf xJumpBuf;
|
||||||
|
|
@ -105,12 +107,12 @@ static jmp_buf xJumpBuf;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
pxISR pxOriginalTickISR;
|
pxISR pxOriginalTickISR;
|
||||||
|
|
||||||
/* This is called with interrupts already disabled. */
|
/* This is called with interrupts already disabled. */
|
||||||
|
|
||||||
/* Remember what was on the interrupts we are going to use
|
/* Remember what was on the interrupts we are going to use
|
||||||
so we can put them back later if required. */
|
* so we can put them back later if required. */
|
||||||
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
||||||
pxOriginalTickISR = _dos_getvect( portTIMER_INT_NUMBER );
|
pxOriginalTickISR = _dos_getvect( portTIMER_INT_NUMBER );
|
||||||
pxOldSwitchISRPlus1 = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
|
pxOldSwitchISRPlus1 = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
|
||||||
|
|
@ -118,16 +120,16 @@ pxISR pxOriginalTickISR;
|
||||||
prvSetTickFrequency( configTICK_RATE_HZ );
|
prvSetTickFrequency( configTICK_RATE_HZ );
|
||||||
|
|
||||||
/* Put our manual switch (yield) function on a known
|
/* Put our manual switch (yield) function on a known
|
||||||
vector. */
|
* vector. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||||
|
|
||||||
/* Put the old tick on a different interrupt number so we can
|
/* Put the old tick on a different interrupt number so we can
|
||||||
call it when we want. */
|
* call it when we want. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOriginalTickISR );
|
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOriginalTickISR );
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative
|
/* The ISR used depends on whether the preemptive or cooperative
|
||||||
scheduler is being used. */
|
* scheduler is being used. */
|
||||||
#if( configUSE_PREEMPTION == 1 )
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
{
|
{
|
||||||
/* Put our tick switch function on the timer interrupt. */
|
/* Put our tick switch function on the timer interrupt. */
|
||||||
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
||||||
|
|
@ -140,8 +142,8 @@ pxISR pxOriginalTickISR;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Setup a counter that is used to call the DOS interrupt as close
|
/* Setup a counter that is used to call the DOS interrupt as close
|
||||||
to it's original frequency as can be achieved given our chosen tick
|
* to it's original frequency as can be achieved given our chosen tick
|
||||||
frequency. */
|
* frequency. */
|
||||||
sDOSTickCounter = portTICKS_PER_DOS_TICK;
|
sDOSTickCounter = portTICKS_PER_DOS_TICK;
|
||||||
|
|
||||||
/* Clean up function if we want to return to DOS. */
|
/* Clean up function if we want to return to DOS. */
|
||||||
|
|
@ -163,8 +165,8 @@ pxISR pxOriginalTickISR;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The ISR used depends on whether the preemptive or cooperative
|
/* The ISR used depends on whether the preemptive or cooperative
|
||||||
scheduler is being used. */
|
* scheduler is being used. */
|
||||||
#if( configUSE_PREEMPTION == 1 )
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
static void __interrupt __far prvPreemptiveTick( void )
|
static void __interrupt __far prvPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Get the scheduler to update the task states following the tick. */
|
/* Get the scheduler to update the task states following the tick. */
|
||||||
|
|
@ -177,15 +179,15 @@ scheduler is being used. */
|
||||||
/* Reset the PIC ready for the next time. */
|
/* Reset the PIC ready for the next time. */
|
||||||
prvPortResetPIC();
|
prvPortResetPIC();
|
||||||
}
|
}
|
||||||
#else
|
#else /* if ( configUSE_PREEMPTION == 1 ) */
|
||||||
static void __interrupt __far prvNonPreemptiveTick( void )
|
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Same as preemptive tick, but the cooperative scheduler is being used
|
/* Same as preemptive tick, but the cooperative scheduler is being used
|
||||||
so we don't have to switch in the context of the next task. */
|
* so we don't have to switch in the context of the next task. */
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
prvPortResetPIC();
|
prvPortResetPIC();
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void __interrupt __far prvYieldProcessor( void )
|
static void __interrupt __far prvYieldProcessor( void )
|
||||||
|
|
@ -198,19 +200,22 @@ static void __interrupt __far prvYieldProcessor( void )
|
||||||
static void prvPortResetPIC( void )
|
static void prvPortResetPIC( void )
|
||||||
{
|
{
|
||||||
/* We are going to call the DOS tick interrupt at as close a
|
/* We are going to call the DOS tick interrupt at as close a
|
||||||
frequency to the normal DOS tick as possible. */
|
* frequency to the normal DOS tick as possible. */
|
||||||
|
|
||||||
/* WE SHOULD NOT DO THIS IF YIELD WAS CALLED. */
|
/* WE SHOULD NOT DO THIS IF YIELD WAS CALLED. */
|
||||||
--sDOSTickCounter;
|
--sDOSTickCounter;
|
||||||
|
|
||||||
if( sDOSTickCounter <= 0 )
|
if( sDOSTickCounter <= 0 )
|
||||||
{
|
{
|
||||||
sDOSTickCounter = ( int16_t ) portTICKS_PER_DOS_TICK;
|
sDOSTickCounter = ( int16_t ) portTICKS_PER_DOS_TICK;
|
||||||
__asm{ int portSWITCH_INT_NUMBER + 1 };
|
__asm {
|
||||||
|
int portSWITCH_INT_NUMBER + 1
|
||||||
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Reset the PIC as the DOS tick is not being called to
|
/* Reset the PIC as the DOS tick is not being called to
|
||||||
do it. */
|
* do it. */
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
mov al, 20H
|
mov al, 20H
|
||||||
|
|
@ -223,19 +228,20 @@ static void prvPortResetPIC( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Jump back to the processor state prior to starting the
|
/* Jump back to the processor state prior to starting the
|
||||||
scheduler. This means we are not going to be using a
|
* scheduler. This means we are not going to be using a
|
||||||
task stack frame so the task can be deleted. */
|
* task stack frame so the task can be deleted. */
|
||||||
longjmp( xJumpBuf, 1 );
|
longjmp( xJumpBuf, 1 );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvExitFunction( void )
|
static void prvExitFunction( void )
|
||||||
{
|
{
|
||||||
void ( __interrupt __far *pxOriginalTickISR )();
|
void( __interrupt __far * pxOriginalTickISR )();
|
||||||
|
|
||||||
/* Interrupts should be disabled here anyway - but no
|
/* Interrupts should be disabled here anyway - but no
|
||||||
harm in making sure. */
|
* harm in making sure. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( xSchedulerRunning == pdTRUE )
|
if( xSchedulerRunning == pdTRUE )
|
||||||
{
|
{
|
||||||
/* Set the DOS tick back onto the timer ticker. */
|
/* Set the DOS tick back onto the timer ticker. */
|
||||||
|
|
@ -244,28 +250,29 @@ void ( __interrupt __far *pxOriginalTickISR )();
|
||||||
prvSetTickFrequencyDefault();
|
prvSetTickFrequencyDefault();
|
||||||
|
|
||||||
/* Put back the switch interrupt routines that was in place
|
/* Put back the switch interrupt routines that was in place
|
||||||
before the scheduler started. */
|
* before the scheduler started. */
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
||||||
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOldSwitchISRPlus1 );
|
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOldSwitchISRPlus1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The tick timer is back how DOS wants it. We can re-enable
|
/* The tick timer is back how DOS wants it. We can re-enable
|
||||||
interrupts without the scheduler being called. */
|
* interrupts without the scheduler being called. */
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
||||||
{
|
{
|
||||||
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
||||||
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
||||||
const uint32_t ulPIT_CONST = ( uint32_t ) 1193180UL;
|
const uint32_t ulPIT_CONST = ( uint32_t ) 1193180UL;
|
||||||
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
||||||
uint32_t ulOutput;
|
uint32_t ulOutput;
|
||||||
|
|
||||||
/* Setup the 8245 to tick at the wanted frequency. */
|
/* Setup the 8245 to tick at the wanted frequency. */
|
||||||
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
||||||
ulOutput = ulPIT_CONST / ulTickRateHz;
|
ulOutput = ulPIT_CONST / ulTickRateHz;
|
||||||
portOUTPUT_BYTE( usPIT0, ( uint16_t )( ulOutput & ( uint32_t ) 0xff ) );
|
portOUTPUT_BYTE( usPIT0, ( uint16_t ) ( ulOutput & ( uint32_t ) 0xff ) );
|
||||||
ulOutput >>= 8;
|
ulOutput >>= 8;
|
||||||
portOUTPUT_BYTE( usPIT0, ( uint16_t ) ( ulOutput & ( uint32_t ) 0xff ) );
|
portOUTPUT_BYTE( usPIT0, ( uint16_t ) ( ulOutput & ( uint32_t ) 0xff ) );
|
||||||
}
|
}
|
||||||
|
|
@ -273,15 +280,14 @@ uint32_t ulOutput;
|
||||||
|
|
||||||
static void prvSetTickFrequencyDefault( void )
|
static void prvSetTickFrequencyDefault( void )
|
||||||
{
|
{
|
||||||
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
||||||
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
||||||
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
||||||
|
|
||||||
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
||||||
portOUTPUT_BYTE( usPIT0,0 );
|
portOUTPUT_BYTE( usPIT0, 0 );
|
||||||
portOUTPUT_BYTE( usPIT0,0 );
|
portOUTPUT_BYTE( usPIT0, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*lint +e950 */
|
/*lint +e950 */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ typedef portSTACK_TYPE StackType_t;
|
||||||
typedef short BaseType_t;
|
typedef short BaseType_t;
|
||||||
typedef unsigned short UBaseType_t;
|
typedef unsigned short UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
|
|
@ -60,7 +60,8 @@ typedef unsigned short UBaseType_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
#define portENTER_CRITICAL() __asm{ pushf } \
|
#define portENTER_CRITICAL() \
|
||||||
|
__asm{ pushf } \
|
||||||
__asm{ cli } \
|
__asm{ cli } \
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() __asm{ popf }
|
#define portEXIT_CRITICAL() __asm{ popf }
|
||||||
|
|
@ -89,8 +90,7 @@ typedef unsigned short UBaseType_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vTaskFunction, pvParameters ) void vTaskFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void * pvParameters )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,16 +46,16 @@ void portSWITCH_CONTEXT( void );
|
||||||
void portFIRST_CONTEXT( void );
|
void portFIRST_CONTEXT( void );
|
||||||
|
|
||||||
/* There are slightly different versions depending on whether you are building
|
/* There are slightly different versions depending on whether you are building
|
||||||
to include debugger information. If debugger information is used then there
|
* to include debugger information. If debugger information is used then there
|
||||||
are a couple of extra bytes left of the ISR stack (presumably for use by the
|
* are a couple of extra bytes left of the ISR stack (presumably for use by the
|
||||||
debugger). The true stack pointer is then stored in the bp register. We add
|
* debugger). The true stack pointer is then stored in the bp register. We add
|
||||||
2 to the stack pointer to remove the extra bytes before we restore our context. */
|
* 2 to the stack pointer to remove the extra bytes before we restore our context. */
|
||||||
|
|
||||||
#define portSWITCH_CONTEXT() \
|
#define portSWITCH_CONTEXT() \
|
||||||
asm { mov ax, seg pxCurrentTCB } \
|
asm { mov ax, seg pxCurrentTCB } \
|
||||||
asm { mov ds, ax } \
|
asm { mov ds, ax } \
|
||||||
asm { les bx, pxCurrentTCB } /* Save the stack pointer into the TCB. */ \
|
asm { les bx, pxCurrentTCB } /* Save the stack pointer into the TCB. */ \
|
||||||
asm { mov es:0x2[ bx ], ss } \
|
asm { mov es : 0x2[ bx ], ss } \
|
||||||
asm { mov es:[ bx ], sp } \
|
asm { mov es:[ bx ], sp } \
|
||||||
asm { call far ptr vTaskSwitchContext } /* Perform the switch. */ \
|
asm { call far ptr vTaskSwitchContext } /* Perform the switch. */ \
|
||||||
asm { mov ax, seg pxCurrentTCB } /* Restore the stack pointer from the TCB. */ \
|
asm { mov ax, seg pxCurrentTCB } /* Restore the stack pointer from the TCB. */ \
|
||||||
|
|
@ -82,5 +82,4 @@ debugger). The true stack pointer is then stored in the bp register. We add
|
||||||
__asm { iret }
|
__asm { iret }
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif /* ifndef PORT_ASM_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,16 +25,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V1.00:
|
* Changes from V1.00:
|
||||||
|
*
|
||||||
+ pxPortInitialiseStack() now initialises the stack of new tasks to the
|
+ pxPortInitialiseStack() now initialises the stack of new tasks to the
|
||||||
same format used by the compiler. This allows the compiler generated
|
+ same format used by the compiler. This allows the compiler generated
|
||||||
interrupt mechanism to be used for context switches.
|
+ interrupt mechanism to be used for context switches.
|
||||||
|
+
|
||||||
Changes from V2.6.1
|
+ Changes from V2.6.1
|
||||||
|
+
|
||||||
+ Move usPortCheckFreeStackSpace() to tasks.c.
|
+ Move usPortCheckFreeStackSpace() to tasks.c.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
|
|
@ -44,12 +44,14 @@ Changes from V2.6.1
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* See header file for description. */
|
/* See header file for description. */
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
StackType_t DS_Reg = 0;
|
StackType_t DS_Reg = 0;
|
||||||
|
|
||||||
/* 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. */
|
* This is just useful for debugging. */
|
||||||
|
|
||||||
*pxTopOfStack = 0x1111;
|
*pxTopOfStack = 0x1111;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
@ -66,8 +68,8 @@ StackType_t DS_Reg = 0;
|
||||||
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
||||||
|
|
||||||
/* We are going to start the scheduler using a return from interrupt
|
/* We are going to start the scheduler using a return from interrupt
|
||||||
instruction to load the program counter, so first there would be the
|
* instruction to load the program counter, so first there would be the
|
||||||
function call with parameters preamble. */
|
* function call with parameters preamble. */
|
||||||
|
|
||||||
*pxTopOfStack = FP_SEG( pvParameters );
|
*pxTopOfStack = FP_SEG( pvParameters );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
@ -87,8 +89,8 @@ StackType_t DS_Reg = 0;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The remaining registers would be pushed on the stack by our context
|
/* The remaining registers would be pushed on the stack by our context
|
||||||
switch function. These are loaded with values simply to make debugging
|
* switch function. These are loaded with values simply to make debugging
|
||||||
easier. */
|
* easier. */
|
||||||
*pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */
|
*pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */
|
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */
|
||||||
|
|
@ -101,7 +103,9 @@ StackType_t DS_Reg = 0;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* We need the true data segment. */
|
/* We need the true data segment. */
|
||||||
__asm{ MOV DS_Reg, DS };
|
__asm {
|
||||||
|
MOV DS_Reg, DS
|
||||||
|
};
|
||||||
|
|
||||||
*pxTopOfStack = DS_Reg; /* DS */
|
*pxTopOfStack = DS_Reg; /* DS */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
@ -116,4 +120,3 @@ StackType_t DS_Reg = 0;
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,15 +25,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM CM4F port.
|
* Implementation of functions defined in portable.h for the ARM CM4F port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#if( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 )
|
#if ( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 )
|
||||||
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html
|
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configSYSTICK_CLOCK_HZ
|
#ifndef configSYSTICK_CLOCK_HZ
|
||||||
|
|
@ -41,16 +41,17 @@
|
||||||
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
#else
|
#else
|
||||||
/* The way the SysTick is clocked is not modified in case it is not the same
|
|
||||||
as the core. */
|
/* 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 )
|
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Constants required to manipulate the core. Registers first... */
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
|
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||||
#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) )
|
#define portNVIC_SYSPRI2_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
/* ...then bits in the registers. */
|
/* ...then bits in the registers. */
|
||||||
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||||
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
@ -64,7 +65,7 @@
|
||||||
/* Constants required to check the validity of an interrupt priority. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) )
|
#define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) )
|
||||||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||||
#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 )
|
#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 )
|
||||||
#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 )
|
#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 )
|
||||||
|
|
@ -81,12 +82,12 @@
|
||||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
||||||
|
|
||||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
/* A fiddle factor to estimate the number of SysTick counts that would have
|
||||||
occurred while the SysTick counter is stopped during tickless idle
|
* occurred while the SysTick counter is stopped during tickless idle
|
||||||
calculations. */
|
* calculations. */
|
||||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
||||||
|
|
||||||
/* For strict compliance with the Cortex-M spec the task start address should
|
/* For strict compliance with the Cortex-M spec the task start address should
|
||||||
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
* have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||||
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -114,17 +115,17 @@ static void prvTaskExitError( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY
|
/* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
setting. */
|
* setting. */
|
||||||
const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
||||||
|
|
||||||
/* Each task maintains its own interrupt status in the critical nesting
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
variable. */
|
* variable. */
|
||||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The number of SysTick increments that make up one tick period.
|
* The number of SysTick increments that make up one tick period.
|
||||||
*/
|
*/
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static uint32_t ulTimerCountsForOneTick = 0;
|
static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
|
@ -132,7 +133,7 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
* The maximum number of tick periods that can be suppressed is limited by the
|
* The maximum number of tick periods that can be suppressed is limited by the
|
||||||
* 24 bit resolution of the SysTick timer.
|
* 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
|
@ -140,7 +141,7 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
||||||
* power functionality only.
|
* power functionality only.
|
||||||
*/
|
*/
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static uint32_t ulStoppedTimerCompensation = 0;
|
static uint32_t ulStoppedTimerCompensation = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
|
@ -165,10 +166,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
void * pvParameters )
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
interrupt. */
|
* interrupt. */
|
||||||
|
|
||||||
/* Offset added to account for the way the MCU uses the stack on entry/exit
|
/* Offset added to account for the way the MCU uses the stack on entry/exit
|
||||||
of interrupts, and to ensure alignment. */
|
* of interrupts, and to ensure alignment. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||||
|
|
@ -190,14 +191,17 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* 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
|
* its caller as there is nothing to return to. If a task wants to exit it
|
||||||
should instead call vTaskDelete( NULL ).
|
* should instead call vTaskDelete( NULL ).
|
||||||
|
*
|
||||||
Artificially force an assert() to be triggered if configASSERT() is
|
* Artificially force an assert() to be triggered if configASSERT() is
|
||||||
defined, then stop here so application writers can catch the error. */
|
* defined, then stop here so application writers can catch the error. */
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
configASSERT( uxCriticalNesting == ~0UL );
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
for( ;; );
|
|
||||||
|
for( ; ; )
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -206,22 +210,22 @@ static void prvTaskExitError( void )
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
volatile uint32_t ulOriginalPriority;
|
||||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
"FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
|
*
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
* Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
/* Determine the number of priority bits available. First write to all
|
||||||
possible bits. */
|
* possible bits. */
|
||||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
|
@ -231,8 +235,9 @@ BaseType_t xPortStartScheduler( void )
|
||||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
of bits read back. */
|
* of bits read back. */
|
||||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulMaxPRIGROUPValue--;
|
ulMaxPRIGROUPValue--;
|
||||||
|
|
@ -242,8 +247,8 @@ BaseType_t xPortStartScheduler( void )
|
||||||
#ifdef __NVIC_PRIO_BITS
|
#ifdef __NVIC_PRIO_BITS
|
||||||
{
|
{
|
||||||
/* Check the CMSIS configuration that defines the number of
|
/* Check the CMSIS configuration that defines the number of
|
||||||
priority bits matches the number of priority bits actually queried
|
* priority bits matches the number of priority bits actually queried
|
||||||
from the hardware. */
|
* from the hardware. */
|
||||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -251,19 +256,19 @@ BaseType_t xPortStartScheduler( void )
|
||||||
#ifdef configPRIO_BITS
|
#ifdef configPRIO_BITS
|
||||||
{
|
{
|
||||||
/* Check the FreeRTOS configuration that defines the number of
|
/* Check the FreeRTOS configuration that defines the number of
|
||||||
priority bits matches the number of priority bits actually queried
|
* priority bits matches the number of priority bits actually queried
|
||||||
from the hardware. */
|
* from the hardware. */
|
||||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
|
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Shift the priority group value back to its position within the AIRCR
|
/* Shift the priority group value back to its position within the AIRCR
|
||||||
register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
* value. */
|
||||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||||
}
|
}
|
||||||
#endif /* conifgASSERT_DEFINED */
|
#endif /* conifgASSERT_DEFINED */
|
||||||
|
|
@ -273,7 +278,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
here already. */
|
* here already. */
|
||||||
vPortSetupTimerInterrupt();
|
vPortSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Initialise the critical nesting count ready for the first task. */
|
/* Initialise the critical nesting count ready for the first task. */
|
||||||
|
|
@ -290,7 +295,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Not implemented in ports where there is nothing to return to.
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
Artificially force an assert. */
|
* Artificially force an assert. */
|
||||||
configASSERT( uxCriticalNesting == 1000UL );
|
configASSERT( uxCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -301,10 +306,10 @@ void vPortEnterCritical( void )
|
||||||
uxCriticalNesting++;
|
uxCriticalNesting++;
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
assert() if it is being called from an interrupt context. Only API
|
* assert() if it is being called from an interrupt context. Only API
|
||||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||||
the critical nesting count is 1 to protect against recursive calls if the
|
* the critical nesting count is 1 to protect against recursive calls if the
|
||||||
assert function also uses a critical section. */
|
* assert function also uses a critical section. */
|
||||||
if( uxCriticalNesting == 1 )
|
if( uxCriticalNesting == 1 )
|
||||||
{
|
{
|
||||||
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
||||||
|
|
@ -316,6 +321,7 @@ void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
configASSERT( uxCriticalNesting );
|
configASSERT( uxCriticalNesting );
|
||||||
uxCriticalNesting--;
|
uxCriticalNesting--;
|
||||||
|
|
||||||
if( uxCriticalNesting == 0 )
|
if( uxCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
@ -326,16 +332,16 @@ void vPortExitCritical( void )
|
||||||
void xPortSysTickHandler( void )
|
void xPortSysTickHandler( void )
|
||||||
{
|
{
|
||||||
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
||||||
executes all interrupts must be unmasked. There is therefore no need to
|
* 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
|
* save and then restore the interrupt mask value as its value is already
|
||||||
known. */
|
* known. */
|
||||||
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
/* Increment the RTOS tick. */
|
/* Increment the RTOS tick. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
{
|
{
|
||||||
/* A context switch is required. Context switching is performed in
|
/* A context switch is required. Context switching is performed in
|
||||||
the PendSV interrupt. Pend the PendSV interrupt. */
|
* the PendSV interrupt. Pend the PendSV interrupt. */
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -343,7 +349,7 @@ void xPortSysTickHandler( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
|
|
||||||
#pragma WEAK( vPortSuppressTicksAndSleep )
|
#pragma WEAK( vPortSuppressTicksAndSleep )
|
||||||
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||||
|
|
@ -358,45 +364,45 @@ void xPortSysTickHandler( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop the SysTick momentarily. The time the SysTick is stopped for
|
/* 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
|
* 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
|
* inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
* kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||||
tick periods. -1 is used because this code will execute part way
|
* tick periods. -1 is used because this code will execute part way
|
||||||
through one of the tick periods. */
|
* through one of the tick periods. */
|
||||||
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
||||||
|
|
||||||
if( ulReloadValue > ulStoppedTimerCompensation )
|
if( ulReloadValue > ulStoppedTimerCompensation )
|
||||||
{
|
{
|
||||||
ulReloadValue -= ulStoppedTimerCompensation;
|
ulReloadValue -= ulStoppedTimerCompensation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||||
method as that will mask interrupts that should exit sleep mode. */
|
* method as that will mask interrupts that should exit sleep mode. */
|
||||||
__asm( " cpsid i" );
|
__asm( " cpsid i");
|
||||||
__asm( " dsb" );
|
__asm( " dsb");
|
||||||
__asm( " isb" );
|
__asm( " isb");
|
||||||
|
|
||||||
|
|
||||||
/* If a context switch is pending or a task is waiting for the scheduler
|
/* If a context switch is pending or a task is waiting for the scheduler
|
||||||
to be unsuspended then abandon the low power entry. */
|
* to be unsuspended then abandon the low power entry. */
|
||||||
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
||||||
{
|
{
|
||||||
/* Restart from whatever is left in the count register to complete
|
/* Restart from whatever is left in the count register to complete
|
||||||
this tick period. */
|
* this tick period. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
/* Reset the reload register to the value required for normal tick
|
||||||
periods. */
|
* periods. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_interrupt()
|
/* Re-enable interrupts - see comments above __disable_interrupt()
|
||||||
call above. */
|
* call above. */
|
||||||
__asm( " cpsie i" );
|
__asm( " cpsie i");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -404,69 +410,71 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
||||||
|
|
||||||
/* Clear the SysTick count flag and set the count value back to
|
/* Clear the SysTick count flag and set the count value back to
|
||||||
zero. */
|
* zero. */
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
* set its parameter to 0 to indicate that its implementation contains
|
||||||
its own wait for interrupt or wait for event instruction, and so wfi
|
* its own wait for interrupt or wait for event instruction, and so wfi
|
||||||
should not be executed again. However, the original expected idle
|
* should not be executed again. However, the original expected idle
|
||||||
time variable must remain unmodified, so a copy is taken. */
|
* time variable must remain unmodified, so a copy is taken. */
|
||||||
xModifiableIdleTime = xExpectedIdleTime;
|
xModifiableIdleTime = xExpectedIdleTime;
|
||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||||
|
|
||||||
if( xModifiableIdleTime > 0 )
|
if( xModifiableIdleTime > 0 )
|
||||||
{
|
{
|
||||||
__asm( " dsb" );
|
__asm( " dsb");
|
||||||
__asm( " wfi" );
|
__asm( " wfi");
|
||||||
__asm( " isb" );
|
__asm( " isb");
|
||||||
}
|
}
|
||||||
|
|
||||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
|
||||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||||
out of sleep mode to execute immediately. see comments above
|
* out of sleep mode to execute immediately. see comments above
|
||||||
__disable_interrupt() call above. */
|
* __disable_interrupt() call above. */
|
||||||
__asm( " cpsie i" );
|
__asm( " cpsie i");
|
||||||
__asm( " dsb" );
|
__asm( " dsb");
|
||||||
__asm( " isb" );
|
__asm( " isb");
|
||||||
|
|
||||||
/* Disable interrupts again because the clock is about to be stopped
|
/* Disable interrupts again because the clock is about to be stopped
|
||||||
and interrupts that execute while the clock is stopped will increase
|
* and interrupts that execute while the clock is stopped will increase
|
||||||
any slippage between the time maintained by the RTOS and calendar
|
* any slippage between the time maintained by the RTOS and calendar
|
||||||
time. */
|
* time. */
|
||||||
__asm( " cpsid i" );
|
__asm( " cpsid i");
|
||||||
__asm( " dsb" );
|
__asm( " dsb");
|
||||||
__asm( " isb" );
|
__asm( " isb");
|
||||||
|
|
||||||
/* Disable the SysTick clock without reading the
|
/* Disable the SysTick clock without reading the
|
||||||
portNVIC_SYSTICK_CTRL_REG register to ensure the
|
* portNVIC_SYSTICK_CTRL_REG register to ensure the
|
||||||
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
|
* portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
|
||||||
the time the SysTick is stopped for is accounted for as best it can
|
* 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
|
* be, but using the tickless mode will inevitably result in some tiny
|
||||||
drift of the time maintained by the kernel with respect to calendar
|
* drift of the time maintained by the kernel with respect to calendar
|
||||||
time*/
|
* time*/
|
||||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
|
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
|
||||||
|
|
||||||
/* Determine if the SysTick clock has already counted to zero and
|
/* Determine if the SysTick clock has already counted to zero and
|
||||||
been set back to the current reload value (the reload back being
|
* been set back to the current reload value (the reload back being
|
||||||
correct for the entire expected idle time) or if the SysTick is yet
|
* correct for the entire expected idle time) or if the SysTick is yet
|
||||||
to count to zero (in which case an interrupt other than the SysTick
|
* to count to zero (in which case an interrupt other than the SysTick
|
||||||
must have brought the system out of sleep mode). */
|
* must have brought the system out of sleep mode). */
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||||
{
|
{
|
||||||
uint32_t ulCalculatedLoadValue;
|
uint32_t ulCalculatedLoadValue;
|
||||||
|
|
||||||
/* The tick interrupt is already pending, and the SysTick count
|
/* The tick interrupt is already pending, and the SysTick count
|
||||||
reloaded with ulReloadValue. Reset the
|
* reloaded with ulReloadValue. Reset the
|
||||||
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
* portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
||||||
period. */
|
* period. */
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
||||||
|
|
||||||
/* Don't allow a tiny value, or values that have somehow
|
/* Don't allow a tiny value, or values that have somehow
|
||||||
underflowed because the post sleep hook did something
|
* underflowed because the post sleep hook did something
|
||||||
that took too long. */
|
* that took too long. */
|
||||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
||||||
{
|
{
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
||||||
|
|
@ -475,37 +483,37 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
||||||
|
|
||||||
/* As the pending tick will be processed as soon as this
|
/* As the pending tick will be processed as soon as this
|
||||||
function exits, the tick value maintained by the tick is stepped
|
* function exits, the tick value maintained by the tick is stepped
|
||||||
forward by one less than the time spent waiting. */
|
* forward by one less than the time spent waiting. */
|
||||||
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Something other than the tick interrupt ended the sleep.
|
/* Something other than the tick interrupt ended the sleep.
|
||||||
Work out how long the sleep lasted rounded to complete tick
|
* Work out how long the sleep lasted rounded to complete tick
|
||||||
periods (not the ulReload value which accounted for part
|
* periods (not the ulReload value which accounted for part
|
||||||
ticks). */
|
* ticks). */
|
||||||
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* How many complete tick periods passed while the processor
|
/* How many complete tick periods passed while the processor
|
||||||
was waiting? */
|
* was waiting? */
|
||||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
||||||
|
|
||||||
/* The reload value is set to whatever fraction of a single tick
|
/* The reload value is set to whatever fraction of a single tick
|
||||||
period remains. */
|
* period remains. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
||||||
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
* again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
||||||
value. */
|
* value. */
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
|
|
||||||
/* Exit with interrupts enabled. */
|
/* Exit with interrupts enabled. */
|
||||||
__asm( " cpsie i" );
|
__asm( " cpsie i");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -520,7 +528,7 @@ void xPortSysTickHandler( void )
|
||||||
void vPortSetupTimerInterrupt( void )
|
void vPortSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
/* Calculate the constants required to configure the tick interrupt. */
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
{
|
{
|
||||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||||
|
|
@ -538,7 +546,7 @@ void vPortSetupTimerInterrupt( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
void vPortValidateInterruptPriority( void )
|
||||||
{
|
{
|
||||||
|
|
@ -555,66 +563,45 @@ void vPortSetupTimerInterrupt( void )
|
||||||
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
|
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
|
||||||
|
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
/* The following assertion will fail if a service routine (ISR) for
|
||||||
an interrupt that has been assigned a priority above
|
* an interrupt that has been assigned a priority above
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||||
function. ISR safe FreeRTOS API functions must *only* be called
|
* function. ISR safe FreeRTOS API functions must *only* be called
|
||||||
from interrupts that have been assigned a priority at or below
|
* from interrupts that have been assigned a priority at or below
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
Numerically low interrupt priority numbers represent logically high
|
* Numerically low interrupt priority numbers represent logically high
|
||||||
interrupt priorities, therefore the priority of the interrupt must
|
* interrupt priorities, therefore the priority of the interrupt must
|
||||||
be set to a value equal to or numerically *higher* than
|
* be set to a value equal to or numerically *higher* than
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
Interrupts that use the FreeRTOS API must not be left at their
|
* Interrupts that use the FreeRTOS API must not be left at their
|
||||||
default priority of zero as that is the highest possible priority,
|
* default priority of zero as that is the highest possible priority,
|
||||||
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
* which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
||||||
and therefore also guaranteed to be invalid.
|
* and therefore also guaranteed to be invalid.
|
||||||
|
*
|
||||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||||
interrupt entry is as fast and simple as possible.
|
* interrupt entry is as fast and simple as possible.
|
||||||
|
*
|
||||||
The following links provide detailed information:
|
* The following links provide detailed information:
|
||||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html
|
* http://www.freertos.org/RTOS-Cortex-M3-M4.html
|
||||||
http://www.freertos.org/FAQHelp.html */
|
* http://www.freertos.org/FAQHelp.html */
|
||||||
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
|
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Priority grouping: The interrupt controller (NVIC) allows the bits
|
/* Priority grouping: The interrupt controller (NVIC) allows the bits
|
||||||
that define each interrupt's priority to be split between bits that
|
* that define each interrupt's priority to be split between bits that
|
||||||
define the interrupt's pre-emption priority bits and bits that define
|
* define the interrupt's pre-emption priority bits and bits that define
|
||||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
* the interrupt's sub-priority. For simplicity all bits must be defined
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
* to be pre-emption priority bits. The following assertion will fail if
|
||||||
this is not the case (if some bits represent a sub-priority).
|
* this is not the case (if some bits represent a sub-priority).
|
||||||
|
*
|
||||||
If the application only uses CMSIS libraries for interrupt
|
* If the application only uses CMSIS libraries for interrupt
|
||||||
configuration then the correct setting can be achieved on all Cortex-M
|
* configuration then the correct setting can be achieved on all Cortex-M
|
||||||
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
* devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||||
scheduler. Note however that some vendor specific peripheral libraries
|
* scheduler. Note however that some vendor specific peripheral libraries
|
||||||
assume a non-zero priority group setting, in which cases using a value
|
* assume a non-zero priority group setting, in which cases using a value
|
||||||
of zero will result in unpredictable behaviour. */
|
* of zero will result in unpredictable behaviour. */
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -43,128 +43,127 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Compiler directives. */
|
/* Compiler directives. */
|
||||||
#define portWEAK_SYMBOL __attribute__((weak))
|
#define portWEAK_SYMBOL __attribute__( ( weak ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
#define portYIELD() \
|
#define portYIELD() \
|
||||||
{ \
|
{ \
|
||||||
/* Set a PendSV to request a context switch. */ \
|
/* Set a PendSV to request a context switch. */ \
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
__asm( " dsb" ); \
|
__asm( " dsb"); \
|
||||||
__asm( " isb" ); \
|
__asm( " isb"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if( configMAX_PRIORITIES > 32 )
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
{ \
|
{ \
|
||||||
_set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \
|
_set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \
|
||||||
__asm( " dsb" ); \
|
__asm( " dsb"); \
|
||||||
__asm( " isb" ); \
|
__asm( " isb"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() _set_interrupt_priority( 0 )
|
#define portENABLE_INTERRUPTS() _set_interrupt_priority( 0 )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() _set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); __asm( " dsb" ); __asm( " isb" )
|
#define portSET_INTERRUPT_MASK_FROM_ISR() _set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); __asm( " dsb" ); __asm( " isb")
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) _set_interrupt_priority( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) _set_interrupt_priority( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
/* Tickless idle/low power functionality. */
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
not necessary for to use this port. They are defined so the common demo files
|
* not necessary for to use this port. They are defined so the common demo files
|
||||||
(which build with all the ports) will build. */
|
* (which build with all the ports) will build. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* portNOP() is not required by this port. */
|
/* portNOP() is not required by this port. */
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM CM4F port.
|
* Implementation of functions defined in portable.h for the ARM CM4F port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
|
@ -36,8 +36,8 @@
|
||||||
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 )
|
#if ( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 )
|
||||||
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html
|
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configSYSTICK_CLOCK_HZ
|
#ifndef configSYSTICK_CLOCK_HZ
|
||||||
|
|
@ -45,16 +45,17 @@
|
||||||
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
#else
|
#else
|
||||||
/* The way the SysTick is clocked is not modified in case it is not the same
|
|
||||||
as the core. */
|
/* 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 )
|
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Constants required to manipulate the core. Registers first... */
|
/* Constants required to manipulate the core. Registers first... */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
|
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||||
#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) )
|
#define portNVIC_SYSPRI2_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
/* ...then bits in the registers. */
|
/* ...then bits in the registers. */
|
||||||
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||||
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
@ -68,7 +69,7 @@
|
||||||
/* Constants required to check the validity of an interrupt priority. */
|
/* Constants required to check the validity of an interrupt priority. */
|
||||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||||
#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) )
|
#define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) )
|
||||||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||||
#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 )
|
#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 )
|
||||||
#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 )
|
#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 )
|
||||||
|
|
@ -90,12 +91,12 @@
|
||||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
||||||
|
|
||||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
/* A fiddle factor to estimate the number of SysTick counts that would have
|
||||||
occurred while the SysTick counter is stopped during tickless idle
|
* occurred while the SysTick counter is stopped during tickless idle
|
||||||
calculations. */
|
* calculations. */
|
||||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
||||||
|
|
||||||
/* For strict compliance with the Cortex-M spec the task start address should
|
/* For strict compliance with the Cortex-M spec the task start address should
|
||||||
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
* have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||||
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -128,17 +129,17 @@ static void prvTaskExitError( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY
|
/* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
setting. */
|
* setting. */
|
||||||
const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
||||||
|
|
||||||
/* Each task maintains its own interrupt status in the critical nesting
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
variable. */
|
* variable. */
|
||||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The number of SysTick increments that make up one tick period.
|
* The number of SysTick increments that make up one tick period.
|
||||||
*/
|
*/
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static uint32_t ulTimerCountsForOneTick = 0;
|
static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
|
@ -146,7 +147,7 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
* The maximum number of tick periods that can be suppressed is limited by the
|
* The maximum number of tick periods that can be suppressed is limited by the
|
||||||
* 24 bit resolution of the SysTick timer.
|
* 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
|
@ -154,7 +155,7 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
||||||
* power functionality only.
|
* power functionality only.
|
||||||
*/
|
*/
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static uint32_t ulStoppedTimerCompensation = 0;
|
static uint32_t ulStoppedTimerCompensation = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
|
@ -174,13 +175,15 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
interrupt. */
|
* interrupt. */
|
||||||
|
|
||||||
/* Offset added to account for the way the MCU uses the stack on entry/exit
|
/* Offset added to account for the way the MCU uses the stack on entry/exit
|
||||||
of interrupts, and to ensure alignment. */
|
* of interrupts, and to ensure alignment. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||||
|
|
@ -194,7 +197,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
|
|
||||||
/* A save method is being used that requires each task to maintain its
|
/* A save method is being used that requires each task to maintain its
|
||||||
own exec return value. */
|
* own exec return value. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
||||||
|
|
||||||
|
|
@ -207,14 +210,17 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* 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
|
* its caller as there is nothing to return to. If a task wants to exit it
|
||||||
should instead call vTaskDelete( NULL ).
|
* should instead call vTaskDelete( NULL ).
|
||||||
|
*
|
||||||
Artificially force an assert() to be triggered if configASSERT() is
|
* Artificially force an assert() to be triggered if configASSERT() is
|
||||||
defined, then stop here so application writers can catch the error. */
|
* defined, then stop here so application writers can catch the error. */
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
configASSERT( uxCriticalNesting == ~0UL );
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
for( ;; );
|
|
||||||
|
for( ; ; )
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -223,22 +229,22 @@ static void prvTaskExitError( void )
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
volatile uint32_t ulOriginalPriority;
|
||||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
functions can be called. ISR safe functions are those that end in
|
* functions can be called. ISR safe functions are those that end in
|
||||||
"FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
* "FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
ensure interrupt entry is as fast and simple as possible.
|
* ensure interrupt entry is as fast and simple as possible.
|
||||||
|
*
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
* Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
/* Determine the number of priority bits available. First write to all
|
||||||
possible bits. */
|
* possible bits. */
|
||||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
|
@ -248,8 +254,9 @@ BaseType_t xPortStartScheduler( void )
|
||||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
of bits read back. */
|
* of bits read back. */
|
||||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||||
|
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||||
{
|
{
|
||||||
ulMaxPRIGROUPValue--;
|
ulMaxPRIGROUPValue--;
|
||||||
|
|
@ -259,8 +266,8 @@ BaseType_t xPortStartScheduler( void )
|
||||||
#ifdef __NVIC_PRIO_BITS
|
#ifdef __NVIC_PRIO_BITS
|
||||||
{
|
{
|
||||||
/* Check the CMSIS configuration that defines the number of
|
/* Check the CMSIS configuration that defines the number of
|
||||||
priority bits matches the number of priority bits actually queried
|
* priority bits matches the number of priority bits actually queried
|
||||||
from the hardware. */
|
* from the hardware. */
|
||||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -268,19 +275,19 @@ BaseType_t xPortStartScheduler( void )
|
||||||
#ifdef configPRIO_BITS
|
#ifdef configPRIO_BITS
|
||||||
{
|
{
|
||||||
/* Check the FreeRTOS configuration that defines the number of
|
/* Check the FreeRTOS configuration that defines the number of
|
||||||
priority bits matches the number of priority bits actually queried
|
* priority bits matches the number of priority bits actually queried
|
||||||
from the hardware. */
|
* from the hardware. */
|
||||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
|
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Shift the priority group value back to its position within the AIRCR
|
/* Shift the priority group value back to its position within the AIRCR
|
||||||
register. */
|
* register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
* value. */
|
||||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||||
}
|
}
|
||||||
#endif /* conifgASSERT_DEFINED */
|
#endif /* conifgASSERT_DEFINED */
|
||||||
|
|
@ -290,7 +297,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
here already. */
|
* here already. */
|
||||||
vPortSetupTimerInterrupt();
|
vPortSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Initialise the critical nesting count ready for the first task. */
|
/* Initialise the critical nesting count ready for the first task. */
|
||||||
|
|
@ -313,7 +320,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Not implemented in ports where there is nothing to return to.
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
Artificially force an assert. */
|
* Artificially force an assert. */
|
||||||
configASSERT( uxCriticalNesting == 1000UL );
|
configASSERT( uxCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -324,10 +331,10 @@ void vPortEnterCritical( void )
|
||||||
uxCriticalNesting++;
|
uxCriticalNesting++;
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
assert() if it is being called from an interrupt context. Only API
|
* assert() if it is being called from an interrupt context. Only API
|
||||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||||
the critical nesting count is 1 to protect against recursive calls if the
|
* the critical nesting count is 1 to protect against recursive calls if the
|
||||||
assert function also uses a critical section. */
|
* assert function also uses a critical section. */
|
||||||
if( uxCriticalNesting == 1 )
|
if( uxCriticalNesting == 1 )
|
||||||
{
|
{
|
||||||
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
||||||
|
|
@ -339,6 +346,7 @@ void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
configASSERT( uxCriticalNesting );
|
configASSERT( uxCriticalNesting );
|
||||||
uxCriticalNesting--;
|
uxCriticalNesting--;
|
||||||
|
|
||||||
if( uxCriticalNesting == 0 )
|
if( uxCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
@ -349,16 +357,16 @@ void vPortExitCritical( void )
|
||||||
void xPortSysTickHandler( void )
|
void xPortSysTickHandler( void )
|
||||||
{
|
{
|
||||||
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
||||||
executes all interrupts must be unmasked. There is therefore no need to
|
* 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
|
* save and then restore the interrupt mask value as its value is already
|
||||||
known. */
|
* known. */
|
||||||
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
/* Increment the RTOS tick. */
|
/* Increment the RTOS tick. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
{
|
{
|
||||||
/* A context switch is required. Context switching is performed in
|
/* A context switch is required. Context switching is performed in
|
||||||
the PendSV interrupt. Pend the PendSV interrupt. */
|
* the PendSV interrupt. Pend the PendSV interrupt. */
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -366,7 +374,7 @@ void xPortSysTickHandler( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
|
|
||||||
#pragma WEAK( vPortSuppressTicksAndSleep )
|
#pragma WEAK( vPortSuppressTicksAndSleep )
|
||||||
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||||
|
|
@ -381,45 +389,45 @@ void xPortSysTickHandler( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop the SysTick momentarily. The time the SysTick is stopped for
|
/* 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
|
* 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
|
* inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
* kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||||
tick periods. -1 is used because this code will execute part way
|
* tick periods. -1 is used because this code will execute part way
|
||||||
through one of the tick periods. */
|
* through one of the tick periods. */
|
||||||
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
||||||
|
|
||||||
if( ulReloadValue > ulStoppedTimerCompensation )
|
if( ulReloadValue > ulStoppedTimerCompensation )
|
||||||
{
|
{
|
||||||
ulReloadValue -= ulStoppedTimerCompensation;
|
ulReloadValue -= ulStoppedTimerCompensation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||||
method as that will mask interrupts that should exit sleep mode. */
|
* method as that will mask interrupts that should exit sleep mode. */
|
||||||
__asm( " cpsid i" );
|
__asm( " cpsid i");
|
||||||
__asm( " dsb" );
|
__asm( " dsb");
|
||||||
__asm( " isb" );
|
__asm( " isb");
|
||||||
|
|
||||||
|
|
||||||
/* If a context switch is pending or a task is waiting for the scheduler
|
/* If a context switch is pending or a task is waiting for the scheduler
|
||||||
to be unsuspended then abandon the low power entry. */
|
* to be unsuspended then abandon the low power entry. */
|
||||||
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
||||||
{
|
{
|
||||||
/* Restart from whatever is left in the count register to complete
|
/* Restart from whatever is left in the count register to complete
|
||||||
this tick period. */
|
* this tick period. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
/* Reset the reload register to the value required for normal tick
|
||||||
periods. */
|
* periods. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above __disable_interrupt()
|
/* Re-enable interrupts - see comments above __disable_interrupt()
|
||||||
call above. */
|
* call above. */
|
||||||
__asm( " cpsie i" );
|
__asm( " cpsie i");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -427,69 +435,71 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
||||||
|
|
||||||
/* Clear the SysTick count flag and set the count value back to
|
/* Clear the SysTick count flag and set the count value back to
|
||||||
zero. */
|
* zero. */
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
* set its parameter to 0 to indicate that its implementation contains
|
||||||
its own wait for interrupt or wait for event instruction, and so wfi
|
* its own wait for interrupt or wait for event instruction, and so wfi
|
||||||
should not be executed again. However, the original expected idle
|
* should not be executed again. However, the original expected idle
|
||||||
time variable must remain unmodified, so a copy is taken. */
|
* time variable must remain unmodified, so a copy is taken. */
|
||||||
xModifiableIdleTime = xExpectedIdleTime;
|
xModifiableIdleTime = xExpectedIdleTime;
|
||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||||
|
|
||||||
if( xModifiableIdleTime > 0 )
|
if( xModifiableIdleTime > 0 )
|
||||||
{
|
{
|
||||||
__asm( " dsb" );
|
__asm( " dsb");
|
||||||
__asm( " wfi" );
|
__asm( " wfi");
|
||||||
__asm( " isb" );
|
__asm( " isb");
|
||||||
}
|
}
|
||||||
|
|
||||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
|
||||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||||
out of sleep mode to execute immediately. see comments above
|
* out of sleep mode to execute immediately. see comments above
|
||||||
__disable_interrupt() call above. */
|
* __disable_interrupt() call above. */
|
||||||
__asm( " cpsie i" );
|
__asm( " cpsie i");
|
||||||
__asm( " dsb" );
|
__asm( " dsb");
|
||||||
__asm( " isb" );
|
__asm( " isb");
|
||||||
|
|
||||||
/* Disable interrupts again because the clock is about to be stopped
|
/* Disable interrupts again because the clock is about to be stopped
|
||||||
and interrupts that execute while the clock is stopped will increase
|
* and interrupts that execute while the clock is stopped will increase
|
||||||
any slippage between the time maintained by the RTOS and calendar
|
* any slippage between the time maintained by the RTOS and calendar
|
||||||
time. */
|
* time. */
|
||||||
__asm( " cpsid i" );
|
__asm( " cpsid i");
|
||||||
__asm( " dsb" );
|
__asm( " dsb");
|
||||||
__asm( " isb" );
|
__asm( " isb");
|
||||||
|
|
||||||
/* Disable the SysTick clock without reading the
|
/* Disable the SysTick clock without reading the
|
||||||
portNVIC_SYSTICK_CTRL_REG register to ensure the
|
* portNVIC_SYSTICK_CTRL_REG register to ensure the
|
||||||
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
|
* portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
|
||||||
the time the SysTick is stopped for is accounted for as best it can
|
* 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
|
* be, but using the tickless mode will inevitably result in some tiny
|
||||||
drift of the time maintained by the kernel with respect to calendar
|
* drift of the time maintained by the kernel with respect to calendar
|
||||||
time*/
|
* time*/
|
||||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
|
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
|
||||||
|
|
||||||
/* Determine if the SysTick clock has already counted to zero and
|
/* Determine if the SysTick clock has already counted to zero and
|
||||||
been set back to the current reload value (the reload back being
|
* been set back to the current reload value (the reload back being
|
||||||
correct for the entire expected idle time) or if the SysTick is yet
|
* correct for the entire expected idle time) or if the SysTick is yet
|
||||||
to count to zero (in which case an interrupt other than the SysTick
|
* to count to zero (in which case an interrupt other than the SysTick
|
||||||
must have brought the system out of sleep mode). */
|
* must have brought the system out of sleep mode). */
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||||
{
|
{
|
||||||
uint32_t ulCalculatedLoadValue;
|
uint32_t ulCalculatedLoadValue;
|
||||||
|
|
||||||
/* The tick interrupt is already pending, and the SysTick count
|
/* The tick interrupt is already pending, and the SysTick count
|
||||||
reloaded with ulReloadValue. Reset the
|
* reloaded with ulReloadValue. Reset the
|
||||||
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
* portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
||||||
period. */
|
* period. */
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
||||||
|
|
||||||
/* Don't allow a tiny value, or values that have somehow
|
/* Don't allow a tiny value, or values that have somehow
|
||||||
underflowed because the post sleep hook did something
|
* underflowed because the post sleep hook did something
|
||||||
that took too long. */
|
* that took too long. */
|
||||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
||||||
{
|
{
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
||||||
|
|
@ -498,37 +508,37 @@ void xPortSysTickHandler( void )
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
||||||
|
|
||||||
/* As the pending tick will be processed as soon as this
|
/* As the pending tick will be processed as soon as this
|
||||||
function exits, the tick value maintained by the tick is stepped
|
* function exits, the tick value maintained by the tick is stepped
|
||||||
forward by one less than the time spent waiting. */
|
* forward by one less than the time spent waiting. */
|
||||||
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Something other than the tick interrupt ended the sleep.
|
/* Something other than the tick interrupt ended the sleep.
|
||||||
Work out how long the sleep lasted rounded to complete tick
|
* Work out how long the sleep lasted rounded to complete tick
|
||||||
periods (not the ulReload value which accounted for part
|
* periods (not the ulReload value which accounted for part
|
||||||
ticks). */
|
* ticks). */
|
||||||
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* How many complete tick periods passed while the processor
|
/* How many complete tick periods passed while the processor
|
||||||
was waiting? */
|
* was waiting? */
|
||||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
||||||
|
|
||||||
/* The reload value is set to whatever fraction of a single tick
|
/* The reload value is set to whatever fraction of a single tick
|
||||||
period remains. */
|
* period remains. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
||||||
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
* again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
||||||
value. */
|
* value. */
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
|
|
||||||
/* Exit with interrupts enabled. */
|
/* Exit with interrupts enabled. */
|
||||||
__asm( " cpsie i" );
|
__asm( " cpsie i");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -543,7 +553,7 @@ void xPortSysTickHandler( void )
|
||||||
void vPortSetupTimerInterrupt( void )
|
void vPortSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
/* Calculate the constants required to configure the tick interrupt. */
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
{
|
{
|
||||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||||
|
|
@ -561,7 +571,7 @@ void vPortSetupTimerInterrupt( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
void vPortValidateInterruptPriority( void )
|
||||||
{
|
{
|
||||||
|
|
@ -578,66 +588,45 @@ void vPortSetupTimerInterrupt( void )
|
||||||
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
|
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
|
||||||
|
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
/* The following assertion will fail if a service routine (ISR) for
|
||||||
an interrupt that has been assigned a priority above
|
* an interrupt that has been assigned a priority above
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||||
function. ISR safe FreeRTOS API functions must *only* be called
|
* function. ISR safe FreeRTOS API functions must *only* be called
|
||||||
from interrupts that have been assigned a priority at or below
|
* from interrupts that have been assigned a priority at or below
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
Numerically low interrupt priority numbers represent logically high
|
* Numerically low interrupt priority numbers represent logically high
|
||||||
interrupt priorities, therefore the priority of the interrupt must
|
* interrupt priorities, therefore the priority of the interrupt must
|
||||||
be set to a value equal to or numerically *higher* than
|
* be set to a value equal to or numerically *higher* than
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
Interrupts that use the FreeRTOS API must not be left at their
|
* Interrupts that use the FreeRTOS API must not be left at their
|
||||||
default priority of zero as that is the highest possible priority,
|
* default priority of zero as that is the highest possible priority,
|
||||||
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
* which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
||||||
and therefore also guaranteed to be invalid.
|
* and therefore also guaranteed to be invalid.
|
||||||
|
*
|
||||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||||
interrupt entry is as fast and simple as possible.
|
* interrupt entry is as fast and simple as possible.
|
||||||
|
*
|
||||||
The following links provide detailed information:
|
* The following links provide detailed information:
|
||||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html
|
* http://www.freertos.org/RTOS-Cortex-M3-M4.html
|
||||||
http://www.freertos.org/FAQHelp.html */
|
* http://www.freertos.org/FAQHelp.html */
|
||||||
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
|
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Priority grouping: The interrupt controller (NVIC) allows the bits
|
/* Priority grouping: The interrupt controller (NVIC) allows the bits
|
||||||
that define each interrupt's priority to be split between bits that
|
* that define each interrupt's priority to be split between bits that
|
||||||
define the interrupt's pre-emption priority bits and bits that define
|
* define the interrupt's pre-emption priority bits and bits that define
|
||||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
* the interrupt's sub-priority. For simplicity all bits must be defined
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
* to be pre-emption priority bits. The following assertion will fail if
|
||||||
this is not the case (if some bits represent a sub-priority).
|
* this is not the case (if some bits represent a sub-priority).
|
||||||
|
*
|
||||||
If the application only uses CMSIS libraries for interrupt
|
* If the application only uses CMSIS libraries for interrupt
|
||||||
configuration then the correct setting can be achieved on all Cortex-M
|
* configuration then the correct setting can be achieved on all Cortex-M
|
||||||
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
* devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||||
scheduler. Note however that some vendor specific peripheral libraries
|
* scheduler. Note however that some vendor specific peripheral libraries
|
||||||
assume a non-zero priority group setting, in which cases using a value
|
* assume a non-zero priority group setting, in which cases using a value
|
||||||
of zero will result in unpredictable behaviour. */
|
* of zero will result in unpredictable behaviour. */
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -43,122 +43,121 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
#define portYIELD() \
|
#define portYIELD() \
|
||||||
{ \
|
{ \
|
||||||
/* Set a PendSV to request a context switch. */ \
|
/* Set a PendSV to request a context switch. */ \
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
__asm( " dsb" ); \
|
__asm( " dsb"); \
|
||||||
__asm( " isb" ); \
|
__asm( " isb"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if( configMAX_PRIORITIES > 32 )
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
{ \
|
{ \
|
||||||
_set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \
|
_set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \
|
||||||
__asm( " dsb" ); \
|
__asm( " dsb"); \
|
||||||
__asm( " isb" ); \
|
__asm( " isb"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() _set_interrupt_priority( 0 )
|
#define portENABLE_INTERRUPTS() _set_interrupt_priority( 0 )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() _set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); __asm( " dsb" ); __asm( " isb" )
|
#define portSET_INTERRUPT_MASK_FROM_ISR() _set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); __asm( " dsb" ); __asm( " isb")
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) _set_interrupt_priority( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) _set_interrupt_priority( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
/* Tickless idle/low power functionality. */
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
not necessary for to use this port. They are defined so the common demo files
|
* not necessary for to use this port. They are defined so the common demo files
|
||||||
(which build with all the ports) will build. */
|
* (which build with all the ports) will build. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* portNOP() is not required by this port. */
|
/* portNOP() is not required by this port. */
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,17 +36,17 @@ uint32_t ulCriticalNesting = 9999;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Registers required to configure the RTI. */
|
/* Registers required to configure the RTI. */
|
||||||
#define portRTI_GCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC00 ) )
|
#define portRTI_GCTRL_REG ( *( ( volatile uint32_t * ) 0xFFFFFC00 ) )
|
||||||
#define portRTI_TBCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC04 ) )
|
#define portRTI_TBCTRL_REG ( *( ( volatile uint32_t * ) 0xFFFFFC04 ) )
|
||||||
#define portRTI_COMPCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC0C ) )
|
#define portRTI_COMPCTRL_REG ( *( ( volatile uint32_t * ) 0xFFFFFC0C ) )
|
||||||
#define portRTI_CNT0_FRC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC10 ) )
|
#define portRTI_CNT0_FRC0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC10 ) )
|
||||||
#define portRTI_CNT0_UC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC14 ) )
|
#define portRTI_CNT0_UC0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC14 ) )
|
||||||
#define portRTI_CNT0_CPUC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC18 ) )
|
#define portRTI_CNT0_CPUC0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC18 ) )
|
||||||
#define portRTI_CNT0_COMP0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC50 ) )
|
#define portRTI_CNT0_COMP0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC50 ) )
|
||||||
#define portRTI_CNT0_UDCP0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC54 ) )
|
#define portRTI_CNT0_UDCP0_REG ( *( ( volatile uint32_t * ) 0xFFFFFC54 ) )
|
||||||
#define portRTI_SETINTENA_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC80 ) )
|
#define portRTI_SETINTENA_REG ( *( ( volatile uint32_t * ) 0xFFFFFC80 ) )
|
||||||
#define portRTI_CLEARINTENA_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC84 ) )
|
#define portRTI_CLEARINTENA_REG ( *( ( volatile uint32_t * ) 0xFFFFFC84 ) )
|
||||||
#define portRTI_INTFLAG_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC88 ) )
|
#define portRTI_INTFLAG_REG ( *( ( volatile uint32_t * ) 0xFFFFFC88 ) )
|
||||||
|
|
||||||
|
|
||||||
/* Constants required to set up the initial stack of each task. */
|
/* Constants required to set up the initial stack of each task. */
|
||||||
|
|
@ -56,7 +56,7 @@ uint32_t ulCriticalNesting = 9999;
|
||||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||||
|
|
||||||
/* The number of words on the stack frame between the saved Top Of Stack and
|
/* The number of words on the stack frame between the saved Top Of Stack and
|
||||||
R0 (in which the parameters are passed. */
|
* R0 (in which the parameters are passed. */
|
||||||
#define portSPACE_BETWEEN_TOS_AND_PARAMETERS ( 12 )
|
#define portSPACE_BETWEEN_TOS_AND_PARAMETERS ( 12 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -67,7 +67,7 @@ extern void vPortStartFirstTask( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Saved as part of the task context. Set to pdFALSE if the task does not
|
/* Saved as part of the task context. Set to pdFALSE if the task does not
|
||||||
require an FPU context. */
|
* require an FPU context. */
|
||||||
uint32_t ulTaskHasFPUContext = 0;
|
uint32_t ulTaskHasFPUContext = 0;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -76,9 +76,11 @@ uint32_t ulTaskHasFPUContext = 0;
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
StackType_t *pxOriginalTOS;
|
StackType_t * pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
|
|
@ -90,11 +92,11 @@ StackType_t *pxOriginalTOS;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. */
|
* expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which is the start of the as
|
/* First on the stack is the return address - which is the start of the as
|
||||||
the task has not executed yet. The offset is added to make the return
|
* the task has not executed yet. The offset is added to make the return
|
||||||
address appear as it would within an IRQ ISR. */
|
* address appear as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
|
@ -130,11 +132,11 @@ StackType_t *pxOriginalTOS;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
}
|
}
|
||||||
#else
|
#else /* ifdef portPRELOAD_TASK_REGISTERS */
|
||||||
{
|
{
|
||||||
pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS;
|
pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* ifdef portPRELOAD_TASK_REGISTERS */
|
||||||
|
|
||||||
/* Function parameters are passed in R0. */
|
/* Function parameters are passed in R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
|
|
@ -154,8 +156,8 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing on the stack is the tasks ulUsingFPU value, which by
|
/* The last thing on the stack is the tasks ulUsingFPU value, which by
|
||||||
default is set to indicate that the stack frame does not include FPU
|
* default is set to indicate that the stack frame does not include FPU
|
||||||
registers. */
|
* registers. */
|
||||||
*pxTopOfStack = pdFALSE;
|
*pxTopOfStack = pdFALSE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -164,7 +166,7 @@ StackType_t *pxOriginalTOS;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvSetupTimerInterrupt(void)
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
/* Disable timer 0. */
|
/* Disable timer 0. */
|
||||||
portRTI_GCTRL_REG &= 0xFFFFFFFEUL;
|
portRTI_GCTRL_REG &= 0xFFFFFFFEUL;
|
||||||
|
|
@ -197,7 +199,7 @@ static void prvSetupTimerInterrupt(void)
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler(void)
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. */
|
/* Start the timer that generates the tick ISR. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
@ -206,7 +208,7 @@ BaseType_t xPortStartScheduler(void)
|
||||||
ulCriticalNesting = 0;
|
ulCriticalNesting = 0;
|
||||||
|
|
||||||
/* Start the first task. This is done from portASM.asm as ARM mode must be
|
/* Start the first task. This is done from portASM.asm as ARM mode must be
|
||||||
used. */
|
* used. */
|
||||||
vPortStartFirstTask();
|
vPortStartFirstTask();
|
||||||
|
|
||||||
/* Should not get here! */
|
/* Should not get here! */
|
||||||
|
|
@ -217,17 +219,17 @@ BaseType_t xPortStartScheduler(void)
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
void vPortEndScheduler(void)
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Not implemented in ports where there is nothing to return to.
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
Artificially force an assert. */
|
* Artificially force an assert. */
|
||||||
configASSERT( ulCriticalNesting == 1000UL );
|
configASSERT( ulCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
* simply increment the system tick. */
|
* simply increment the system tick. */
|
||||||
__interrupt void vPortNonPreemptiveTick( void )
|
__interrupt void vPortNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
|
|
@ -235,13 +237,13 @@ void vPortEndScheduler(void)
|
||||||
portRTI_INTFLAG_REG = 0x00000001;
|
portRTI_INTFLAG_REG = 0x00000001;
|
||||||
|
|
||||||
/* Increment the tick count - this may make a delaying task ready
|
/* Increment the tick count - this may make a delaying task ready
|
||||||
to run - but a context switch is not performed. */
|
* to run - but a context switch is not performed. */
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else /* if configUSE_PREEMPTION == 0 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* The preemptive scheduler ISR is written in assembler and can be found
|
* The preemptive scheduler ISR is written in assembler and can be found
|
||||||
* in the portASM.asm file. This will only get used if portUSE_PREEMPTION
|
* in the portASM.asm file. This will only get used if portUSE_PREEMPTION
|
||||||
|
|
@ -250,7 +252,7 @@ void vPortEndScheduler(void)
|
||||||
*/
|
*/
|
||||||
void vPortPreemptiveTick( void );
|
void vPortPreemptiveTick( void );
|
||||||
|
|
||||||
#endif
|
#endif /* if configUSE_PREEMPTION == 0 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -263,8 +265,8 @@ void vPortEnterCritical( void )
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -281,7 +283,7 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
re-enabled. */
|
* re-enabled. */
|
||||||
if( ulCriticalNesting == 0 )
|
if( ulCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portENABLE_INTERRUPTS(). */
|
/* Enable interrupts as per portENABLE_INTERRUPTS(). */
|
||||||
|
|
@ -298,7 +300,7 @@ void vPortExitCritical( void )
|
||||||
extern void vPortInitialiseFPSCR( void );
|
extern void vPortInitialiseFPSCR( void );
|
||||||
|
|
||||||
/* A task is registering the fact that it needs an FPU context. Set the
|
/* A task is registering the fact that it needs an FPU context. Set the
|
||||||
FPU flag (saved as part of the task context. */
|
* FPU flag (saved as part of the task context. */
|
||||||
ulTaskHasFPUContext = pdTRUE;
|
ulTaskHasFPUContext = pdTRUE;
|
||||||
|
|
||||||
/* Initialise the floating point status register. */
|
/* Initialise the floating point status register. */
|
||||||
|
|
@ -308,4 +310,3 @@ void vPortExitCritical( void )
|
||||||
#endif /* __TI_VFP_SUPPORT__ */
|
#endif /* __TI_VFP_SUPPORT__ */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,40 +50,40 @@ typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if (configUSE_16_BIT_TICKS == 1)
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY (TickType_t) 0xFFFF
|
#define portMAX_DELAY ( TickType_t ) 0xFFFF
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY (TickType_t) 0xFFFFFFFFF
|
#define portMAX_DELAY ( TickType_t ) 0xFFFFFFFFF
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH (-1)
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ((TickType_t) 1000 / configTICK_RATE_HZ)
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
|
||||||
/* Critical section handling. */
|
/* Critical section handling. */
|
||||||
extern void vPortEnterCritical(void);
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical(void);
|
extern void vPortExitCritical( void );
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
#define portDISABLE_INTERRUPTS() asm( " CPSID I" )
|
#define portDISABLE_INTERRUPTS() asm ( " CPSID I" )
|
||||||
#define portENABLE_INTERRUPTS() asm( " CPSIE I" )
|
#define portENABLE_INTERRUPTS() asm ( " CPSIE I" )
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
#pragma SWI_ALIAS( vPortYield, 0 )
|
#pragma SWI_ALIAS( vPortYield, 0 )
|
||||||
extern void vPortYield( void );
|
extern void vPortYield( void );
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portSYS_SSIR1_REG ( * ( ( volatile uint32_t * ) 0xFFFFFFB0 ) )
|
#define portSYS_SSIR1_REG ( *( ( volatile uint32_t * ) 0xFFFFFFB0 ) )
|
||||||
#define portSYS_SSIR1_SSKEY ( 0x7500UL )
|
#define portSYS_SSIR1_SSKEY ( 0x7500UL )
|
||||||
#define portYIELD_WITHIN_API() { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; asm( " DSB " ); asm( " ISB " ); }
|
#define portYIELD_WITHIN_API() { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; asm ( " DSB " ); asm ( " ISB " ); }
|
||||||
#define portYIELD_FROM_ISR( x ) if( x != pdFALSE ){ portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; ( void ) portSYS_SSIR1_REG; }
|
#define portYIELD_FROM_ISR( x ) if( x != pdFALSE ) { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; ( void ) portSYS_SSIR1_REG; }
|
||||||
|
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
|
@ -92,16 +92,16 @@ extern void vPortYield( void );
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if( configMAX_PRIORITIES > 32 )
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
|
@ -109,8 +109,7 @@ extern void vPortYield( void );
|
||||||
|
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters)
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters)
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
#endif /* __PORTMACRO_H__ */
|
#endif /* __PORTMACRO_H__ */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,30 @@
|
||||||
;/*
|
; /*
|
||||||
; * FreeRTOS Kernel V10.3.1
|
* ; * FreeRTOS Kernel V10.3.1
|
||||||
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
; *
|
* ; *
|
||||||
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
; * this software and associated documentation files (the "Software"), to deal in
|
* ; * this software and associated documentation files (the "Software"), to deal in
|
||||||
; * the Software without restriction, including without limitation the rights to
|
* ; * the Software without restriction, including without limitation the rights to
|
||||||
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
* ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
; * the Software, and to permit persons to whom the Software is furnished to do so,
|
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
; * subject to the following conditions:
|
* ; * subject to the following conditions:
|
||||||
; *
|
* ; *
|
||||||
; * The above copyright notice and this permission notice shall be included in all
|
* ; * The above copyright notice and this permission notice shall be included in all
|
||||||
; * copies or substantial portions of the Software.
|
* ; * copies or substantial portions of the Software.
|
||||||
; *
|
* ; *
|
||||||
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
* ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
* ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
* ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
; *
|
* ; *
|
||||||
; * http://www.FreeRTOS.org
|
* ; * http://www.FreeRTOS.org
|
||||||
; * http://aws.amazon.com/freertos
|
* ; * http://aws.amazon.com/freertos
|
||||||
; *
|
* ; *
|
||||||
; */
|
* ; */
|
||||||
|
|
||||||
.if $DEFINED( __LARGE_DATA_MODEL__ )
|
.if $DEFINED( __LARGE_DATA_MODEL__ )
|
||||||
.define "pushm.a", pushm_x
|
.define "pushm.a", pushm_x
|
||||||
.define "popm.a", popm_x
|
.define "popm.a", popm_x
|
||||||
.define "push.a", push_x
|
.define "push.a", push_x
|
||||||
|
|
@ -45,8 +45,3 @@
|
||||||
.define "call", call_x
|
.define "call", call_x
|
||||||
.define "ret", ret_x
|
.define "ret", ret_x
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,28 +29,28 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the MSP430X port.
|
* Implementation of functions defined in portable.h for the MSP430X port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
|
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
|
||||||
not the MCLK. */
|
* not the MCLK. */
|
||||||
#define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 )
|
#define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 )
|
||||||
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
|
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
|
||||||
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 )
|
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 )
|
||||||
|
|
||||||
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
||||||
any details of its type. */
|
* any details of its type. */
|
||||||
typedef void TCB_t;
|
typedef void TCB_t;
|
||||||
extern volatile TCB_t * volatile pxCurrentTCB;
|
extern volatile TCB_t * volatile pxCurrentTCB;
|
||||||
|
|
||||||
/* Each task maintains a count of the critical section nesting depth. Each
|
/* Each task maintains a count of the critical section nesting depth. Each
|
||||||
time a critical section is entered the count is incremented. Each time a
|
* time a critical section is entered the count is incremented. Each time a
|
||||||
critical section is exited the count is decremented - with interrupts only
|
* critical section is exited the count is decremented - with interrupts only
|
||||||
being re-enabled if the count is zero.
|
* being re-enabled if the count is zero.
|
||||||
|
*
|
||||||
usCriticalNesting will get set to zero when the scheduler starts, but must
|
* usCriticalNesting will get set to zero when the scheduler starts, but must
|
||||||
not be initialised to zero as this will cause problems during the startup
|
* not be initialised to zero as this will cause problems during the startup
|
||||||
sequence. */
|
* sequence. */
|
||||||
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -68,25 +68,27 @@ void vPortSetupTimerInterrupt( void );
|
||||||
*
|
*
|
||||||
* See the header file portable.h.
|
* See the header file portable.h.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
uint16_t *pusTopOfStack;
|
uint16_t * pusTopOfStack;
|
||||||
uint32_t *pulTopOfStack, ulTemp;
|
uint32_t * pulTopOfStack, ulTemp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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 and can be included if required.
|
* This is just useful for debugging and can be included if required.
|
||||||
|
*
|
||||||
*pxTopOfStack = ( StackType_t ) 0x1111;
|
* pxTopOfStack = ( StackType_t ) 0x1111;
|
||||||
pxTopOfStack--;
|
* pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x2222;
|
* pxTopOfStack = ( StackType_t ) 0x2222;
|
||||||
pxTopOfStack--;
|
* pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x3333;
|
* pxTopOfStack = ( StackType_t ) 0x3333;
|
||||||
pxTopOfStack--;
|
* pxTopOfStack--;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Data types are need either 16 bits or 32 bits depending on the data
|
/* Data types are need either 16 bits or 32 bits depending on the data
|
||||||
and code model used. */
|
* and code model used. */
|
||||||
if( sizeof( pxCode ) == sizeof( uint16_t ) )
|
if( sizeof( pxCode ) == sizeof( uint16_t ) )
|
||||||
{
|
{
|
||||||
pusTopOfStack = ( uint16_t * ) pxTopOfStack;
|
pusTopOfStack = ( uint16_t * ) pxTopOfStack;
|
||||||
|
|
@ -135,19 +137,19 @@ uint32_t *pulTopOfStack, ulTemp;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x4444;
|
*pxTopOfStack = ( StackType_t ) 0x4444;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
#else
|
#else /* ifdef PRELOAD_REGISTER_VALUES */
|
||||||
pxTopOfStack -= 3;
|
pxTopOfStack -= 3;
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||||
pxTopOfStack -= 9;
|
pxTopOfStack -= 9;
|
||||||
#endif
|
#endif /* ifdef PRELOAD_REGISTER_VALUES */
|
||||||
|
|
||||||
/* A variable is used to keep track of the critical section nesting.
|
/* 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
|
* This variable has to be stored as part of the task context and is
|
||||||
initially set to zero. */
|
* initially set to zero. */
|
||||||
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
/* Return a pointer to the top of the stack we have generated so this can
|
/* Return a pointer to the top of the stack we have generated so this can
|
||||||
be stored in the task control block for the task. */
|
* be stored in the task control block for the task. */
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -155,7 +157,7 @@ uint32_t *pulTopOfStack, ulTemp;
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the MSP430 port will get stopped. If required simply
|
/* It is unlikely that the MSP430 port will get stopped. If required simply
|
||||||
disable the tick interrupt here. */
|
* disable the tick interrupt here. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -171,7 +173,7 @@ void vPortSetupTimerInterrupt( void )
|
||||||
#pragma vector=configTICK_VECTOR
|
#pragma vector=configTICK_VECTOR
|
||||||
interrupt void vTickISREntry( void )
|
interrupt void vTickISREntry( void )
|
||||||
{
|
{
|
||||||
extern void vPortTickISR( void );
|
extern void vPortTickISR( void );
|
||||||
|
|
||||||
__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
|
__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
|
||||||
#if configUSE_PREEMPTION == 1
|
#if configUSE_PREEMPTION == 1
|
||||||
|
|
@ -182,5 +184,3 @@ extern void vPortTickISR( void );
|
||||||
vPortCooperativeTickISR();
|
vPortCooperativeTickISR();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ typedef portSTACK_TYPE StackType_t;
|
||||||
typedef short BaseType_t;
|
typedef short BaseType_t;
|
||||||
typedef unsigned short UBaseType_t;
|
typedef unsigned short UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
|
|
@ -79,8 +79,8 @@ typedef unsigned short UBaseType_t;
|
||||||
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
|
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
|
||||||
|
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint16_t usCriticalNesting; \
|
extern volatile uint16_t usCriticalNesting; \
|
||||||
\
|
\
|
||||||
portDISABLE_INTERRUPTS(); \
|
portDISABLE_INTERRUPTS(); \
|
||||||
\
|
\
|
||||||
|
|
@ -88,11 +88,11 @@ extern volatile uint16_t usCriticalNesting; \
|
||||||
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
|
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
|
||||||
/* times portENTER_CRITICAL() has been called. */ \
|
/* times portENTER_CRITICAL() has been called. */ \
|
||||||
usCriticalNesting++; \
|
usCriticalNesting++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile uint16_t usCriticalNesting; \
|
extern volatile uint16_t usCriticalNesting; \
|
||||||
\
|
\
|
||||||
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
|
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
|
||||||
{ \
|
{ \
|
||||||
|
|
@ -106,7 +106,7 @@ extern volatile uint16_t usCriticalNesting; \
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
@ -126,8 +126,8 @@ extern void vPortYield( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
extern void vTaskSwitchContext( void );
|
extern void vTaskSwitchContext( void );
|
||||||
#define portYIELD_FROM_ISR( x ) if( x ) vPortYield()
|
#define portYIELD_FROM_ISR( x ) if( x ) vPortYield()
|
||||||
|
|
@ -135,8 +135,7 @@ extern void vTaskSwitchContext( void );
|
||||||
void vApplicationSetupTimerInterrupt( void );
|
void vApplicationSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/* sizeof( int ) != sizeof( long ) so a full printf() library is required if
|
/* sizeof( int ) != sizeof( long ) so a full printf() library is required if
|
||||||
run time stats information is to be displayed. */
|
* run time stats information is to be displayed. */
|
||||||
#define portLU_PRINTF_SPECIFIER_REQUIRED
|
#define portLU_PRINTF_SPECIFIER_REQUIRED
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
||||||
|
|
||||||
/* Supervisor mode set. */
|
/* Supervisor mode set. */
|
||||||
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000)
|
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000 )
|
||||||
|
|
||||||
/* The clock prescale into the timer peripheral. */
|
/* The clock prescale into the timer peripheral. */
|
||||||
#define portPRESCALE_VALUE ( ( uint8_t ) 10 )
|
#define portPRESCALE_VALUE ( ( uint8_t ) 10 )
|
||||||
|
|
@ -44,20 +44,23 @@ asm void interrupt VectorNumber_VL1swi vPortYieldISR( void );
|
||||||
static void prvSetupTimerInterrupt( void );
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
||||||
will be set to 0 prior to the first task being started. */
|
* will be set to 0 prior to the first task being started. */
|
||||||
static uint32_t ulCriticalNesting = 0x9999UL;
|
static uint32_t ulCriticalNesting = 0x9999UL;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
|
uint32_t ulOriginalA5;
|
||||||
|
|
||||||
uint32_t ulOriginalA5;
|
__asm {
|
||||||
|
MOVE.L A5, ulOriginalA5
|
||||||
__asm{ MOVE.L A5, ulOriginalA5 };
|
};
|
||||||
|
|
||||||
|
|
||||||
*pxTopOfStack = (StackType_t) 0xDEADBEEF;
|
*pxTopOfStack = ( StackType_t ) 0xDEADBEEF;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Exception stack frame starts with the return address. */
|
/* Exception stack frame starts with the return address. */
|
||||||
|
|
@ -82,7 +85,7 @@ uint32_t ulOriginalA5;
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void vPortStartFirstTask( void );
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
ulCriticalNesting = 0UL;
|
ulCriticalNesting = 0UL;
|
||||||
|
|
||||||
|
|
@ -105,7 +108,7 @@ static void prvSetupTimerInterrupt( void )
|
||||||
RTCMOD = portRTC_CLOCK_HZ / configTICK_RATE_HZ;
|
RTCMOD = portRTC_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
/* Enable the RTC to generate interrupts - interrupts are already disabled
|
/* Enable the RTC to generate interrupts - interrupts are already disabled
|
||||||
when this code executes. */
|
* when this code executes. */
|
||||||
RTCSC_RTIE = 1;
|
RTCSC_RTIE = 1;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -121,19 +124,20 @@ void vPortEnterCritical( void )
|
||||||
if( ulCriticalNesting == 0UL )
|
if( ulCriticalNesting == 0UL )
|
||||||
{
|
{
|
||||||
/* Guard against context switches being pended simultaneously with a
|
/* Guard against context switches being pended simultaneously with a
|
||||||
critical section being entered. */
|
* critical section being entered. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( INTC_FRC == 0UL )
|
if( INTC_FRC == 0UL )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
} while( 1 );
|
} while( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -141,6 +145,7 @@ void vPortEnterCritical( void )
|
||||||
void vPortExitCritical( void )
|
void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
if( ulCriticalNesting == 0 )
|
if( ulCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
@ -150,7 +155,7 @@ void vPortExitCritical( void )
|
||||||
|
|
||||||
void vPortYieldHandler( void )
|
void vPortYieldHandler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulSavedInterruptMask;
|
uint32_t ulSavedInterruptMask;
|
||||||
|
|
||||||
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
|
|
@ -164,7 +169,7 @@ uint32_t ulSavedInterruptMask;
|
||||||
|
|
||||||
void interrupt VectorNumber_Vrtc vPortTickISR( void )
|
void interrupt VectorNumber_Vrtc vPortTickISR( void )
|
||||||
{
|
{
|
||||||
uint32_t ulSavedInterruptMask;
|
uint32_t ulSavedInterruptMask;
|
||||||
|
|
||||||
/* Clear the interrupt. */
|
/* Clear the interrupt. */
|
||||||
RTCSC |= RTCSC_RTIF_MASK;
|
RTCSC |= RTCSC_RTIF_MASK;
|
||||||
|
|
@ -179,4 +184,3 @@ uint32_t ulSavedInterruptMask;
|
||||||
}
|
}
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -42,73 +42,73 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#define portSTACK_GROWTH -1
|
#define portSTACK_GROWTH -1
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
uint32_t ulPortSetIPL( uint32_t );
|
uint32_t ulPortSetIPL( uint32_t );
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
||||||
|
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
||||||
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
#define portNOP() asm volatile ( "nop" )
|
#define portNOP() asm volatile ( "nop" )
|
||||||
|
|
||||||
/* Context switches are requested using the force register. */
|
/* Context switches are requested using the force register. */
|
||||||
#define portYIELD() INTC_SFRC = 0x3E; portNOP(); portNOP(); portNOP(); portNOP(); portNOP()
|
#define portYIELD() INTC_SFRC = 0x3E; portNOP(); portNOP(); portNOP(); portNOP(); portNOP()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn))
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) __attribute__( ( noreturn ) )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
|
if( xSwitchRequired != pdFALSE ) \
|
||||||
{ \
|
{ \
|
||||||
portYIELD(); \
|
portYIELD(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,36 +32,38 @@
|
||||||
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
||||||
|
|
||||||
/* Supervisor mode set. */
|
/* Supervisor mode set. */
|
||||||
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000)
|
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000 )
|
||||||
|
|
||||||
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
||||||
will be set to 0 prior to the first task being started. */
|
* will be set to 0 prior to the first task being started. */
|
||||||
static uint32_t ulCriticalNesting = 0x9999UL;
|
static uint32_t ulCriticalNesting = 0x9999UL;
|
||||||
|
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
lea.l (-60, %sp), %sp; \
|
lea.l( -60, % sp ), % sp; \
|
||||||
movem.l %d0-%fp, (%sp); \
|
movem.l % d0 - % fp, ( % sp ); \
|
||||||
move.l pxCurrentTCB, %a0; \
|
move.l pxCurrentTCB, % a0; \
|
||||||
move.l %sp, (%a0);
|
move.l % sp, ( % a0 );
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
move.l pxCurrentTCB, %a0; \
|
move.l pxCurrentTCB, % a0; \
|
||||||
move.l (%a0), %sp; \
|
move.l( % a0 ), % sp; \
|
||||||
movem.l (%sp), %d0-%fp; \
|
movem.l( % sp ), % d0 - % fp; \
|
||||||
lea.l %sp@(60), %sp; \
|
lea.l % sp@( 60 ), % sp; \
|
||||||
rte
|
rte
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
*pxTopOfStack = (StackType_t) 0xDEADBEEF;
|
*pxTopOfStack = ( StackType_t ) 0xDEADBEEF;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Exception stack frame starts with the return address. */
|
/* Exception stack frame starts with the return address. */
|
||||||
|
|
@ -80,7 +82,7 @@ StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t p
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
extern void vPortStartFirstTask( void );
|
extern void vPortStartFirstTask( void );
|
||||||
|
|
||||||
ulCriticalNesting = 0UL;
|
ulCriticalNesting = 0UL;
|
||||||
|
|
||||||
|
|
@ -105,19 +107,20 @@ void vPortEnterCritical( void )
|
||||||
if( ulCriticalNesting == 0UL )
|
if( ulCriticalNesting == 0UL )
|
||||||
{
|
{
|
||||||
/* Guard against context switches being pended simultaneously with a
|
/* Guard against context switches being pended simultaneously with a
|
||||||
critical section being entered. */
|
* critical section being entered. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( MCF_INTC0_INTFRCH == 0UL )
|
if( MCF_INTC0_INTFRCH == 0UL )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
} while( 1 );
|
} while( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -125,6 +128,7 @@ void vPortEnterCritical( void )
|
||||||
void vPortExitCritical( void )
|
void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
if( ulCriticalNesting == 0 )
|
if( ulCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
@ -134,7 +138,7 @@ void vPortExitCritical( void )
|
||||||
|
|
||||||
void vPortYieldHandler( void )
|
void vPortYieldHandler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulSavedInterruptMask;
|
uint32_t ulSavedInterruptMask;
|
||||||
|
|
||||||
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
/* Note this will clear all forced interrupts - this is done for speed. */
|
/* Note this will clear all forced interrupts - this is done for speed. */
|
||||||
|
|
@ -143,4 +147,3 @@ uint32_t ulSavedInterruptMask;
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -42,72 +42,72 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portBYTE_ALIGNMENT 4
|
#define portBYTE_ALIGNMENT 4
|
||||||
#define portSTACK_GROWTH -1
|
#define portSTACK_GROWTH -1
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
uint32_t ulPortSetIPL( uint32_t );
|
uint32_t ulPortSetIPL( uint32_t );
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
||||||
|
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
||||||
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
#define portNOP() asm volatile ( "nop" )
|
#define portNOP() asm volatile ( "nop" )
|
||||||
|
|
||||||
/* Note this will overwrite all other bits in the force register, it is done this way for speed. */
|
/* Note this will overwrite all other bits in the force register, it is done this way for speed. */
|
||||||
#define portYIELD() MCF_INTC0_INTFRCL = ( 1UL << configYIELD_INTERRUPT_VECTOR ); portNOP(); portNOP() /* -32 as we are using the high word of the 64bit mask. */
|
#define portYIELD() MCF_INTC0_INTFRCL = ( 1UL << configYIELD_INTERRUPT_VECTOR ); portNOP(); portNOP() /* -32 as we are using the high word of the 64bit mask. */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__((noreturn))
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) __attribute__( ( noreturn ) )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
|
if( xSwitchRequired != pdFALSE ) \
|
||||||
{ \
|
{ \
|
||||||
portYIELD(); \
|
portYIELD(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the HCS12 port.
|
* Implementation of functions defined in portable.h for the HCS12 port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -41,29 +41,29 @@
|
||||||
static void prvSetupTimerInterrupt( void );
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/* Interrupt service routines have to be in non-banked memory - as does the
|
/* Interrupt service routines have to be in non-banked memory - as does the
|
||||||
scheduler startup function. */
|
* scheduler startup function. */
|
||||||
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
||||||
|
|
||||||
/* Manual context switch function. This is the SWI ISR. */
|
/* Manual context switch function. This is the SWI ISR. */
|
||||||
void interrupt vPortYield( void );
|
void interrupt vPortYield( void );
|
||||||
|
|
||||||
/* Tick context switch function. This is the timer ISR. */
|
/* Tick context switch function. This is the timer ISR. */
|
||||||
void interrupt vPortTickInterrupt( void );
|
void interrupt vPortTickInterrupt( void );
|
||||||
|
|
||||||
/* Simply called by xPortStartScheduler(). xPortStartScheduler() does not
|
/* Simply called by xPortStartScheduler(). xPortStartScheduler() does not
|
||||||
start the scheduler directly because the header file containing the
|
* start the scheduler directly because the header file containing the
|
||||||
xPortStartScheduler() prototype is part of the common kernel code, and
|
* xPortStartScheduler() prototype is part of the common kernel code, and
|
||||||
therefore cannot use the CODE_SEG pragma. */
|
* therefore cannot use the CODE_SEG pragma. */
|
||||||
static BaseType_t xBankedStartScheduler( void );
|
static BaseType_t xBankedStartScheduler( void );
|
||||||
|
|
||||||
#pragma CODE_SEG DEFAULT
|
#pragma CODE_SEG DEFAULT
|
||||||
|
|
||||||
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
|
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the
|
||||||
critical section should not be left (i.e. interrupts should not be re-enabled)
|
* critical section should not be left (i.e. interrupts should not be re-enabled)
|
||||||
until the nesting depth reaches 0. This variable simply tracks the nesting
|
* until the nesting depth reaches 0. This variable simply tracks the nesting
|
||||||
depth. Each task maintains it's own critical nesting depth variable so
|
* depth. Each task maintains it's own critical nesting depth variable so
|
||||||
uxCriticalNesting is saved and restored from the task stack during a context
|
* uxCriticalNesting is saved and restored from the task stack during a context
|
||||||
switch. */
|
* switch. */
|
||||||
volatile UBaseType_t uxCriticalNesting = 0xff;
|
volatile UBaseType_t uxCriticalNesting = 0xff;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -71,31 +71,33 @@ volatile UBaseType_t uxCriticalNesting = 0xff;
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
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 can be uncommented to provide useful stack markers when debugging.
|
* This can be uncommented to provide useful stack markers when debugging.
|
||||||
|
*
|
||||||
*pxTopOfStack = ( StackType_t ) 0x11;
|
* pxTopOfStack = ( StackType_t ) 0x11;
|
||||||
pxTopOfStack--;
|
* pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x22;
|
* pxTopOfStack = ( StackType_t ) 0x22;
|
||||||
pxTopOfStack--;
|
* pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) 0x33;
|
* pxTopOfStack = ( StackType_t ) 0x33;
|
||||||
pxTopOfStack--;
|
* pxTopOfStack--;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. In this case the stack as
|
* expected by the portRESTORE_CONTEXT() macro. In this case the stack as
|
||||||
expected by the HCS12 RTI instruction. */
|
* expected by the HCS12 RTI instruction. */
|
||||||
|
|
||||||
|
|
||||||
/* The address of the task function is placed in the stack byte at a time. */
|
/* The address of the task function is placed in the stack byte at a time. */
|
||||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pxCode) ) + 1 );
|
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pxCode ) ) + 1 );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pxCode) ) + 0 );
|
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pxCode ) ) + 0 );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Next are all the registers that form part of the task context. */
|
/* Next are all the registers that form part of the task context. */
|
||||||
|
|
@ -113,15 +115,15 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* A register contains parameter high byte. */
|
/* A register contains parameter high byte. */
|
||||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pvParameters) ) + 0 );
|
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pvParameters ) ) + 0 );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* B register contains parameter low byte. */
|
/* B register contains parameter low byte. */
|
||||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pvParameters) ) + 1 );
|
*pxTopOfStack = ( StackType_t ) *( ( ( StackType_t * ) ( &pvParameters ) ) + 1 );
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* CCR: Note that when the task starts interrupts will be enabled since
|
/* CCR: Note that when the task starts interrupts will be enabled since
|
||||||
"I" bit of CCR is cleared */
|
* "I" bit of CCR is cleared */
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
|
@ -132,7 +134,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Finally the critical nesting depth is initialised with 0 (not within
|
/* Finally the critical nesting depth is initialised with 0 (not within
|
||||||
a critical section). */
|
* a critical section). */
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
|
@ -155,10 +157,10 @@ static void prvSetupTimerInterrupt( void )
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* xPortStartScheduler() does not start the scheduler directly because
|
/* xPortStartScheduler() does not start the scheduler directly because
|
||||||
the header file containing the xPortStartScheduler() prototype is part
|
* the header file containing the xPortStartScheduler() prototype is part
|
||||||
of the common kernel code, and therefore cannot use the CODE_SEG pragma.
|
* of the common kernel code, and therefore cannot use the CODE_SEG pragma.
|
||||||
Instead it simply calls the locally defined xBankedStartScheduler() -
|
* Instead it simply calls the locally defined xBankedStartScheduler() -
|
||||||
which does use the CODE_SEG pragma. */
|
* which does use the CODE_SEG pragma. */
|
||||||
|
|
||||||
return xBankedStartScheduler();
|
return xBankedStartScheduler();
|
||||||
}
|
}
|
||||||
|
|
@ -169,7 +171,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
static BaseType_t xBankedStartScheduler( void )
|
static BaseType_t xBankedStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Configure the timer that will generate the RTOS tick. Interrupts are
|
/* Configure the timer that will generate the RTOS tick. Interrupts are
|
||||||
disabled when this function is called. */
|
* disabled when this function is called. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Restore the context of the first task. */
|
/* Restore the context of the first task. */
|
||||||
|
|
@ -220,17 +222,15 @@ void interrupt vPortTickInterrupt( void )
|
||||||
TFLG1 = 1;
|
TFLG1 = 1;
|
||||||
|
|
||||||
/* Restore the context of a task - which may be a different task
|
/* Restore the context of a task - which may be a different task
|
||||||
to that interrupted. */
|
* to that interrupted. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
#else
|
#else /* if configUSE_PREEMPTION == 1 */
|
||||||
{
|
{
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
TFLG1 = 1;
|
TFLG1 = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* if configUSE_PREEMPTION == 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma CODE_SEG DEFAULT
|
#pragma CODE_SEG DEFAULT
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ typedef portSTACK_TYPE StackType_t;
|
||||||
typedef signed char BaseType_t;
|
typedef signed char BaseType_t;
|
||||||
typedef unsigned char UBaseType_t;
|
typedef unsigned char UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
|
|
@ -79,12 +79,12 @@ typedef unsigned char UBaseType_t;
|
||||||
* directly. Each task maintains its own nesting count.
|
* directly. Each task maintains its own nesting count.
|
||||||
*/
|
*/
|
||||||
#define portENTER_CRITICAL() \
|
#define portENTER_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
\
|
\
|
||||||
portDISABLE_INTERRUPTS(); \
|
portDISABLE_INTERRUPTS(); \
|
||||||
uxCriticalNesting++; \
|
uxCriticalNesting++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interrupts are disabled so we can access the nesting count directly. If the
|
* Interrupts are disabled so we can access the nesting count directly. If the
|
||||||
|
|
@ -92,7 +92,7 @@ typedef unsigned char UBaseType_t;
|
||||||
* section and interrupts can be re-enabled.
|
* section and interrupts can be re-enabled.
|
||||||
*/
|
*/
|
||||||
#define portEXIT_CRITICAL() \
|
#define portEXIT_CRITICAL() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile UBaseType_t uxCriticalNesting; \
|
extern volatile UBaseType_t uxCriticalNesting; \
|
||||||
\
|
\
|
||||||
uxCriticalNesting--; \
|
uxCriticalNesting--; \
|
||||||
|
|
@ -100,7 +100,7 @@ typedef unsigned char UBaseType_t;
|
||||||
{ \
|
{ \
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
@ -116,7 +116,8 @@ typedef unsigned char UBaseType_t;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef BANKED_MODEL
|
#ifdef BANKED_MODEL
|
||||||
/*
|
|
||||||
|
/*
|
||||||
* Load the stack pointer for the task, then pull the critical nesting
|
* Load the stack pointer for the task, then pull the critical nesting
|
||||||
* count and PPAGE register from the stack. The remains of the
|
* count and PPAGE register from the stack. The remains of the
|
||||||
* context are restored by the RTI instruction.
|
* context are restored by the RTI instruction.
|
||||||
|
|
@ -134,7 +135,7 @@ typedef unsigned char UBaseType_t;
|
||||||
__asm( "staa 0x30" ); /* 0x30 = PPAGE */ \
|
__asm( "staa 0x30" ); /* 0x30 = PPAGE */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* By the time this macro is called the processor has already stacked the
|
* By the time this macro is called the processor has already stacked the
|
||||||
* registers. Simply stack the nesting count and PPAGE value, then save
|
* registers. Simply stack the nesting count and PPAGE value, then save
|
||||||
* the task stack pointer.
|
* the task stack pointer.
|
||||||
|
|
@ -151,9 +152,9 @@ typedef unsigned char UBaseType_t;
|
||||||
__asm( "ldx pxCurrentTCB" ); \
|
__asm( "ldx pxCurrentTCB" ); \
|
||||||
__asm( "sts 0, x" ); \
|
__asm( "sts 0, x" ); \
|
||||||
}
|
}
|
||||||
#else
|
#else /* ifdef BANKED_MODEL */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These macros are as per the BANKED versions above, but without saving
|
* These macros are as per the BANKED versions above, but without saving
|
||||||
* and restoring the PPAGE register.
|
* and restoring the PPAGE register.
|
||||||
*/
|
*/
|
||||||
|
|
@ -179,7 +180,7 @@ typedef unsigned char UBaseType_t;
|
||||||
__asm( "ldx pxCurrentTCB" ); \
|
__asm( "ldx pxCurrentTCB" ); \
|
||||||
__asm( "sts 0, x" ); \
|
__asm( "sts 0, x" ); \
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* ifdef BANKED_MODEL */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility macro to call macros above in correct order in order to perform a
|
* Utility macro to call macros above in correct order in order to perform a
|
||||||
|
|
@ -194,8 +195,7 @@ typedef unsigned char UBaseType_t;
|
||||||
|
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -26,13 +26,13 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the Atmel AT91R40008
|
* Implementation of functions defined in portable.h for the Atmel AT91R40008
|
||||||
* port.
|
* port.
|
||||||
*
|
*
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in this file. The ISR routines, which can only be compiled
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
* to ARM mode are contained in portISR.c.
|
* to ARM mode are contained in portISR.c.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -72,22 +72,24 @@ extern void vPortISRStartFirstTask( void );
|
||||||
*
|
*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
StackType_t *pxOriginalTOS;
|
StackType_t * pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
is not really required. */
|
* is not really required. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. */
|
* expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which in this case is the
|
/* First on the stack is the return address - which in this case is the
|
||||||
start of the task. The offset is added to make the return address appear
|
* start of the task. The offset is added to make the return address appear
|
||||||
as it would within an IRQ ISR. */
|
* as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
|
@ -121,12 +123,12 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* When the task starts is will expect to find the function parameter in
|
/* When the task starts is will expect to find the function parameter in
|
||||||
R0. */
|
* R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing onto the stack is the status register, which is set for
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
system mode, with interrupts enabled. */
|
* system mode, with interrupts enabled. */
|
||||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
@ -139,9 +141,9 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Some optimisation levels use the stack differently to others. This
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
means the interrupt flags cannot always be stored on the stack and will
|
* means the interrupt flags cannot always be stored on the stack and will
|
||||||
instead be stored in a variable, which is then saved as part of the
|
* instead be stored in a variable, which is then saved as part of the
|
||||||
tasks context. */
|
* tasks context. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
|
@ -151,7 +153,7 @@ StackType_t *pxOriginalTOS;
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
here already. */
|
* here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
|
@ -165,7 +167,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the ARM port will require this function as there
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
is nothing to return to. */
|
* is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -174,7 +176,7 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulDummy;
|
volatile uint32_t ulDummy;
|
||||||
|
|
||||||
/* Enable clock to the tick timer... */
|
/* Enable clock to the tick timer... */
|
||||||
AT91C_BASE_PS->PS_PCER = portTIMER_CLK_ENABLE_BIT;
|
AT91C_BASE_PS->PS_PCER = portTIMER_CLK_ENABLE_BIT;
|
||||||
|
|
@ -189,17 +191,17 @@ volatile uint32_t ulDummy;
|
||||||
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||||
|
|
||||||
/* Store interrupt handler function address in tick timer vector register...
|
/* Store interrupt handler function address in tick timer vector register...
|
||||||
The ISR installed depends on whether the preemptive or cooperative
|
* The ISR installed depends on whether the preemptive or cooperative
|
||||||
scheduler is being used. */
|
* scheduler is being used. */
|
||||||
#if configUSE_PREEMPTION == 1
|
#if configUSE_PREEMPTION == 1
|
||||||
{
|
{
|
||||||
extern void ( vPreemptiveTick )( void );
|
extern void( vPreemptiveTick )( void );
|
||||||
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( uint32_t ) vPreemptiveTick;
|
AT91C_BASE_AIC->AIC_SVR[ portTIMER_AIC_CHANNEL ] = ( uint32_t ) vPreemptiveTick;
|
||||||
}
|
}
|
||||||
#else // else use cooperative scheduler
|
#else // else use cooperative scheduler
|
||||||
{
|
{
|
||||||
extern void ( vNonPreemptiveTick )( void );
|
extern void( vNonPreemptiveTick )( void );
|
||||||
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( uint32_t ) vNonPreemptiveTick;
|
AT91C_BASE_AIC->AIC_SVR[ portTIMER_AIC_CHANNEL ] = ( uint32_t ) vNonPreemptiveTick;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -207,31 +209,30 @@ volatile uint32_t ulDummy;
|
||||||
AT91C_BASE_AIC->AIC_SMR[ portTIMER_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | portTICK_PRIORITY_6;
|
AT91C_BASE_AIC->AIC_SMR[ portTIMER_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | portTICK_PRIORITY_6;
|
||||||
|
|
||||||
/* Enable the tick timer interrupt...
|
/* Enable the tick timer interrupt...
|
||||||
|
*
|
||||||
First at timer level */
|
* First at timer level */
|
||||||
portTIMER_REG_BASE_PTR->TC_IER = TC_CPCS;
|
portTIMER_REG_BASE_PTR->TC_IER = TC_CPCS;
|
||||||
|
|
||||||
/* Then at the AIC level. */
|
/* Then at the AIC level. */
|
||||||
AT91C_BASE_AIC->AIC_IECR = (1 << portTIMER_AIC_CHANNEL);
|
AT91C_BASE_AIC->AIC_IECR = ( 1 << portTIMER_AIC_CHANNEL );
|
||||||
|
|
||||||
/* Calculate timer compare value to achieve the desired tick rate... */
|
/* Calculate timer compare value to achieve the desired tick rate... */
|
||||||
if( (configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2) ) <= 0xFFFF )
|
if( ( configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 2 ) ) <= 0xFFFF )
|
||||||
{
|
{
|
||||||
/* The tick rate is fast enough for us to use the faster timer input
|
/* The tick rate is fast enough for us to use the faster timer input
|
||||||
clock (main clock / 2). */
|
* clock (main clock / 2). */
|
||||||
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK2 | TC_BURST_NONE | TC_CPCTRG;
|
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK2 | TC_BURST_NONE | TC_CPCTRG;
|
||||||
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2);
|
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 2 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We must use a slower timer input clock (main clock / 8) because the
|
/* We must use a slower timer input clock (main clock / 8) because the
|
||||||
tick rate is too slow for the faster input clock. */
|
* tick rate is too slow for the faster input clock. */
|
||||||
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK8 | TC_BURST_NONE | TC_CPCTRG;
|
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK8 | TC_BURST_NONE | TC_CPCTRG;
|
||||||
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 8);
|
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 8 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start tick timer... */
|
/* Start tick timer... */
|
||||||
portTIMER_REG_BASE_PTR->TC_CCR = TC_SWTRG | TC_CLKEN;
|
portTIMER_REG_BASE_PTR->TC_CCR = TC_SWTRG | TC_CLKEN;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,17 +26,17 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in port.c The ISR routines, which can only be compiled
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
* to ARM mode, are contained in this file.
|
* to ARM mode, are contained in this file.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V3.2.4
|
* Changes from V3.2.4
|
||||||
|
*
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
than each line having its own asm block.
|
+ than each line having its own asm block.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
|
|
@ -53,7 +53,7 @@ volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
|
@ -65,7 +65,7 @@ void vPortISRStartFirstTask( void );
|
||||||
void vPortISRStartFirstTask( void )
|
void vPortISRStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* Simply start the scheduler. This is included here as it can only be
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
called from ARM mode. */
|
* called from ARM mode. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -81,9 +81,9 @@ void vPortISRStartFirstTask( void )
|
||||||
void vPortYieldProcessor( void )
|
void vPortYieldProcessor( void )
|
||||||
{
|
{
|
||||||
/* Within an IRQ ISR the link register has an offset from the true return
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
address, but an SWI ISR does not. Add the offset manually so the same
|
* address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
ISR return code can be used in both cases. */
|
* ISR return code can be used in both cases. */
|
||||||
asm volatile ( "ADD LR, LR, #4" );
|
asm volatile ( "ADD LR, LR, #4");
|
||||||
|
|
||||||
/* Perform the context switch. First save the context of the current task. */
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
@ -103,9 +103,9 @@ void vPortYieldProcessor( void )
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
simply increment the system tick. */
|
* simply increment the system tick. */
|
||||||
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
||||||
void vNonPreemptiveTick( void )
|
void vNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
static volatile uint32_t ulDummy;
|
static volatile uint32_t ulDummy;
|
||||||
|
|
@ -121,23 +121,23 @@ void vPortYieldProcessor( void )
|
||||||
|
|
||||||
#else /* else preemption is turned on */
|
#else /* else preemption is turned on */
|
||||||
|
|
||||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||||
saved on entry as part of the context switch. */
|
* saved on entry as part of the context switch. */
|
||||||
void vPreemptiveTick( void ) __attribute__((naked));
|
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
||||||
void vPreemptiveTick( void )
|
void vPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
/* WARNING - Do not use local (stack) variables here. Use globals
|
/* WARNING - Do not use local (stack) variables here. Use globals
|
||||||
if you must! */
|
* if you must! */
|
||||||
static volatile uint32_t ulDummy;
|
static volatile uint32_t ulDummy;
|
||||||
|
|
||||||
/* Clear tick timer interrupt indication. */
|
/* Clear tick timer interrupt indication. */
|
||||||
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||||
|
|
||||||
/* Increment the RTOS tick count, then look for the highest priority
|
/* Increment the RTOS tick count, then look for the highest priority
|
||||||
task that is ready to run. */
|
* task that is ready to run. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
{
|
{
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
|
|
@ -150,7 +150,7 @@ void vPortYieldProcessor( void )
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* if configUSE_PREEMPTION == 0 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -161,50 +161,50 @@ void vPortYieldProcessor( void )
|
||||||
*/
|
*/
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void )
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14"); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortEnableInterruptsFromThumb( void )
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14"); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
different optimisation levels. The interrupt flags can therefore not always
|
* different optimisation levels. The interrupt flags can therefore not always
|
||||||
be saved to the stack. Instead the critical section nesting level is stored
|
* be saved to the stack. Instead the critical section nesting level is stored
|
||||||
in a variable, which is then saved as part of the stack context. */
|
* in a variable, which is then saved as part of the stack context. */
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}"); /* Pop R0. */
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,17 +216,16 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
re-enabled. */
|
* re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}"); /* Pop R0. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,34 +25,34 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V3.2.3
|
* Changes from V3.2.3
|
||||||
|
*
|
||||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||||
|
+
|
||||||
Changes from V3.2.4
|
+ Changes from V3.2.4
|
||||||
|
+
|
||||||
+ Removed the use of the %0 parameter within the assembler macros and
|
+ Removed the use of the %0 parameter within the assembler macros and
|
||||||
replaced them with hard coded registers. This will ensure the
|
+ replaced them with hard coded registers. This will ensure the
|
||||||
assembler does not select the link register as the temp register as
|
+ assembler does not select the link register as the temp register as
|
||||||
was occasionally happening previously.
|
+ was occasionally happening previously.
|
||||||
|
+
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
than each line having its own asm block.
|
+ than each line having its own asm block.
|
||||||
|
+
|
||||||
Changes from V4.5.0
|
+ Changes from V4.5.0
|
||||||
|
+
|
||||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||||
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
+ and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||||
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
+ should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||||
macros as per the V4.5.1 demo code.
|
+ macros as per the V4.5.1 demo code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -65,42 +65,42 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portYIELD() asm volatile ( "SWI 0" )
|
#define portYIELD() asm volatile ( "SWI 0" )
|
||||||
#define portNOP() asm volatile ( "NOP" )
|
#define portNOP() asm volatile ( "NOP" )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These define the timer to use for generating the tick interrupt.
|
* These define the timer to use for generating the tick interrupt.
|
||||||
* They are put in this file so they can be shared between "port.c"
|
* They are put in this file so they can be shared between "port.c"
|
||||||
* and "portisr.c".
|
* and "portisr.c".
|
||||||
*/
|
*/
|
||||||
#define portTIMER_REG_BASE_PTR AT91C_BASE_TC0
|
#define portTIMER_REG_BASE_PTR AT91C_BASE_TC0
|
||||||
#define portTIMER_CLK_ENABLE_BIT AT91C_PS_TC0
|
#define portTIMER_CLK_ENABLE_BIT AT91C_PS_TC0
|
||||||
#define portTIMER_AIC_CHANNEL ( ( uint32_t ) 4 )
|
#define portTIMER_AIC_CHANNEL ( ( uint32_t ) 4 )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
@ -112,90 +112,90 @@ typedef unsigned long UBaseType_t;
|
||||||
* THUMB mode code will result in a compile time error.
|
* THUMB mode code will result in a compile time error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Set the LR to the task stack. */ \
|
/* Set the LR to the task stack. */ \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t"\
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t"\
|
||||||
"LDR LR, [R0] \n\t" \
|
"LDR LR, [R0] \n\t"\
|
||||||
\
|
\
|
||||||
/* The critical nesting depth is the first item on the stack. */ \
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
/* Load it into the ulCriticalNesting variable. */ \
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t"\
|
||||||
"LDMFD LR!, {R1} \n\t" \
|
"LDMFD LR!, {R1} \n\t"\
|
||||||
"STR R1, [R0] \n\t" \
|
"STR R1, [R0] \n\t"\
|
||||||
\
|
\
|
||||||
/* Get the SPSR from the stack. */ \
|
/* Get the SPSR from the stack. */ \
|
||||||
"LDMFD LR!, {R0} \n\t" \
|
"LDMFD LR!, {R0} \n\t"\
|
||||||
"MSR SPSR, R0 \n\t" \
|
"MSR SPSR, R0 \n\t"\
|
||||||
\
|
\
|
||||||
/* Restore all system mode registers for the task. */ \
|
/* Restore all system mode registers for the task. */ \
|
||||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
"LDMFD LR, {R0-R14}^ \n\t"\
|
||||||
"NOP \n\t" \
|
"NOP \n\t"\
|
||||||
\
|
\
|
||||||
/* Restore the return address. */ \
|
/* Restore the return address. */ \
|
||||||
"LDR LR, [LR, #+60] \n\t" \
|
"LDR LR, [LR, #+60] \n\t"\
|
||||||
\
|
\
|
||||||
/* And return - correcting the offset in the LR to obtain the */ \
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
/* correct address. */ \
|
/* correct address. */ \
|
||||||
"SUBS PC, LR, #4 \n\t" \
|
"SUBS PC, LR, #4 \n\t"\
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Push R0 as we are going to use the register. */ \
|
/* Push R0 as we are going to use the register. */ \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" \
|
"STMDB SP!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Set R0 to point to the task stack pointer. */ \
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
"STMDB SP,{SP}^ \n\t" \
|
"STMDB SP,{SP}^ \n\t"\
|
||||||
"NOP \n\t" \
|
"NOP \n\t"\
|
||||||
"SUB SP, SP, #4 \n\t" \
|
"SUB SP, SP, #4 \n\t"\
|
||||||
"LDMIA SP!,{R0} \n\t" \
|
"LDMIA SP!,{R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Push the return address onto the stack. */ \
|
/* Push the return address onto the stack. */ \
|
||||||
"STMDB R0!, {LR} \n\t" \
|
"STMDB R0!, {LR} \n\t"\
|
||||||
\
|
\
|
||||||
/* Now we have saved LR we can use it instead of R0. */ \
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
"MOV LR, R0 \n\t" \
|
"MOV LR, R0 \n\t"\
|
||||||
\
|
\
|
||||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
"LDMIA SP!, {R0} \n\t" \
|
"LDMIA SP!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Push all the system mode registers onto the task stack. */ \
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
"STMDB LR,{R0-LR}^ \n\t" \
|
"STMDB LR,{R0-LR}^ \n\t"\
|
||||||
"NOP \n\t" \
|
"NOP \n\t"\
|
||||||
"SUB LR, LR, #60 \n\t" \
|
"SUB LR, LR, #60 \n\t"\
|
||||||
\
|
\
|
||||||
/* Push the SPSR onto the task stack. */ \
|
/* Push the SPSR onto the task stack. */ \
|
||||||
"MRS R0, SPSR \n\t" \
|
"MRS R0, SPSR \n\t"\
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t"\
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t"\
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Store the new top of stack for the task. */ \
|
/* Store the new top of stack for the task. */ \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t"\
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t"\
|
||||||
"STR LR, [R0] \n\t" \
|
"STR LR, [R0] \n\t"\
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
|
|
||||||
/* Critical section handling. */
|
/* Critical section handling. */
|
||||||
|
|
||||||
|
|
@ -206,49 +206,48 @@ extern volatile uint32_t ulCriticalNesting; \
|
||||||
* defined then the utilities are defined as macros here - as per other ports.
|
* defined then the utilities are defined as macros here - as per other ports.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */\
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */\
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */\
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */\
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} ") /* Pop R0. */
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */\
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */\
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */\
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */\
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} ") /* Pop R0. */
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,51 +1,50 @@
|
||||||
//* ----------------------------------------------------------------------------
|
/** ---------------------------------------------------------------------------- */
|
||||||
//* ATMEL Microcontroller Software Support - ROUSSET -
|
/** ATMEL Microcontroller Software Support - ROUSSET - */
|
||||||
//* ----------------------------------------------------------------------------
|
/** ---------------------------------------------------------------------------- */
|
||||||
//* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
/** DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */
|
||||||
//* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
/** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
|
||||||
//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
/** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */
|
||||||
//* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
/** DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */
|
||||||
//* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
/** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
|
||||||
//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
/** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
|
||||||
//* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
/** OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
|
||||||
//* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
/** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
|
||||||
//* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
/** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
|
||||||
//* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
/** EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||||
//* ----------------------------------------------------------------------------
|
/** ---------------------------------------------------------------------------- */
|
||||||
//* File Name : lib_AT91SAM7X256.h
|
/** File Name : lib_AT91SAM7X256.h */
|
||||||
//* Object : AT91SAM7X256 inlined functions
|
/** Object : AT91SAM7X256 inlined functions */
|
||||||
//* Generated : AT91 SW Application Group 05/20/2005 (16:22:29)
|
/** Generated : AT91 SW Application Group 05/20/2005 (16:22:29) */
|
||||||
//*
|
/** */
|
||||||
//* CVS Reference : /lib_dbgu.h/1.1/Fri Jan 31 12:18:40 2003//
|
/** CVS Reference : /lib_dbgu.h/1.1/Fri Jan 31 12:18:40 2003// */
|
||||||
//* CVS Reference : /lib_pmc_SAM7X.h/1.1/Tue Feb 1 08:32:10 2005//
|
/** CVS Reference : /lib_pmc_SAM7X.h/1.1/Tue Feb 1 08:32:10 2005// */
|
||||||
//* CVS Reference : /lib_VREG_6085B.h/1.1/Tue Feb 1 16:20:47 2005//
|
/** CVS Reference : /lib_VREG_6085B.h/1.1/Tue Feb 1 16:20:47 2005// */
|
||||||
//* CVS Reference : /lib_rstc_6098A.h/1.1/Wed Oct 6 10:39:20 2004//
|
/** CVS Reference : /lib_rstc_6098A.h/1.1/Wed Oct 6 10:39:20 2004// */
|
||||||
//* CVS Reference : /lib_ssc.h/1.4/Fri Jan 31 12:19:20 2003//
|
/** CVS Reference : /lib_ssc.h/1.4/Fri Jan 31 12:19:20 2003// */
|
||||||
//* CVS Reference : /lib_wdtc_6080A.h/1.1/Wed Oct 6 10:38:30 2004//
|
/** CVS Reference : /lib_wdtc_6080A.h/1.1/Wed Oct 6 10:38:30 2004// */
|
||||||
//* CVS Reference : /lib_usart.h/1.5/Thu Nov 21 16:01:54 2002//
|
/** CVS Reference : /lib_usart.h/1.5/Thu Nov 21 16:01:54 2002// */
|
||||||
//* CVS Reference : /lib_spi2.h/1.1/Mon Aug 25 14:23:52 2003//
|
/** CVS Reference : /lib_spi2.h/1.1/Mon Aug 25 14:23:52 2003// */
|
||||||
//* CVS Reference : /lib_pitc_6079A.h/1.2/Tue Nov 9 14:43:56 2004//
|
/** CVS Reference : /lib_pitc_6079A.h/1.2/Tue Nov 9 14:43:56 2004// */
|
||||||
//* CVS Reference : /lib_aic_6075b.h/1.1/Fri May 20 14:01:19 2005//
|
/** CVS Reference : /lib_aic_6075b.h/1.1/Fri May 20 14:01:19 2005// */
|
||||||
//* CVS Reference : /lib_aes_6149a.h/1.1/Mon Jan 17 07:43:09 2005//
|
/** CVS Reference : /lib_aes_6149a.h/1.1/Mon Jan 17 07:43:09 2005// */
|
||||||
//* CVS Reference : /lib_twi.h/1.3/Mon Jul 19 14:27:58 2004//
|
/** CVS Reference : /lib_twi.h/1.3/Mon Jul 19 14:27:58 2004// */
|
||||||
//* CVS Reference : /lib_adc.h/1.6/Fri Oct 17 09:12:38 2003//
|
/** CVS Reference : /lib_adc.h/1.6/Fri Oct 17 09:12:38 2003// */
|
||||||
//* CVS Reference : /lib_rttc_6081A.h/1.1/Wed Oct 6 10:39:38 2004//
|
/** CVS Reference : /lib_rttc_6081A.h/1.1/Wed Oct 6 10:39:38 2004// */
|
||||||
//* CVS Reference : /lib_udp.h/1.4/Wed Feb 16 08:39:34 2005//
|
/** CVS Reference : /lib_udp.h/1.4/Wed Feb 16 08:39:34 2005// */
|
||||||
//* CVS Reference : /lib_des3_6150a.h/1.1/Mon Jan 17 09:19:19 2005//
|
/** CVS Reference : /lib_des3_6150a.h/1.1/Mon Jan 17 09:19:19 2005// */
|
||||||
//* CVS Reference : /lib_tc_1753b.h/1.1/Fri Jan 31 12:20:02 2003//
|
/** CVS Reference : /lib_tc_1753b.h/1.1/Fri Jan 31 12:20:02 2003// */
|
||||||
//* CVS Reference : /lib_MC_SAM7X.h/1.1/Thu Mar 25 15:19:14 2004//
|
/** CVS Reference : /lib_MC_SAM7X.h/1.1/Thu Mar 25 15:19:14 2004// */
|
||||||
//* CVS Reference : /lib_pio.h/1.3/Fri Jan 31 12:18:56 2003//
|
/** CVS Reference : /lib_pio.h/1.3/Fri Jan 31 12:18:56 2003// */
|
||||||
//* CVS Reference : /lib_can_AT91.h/1.4/Fri Oct 17 09:12:50 2003//
|
/** CVS Reference : /lib_can_AT91.h/1.4/Fri Oct 17 09:12:50 2003// */
|
||||||
//* CVS Reference : /lib_PWM_SAM.h/1.3/Thu Jan 22 10:10:50 2004//
|
/** CVS Reference : /lib_PWM_SAM.h/1.3/Thu Jan 22 10:10:50 2004// */
|
||||||
//* CVS Reference : /lib_pdc.h/1.2/Tue Jul 2 13:29:40 2002//
|
/** CVS Reference : /lib_pdc.h/1.2/Tue Jul 2 13:29:40 2002// */
|
||||||
//* ----------------------------------------------------------------------------
|
/** ---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
#include "AT91SAM7X256.h"
|
#include "AT91SAM7X256.h"
|
||||||
|
|
||||||
|
|
||||||
//*----------------------------------------------------------------------------
|
/**---------------------------------------------------------------------------- */
|
||||||
//* \fn AT91F_AIC_ConfigureIt
|
/** \fn AT91F_AIC_ConfigureIt */
|
||||||
//* \brief Interrupt Handler Initialization
|
/** \brief Interrupt Handler Initialization */
|
||||||
//*----------------------------------------------------------------------------
|
/**---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -26,12 +26,12 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||||
*
|
*
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in this file. The ISR routines, which can only be compiled
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
* to ARM mode are contained in portISR.c.
|
* to ARM mode are contained in portISR.c.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -81,22 +81,24 @@ extern void vPortISRStartFirstTask( void );
|
||||||
*
|
*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
StackType_t *pxOriginalTOS;
|
StackType_t * pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
is not really required. */
|
* is not really required. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. */
|
* expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which in this case is the
|
/* First on the stack is the return address - which in this case is the
|
||||||
start of the task. The offset is added to make the return address appear
|
* start of the task. The offset is added to make the return address appear
|
||||||
as it would within an IRQ ISR. */
|
* as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
|
@ -130,12 +132,12 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* When the task starts is will expect to find the function parameter in
|
/* When the task starts is will expect to find the function parameter in
|
||||||
R0. */
|
* R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing onto the stack is the status register, which is set for
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
system mode, with interrupts enabled. */
|
* system mode, with interrupts enabled. */
|
||||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
@ -148,9 +150,9 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Some optimisation levels use the stack differently to others. This
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
means the interrupt flags cannot always be stored on the stack and will
|
* means the interrupt flags cannot always be stored on the stack and will
|
||||||
instead be stored in a variable, which is then saved as part of the
|
* instead be stored in a variable, which is then saved as part of the
|
||||||
tasks context. */
|
* tasks context. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
|
@ -160,7 +162,7 @@ StackType_t *pxOriginalTOS;
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
here already. */
|
* here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
|
@ -174,7 +176,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the ARM port will require this function as there
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
is nothing to return to. */
|
* is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -183,30 +185,23 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
|
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
|
||||||
|
|
||||||
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
|
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
|
||||||
on whether the preemptive or cooperative scheduler is being used. */
|
* on whether the preemptive or cooperative scheduler is being used. */
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
extern void( vNonPreemptiveTick ) ( void );
|
||||||
extern void ( vNonPreemptiveTick ) ( void );
|
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vNonPreemptiveTick );
|
||||||
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vNonPreemptiveTick );
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
extern void( vPreemptiveTick )( void );
|
||||||
extern void ( vPreemptiveTick )( void );
|
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vPreemptiveTick );
|
||||||
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vPreemptiveTick );
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configure the PIT period. */
|
/* Configure the PIT period. */
|
||||||
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
|
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
|
||||||
|
|
||||||
/* Enable the interrupt. Global interrupts are disables at this point so
|
/* Enable the interrupt. Global interrupts are disables at this point so
|
||||||
this is safe. */
|
* this is safe. */
|
||||||
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
|
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,17 +26,17 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in port.c The ISR routines, which can only be compiled
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
* to ARM mode, are contained in this file.
|
* to ARM mode, are contained in this file.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V3.2.4
|
* Changes from V3.2.4
|
||||||
|
*
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
than each line having its own asm block.
|
+ than each line having its own asm block.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
|
@ -55,7 +55,7 @@ volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
|
@ -67,7 +67,7 @@ void vPortISRStartFirstTask( void );
|
||||||
void vPortISRStartFirstTask( void )
|
void vPortISRStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* Simply start the scheduler. This is included here as it can only be
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
called from ARM mode. */
|
* called from ARM mode. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -83,9 +83,9 @@ void vPortISRStartFirstTask( void )
|
||||||
void vPortYieldProcessor( void )
|
void vPortYieldProcessor( void )
|
||||||
{
|
{
|
||||||
/* Within an IRQ ISR the link register has an offset from the true return
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
address, but an SWI ISR does not. Add the offset manually so the same
|
* address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
ISR return code can be used in both cases. */
|
* ISR return code can be used in both cases. */
|
||||||
__asm volatile ( "ADD LR, LR, #4" );
|
__asm volatile ( "ADD LR, LR, #4");
|
||||||
|
|
||||||
/* Perform the context switch. First save the context of the current task. */
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
@ -105,16 +105,16 @@ void vPortYieldProcessor( void )
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
simply increment the system tick. */
|
* simply increment the system tick. */
|
||||||
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
||||||
void vNonPreemptiveTick( void )
|
void vNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
uint32_t ulDummy;
|
uint32_t ulDummy;
|
||||||
|
|
||||||
/* Increment the tick count - which may wake some tasks but as the
|
/* Increment the tick count - which may wake some tasks but as the
|
||||||
preemptive scheduler is not being used any woken task is not given
|
* preemptive scheduler is not being used any woken task is not given
|
||||||
processor time no matter what its priority. */
|
* processor time no matter what its priority. */
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
|
|
||||||
/* Clear the PIT interrupt. */
|
/* Clear the PIT interrupt. */
|
||||||
|
|
@ -124,11 +124,11 @@ void vPortYieldProcessor( void )
|
||||||
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
|
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else /* if configUSE_PREEMPTION == 0 */
|
||||||
|
|
||||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||||
saved on entry as part of the context switch. */
|
* saved on entry as part of the context switch. */
|
||||||
void vPreemptiveTick( void ) __attribute__((naked));
|
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
||||||
void vPreemptiveTick( void )
|
void vPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the current task. */
|
/* Save the context of the current task. */
|
||||||
|
|
@ -147,7 +147,7 @@ void vPortYieldProcessor( void )
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* if configUSE_PREEMPTION == 0 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -156,49 +156,49 @@ void vPortYieldProcessor( void )
|
||||||
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
|
* ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
|
||||||
* the utilities are defined as macros in portmacro.h - as per other ports.
|
* the utilities are defined as macros in portmacro.h - as per other ports.
|
||||||
*/
|
*/
|
||||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void )
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14"); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortEnableInterruptsFromThumb( void )
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14"); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
different optimisation levels. The interrupt flags can therefore not always
|
* different optimisation levels. The interrupt flags can therefore not always
|
||||||
be saved to the stack. Instead the critical section nesting level is stored
|
* be saved to the stack. Instead the critical section nesting level is stored
|
||||||
in a variable, which is then saved as part of the stack context. */
|
* in a variable, which is then saved as part of the stack context. */
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}"); /* Pop R0. */
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,17 +210,16 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
re-enabled. */
|
* re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}"); /* Pop R0. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,34 +25,34 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V3.2.3
|
* Changes from V3.2.3
|
||||||
|
*
|
||||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||||
|
+
|
||||||
Changes from V3.2.4
|
+ Changes from V3.2.4
|
||||||
|
+
|
||||||
+ Removed the use of the %0 parameter within the assembler macros and
|
+ Removed the use of the %0 parameter within the assembler macros and
|
||||||
replaced them with hard coded registers. This will ensure the
|
+ replaced them with hard coded registers. This will ensure the
|
||||||
assembler does not select the link register as the temp register as
|
+ assembler does not select the link register as the temp register as
|
||||||
was occasionally happening previously.
|
+ was occasionally happening previously.
|
||||||
|
+
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
than each line having its own asm block.
|
+ than each line having its own asm block.
|
||||||
|
+
|
||||||
Changes from V4.5.0
|
+ Changes from V4.5.0
|
||||||
|
+
|
||||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||||
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
+ and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||||
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
+ should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||||
macros as per the V4.5.1 demo code.
|
+ macros as per the V4.5.1 demo code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -65,32 +65,32 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE portLONG
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP() __asm volatile ( "NOP" );
|
#define portNOP() __asm volatile ( "NOP" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -103,92 +103,92 @@ typedef unsigned long UBaseType_t;
|
||||||
* THUMB mode code will result in a compile time error.
|
* THUMB mode code will result in a compile time error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Set the LR to the task stack. */ \
|
/* Set the LR to the task stack. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t"\
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t"\
|
||||||
"LDR LR, [R0] \n\t" \
|
"LDR LR, [R0] \n\t"\
|
||||||
\
|
\
|
||||||
/* The critical nesting depth is the first item on the stack. */ \
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
/* Load it into the ulCriticalNesting variable. */ \
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t"\
|
||||||
"LDMFD LR!, {R1} \n\t" \
|
"LDMFD LR!, {R1} \n\t"\
|
||||||
"STR R1, [R0] \n\t" \
|
"STR R1, [R0] \n\t"\
|
||||||
\
|
\
|
||||||
/* Get the SPSR from the stack. */ \
|
/* Get the SPSR from the stack. */ \
|
||||||
"LDMFD LR!, {R0} \n\t" \
|
"LDMFD LR!, {R0} \n\t"\
|
||||||
"MSR SPSR, R0 \n\t" \
|
"MSR SPSR, R0 \n\t"\
|
||||||
\
|
\
|
||||||
/* Restore all system mode registers for the task. */ \
|
/* Restore all system mode registers for the task. */ \
|
||||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
"LDMFD LR, {R0-R14}^ \n\t"\
|
||||||
"NOP \n\t" \
|
"NOP \n\t"\
|
||||||
\
|
\
|
||||||
/* Restore the return address. */ \
|
/* Restore the return address. */ \
|
||||||
"LDR LR, [LR, #+60] \n\t" \
|
"LDR LR, [LR, #+60] \n\t"\
|
||||||
\
|
\
|
||||||
/* And return - correcting the offset in the LR to obtain the */ \
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
/* correct address. */ \
|
/* correct address. */ \
|
||||||
"SUBS PC, LR, #4 \n\t" \
|
"SUBS PC, LR, #4 \n\t"\
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Push R0 as we are going to use the register. */ \
|
/* Push R0 as we are going to use the register. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" \
|
"STMDB SP!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Set R0 to point to the task stack pointer. */ \
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
"STMDB SP,{SP}^ \n\t" \
|
"STMDB SP,{SP}^ \n\t"\
|
||||||
"NOP \n\t" \
|
"NOP \n\t"\
|
||||||
"SUB SP, SP, #4 \n\t" \
|
"SUB SP, SP, #4 \n\t"\
|
||||||
"LDMIA SP!,{R0} \n\t" \
|
"LDMIA SP!,{R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Push the return address onto the stack. */ \
|
/* Push the return address onto the stack. */ \
|
||||||
"STMDB R0!, {LR} \n\t" \
|
"STMDB R0!, {LR} \n\t"\
|
||||||
\
|
\
|
||||||
/* Now we have saved LR we can use it instead of R0. */ \
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
"MOV LR, R0 \n\t" \
|
"MOV LR, R0 \n\t"\
|
||||||
\
|
\
|
||||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
"LDMIA SP!, {R0} \n\t" \
|
"LDMIA SP!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Push all the system mode registers onto the task stack. */ \
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
"STMDB LR,{R0-LR}^ \n\t" \
|
"STMDB LR,{R0-LR}^ \n\t"\
|
||||||
"NOP \n\t" \
|
"NOP \n\t"\
|
||||||
"SUB LR, LR, #60 \n\t" \
|
"SUB LR, LR, #60 \n\t"\
|
||||||
\
|
\
|
||||||
/* Push the SPSR onto the task stack. */ \
|
/* Push the SPSR onto the task stack. */ \
|
||||||
"MRS R0, SPSR \n\t" \
|
"MRS R0, SPSR \n\t"\
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t"\
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t"\
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Store the new top of stack for the task. */ \
|
/* Store the new top of stack for the task. */ \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t"\
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t"\
|
||||||
"STR LR, [R0] \n\t" \
|
"STR LR, [R0] \n\t"\
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -201,48 +201,47 @@ extern volatile uint32_t ulCriticalNesting; \
|
||||||
* defined then the utilities are defined as macros here - as per other ports.
|
* defined then the utilities are defined as macros here - as per other ports.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */\
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */\
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */\
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */\
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} ") /* Pop R0. */
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */\
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */\
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */\
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */\
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} ") /* Pop R0. */
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,12 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||||
*
|
*
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in this file. The ISR routines, which can only be compiled
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
* to ARM mode are contained in portISR.c.
|
* to ARM mode are contained in portISR.c.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
|
|
@ -77,22 +77,24 @@ extern void vPortISRStartFirstTask( void );
|
||||||
*
|
*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
StackType_t *pxOriginalTOS;
|
StackType_t * pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
is not really required. */
|
* is not really required. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. */
|
* expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which in this case is the
|
/* First on the stack is the return address - which in this case is the
|
||||||
start of the task. The offset is added to make the return address appear
|
* start of the task. The offset is added to make the return address appear
|
||||||
as it would within an IRQ ISR. */
|
* as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
|
@ -126,12 +128,12 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* When the task starts is will expect to find the function parameter in
|
/* When the task starts is will expect to find the function parameter in
|
||||||
R0. */
|
* R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing onto the stack is the status register, which is set for
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
system mode, with interrupts enabled. */
|
* system mode, with interrupts enabled. */
|
||||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||||
|
|
||||||
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
||||||
|
|
@ -143,9 +145,9 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Some optimisation levels use the stack differently to others. This
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
means the interrupt flags cannot always be stored on the stack and will
|
* means the interrupt flags cannot always be stored on the stack and will
|
||||||
instead be stored in a variable, which is then saved as part of the
|
* instead be stored in a variable, which is then saved as part of the
|
||||||
tasks context. */
|
* tasks context. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
|
@ -155,7 +157,7 @@ StackType_t *pxOriginalTOS;
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
here already. */
|
* here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
|
@ -169,7 +171,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the ARM port will require this function as there
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
is nothing to return to. */
|
* is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -178,18 +180,19 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
uint32_t ulCompareMatch;
|
uint32_t ulCompareMatch;
|
||||||
extern void ( vTickISR )( void );
|
|
||||||
|
extern void( vTickISR )( void );
|
||||||
|
|
||||||
/* A 1ms tick does not require the use of the timer prescale. This is
|
/* A 1ms tick does not require the use of the timer prescale. This is
|
||||||
defaulted to zero but can be used if necessary. */
|
* defaulted to zero but can be used if necessary. */
|
||||||
T0_PR = portPRESCALE_VALUE;
|
T0_PR = portPRESCALE_VALUE;
|
||||||
|
|
||||||
/* Calculate the match value required for our wanted tick rate. */
|
/* Calculate the match value required for our wanted tick rate. */
|
||||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
/* Protect against divide by zero. Using an if() statement still results
|
/* Protect against divide by zero. Using an if() statement still results
|
||||||
in a warning - hence the #if. */
|
* in a warning - hence the #if. */
|
||||||
#if portPRESCALE_VALUE != 0
|
#if portPRESCALE_VALUE != 0
|
||||||
{
|
{
|
||||||
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||||
|
|
@ -205,16 +208,13 @@ extern void ( vTickISR )( void );
|
||||||
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
|
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
|
||||||
|
|
||||||
/* The ISR installed depends on whether the preemptive or cooperative
|
/* The ISR installed depends on whether the preemptive or cooperative
|
||||||
scheduler is being used. */
|
* scheduler is being used. */
|
||||||
|
|
||||||
VICVectAddr0 = ( int32_t ) vTickISR;
|
VICVectAddr0 = ( int32_t ) vTickISR;
|
||||||
VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
|
VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
|
||||||
|
|
||||||
/* Start the timer - interrupts are disabled when this function is called
|
/* Start the timer - interrupts are disabled when this function is called
|
||||||
so it is okay to do this here. */
|
* so it is okay to do this here. */
|
||||||
T0_TCR = portENABLE_TIMER;
|
T0_TCR = portENABLE_TIMER;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,28 +26,28 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in port.c The ISR routines, which can only be compiled
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
* to ARM mode, are contained in this file.
|
* to ARM mode, are contained in this file.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V2.5.2
|
* Changes from V2.5.2
|
||||||
|
*
|
||||||
+ The critical section management functions have been changed. These no
|
+ The critical section management functions have been changed. These no
|
||||||
longer modify the stack and are safe to use at all optimisation levels.
|
+ longer modify the stack and are safe to use at all optimisation levels.
|
||||||
The functions are now also the same for both ARM and THUMB modes.
|
+ The functions are now also the same for both ARM and THUMB modes.
|
||||||
|
+
|
||||||
Changes from V2.6.0
|
+ Changes from V2.6.0
|
||||||
|
+
|
||||||
+ Removed the 'static' from the definition of vNonPreemptiveTick() to
|
+ Removed the 'static' from the definition of vNonPreemptiveTick() to
|
||||||
allow the demo to link when using the cooperative scheduler.
|
+ allow the demo to link when using the cooperative scheduler.
|
||||||
|
+
|
||||||
Changes from V3.2.4
|
+ Changes from V3.2.4
|
||||||
|
+
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
than each line having its own asm block.
|
+ than each line having its own asm block.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
|
|
@ -64,7 +64,7 @@ volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
|
@ -76,7 +76,7 @@ void vPortISRStartFirstTask( void );
|
||||||
void vPortISRStartFirstTask( void )
|
void vPortISRStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* Simply start the scheduler. This is included here as it can only be
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
called from ARM mode. */
|
* called from ARM mode. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -92,9 +92,9 @@ void vPortISRStartFirstTask( void )
|
||||||
void vPortYieldProcessor( void )
|
void vPortYieldProcessor( void )
|
||||||
{
|
{
|
||||||
/* Within an IRQ ISR the link register has an offset from the true return
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
address, but an SWI ISR does not. Add the offset manually so the same
|
* address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
ISR return code can be used in both cases. */
|
* ISR return code can be used in both cases. */
|
||||||
__asm volatile ( "ADD LR, LR, #4" );
|
__asm volatile ( "ADD LR, LR, #4");
|
||||||
|
|
||||||
/* Perform the context switch. First save the context of the current task. */
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
@ -110,20 +110,20 @@ void vPortYieldProcessor( void )
|
||||||
/*
|
/*
|
||||||
* The ISR used for the scheduler tick.
|
* The ISR used for the scheduler tick.
|
||||||
*/
|
*/
|
||||||
void vTickISR( void ) __attribute__((naked));
|
void vTickISR( void ) __attribute__( ( naked ) );
|
||||||
void vTickISR( void )
|
void vTickISR( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
/* Increment the RTOS tick count, then look for the highest priority
|
/* Increment the RTOS tick count, then look for the highest priority
|
||||||
task that is ready to run. */
|
* task that is ready to run. */
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" bl xTaskIncrementTick \t\n" \
|
" bl xTaskIncrementTick \t\n"\
|
||||||
" cmp r0, #0 \t\n" \
|
" cmp r0, #0 \t\n"\
|
||||||
" beq SkipContextSwitch \t\n" \
|
" beq SkipContextSwitch \t\n"\
|
||||||
" bl vTaskSwitchContext \t\n" \
|
" bl vTaskSwitchContext \t\n"\
|
||||||
"SkipContextSwitch: \t\n"
|
"SkipContextSwitch: \t\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -144,50 +144,50 @@ void vTickISR( void )
|
||||||
*/
|
*/
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void )
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14"); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortEnableInterruptsFromThumb( void )
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14"); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
different optimisation levels. The interrupt flags can therefore not always
|
* different optimisation levels. The interrupt flags can therefore not always
|
||||||
be saved to the stack. Instead the critical section nesting level is stored
|
* be saved to the stack. Instead the critical section nesting level is stored
|
||||||
in a variable, which is then saved as part of the stack context. */
|
* in a variable, which is then saved as part of the stack context. */
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}"); /* Pop R0. */
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,16 +199,16 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
re-enabled. */
|
* re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}"); /* Pop R0. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -42,32 +42,32 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE portLONG
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP() __asm volatile ( "NOP" );
|
#define portNOP() __asm volatile ( "NOP" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -80,92 +80,92 @@ typedef unsigned long UBaseType_t;
|
||||||
* THUMB mode code will result in a compile time error.
|
* THUMB mode code will result in a compile time error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Set the LR to the task stack. */ \
|
/* Set the LR to the task stack. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t"\
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t"\
|
||||||
"LDR LR, [R0] \n\t" \
|
"LDR LR, [R0] \n\t"\
|
||||||
\
|
\
|
||||||
/* The critical nesting depth is the first item on the stack. */ \
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
/* Load it into the ulCriticalNesting variable. */ \
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t"\
|
||||||
"LDMFD LR!, {R1} \n\t" \
|
"LDMFD LR!, {R1} \n\t"\
|
||||||
"STR R1, [R0] \n\t" \
|
"STR R1, [R0] \n\t"\
|
||||||
\
|
\
|
||||||
/* Get the SPSR from the stack. */ \
|
/* Get the SPSR from the stack. */ \
|
||||||
"LDMFD LR!, {R0} \n\t" \
|
"LDMFD LR!, {R0} \n\t"\
|
||||||
"MSR SPSR, R0 \n\t" \
|
"MSR SPSR, R0 \n\t"\
|
||||||
\
|
\
|
||||||
/* Restore all system mode registers for the task. */ \
|
/* Restore all system mode registers for the task. */ \
|
||||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
"LDMFD LR, {R0-R14}^ \n\t"\
|
||||||
"NOP \n\t" \
|
"NOP \n\t"\
|
||||||
\
|
\
|
||||||
/* Restore the return address. */ \
|
/* Restore the return address. */ \
|
||||||
"LDR LR, [LR, #+60] \n\t" \
|
"LDR LR, [LR, #+60] \n\t"\
|
||||||
\
|
\
|
||||||
/* And return - correcting the offset in the LR to obtain the */ \
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
/* correct address. */ \
|
/* correct address. */ \
|
||||||
"SUBS PC, LR, #4 \n\t" \
|
"SUBS PC, LR, #4 \n\t"\
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Push R0 as we are going to use the register. */ \
|
/* Push R0 as we are going to use the register. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" \
|
"STMDB SP!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Set R0 to point to the task stack pointer. */ \
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
"STMDB SP,{SP}^ \n\t" \
|
"STMDB SP,{SP}^ \n\t"\
|
||||||
"NOP \n\t" \
|
"NOP \n\t"\
|
||||||
"SUB SP, SP, #4 \n\t" \
|
"SUB SP, SP, #4 \n\t"\
|
||||||
"LDMIA SP!,{R0} \n\t" \
|
"LDMIA SP!,{R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Push the return address onto the stack. */ \
|
/* Push the return address onto the stack. */ \
|
||||||
"STMDB R0!, {LR} \n\t" \
|
"STMDB R0!, {LR} \n\t"\
|
||||||
\
|
\
|
||||||
/* Now we have saved LR we can use it instead of R0. */ \
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
"MOV LR, R0 \n\t" \
|
"MOV LR, R0 \n\t"\
|
||||||
\
|
\
|
||||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
"LDMIA SP!, {R0} \n\t" \
|
"LDMIA SP!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Push all the system mode registers onto the task stack. */ \
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
"STMDB LR,{R0-LR}^ \n\t" \
|
"STMDB LR,{R0-LR}^ \n\t"\
|
||||||
"NOP \n\t" \
|
"NOP \n\t"\
|
||||||
"SUB LR, LR, #60 \n\t" \
|
"SUB LR, LR, #60 \n\t"\
|
||||||
\
|
\
|
||||||
/* Push the SPSR onto the task stack. */ \
|
/* Push the SPSR onto the task stack. */ \
|
||||||
"MRS R0, SPSR \n\t" \
|
"MRS R0, SPSR \n\t"\
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t"\
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t"\
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Store the new top of stack for the task. */ \
|
/* Store the new top of stack for the task. */ \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t"\
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t"\
|
||||||
"STR LR, [R0] \n\t" \
|
"STR LR, [R0] \n\t"\
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void vTaskSwitchContext( void );
|
extern void vTaskSwitchContext( void );
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -178,48 +178,47 @@ extern void vTaskSwitchContext( void );
|
||||||
* defined then the utilities are defined as macros here - as per other ports.
|
* defined then the utilities are defined as macros here - as per other ports.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */\
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */\
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */\
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */\
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} ") /* Pop R0. */
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */\
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */\
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */\
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */\
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} ") /* Pop R0. */
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,12 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||||
*
|
*
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in this file. The ISR routines, which can only be compiled
|
* contained in this file. The ISR routines, which can only be compiled
|
||||||
* to ARM mode are contained in portISR.c.
|
* to ARM mode are contained in portISR.c.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
|
|
@ -77,22 +77,24 @@ extern void vPortISRStartFirstTask( void );
|
||||||
*
|
*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
StackType_t *pxOriginalTOS;
|
StackType_t * pxOriginalTOS;
|
||||||
|
|
||||||
pxOriginalTOS = pxTopOfStack;
|
pxOriginalTOS = pxTopOfStack;
|
||||||
|
|
||||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||||
is not really required. */
|
* is not really required. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. */
|
* expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First on the stack is the return address - which in this case is the
|
/* First on the stack is the return address - which in this case is the
|
||||||
start of the task. The offset is added to make the return address appear
|
* start of the task. The offset is added to make the return address appear
|
||||||
as it would within an IRQ ISR. */
|
* as it would within an IRQ ISR. */
|
||||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
|
|
@ -126,12 +128,12 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* When the task starts is will expect to find the function parameter in
|
/* When the task starts is will expect to find the function parameter in
|
||||||
R0. */
|
* R0. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The last thing onto the stack is the status register, which is set for
|
/* The last thing onto the stack is the status register, which is set for
|
||||||
system mode, with interrupts enabled. */
|
* system mode, with interrupts enabled. */
|
||||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||||
|
|
||||||
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
||||||
|
|
@ -143,9 +145,9 @@ StackType_t *pxOriginalTOS;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* Some optimisation levels use the stack differently to others. This
|
/* Some optimisation levels use the stack differently to others. This
|
||||||
means the interrupt flags cannot always be stored on the stack and will
|
* means the interrupt flags cannot always be stored on the stack and will
|
||||||
instead be stored in a variable, which is then saved as part of the
|
* instead be stored in a variable, which is then saved as part of the
|
||||||
tasks context. */
|
* tasks context. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
|
@ -155,7 +157,7 @@ StackType_t *pxOriginalTOS;
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
here already. */
|
* here already. */
|
||||||
prvSetupTimerInterrupt();
|
prvSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
|
|
@ -169,7 +171,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* It is unlikely that the ARM port will require this function as there
|
/* It is unlikely that the ARM port will require this function as there
|
||||||
is nothing to return to. */
|
* is nothing to return to. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -178,21 +180,21 @@ void vPortEndScheduler( void )
|
||||||
*/
|
*/
|
||||||
static void prvSetupTimerInterrupt( void )
|
static void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
uint32_t ulCompareMatch;
|
uint32_t ulCompareMatch;
|
||||||
|
|
||||||
PCLKSEL0 = (PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
|
PCLKSEL0 = ( PCLKSEL0 & ( ~( 0x3 << 2 ) ) ) | ( 0x01 << 2 );
|
||||||
T0TCR = 2; /* Stop and reset the timer */
|
T0TCR = 2; /* Stop and reset the timer */
|
||||||
T0CTCR = 0; /* Timer mode */
|
T0CTCR = 0; /* Timer mode */
|
||||||
|
|
||||||
/* A 1ms tick does not require the use of the timer prescale. This is
|
/* A 1ms tick does not require the use of the timer prescale. This is
|
||||||
defaulted to zero but can be used if necessary. */
|
* defaulted to zero but can be used if necessary. */
|
||||||
T0PR = portPRESCALE_VALUE;
|
T0PR = portPRESCALE_VALUE;
|
||||||
|
|
||||||
/* Calculate the match value required for our wanted tick rate. */
|
/* Calculate the match value required for our wanted tick rate. */
|
||||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||||
|
|
||||||
/* Protect against divide by zero. Using an if() statement still results
|
/* Protect against divide by zero. Using an if() statement still results
|
||||||
in a warning - hence the #if. */
|
* in a warning - hence the #if. */
|
||||||
#if portPRESCALE_VALUE != 0
|
#if portPRESCALE_VALUE != 0
|
||||||
{
|
{
|
||||||
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||||
|
|
@ -201,21 +203,21 @@ uint32_t ulCompareMatch;
|
||||||
T0MR1 = ulCompareMatch;
|
T0MR1 = ulCompareMatch;
|
||||||
|
|
||||||
/* Generate tick with timer 0 compare match. */
|
/* Generate tick with timer 0 compare match. */
|
||||||
T0MCR = (3 << 3); /* Reset timer on match and generate interrupt */
|
T0MCR = ( 3 << 3 ); /* Reset timer on match and generate interrupt */
|
||||||
|
|
||||||
/* Setup the VIC for the timer. */
|
/* Setup the VIC for the timer. */
|
||||||
VICIntEnable = 0x00000010;
|
VICIntEnable = 0x00000010;
|
||||||
|
|
||||||
/* The ISR installed depends on whether the preemptive or cooperative
|
/* The ISR installed depends on whether the preemptive or cooperative
|
||||||
scheduler is being used. */
|
* scheduler is being used. */
|
||||||
#if configUSE_PREEMPTION == 1
|
#if configUSE_PREEMPTION == 1
|
||||||
{
|
{
|
||||||
extern void ( vPreemptiveTick )( void );
|
extern void( vPreemptiveTick )( void );
|
||||||
VICVectAddr4 = ( int32_t ) vPreemptiveTick;
|
VICVectAddr4 = ( int32_t ) vPreemptiveTick;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
extern void ( vNonPreemptiveTick )( void );
|
extern void( vNonPreemptiveTick )( void );
|
||||||
VICVectAddr4 = ( int32_t ) vNonPreemptiveTick;
|
VICVectAddr4 = ( int32_t ) vNonPreemptiveTick;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -223,10 +225,7 @@ uint32_t ulCompareMatch;
|
||||||
VICVectCntl4 = 1;
|
VICVectCntl4 = 1;
|
||||||
|
|
||||||
/* Start the timer - interrupts are disabled when this function is called
|
/* Start the timer - interrupts are disabled when this function is called
|
||||||
so it is okay to do this here. */
|
* so it is okay to do this here. */
|
||||||
T0TCR = portENABLE_TIMER;
|
T0TCR = portENABLE_TIMER;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,10 @@
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Components that can be compiled to either ARM or THUMB mode are
|
* Components that can be compiled to either ARM or THUMB mode are
|
||||||
* contained in port.c The ISR routines, which can only be compiled
|
* contained in port.c The ISR routines, which can only be compiled
|
||||||
* to ARM mode, are contained in this file.
|
* to ARM mode, are contained in this file.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
|
@ -46,7 +46,7 @@ volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
void vPortYieldProcessor( void ) __attribute__( ( interrupt( "SWI" ), naked ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||||
|
|
@ -58,7 +58,7 @@ void vPortISRStartFirstTask( void );
|
||||||
void vPortISRStartFirstTask( void )
|
void vPortISRStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* Simply start the scheduler. This is included here as it can only be
|
/* Simply start the scheduler. This is included here as it can only be
|
||||||
called from ARM mode. */
|
* called from ARM mode. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -74,15 +74,15 @@ void vPortISRStartFirstTask( void )
|
||||||
void vPortYieldProcessor( void )
|
void vPortYieldProcessor( void )
|
||||||
{
|
{
|
||||||
/* Within an IRQ ISR the link register has an offset from the true return
|
/* Within an IRQ ISR the link register has an offset from the true return
|
||||||
address, but an SWI ISR does not. Add the offset manually so the same
|
* address, but an SWI ISR does not. Add the offset manually so the same
|
||||||
ISR return code can be used in both cases. */
|
* ISR return code can be used in both cases. */
|
||||||
__asm volatile ( "ADD LR, LR, #4" );
|
__asm volatile ( "ADD LR, LR, #4");
|
||||||
|
|
||||||
/* Perform the context switch. First save the context of the current task. */
|
/* Perform the context switch. First save the context of the current task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
/* Find the highest priority task that is ready to run. */
|
/* Find the highest priority task that is ready to run. */
|
||||||
__asm volatile( "bl vTaskSwitchContext" );
|
__asm volatile ( "bl vTaskSwitchContext");
|
||||||
|
|
||||||
/* Restore the context of the new task. */
|
/* Restore the context of the new task. */
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
|
|
@ -97,9 +97,9 @@ void vPortYieldProcessor( void )
|
||||||
|
|
||||||
#if configUSE_PREEMPTION == 0
|
#if configUSE_PREEMPTION == 0
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
simply increment the system tick. */
|
* simply increment the system tick. */
|
||||||
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
||||||
void vNonPreemptiveTick( void )
|
void vNonPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
|
|
@ -107,24 +107,24 @@ void vPortYieldProcessor( void )
|
||||||
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else /* if configUSE_PREEMPTION == 0 */
|
||||||
|
|
||||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||||
saved on entry as part of the context switch. */
|
* saved on entry as part of the context switch. */
|
||||||
void vPreemptiveTick( void ) __attribute__((naked));
|
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
||||||
void vPreemptiveTick( void )
|
void vPreemptiveTick( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
portSAVE_CONTEXT();
|
portSAVE_CONTEXT();
|
||||||
|
|
||||||
/* Increment the RTOS tick count, then look for the highest priority
|
/* Increment the RTOS tick count, then look for the highest priority
|
||||||
task that is ready to run. */
|
* task that is ready to run. */
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" bl xTaskIncrementTick \t\n" \
|
" bl xTaskIncrementTick \t\n"\
|
||||||
" cmp r0, #0 \t\n" \
|
" cmp r0, #0 \t\n"\
|
||||||
" beq SkipContextSwitch \t\n" \
|
" beq SkipContextSwitch \t\n"\
|
||||||
" bl vTaskSwitchContext \t\n" \
|
" bl vTaskSwitchContext \t\n"\
|
||||||
"SkipContextSwitch: \t\n"
|
"SkipContextSwitch: \t\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -136,7 +136,7 @@ void vPortYieldProcessor( void )
|
||||||
portRESTORE_CONTEXT();
|
portRESTORE_CONTEXT();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* if configUSE_PREEMPTION == 0 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -147,50 +147,50 @@ void vPortYieldProcessor( void )
|
||||||
*/
|
*/
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
void vPortDisableInterruptsFromThumb( void )
|
void vPortDisableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14"); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vPortEnableInterruptsFromThumb( void )
|
void vPortEnableInterruptsFromThumb( void )
|
||||||
{
|
{
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
"LDMIA SP!, {R0} \n\t"/* Pop R0. */
|
||||||
"BX R14" ); /* Return back to thumb. */
|
"BX R14"); /* Return back to thumb. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||||
different optimisation levels. The interrupt flags can therefore not always
|
* different optimisation levels. The interrupt flags can therefore not always
|
||||||
be saved to the stack. Instead the critical section nesting level is stored
|
* be saved to the stack. Instead the critical section nesting level is stored
|
||||||
in a variable, which is then saved as part of the stack context. */
|
* in a variable, which is then saved as part of the stack context. */
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
"ORR R0, R0, #0xC0 \n\t"/* Disable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}"); /* Pop R0. */
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,16 +202,16 @@ void vPortExitCritical( void )
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then interrupts should be
|
/* If the nesting level has reached zero then interrupts should be
|
||||||
re-enabled. */
|
* re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
"STMDB SP!, {R0} \n\t"/* Push R0. */
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
"MRS R0, CPSR \n\t"/* Get CPSR. */
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
"BIC R0, R0, #0xC0 \n\t"/* Enable IRQ, FIQ. */
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
"MSR CPSR, R0 \n\t"/* Write back modified value. */
|
||||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
"LDMIA SP!, {R0}"); /* Pop R0. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,34 +25,34 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes from V3.2.3
|
* Changes from V3.2.3
|
||||||
|
*
|
||||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||||
|
+
|
||||||
Changes from V3.2.4
|
+ Changes from V3.2.4
|
||||||
|
+
|
||||||
+ Removed the use of the %0 parameter within the assembler macros and
|
+ Removed the use of the %0 parameter within the assembler macros and
|
||||||
replaced them with hard coded registers. This will ensure the
|
+ replaced them with hard coded registers. This will ensure the
|
||||||
assembler does not select the link register as the temp register as
|
+ assembler does not select the link register as the temp register as
|
||||||
was occasionally happening previously.
|
+ was occasionally happening previously.
|
||||||
|
+
|
||||||
+ The assembler statements are now included in a single asm block rather
|
+ The assembler statements are now included in a single asm block rather
|
||||||
than each line having its own asm block.
|
+ than each line having its own asm block.
|
||||||
|
+
|
||||||
Changes from V4.5.0
|
+ Changes from V4.5.0
|
||||||
|
+
|
||||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||||
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
+ and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||||
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
+ should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||||
macros as per the V4.5.1 demo code.
|
+ macros as per the V4.5.1 demo code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -65,32 +65,32 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE portLONG
|
#define portBASE_TYPE portLONG
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP() __asm volatile ( "NOP" );
|
#define portNOP() __asm volatile ( "NOP" );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -103,92 +103,92 @@ typedef unsigned long UBaseType_t;
|
||||||
* THUMB mode code will result in a compile time error.
|
* THUMB mode code will result in a compile time error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Set the LR to the task stack. */ \
|
/* Set the LR to the task stack. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t"\
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t"\
|
||||||
"LDR LR, [R0] \n\t" \
|
"LDR LR, [R0] \n\t"\
|
||||||
\
|
\
|
||||||
/* The critical nesting depth is the first item on the stack. */ \
|
/* The critical nesting depth is the first item on the stack. */ \
|
||||||
/* Load it into the ulCriticalNesting variable. */ \
|
/* Load it into the ulCriticalNesting variable. */ \
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t"\
|
||||||
"LDMFD LR!, {R1} \n\t" \
|
"LDMFD LR!, {R1} \n\t"\
|
||||||
"STR R1, [R0] \n\t" \
|
"STR R1, [R0] \n\t"\
|
||||||
\
|
\
|
||||||
/* Get the SPSR from the stack. */ \
|
/* Get the SPSR from the stack. */ \
|
||||||
"LDMFD LR!, {R0} \n\t" \
|
"LDMFD LR!, {R0} \n\t"\
|
||||||
"MSR SPSR, R0 \n\t" \
|
"MSR SPSR, R0 \n\t"\
|
||||||
\
|
\
|
||||||
/* Restore all system mode registers for the task. */ \
|
/* Restore all system mode registers for the task. */ \
|
||||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
"LDMFD LR, {R0-R14}^ \n\t"\
|
||||||
"NOP \n\t" \
|
"NOP \n\t"\
|
||||||
\
|
\
|
||||||
/* Restore the return address. */ \
|
/* Restore the return address. */ \
|
||||||
"LDR LR, [LR, #+60] \n\t" \
|
"LDR LR, [LR, #+60] \n\t"\
|
||||||
\
|
\
|
||||||
/* And return - correcting the offset in the LR to obtain the */ \
|
/* And return - correcting the offset in the LR to obtain the */ \
|
||||||
/* correct address. */ \
|
/* correct address. */ \
|
||||||
"SUBS PC, LR, #4 \n\t" \
|
"SUBS PC, LR, #4 \n\t"\
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
{ \
|
{ \
|
||||||
extern volatile void * volatile pxCurrentTCB; \
|
extern volatile void * volatile pxCurrentTCB; \
|
||||||
extern volatile uint32_t ulCriticalNesting; \
|
extern volatile uint32_t ulCriticalNesting; \
|
||||||
\
|
\
|
||||||
/* Push R0 as we are going to use the register. */ \
|
/* Push R0 as we are going to use the register. */ \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" \
|
"STMDB SP!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Set R0 to point to the task stack pointer. */ \
|
/* Set R0 to point to the task stack pointer. */ \
|
||||||
"STMDB SP,{SP}^ \n\t" \
|
"STMDB SP,{SP}^ \n\t"\
|
||||||
"NOP \n\t" \
|
"NOP \n\t"\
|
||||||
"SUB SP, SP, #4 \n\t" \
|
"SUB SP, SP, #4 \n\t"\
|
||||||
"LDMIA SP!,{R0} \n\t" \
|
"LDMIA SP!,{R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Push the return address onto the stack. */ \
|
/* Push the return address onto the stack. */ \
|
||||||
"STMDB R0!, {LR} \n\t" \
|
"STMDB R0!, {LR} \n\t"\
|
||||||
\
|
\
|
||||||
/* Now we have saved LR we can use it instead of R0. */ \
|
/* Now we have saved LR we can use it instead of R0. */ \
|
||||||
"MOV LR, R0 \n\t" \
|
"MOV LR, R0 \n\t"\
|
||||||
\
|
\
|
||||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||||
"LDMIA SP!, {R0} \n\t" \
|
"LDMIA SP!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Push all the system mode registers onto the task stack. */ \
|
/* Push all the system mode registers onto the task stack. */ \
|
||||||
"STMDB LR,{R0-LR}^ \n\t" \
|
"STMDB LR,{R0-LR}^ \n\t"\
|
||||||
"NOP \n\t" \
|
"NOP \n\t"\
|
||||||
"SUB LR, LR, #60 \n\t" \
|
"SUB LR, LR, #60 \n\t"\
|
||||||
\
|
\
|
||||||
/* Push the SPSR onto the task stack. */ \
|
/* Push the SPSR onto the task stack. */ \
|
||||||
"MRS R0, SPSR \n\t" \
|
"MRS R0, SPSR \n\t"\
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
"LDR R0, =ulCriticalNesting \n\t" \
|
"LDR R0, =ulCriticalNesting \n\t"\
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t"\
|
||||||
"STMDB LR!, {R0} \n\t" \
|
"STMDB LR!, {R0} \n\t"\
|
||||||
\
|
\
|
||||||
/* Store the new top of stack for the task. */ \
|
/* Store the new top of stack for the task. */ \
|
||||||
"LDR R0, =pxCurrentTCB \n\t" \
|
"LDR R0, =pxCurrentTCB \n\t"\
|
||||||
"LDR R0, [R0] \n\t" \
|
"LDR R0, [R0] \n\t"\
|
||||||
"STR LR, [R0] \n\t" \
|
"STR LR, [R0] \n\t"\
|
||||||
); \
|
); \
|
||||||
( void ) ulCriticalNesting; \
|
( void ) ulCriticalNesting; \
|
||||||
( void ) pxCurrentTCB; \
|
( void ) pxCurrentTCB; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -201,48 +201,47 @@ extern volatile uint32_t ulCriticalNesting; \
|
||||||
* defined then the utilities are defined as macros here - as per other ports.
|
* defined then the utilities are defined as macros here - as per other ports.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef THUMB_INTERWORK
|
#ifdef THUMB_INTERWORK
|
||||||
|
|
||||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */\
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */\
|
||||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */\
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */\
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} ") /* Pop R0. */
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( \
|
__asm volatile ( \
|
||||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
"STMDB SP!, {R0} \n\t" /* Push R0. */\
|
||||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
"MRS R0, CPSR \n\t" /* Get CPSR. */\
|
||||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */\
|
||||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
"MSR CPSR, R0 \n\t" /* Write back modified value. */\
|
||||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
"LDMIA SP!, {R0} ") /* Pop R0. */
|
||||||
|
|
||||||
#endif /* THUMB_INTERWORK */
|
#endif /* THUMB_INTERWORK */
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,23 +32,23 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
||||||
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
||||||
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
||||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configSETUP_TICK_INTERRUPT
|
#ifndef configSETUP_TICK_INTERRUPT
|
||||||
#error configSETUP_TICK_INTERRUPT() must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error configSETUP_TICK_INTERRUPT() must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||||
#endif /* configSETUP_TICK_INTERRUPT */
|
#endif /* configSETUP_TICK_INTERRUPT */
|
||||||
|
|
||||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
||||||
|
|
@ -61,7 +61,7 @@
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if( configMAX_PRIORITIES > 32 )
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
@ -72,24 +72,24 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||||
portmacro.h. */
|
* portmacro.h. */
|
||||||
#ifndef configCLEAR_TICK_INTERRUPT
|
#ifndef configCLEAR_TICK_INTERRUPT
|
||||||
#define configCLEAR_TICK_INTERRUPT()
|
#define configCLEAR_TICK_INTERRUPT()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* A critical section is exited when the critical section nesting count reaches
|
/* A critical section is exited when the critical section nesting count reaches
|
||||||
this value. */
|
* this value. */
|
||||||
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
|
||||||
|
|
||||||
/* In all GICs 255 can be written to the priority mask register to unmask all
|
/* In all GICs 255 can be written to the priority mask register to unmask all
|
||||||
(but the lowest) interrupt priority. */
|
* (but the lowest) interrupt priority. */
|
||||||
#define portUNMASK_VALUE ( 0xFFUL )
|
#define portUNMASK_VALUE ( 0xFFUL )
|
||||||
|
|
||||||
/* Tasks are not created with a floating point context, but can be given a
|
/* Tasks are not created with a floating point context, but can be given a
|
||||||
floating point context after they have been created. A variable is stored as
|
* floating point context after they have been created. A variable is stored as
|
||||||
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||||
does not have an FPU context, or any other value if the task does have an FPU
|
* does not have an FPU context, or any other value if the task does have an FPU
|
||||||
context. */
|
* context. */
|
||||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to setup the initial task context. */
|
/* Constants required to setup the initial task context. */
|
||||||
|
|
@ -107,7 +107,7 @@ context. */
|
||||||
|
|
||||||
|
|
||||||
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
||||||
point is zero. */
|
* point is zero. */
|
||||||
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
||||||
|
|
||||||
/* Masks all bits in the APSR other than the mode bits. */
|
/* Masks all bits in the APSR other than the mode bits. */
|
||||||
|
|
@ -118,13 +118,13 @@ point is zero. */
|
||||||
|
|
||||||
/* Macro to unmask all interrupt priorities. */
|
/* Macro to unmask all interrupt priorities. */
|
||||||
#define portCLEAR_INTERRUPT_MASK() \
|
#define portCLEAR_INTERRUPT_MASK() \
|
||||||
{ \
|
{ \
|
||||||
portDISABLE_INTERRUPTS(); \
|
portDISABLE_INTERRUPTS(); \
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
||||||
__asm volatile ( "DSB SY \n" \
|
__asm volatile ( "DSB SY \n" \
|
||||||
"ISB SY \n" ); \
|
"ISB SY \n"); \
|
||||||
portENABLE_INTERRUPTS(); \
|
portENABLE_INTERRUPTS(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hardware specifics used when sanity checking the configuration. */
|
/* Hardware specifics used when sanity checking the configuration. */
|
||||||
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
||||||
|
|
@ -142,38 +142,40 @@ extern void vPortRestoreTaskContext( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* A variable is used to keep track of the critical section nesting. This
|
/* 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 must be initialised to
|
* variable has to be stored as part of the task context and must be initialised to
|
||||||
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
* a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||||
the scheduler starts. As it is stored as part of the task context it will
|
* the scheduler starts. As it is stored as part of the task context it will
|
||||||
automatically be set to 0 when the first task is started. */
|
* automatically be set to 0 when the first task is started. */
|
||||||
volatile uint64_t ullCriticalNesting = 9999ULL;
|
volatile uint64_t ullCriticalNesting = 9999ULL;
|
||||||
|
|
||||||
/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
|
/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
|
||||||
then floating point context must be saved and restored for the task. */
|
* then floating point context must be saved and restored for the task. */
|
||||||
uint64_t ullPortTaskHasFPUContext = pdFALSE;
|
uint64_t ullPortTaskHasFPUContext = pdFALSE;
|
||||||
|
|
||||||
/* Set to 1 to pend a context switch from an ISR. */
|
/* Set to 1 to pend a context switch from an ISR. */
|
||||||
uint64_t ullPortYieldRequired = pdFALSE;
|
uint64_t ullPortYieldRequired = pdFALSE;
|
||||||
|
|
||||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||||
if the nesting depth is 0. */
|
* if the nesting depth is 0. */
|
||||||
uint64_t ullPortInterruptNesting = 0;
|
uint64_t ullPortInterruptNesting = 0;
|
||||||
|
|
||||||
/* Used in the ASM code. */
|
/* Used in the ASM code. */
|
||||||
__attribute__(( used )) const uint64_t ullICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
__attribute__( ( used ) ) const uint64_t ullICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
||||||
__attribute__(( used )) const uint64_t ullICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
__attribute__( ( used ) ) const uint64_t ullICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
||||||
__attribute__(( used )) const uint64_t ullICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
__attribute__( ( used ) ) const uint64_t ullICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
||||||
__attribute__(( used )) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
__attribute__( ( used ) ) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro. */
|
* expected by the portRESTORE_CONTEXT() macro. */
|
||||||
|
|
||||||
/* First all the general purpose registers. */
|
/* First all the general purpose registers. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
@ -249,13 +251,13 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||||
enabled. */
|
* enabled. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The task will start without a floating point context. A task that uses
|
/* The task will start without a floating point context. A task that uses
|
||||||
the floating point hardware must call vPortTaskUsesFPU() before executing
|
* the floating point hardware must call vPortTaskUsesFPU() before executing
|
||||||
any floating point instructions. */
|
* any floating point instructions. */
|
||||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
|
@ -264,21 +266,21 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulAPSR;
|
uint32_t ulAPSR;
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
volatile uint32_t ulOriginalPriority;
|
||||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine how many priority bits are implemented in the GIC.
|
/* Determine how many priority bits are implemented in the GIC.
|
||||||
|
*
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
* Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to
|
/* Determine the number of priority bits available. First write to
|
||||||
all possible bits. */
|
* all possible bits. */
|
||||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
|
@ -291,13 +293,13 @@ uint32_t ulAPSR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
||||||
value. */
|
* value. */
|
||||||
|
|
||||||
configASSERT( ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY );
|
configASSERT( ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY );
|
||||||
|
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
* value. */
|
||||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||||
}
|
}
|
||||||
#endif /* conifgASSERT_DEFINED */
|
#endif /* conifgASSERT_DEFINED */
|
||||||
|
|
@ -307,26 +309,28 @@ uint32_t ulAPSR;
|
||||||
__asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) );
|
__asm volatile ( "MRS %0, CurrentEL" : "=r" ( ulAPSR ) );
|
||||||
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
||||||
|
|
||||||
#if defined( GUEST )
|
#if defined( GUEST )
|
||||||
#warning Building for execution as a guest under XEN. THIS IS NOT A FULLY TESTED PATH.
|
#warning Building for execution as a guest under XEN. THIS IS NOT A FULLY TESTED PATH.
|
||||||
configASSERT( ulAPSR == portEL1 );
|
configASSERT( ulAPSR == portEL1 );
|
||||||
|
|
||||||
if( ulAPSR == portEL1 )
|
if( ulAPSR == portEL1 )
|
||||||
#else
|
#else
|
||||||
configASSERT( ulAPSR == portEL3 );
|
configASSERT( ulAPSR == portEL3 );
|
||||||
|
|
||||||
if( ulAPSR == portEL3 )
|
if( ulAPSR == portEL3 )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* Only continue if the binary point value is set to its lowest possible
|
/* Only continue if the binary point value is set to its lowest possible
|
||||||
setting. See the comments in vPortValidateInterruptPriority() below for
|
* setting. See the comments in vPortValidateInterruptPriority() below for
|
||||||
more information. */
|
* more information. */
|
||||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||||
|
|
||||||
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
||||||
{
|
{
|
||||||
/* Interrupts are turned off in the CPU itself to ensure a tick does
|
/* Interrupts are turned off in the CPU itself to ensure a tick does
|
||||||
not execute while the scheduler is being started. Interrupts are
|
* not execute while the scheduler is being started. Interrupts are
|
||||||
automatically turned back on in the CPU when the first task starts
|
* automatically turned back on in the CPU when the first task starts
|
||||||
executing. */
|
* executing. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. */
|
/* Start the timer that generates the tick ISR. */
|
||||||
|
|
@ -344,7 +348,7 @@ uint32_t ulAPSR;
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Not implemented in ports where there is nothing to return to.
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
Artificially force an assert. */
|
* Artificially force an assert. */
|
||||||
configASSERT( ullCriticalNesting == 1000ULL );
|
configASSERT( ullCriticalNesting == 1000ULL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -355,15 +359,15 @@ void vPortEnterCritical( void )
|
||||||
uxPortSetInterruptMask();
|
uxPortSetInterruptMask();
|
||||||
|
|
||||||
/* Now interrupts are disabled ullCriticalNesting can be accessed
|
/* Now interrupts are disabled ullCriticalNesting can be accessed
|
||||||
directly. Increment ullCriticalNesting to keep a count of how many times
|
* directly. Increment ullCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ullCriticalNesting++;
|
ullCriticalNesting++;
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
assert() if it is being called from an interrupt context. Only API
|
* assert() if it is being called from an interrupt context. Only API
|
||||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||||
the critical nesting count is 1 to protect against recursive calls if the
|
* the critical nesting count is 1 to protect against recursive calls if the
|
||||||
assert function also uses a critical section. */
|
* assert function also uses a critical section. */
|
||||||
if( ullCriticalNesting == 1ULL )
|
if( ullCriticalNesting == 1ULL )
|
||||||
{
|
{
|
||||||
configASSERT( ullPortInterruptNesting == 0 );
|
configASSERT( ullPortInterruptNesting == 0 );
|
||||||
|
|
@ -376,15 +380,15 @@ void vPortExitCritical( void )
|
||||||
if( ullCriticalNesting > portNO_CRITICAL_NESTING )
|
if( ullCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Decrement the nesting count as the critical section is being
|
/* Decrement the nesting count as the critical section is being
|
||||||
exited. */
|
* exited. */
|
||||||
ullCriticalNesting--;
|
ullCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then all interrupt
|
/* If the nesting level has reached zero then all interrupt
|
||||||
priorities must be re-enabled. */
|
* priorities must be re-enabled. */
|
||||||
if( ullCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ullCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Critical nesting has reached zero so all interrupt priorities
|
/* Critical nesting has reached zero so all interrupt priorities
|
||||||
should be unmasked. */
|
* should be unmasked. */
|
||||||
portCLEAR_INTERRUPT_MASK();
|
portCLEAR_INTERRUPT_MASK();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -401,23 +405,23 @@ void FreeRTOS_Tick_Handler( void )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Interrupts should not be enabled before this point. */
|
/* Interrupts should not be enabled before this point. */
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
uint32_t ulMaskBits;
|
uint32_t ulMaskBits;
|
||||||
|
|
||||||
__asm volatile( "mrs %0, daif" : "=r"( ulMaskBits ) :: "memory" );
|
__asm volatile ( "mrs %0, daif" : "=r" ( ulMaskBits )::"memory" );
|
||||||
configASSERT( ( ulMaskBits & portDAIF_I ) != 0 );
|
configASSERT( ( ulMaskBits & portDAIF_I ) != 0 );
|
||||||
}
|
}
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/* Set interrupt mask before altering scheduler structures. The tick
|
/* Set interrupt mask before altering scheduler structures. The tick
|
||||||
handler runs at the lowest priority, so interrupts cannot already be masked,
|
* handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||||
so there is no need to save and restore the current mask value. It is
|
* so there is no need to save and restore the current mask value. It is
|
||||||
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||||
updated. */
|
* updated. */
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
__asm volatile ( "dsb sy \n"
|
__asm volatile ( "dsb sy \n"
|
||||||
"isb sy \n" ::: "memory" );
|
"isb sy \n"::: "memory" );
|
||||||
|
|
||||||
/* Ok to enable interrupts after the interrupt source has been cleared. */
|
/* Ok to enable interrupts after the interrupt source has been cleared. */
|
||||||
configCLEAR_TICK_INTERRUPT();
|
configCLEAR_TICK_INTERRUPT();
|
||||||
|
|
@ -437,11 +441,11 @@ void FreeRTOS_Tick_Handler( void )
|
||||||
void vPortTaskUsesFPU( void )
|
void vPortTaskUsesFPU( void )
|
||||||
{
|
{
|
||||||
/* A task is registering the fact that it needs an FPU context. Set the
|
/* A task is registering the fact that it needs an FPU context. Set the
|
||||||
FPU flag (which is saved as part of the task context). */
|
* FPU flag (which is saved as part of the task context). */
|
||||||
ullPortTaskHasFPUContext = pdTRUE;
|
ullPortTaskHasFPUContext = pdTRUE;
|
||||||
|
|
||||||
/* Consider initialising the FPSR here - but probably not necessary in
|
/* Consider initialising the FPSR here - but probably not necessary in
|
||||||
AArch64. */
|
* AArch64. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -456,11 +460,12 @@ void vPortClearInterruptMask( UBaseType_t uxNewMaskValue )
|
||||||
|
|
||||||
UBaseType_t uxPortSetInterruptMask( void )
|
UBaseType_t uxPortSetInterruptMask( void )
|
||||||
{
|
{
|
||||||
uint32_t ulReturn;
|
uint32_t ulReturn;
|
||||||
|
|
||||||
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
||||||
updated. */
|
* updated. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
||||||
{
|
{
|
||||||
/* Interrupts were already masked. */
|
/* Interrupts were already masked. */
|
||||||
|
|
@ -471,47 +476,47 @@ uint32_t ulReturn;
|
||||||
ulReturn = pdFALSE;
|
ulReturn = pdFALSE;
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
__asm volatile ( "dsb sy \n"
|
__asm volatile ( "dsb sy \n"
|
||||||
"isb sy \n" ::: "memory" );
|
"isb sy \n"::: "memory" );
|
||||||
}
|
}
|
||||||
|
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
return ulReturn;
|
return ulReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
void vPortValidateInterruptPriority( void )
|
||||||
{
|
{
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
/* The following assertion will fail if a service routine (ISR) for
|
||||||
an interrupt that has been assigned a priority above
|
* an interrupt that has been assigned a priority above
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||||
function. ISR safe FreeRTOS API functions must *only* be called
|
* function. ISR safe FreeRTOS API functions must *only* be called
|
||||||
from interrupts that have been assigned a priority at or below
|
* from interrupts that have been assigned a priority at or below
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
Numerically low interrupt priority numbers represent logically high
|
* Numerically low interrupt priority numbers represent logically high
|
||||||
interrupt priorities, therefore the priority of the interrupt must
|
* interrupt priorities, therefore the priority of the interrupt must
|
||||||
be set to a value equal to or numerically *higher* than
|
* be set to a value equal to or numerically *higher* than
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||||
interrupt entry is as fast and simple as possible. */
|
* interrupt entry is as fast and simple as possible. */
|
||||||
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
||||||
|
|
||||||
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
||||||
that define each interrupt's priority to be split between bits that
|
* that define each interrupt's priority to be split between bits that
|
||||||
define the interrupt's pre-emption priority bits and bits that define
|
* define the interrupt's pre-emption priority bits and bits that define
|
||||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
* the interrupt's sub-priority. For simplicity all bits must be defined
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
* to be pre-emption priority bits. The following assertion will fail if
|
||||||
this is not the case (if some bits represent a sub-priority).
|
* this is not the case (if some bits represent a sub-priority).
|
||||||
|
*
|
||||||
The priority grouping is configured by the GIC's binary point register
|
* The priority grouping is configured by the GIC's binary point register
|
||||||
(ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
* (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||||
possible value (which may be above 0). */
|
* possible value (which may be above 0). */
|
||||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -42,169 +42,169 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE size_t
|
#define portSTACK_TYPE size_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef portBASE_TYPE BaseType_t;
|
typedef portBASE_TYPE BaseType_t;
|
||||||
typedef uint64_t UBaseType_t;
|
typedef uint64_t UBaseType_t;
|
||||||
|
|
||||||
typedef uint64_t TickType_t;
|
typedef uint64_t TickType_t;
|
||||||
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
|
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 16
|
#define portBYTE_ALIGNMENT 16
|
||||||
#define portPOINTER_SIZE_TYPE uint64_t
|
#define portPOINTER_SIZE_TYPE uint64_t
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
/* Called at the end of an ISR that can cause a context switch. */
|
/* Called at the end of an ISR that can cause a context switch. */
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired )\
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
{ \
|
{ \
|
||||||
extern uint64_t ullPortYieldRequired; \
|
extern uint64_t ullPortYieldRequired; \
|
||||||
\
|
\
|
||||||
if( xSwitchRequired != pdFALSE ) \
|
if( xSwitchRequired != pdFALSE ) \
|
||||||
{ \
|
{ \
|
||||||
ullPortYieldRequired = pdTRUE; \
|
ullPortYieldRequired = pdTRUE; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
#if defined( GUEST )
|
#if defined( GUEST )
|
||||||
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
#define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
|
||||||
#else
|
#else
|
||||||
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Critical section control
|
* Critical section control
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
extern UBaseType_t uxPortSetInterruptMask( void );
|
extern UBaseType_t uxPortSetInterruptMask( void );
|
||||||
extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue );
|
extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue );
|
||||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
#define portDISABLE_INTERRUPTS() \
|
||||||
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
__asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
|
||||||
__asm volatile ( "DSB SY" ); \
|
__asm volatile ( "DSB SY" ); \
|
||||||
__asm volatile ( "ISB SY" );
|
__asm volatile ( "ISB SY" );
|
||||||
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
#define portENABLE_INTERRUPTS() \
|
||||||
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
__asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
|
||||||
__asm volatile ( "DSB SY" ); \
|
__asm volatile ( "DSB SY" ); \
|
||||||
__asm volatile ( "ISB SY" );
|
__asm volatile ( "ISB SY" );
|
||||||
|
|
||||||
|
|
||||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||||
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
not required for this port but included in case common demo code that uses these
|
* not required for this port but included in case common demo code that uses these
|
||||||
macros is used. */
|
* macros is used. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||||
handler for whichever peripheral is used to generate the RTOS tick. */
|
* handler for whichever peripheral is used to generate the RTOS tick. */
|
||||||
void FreeRTOS_Tick_Handler( void );
|
void FreeRTOS_Tick_Handler( void );
|
||||||
|
|
||||||
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
||||||
before any floating point instructions are executed. */
|
* before any floating point instructions are executed. */
|
||||||
void vPortTaskUsesFPU( void );
|
void vPortTaskUsesFPU( void );
|
||||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||||
|
|
||||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif /* configASSERT */
|
#endif /* configASSERT */
|
||||||
|
|
||||||
#define portNOP() __asm volatile( "NOP" )
|
#define portNOP() __asm volatile ( "NOP" )
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern C */
|
} /* extern C */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* The number of bits to shift for an interrupt priority is dependent on the
|
/* The number of bits to shift for an interrupt priority is dependent on the
|
||||||
number of bits implemented by the interrupt controller. */
|
* number of bits implemented by the interrupt controller. */
|
||||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||||
#define portPRIORITY_SHIFT 4
|
#define portPRIORITY_SHIFT 4
|
||||||
#define portMAX_BINARY_POINT_VALUE 3
|
#define portMAX_BINARY_POINT_VALUE 3
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
||||||
#define portPRIORITY_SHIFT 3
|
#define portPRIORITY_SHIFT 3
|
||||||
#define portMAX_BINARY_POINT_VALUE 2
|
#define portMAX_BINARY_POINT_VALUE 2
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
||||||
#define portPRIORITY_SHIFT 2
|
#define portPRIORITY_SHIFT 2
|
||||||
#define portMAX_BINARY_POINT_VALUE 1
|
#define portMAX_BINARY_POINT_VALUE 1
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
||||||
#define portPRIORITY_SHIFT 1
|
#define portPRIORITY_SHIFT 1
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||||
#define portPRIORITY_SHIFT 0
|
#define portPRIORITY_SHIFT 0
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#else
|
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||||
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
||||||
#endif
|
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||||
|
|
||||||
/* Interrupt controller access addresses. */
|
/* Interrupt controller access addresses. */
|
||||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
||||||
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
||||||
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
||||||
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
||||||
|
|
||||||
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
||||||
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
||||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
||||||
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
||||||
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
||||||
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
||||||
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
||||||
|
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,23 +32,23 @@
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
||||||
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
||||||
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
||||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configSETUP_TICK_INTERRUPT
|
#ifndef configSETUP_TICK_INTERRUPT
|
||||||
#error configSETUP_TICK_INTERRUPT() must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error configSETUP_TICK_INTERRUPT() must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||||
#endif /* configSETUP_TICK_INTERRUPT */
|
#endif /* configSETUP_TICK_INTERRUPT */
|
||||||
|
|
||||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
||||||
|
|
@ -61,7 +61,7 @@
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if( configMAX_PRIORITIES > 32 )
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
@ -72,24 +72,24 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||||
portmacro.h. */
|
* portmacro.h. */
|
||||||
#ifndef configCLEAR_TICK_INTERRUPT
|
#ifndef configCLEAR_TICK_INTERRUPT
|
||||||
#define configCLEAR_TICK_INTERRUPT()
|
#define configCLEAR_TICK_INTERRUPT()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* A critical section is exited when the critical section nesting count reaches
|
/* A critical section is exited when the critical section nesting count reaches
|
||||||
this value. */
|
* this value. */
|
||||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||||
|
|
||||||
/* In all GICs 255 can be written to the priority mask register to unmask all
|
/* In all GICs 255 can be written to the priority mask register to unmask all
|
||||||
(but the lowest) interrupt priority. */
|
* (but the lowest) interrupt priority. */
|
||||||
#define portUNMASK_VALUE ( 0xFFUL )
|
#define portUNMASK_VALUE ( 0xFFUL )
|
||||||
|
|
||||||
/* Tasks are not created with a floating point context, but can be given a
|
/* Tasks are not created with a floating point context, but can be given a
|
||||||
floating point context after they have been created. A variable is stored as
|
* floating point context after they have been created. A variable is stored as
|
||||||
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||||
does not have an FPU context, or any other value if the task does have an FPU
|
* does not have an FPU context, or any other value if the task does have an FPU
|
||||||
context. */
|
* context. */
|
||||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||||
|
|
||||||
/* Constants required to setup the initial task context. */
|
/* Constants required to setup the initial task context. */
|
||||||
|
|
@ -99,19 +99,19 @@ context. */
|
||||||
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
|
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
|
||||||
|
|
||||||
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
||||||
point is zero. */
|
* point is zero. */
|
||||||
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
||||||
|
|
||||||
/* Masks all bits in the APSR other than the mode bits. */
|
/* Masks all bits in the APSR other than the mode bits. */
|
||||||
#define portAPSR_MODE_BITS_MASK ( 0x1F )
|
#define portAPSR_MODE_BITS_MASK ( 0x1F )
|
||||||
|
|
||||||
/* The value of the mode bits in the APSR when the CPU is executing in user
|
/* The value of the mode bits in the APSR when the CPU is executing in user
|
||||||
mode. */
|
* mode. */
|
||||||
#define portAPSR_USER_MODE ( 0x10 )
|
#define portAPSR_USER_MODE ( 0x10 )
|
||||||
|
|
||||||
/* The critical section macros only mask interrupts up to an application
|
/* The critical section macros only mask interrupts up to an application
|
||||||
determined priority level. Sometimes it is necessary to turn interrupt off in
|
* determined priority level. Sometimes it is necessary to turn interrupt off in
|
||||||
the CPU itself before modifying certain hardware registers. */
|
* the CPU itself before modifying certain hardware registers. */
|
||||||
#define portCPU_IRQ_DISABLE() \
|
#define portCPU_IRQ_DISABLE() \
|
||||||
__asm volatile ( "CPSID i" ::: "memory" ); \
|
__asm volatile ( "CPSID i" ::: "memory" ); \
|
||||||
__asm volatile ( "DSB" ); \
|
__asm volatile ( "DSB" ); \
|
||||||
|
|
@ -125,21 +125,21 @@ the CPU itself before modifying certain hardware registers. */
|
||||||
|
|
||||||
/* Macro to unmask all interrupt priorities. */
|
/* Macro to unmask all interrupt priorities. */
|
||||||
#define portCLEAR_INTERRUPT_MASK() \
|
#define portCLEAR_INTERRUPT_MASK() \
|
||||||
{ \
|
{ \
|
||||||
portCPU_IRQ_DISABLE(); \
|
portCPU_IRQ_DISABLE(); \
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
||||||
__asm volatile ( "DSB \n" \
|
__asm volatile ( "DSB \n" \
|
||||||
"ISB \n" ); \
|
"ISB \n"); \
|
||||||
portCPU_IRQ_ENABLE(); \
|
portCPU_IRQ_ENABLE(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
#define portINTERRUPT_PRIORITY_REGISTER_OFFSET 0x400UL
|
||||||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||||
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
||||||
|
|
||||||
/* Let the user override the pre-loading of the initial LR with the address of
|
/* Let the user override the pre-loading of the initial LR with the address of
|
||||||
prvTaskExitError() in case it messes up unwinding of the stack in the
|
* prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||||
debugger. */
|
* debugger. */
|
||||||
#ifdef configTASK_RETURN_ADDRESS
|
#ifdef configTASK_RETURN_ADDRESS
|
||||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||||
#else
|
#else
|
||||||
|
|
@ -147,7 +147,7 @@ debugger. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The space on the stack required to hold the FPU registers. This is 32 64-bit
|
/* The space on the stack required to hold the FPU registers. This is 32 64-bit
|
||||||
registers, plus a 32-bit status register. */
|
* registers, plus a 32-bit status register. */
|
||||||
#define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 )
|
#define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -182,47 +182,49 @@ static void prvTaskExitError( void );
|
||||||
* FPU registers to be saved on interrupt entry their IRQ handler must be
|
* FPU registers to be saved on interrupt entry their IRQ handler must be
|
||||||
* called vApplicationIRQHandler().
|
* called vApplicationIRQHandler().
|
||||||
*/
|
*/
|
||||||
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) );
|
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__( ( weak ) );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* A variable is used to keep track of the critical section nesting. This
|
/* 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 must be initialised to
|
* variable has to be stored as part of the task context and must be initialised to
|
||||||
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
* a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||||
the scheduler starts. As it is stored as part of the task context it will
|
* the scheduler starts. As it is stored as part of the task context it will
|
||||||
automatically be set to 0 when the first task is started. */
|
* automatically be set to 0 when the first task is started. */
|
||||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
|
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
|
||||||
a floating point context must be saved and restored for the task. */
|
* a floating point context must be saved and restored for the task. */
|
||||||
volatile uint32_t ulPortTaskHasFPUContext = pdFALSE;
|
volatile uint32_t ulPortTaskHasFPUContext = pdFALSE;
|
||||||
|
|
||||||
/* Set to 1 to pend a context switch from an ISR. */
|
/* Set to 1 to pend a context switch from an ISR. */
|
||||||
volatile uint32_t ulPortYieldRequired = pdFALSE;
|
volatile uint32_t ulPortYieldRequired = pdFALSE;
|
||||||
|
|
||||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||||
if the nesting depth is 0. */
|
* if the nesting depth is 0. */
|
||||||
volatile uint32_t ulPortInterruptNesting = 0UL;
|
volatile uint32_t ulPortInterruptNesting = 0UL;
|
||||||
|
|
||||||
/* Used in the asm file. */
|
/* Used in the asm file. */
|
||||||
__attribute__(( used )) const uint32_t ulICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
__attribute__( ( used ) ) const uint32_t ulICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS;
|
||||||
__attribute__(( used )) const uint32_t ulICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
__attribute__( ( used ) ) const uint32_t ulICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS;
|
||||||
__attribute__(( used )) const uint32_t ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
__attribute__( ( used ) ) const uint32_t ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS;
|
||||||
__attribute__(( used )) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
__attribute__( ( used ) ) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
/* Setup the initial stack of the task. The stack is set exactly as
|
/* Setup the initial stack of the task. The stack is set exactly as
|
||||||
expected by the portRESTORE_CONTEXT() macro.
|
* expected by the portRESTORE_CONTEXT() macro.
|
||||||
|
*
|
||||||
The fist real value on the stack is the status register, which is set for
|
* The fist real value on the stack is the status register, which is set for
|
||||||
system mode, with interrupts enabled. A few NULLs are added first to ensure
|
* system mode, with interrupts enabled. A few NULLs are added first to ensure
|
||||||
GDB does not try decoding a non-existent return address. */
|
* GDB does not try decoding a non-existent return address. */
|
||||||
*pxTopOfStack = ( StackType_t ) NULL;
|
*pxTopOfStack = ( StackType_t ) NULL;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) NULL;
|
*pxTopOfStack = ( StackType_t ) NULL;
|
||||||
|
|
@ -274,21 +276,21 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||||
enabled. */
|
* enabled. */
|
||||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||||
|
|
||||||
#if( configUSE_TASK_FPU_SUPPORT == 1 )
|
#if ( configUSE_TASK_FPU_SUPPORT == 1 )
|
||||||
{
|
{
|
||||||
/* The task will start without a floating point context. A task that
|
/* The task will start without a floating point context. A task that
|
||||||
uses the floating point hardware must call vPortTaskUsesFPU() before
|
* uses the floating point hardware must call vPortTaskUsesFPU() before
|
||||||
executing any floating point instructions. */
|
* executing any floating point instructions. */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||||
}
|
}
|
||||||
#elif( configUSE_TASK_FPU_SUPPORT == 2 )
|
#elif ( configUSE_TASK_FPU_SUPPORT == 2 )
|
||||||
{
|
{
|
||||||
/* The task will start with a floating point context. Leave enough
|
/* The task will start with a floating point context. Leave enough
|
||||||
space for the registers - and ensure they are initialised to 0. */
|
* space for the registers - and ensure they are initialised to 0. */
|
||||||
pxTopOfStack -= portFPU_REGISTER_WORDS;
|
pxTopOfStack -= portFPU_REGISTER_WORDS;
|
||||||
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
|
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
|
||||||
|
|
||||||
|
|
@ -296,11 +298,11 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
*pxTopOfStack = pdTRUE;
|
*pxTopOfStack = pdTRUE;
|
||||||
ulPortTaskHasFPUContext = pdTRUE;
|
ulPortTaskHasFPUContext = pdTRUE;
|
||||||
}
|
}
|
||||||
#else
|
#else /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
|
||||||
{
|
{
|
||||||
#error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined.
|
#error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined.
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
|
|
@ -309,34 +311,37 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* 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
|
* its caller as there is nothing to return to. If a task wants to exit it
|
||||||
should instead call vTaskDelete( NULL ).
|
* should instead call vTaskDelete( NULL ).
|
||||||
|
*
|
||||||
Artificially force an assert() to be triggered if configASSERT() is
|
* Artificially force an assert() to be triggered if configASSERT() is
|
||||||
defined, then stop here so application writers can catch the error. */
|
* defined, then stop here so application writers can catch the error. */
|
||||||
configASSERT( ulPortInterruptNesting == ~0UL );
|
configASSERT( ulPortInterruptNesting == ~0UL );
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
for( ;; );
|
|
||||||
|
for( ; ; )
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulAPSR;
|
uint32_t ulAPSR;
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
volatile uint32_t ulOriginalPriority;
|
||||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine how many priority bits are implemented in the GIC.
|
/* Determine how many priority bits are implemented in the GIC.
|
||||||
|
*
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
* Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to
|
/* Determine the number of priority bits available. First write to
|
||||||
all possible bits. */
|
* all possible bits. */
|
||||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
|
|
@ -349,35 +354,35 @@ uint32_t ulAPSR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
||||||
value. */
|
* value. */
|
||||||
configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY );
|
configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY );
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
* value. */
|
||||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||||
}
|
}
|
||||||
#endif /* conifgASSERT_DEFINED */
|
#endif /* conifgASSERT_DEFINED */
|
||||||
|
|
||||||
|
|
||||||
/* Only continue if the CPU is not in User mode. The CPU must be in a
|
/* Only continue if the CPU is not in User mode. The CPU must be in a
|
||||||
Privileged mode for the scheduler to start. */
|
* Privileged mode for the scheduler to start. */
|
||||||
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) :: "memory" );
|
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR )::"memory" );
|
||||||
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
||||||
configASSERT( ulAPSR != portAPSR_USER_MODE );
|
configASSERT( ulAPSR != portAPSR_USER_MODE );
|
||||||
|
|
||||||
if( ulAPSR != portAPSR_USER_MODE )
|
if( ulAPSR != portAPSR_USER_MODE )
|
||||||
{
|
{
|
||||||
/* Only continue if the binary point value is set to its lowest possible
|
/* Only continue if the binary point value is set to its lowest possible
|
||||||
setting. See the comments in vPortValidateInterruptPriority() below for
|
* setting. See the comments in vPortValidateInterruptPriority() below for
|
||||||
more information. */
|
* more information. */
|
||||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||||
|
|
||||||
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
||||||
{
|
{
|
||||||
/* Interrupts are turned off in the CPU itself to ensure tick does
|
/* Interrupts are turned off in the CPU itself to ensure tick does
|
||||||
not execute while the scheduler is being started. Interrupts are
|
* not execute while the scheduler is being started. Interrupts are
|
||||||
automatically turned back on in the CPU when the first task starts
|
* automatically turned back on in the CPU when the first task starts
|
||||||
executing. */
|
* executing. */
|
||||||
portCPU_IRQ_DISABLE();
|
portCPU_IRQ_DISABLE();
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. */
|
/* Start the timer that generates the tick ISR. */
|
||||||
|
|
@ -389,10 +394,10 @@ uint32_t ulAPSR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Will only get here if vTaskStartScheduler() was called with the CPU in
|
/* Will only get here if vTaskStartScheduler() was called with the CPU in
|
||||||
a non-privileged mode or the binary point register was not set to its lowest
|
* a non-privileged mode or the binary point register was not set to its lowest
|
||||||
possible value. prvTaskExitError() is referenced to prevent a compiler
|
* possible value. prvTaskExitError() is referenced to prevent a compiler
|
||||||
warning about it being defined but not referenced in the case that the user
|
* warning about it being defined but not referenced in the case that the user
|
||||||
defines their own exit address. */
|
* defines their own exit address. */
|
||||||
( void ) prvTaskExitError;
|
( void ) prvTaskExitError;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -401,7 +406,7 @@ uint32_t ulAPSR;
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Not implemented in ports where there is nothing to return to.
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
Artificially force an assert. */
|
* Artificially force an assert. */
|
||||||
configASSERT( ulCriticalNesting == 1000UL );
|
configASSERT( ulCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -412,15 +417,15 @@ void vPortEnterCritical( void )
|
||||||
ulPortSetInterruptMask();
|
ulPortSetInterruptMask();
|
||||||
|
|
||||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||||
portENTER_CRITICAL() has been called. */
|
* portENTER_CRITICAL() has been called. */
|
||||||
ulCriticalNesting++;
|
ulCriticalNesting++;
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
assert() if it is being called from an interrupt context. Only API
|
* assert() if it is being called from an interrupt context. Only API
|
||||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
* functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||||
the critical nesting count is 1 to protect against recursive calls if the
|
* the critical nesting count is 1 to protect against recursive calls if the
|
||||||
assert function also uses a critical section. */
|
* assert function also uses a critical section. */
|
||||||
if( ulCriticalNesting == 1 )
|
if( ulCriticalNesting == 1 )
|
||||||
{
|
{
|
||||||
configASSERT( ulPortInterruptNesting == 0 );
|
configASSERT( ulPortInterruptNesting == 0 );
|
||||||
|
|
@ -433,15 +438,15 @@ void vPortExitCritical( void )
|
||||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Decrement the nesting count as the critical section is being
|
/* Decrement the nesting count as the critical section is being
|
||||||
exited. */
|
* exited. */
|
||||||
ulCriticalNesting--;
|
ulCriticalNesting--;
|
||||||
|
|
||||||
/* If the nesting level has reached zero then all interrupt
|
/* If the nesting level has reached zero then all interrupt
|
||||||
priorities must be re-enabled. */
|
* priorities must be re-enabled. */
|
||||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||||
{
|
{
|
||||||
/* Critical nesting has reached zero so all interrupt priorities
|
/* Critical nesting has reached zero so all interrupt priorities
|
||||||
should be unmasked. */
|
* should be unmasked. */
|
||||||
portCLEAR_INTERRUPT_MASK();
|
portCLEAR_INTERRUPT_MASK();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -451,14 +456,14 @@ void vPortExitCritical( void )
|
||||||
void FreeRTOS_Tick_Handler( void )
|
void FreeRTOS_Tick_Handler( void )
|
||||||
{
|
{
|
||||||
/* Set interrupt mask before altering scheduler structures. The tick
|
/* Set interrupt mask before altering scheduler structures. The tick
|
||||||
handler runs at the lowest priority, so interrupts cannot already be masked,
|
* handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||||
so there is no need to save and restore the current mask value. It is
|
* so there is no need to save and restore the current mask value. It is
|
||||||
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||||
updated. */
|
* updated. */
|
||||||
portCPU_IRQ_DISABLE();
|
portCPU_IRQ_DISABLE();
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
__asm volatile ( "dsb \n"
|
__asm volatile ( "dsb \n"
|
||||||
"isb \n" ::: "memory" );
|
"isb \n"::: "memory" );
|
||||||
portCPU_IRQ_ENABLE();
|
portCPU_IRQ_ENABLE();
|
||||||
|
|
||||||
/* Increment the RTOS tick. */
|
/* Increment the RTOS tick. */
|
||||||
|
|
@ -473,18 +478,18 @@ void FreeRTOS_Tick_Handler( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configUSE_TASK_FPU_SUPPORT != 2 )
|
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
|
||||||
|
|
||||||
void vPortTaskUsesFPU( void )
|
void vPortTaskUsesFPU( void )
|
||||||
{
|
{
|
||||||
uint32_t ulInitialFPSCR = 0;
|
uint32_t ulInitialFPSCR = 0;
|
||||||
|
|
||||||
/* A task is registering the fact that it needs an FPU context. Set the
|
/* A task is registering the fact that it needs an FPU context. Set the
|
||||||
FPU flag (which is saved as part of the task context). */
|
* FPU flag (which is saved as part of the task context). */
|
||||||
ulPortTaskHasFPUContext = pdTRUE;
|
ulPortTaskHasFPUContext = pdTRUE;
|
||||||
|
|
||||||
/* Initialise the floating point status register. */
|
/* Initialise the floating point status register. */
|
||||||
__asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) : "memory" );
|
__asm volatile ( "FMXR FPSCR, %0" ::"r" ( ulInitialFPSCR ) : "memory" );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configUSE_TASK_FPU_SUPPORT */
|
#endif /* configUSE_TASK_FPU_SUPPORT */
|
||||||
|
|
@ -501,11 +506,12 @@ void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
||||||
|
|
||||||
uint32_t ulPortSetInterruptMask( void )
|
uint32_t ulPortSetInterruptMask( void )
|
||||||
{
|
{
|
||||||
uint32_t ulReturn;
|
uint32_t ulReturn;
|
||||||
|
|
||||||
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
||||||
updated. */
|
* updated. */
|
||||||
portCPU_IRQ_DISABLE();
|
portCPU_IRQ_DISABLE();
|
||||||
|
|
||||||
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
||||||
{
|
{
|
||||||
/* Interrupts were already masked. */
|
/* Interrupts were already masked. */
|
||||||
|
|
@ -516,44 +522,45 @@ uint32_t ulReturn;
|
||||||
ulReturn = pdFALSE;
|
ulReturn = pdFALSE;
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||||
__asm volatile ( "dsb \n"
|
__asm volatile ( "dsb \n"
|
||||||
"isb \n" ::: "memory" );
|
"isb \n"::: "memory" );
|
||||||
}
|
}
|
||||||
|
|
||||||
portCPU_IRQ_ENABLE();
|
portCPU_IRQ_ENABLE();
|
||||||
|
|
||||||
return ulReturn;
|
return ulReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
void vPortValidateInterruptPriority( void )
|
||||||
{
|
{
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
/* The following assertion will fail if a service routine (ISR) for
|
||||||
an interrupt that has been assigned a priority above
|
* an interrupt that has been assigned a priority above
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||||
function. ISR safe FreeRTOS API functions must *only* be called
|
* function. ISR safe FreeRTOS API functions must *only* be called
|
||||||
from interrupts that have been assigned a priority at or below
|
* from interrupts that have been assigned a priority at or below
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
Numerically low interrupt priority numbers represent logically high
|
* Numerically low interrupt priority numbers represent logically high
|
||||||
interrupt priorities, therefore the priority of the interrupt must
|
* interrupt priorities, therefore the priority of the interrupt must
|
||||||
be set to a value equal to or numerically *higher* than
|
* be set to a value equal to or numerically *higher* than
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
*
|
||||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||||
interrupt entry is as fast and simple as possible. */
|
* interrupt entry is as fast and simple as possible. */
|
||||||
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
||||||
|
|
||||||
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
||||||
that define each interrupt's priority to be split between bits that
|
* that define each interrupt's priority to be split between bits that
|
||||||
define the interrupt's pre-emption priority bits and bits that define
|
* define the interrupt's pre-emption priority bits and bits that define
|
||||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
* the interrupt's sub-priority. For simplicity all bits must be defined
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
* to be pre-emption priority bits. The following assertion will fail if
|
||||||
this is not the case (if some bits represent a sub-priority).
|
* this is not the case (if some bits represent a sub-priority).
|
||||||
|
*
|
||||||
The priority grouping is configured by the GIC's binary point register
|
* The priority grouping is configured by the GIC's binary point register
|
||||||
(ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
* (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||||
possible value (which may be above 0). */
|
* possible value (which may be above 0). */
|
||||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -42,166 +42,166 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Hardware specifics. */
|
/* Hardware specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
|
||||||
/* Called at the end of an ISR that can cause a context switch. */
|
/* Called at the end of an ISR that can cause a context switch. */
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired )\
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
{ \
|
{ \
|
||||||
extern uint32_t ulPortYieldRequired; \
|
extern uint32_t ulPortYieldRequired; \
|
||||||
\
|
\
|
||||||
if( xSwitchRequired != pdFALSE ) \
|
if( xSwitchRequired != pdFALSE ) \
|
||||||
{ \
|
{ \
|
||||||
ulPortYieldRequired = pdTRUE; \
|
ulPortYieldRequired = pdTRUE; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
#define portYIELD() __asm volatile ( "SWI 0" ::: "memory" );
|
#define portYIELD() __asm volatile ( "SWI 0" ::: "memory" );
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Critical section control
|
* Critical section control
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
extern uint32_t ulPortSetInterruptMask( void );
|
extern uint32_t ulPortSetInterruptMask( void );
|
||||||
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
||||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||||
|
|
||||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||||
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
not required for this port but included in case common demo code that uses these
|
* not required for this port but included in case common demo code that uses these
|
||||||
macros is used. */
|
* macros is used. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||||
handler for whichever peripheral is used to generate the RTOS tick. */
|
* handler for whichever peripheral is used to generate the RTOS tick. */
|
||||||
void FreeRTOS_Tick_Handler( void );
|
void FreeRTOS_Tick_Handler( void );
|
||||||
|
|
||||||
/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
|
/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
|
||||||
created without an FPU context and must call vPortTaskUsesFPU() to give
|
* created without an FPU context and must call vPortTaskUsesFPU() to give
|
||||||
themselves an FPU context before using any FPU instructions. If
|
* themselves an FPU context before using any FPU instructions. If
|
||||||
configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
|
* configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
|
||||||
by default. */
|
* by default. */
|
||||||
#if( configUSE_TASK_FPU_SUPPORT != 2 )
|
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
|
||||||
void vPortTaskUsesFPU( void );
|
void vPortTaskUsesFPU( void );
|
||||||
#else
|
#else
|
||||||
/* Each task has an FPU context already, so define this function away to
|
|
||||||
nothing to prevent it being called accidentally. */
|
|
||||||
#define vPortTaskUsesFPU()
|
|
||||||
#endif
|
|
||||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
|
||||||
|
|
||||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
/* Each task has an FPU context already, so define this function away to
|
||||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
* nothing to prevent it being called accidentally. */
|
||||||
|
#define vPortTaskUsesFPU()
|
||||||
|
#endif
|
||||||
|
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||||
|
|
||||||
|
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||||
|
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif /* configASSERT */
|
#endif /* configASSERT */
|
||||||
|
|
||||||
#define portNOP() __asm volatile( "NOP" )
|
#define portNOP() __asm volatile ( "NOP" )
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern C */
|
} /* extern C */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* The number of bits to shift for an interrupt priority is dependent on the
|
/* The number of bits to shift for an interrupt priority is dependent on the
|
||||||
number of bits implemented by the interrupt controller. */
|
* number of bits implemented by the interrupt controller. */
|
||||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||||
#define portPRIORITY_SHIFT 4
|
#define portPRIORITY_SHIFT 4
|
||||||
#define portMAX_BINARY_POINT_VALUE 3
|
#define portMAX_BINARY_POINT_VALUE 3
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
||||||
#define portPRIORITY_SHIFT 3
|
#define portPRIORITY_SHIFT 3
|
||||||
#define portMAX_BINARY_POINT_VALUE 2
|
#define portMAX_BINARY_POINT_VALUE 2
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
||||||
#define portPRIORITY_SHIFT 2
|
#define portPRIORITY_SHIFT 2
|
||||||
#define portMAX_BINARY_POINT_VALUE 1
|
#define portMAX_BINARY_POINT_VALUE 1
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
||||||
#define portPRIORITY_SHIFT 1
|
#define portPRIORITY_SHIFT 1
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||||
#define portPRIORITY_SHIFT 0
|
#define portPRIORITY_SHIFT 0
|
||||||
#define portMAX_BINARY_POINT_VALUE 0
|
#define portMAX_BINARY_POINT_VALUE 0
|
||||||
#else
|
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||||
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
||||||
#endif
|
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||||
|
|
||||||
/* Interrupt controller access addresses. */
|
/* Interrupt controller access addresses. */
|
||||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
||||||
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
||||||
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
||||||
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
||||||
|
|
||||||
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
||||||
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
||||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
||||||
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
||||||
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
||||||
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
||||||
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
||||||
|
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,19 +25,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Implementation of functions defined in portable.h for the ARM CM0 port.
|
* Implementation of functions defined in portable.h for the ARM CM0 port.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/* Constants required to manipulate the NVIC. */
|
/* Constants required to manipulate the NVIC. */
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
|
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) )
|
#define portNVIC_SYSPRI2_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||||
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||||
|
|
@ -54,15 +54,15 @@
|
||||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
||||||
|
|
||||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
/* A fiddle factor to estimate the number of SysTick counts that would have
|
||||||
occurred while the SysTick counter is stopped during tickless idle
|
* occurred while the SysTick counter is stopped during tickless idle
|
||||||
calculations. */
|
* calculations. */
|
||||||
#ifndef portMISSED_COUNTS_FACTOR
|
#ifndef portMISSED_COUNTS_FACTOR
|
||||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Let the user override the pre-loading of the initial LR with the address of
|
/* Let the user override the pre-loading of the initial LR with the address of
|
||||||
prvTaskExitError() in case it messes up unwinding of the stack in the
|
* prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||||
debugger. */
|
* debugger. */
|
||||||
#ifdef configTASK_RETURN_ADDRESS
|
#ifdef configTASK_RETURN_ADDRESS
|
||||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||||
#else
|
#else
|
||||||
|
|
@ -79,14 +79,14 @@ void vPortSetupTimerInterrupt( void );
|
||||||
/*
|
/*
|
||||||
* Exception handlers.
|
* Exception handlers.
|
||||||
*/
|
*/
|
||||||
void xPortPendSVHandler( void ) __attribute__ (( naked ));
|
void xPortPendSVHandler( void ) __attribute__( ( naked ) );
|
||||||
void xPortSysTickHandler( void );
|
void xPortSysTickHandler( void );
|
||||||
void vPortSVCHandler( void );
|
void vPortSVCHandler( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start first task is a separate function so it can be tested in isolation.
|
* Start first task is a separate function so it can be tested in isolation.
|
||||||
*/
|
*/
|
||||||
static void vPortStartFirstTask( void ) __attribute__ (( naked ));
|
static void vPortStartFirstTask( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to catch tasks that attempt to return from their implementing function.
|
* Used to catch tasks that attempt to return from their implementing function.
|
||||||
|
|
@ -96,15 +96,15 @@ static void prvTaskExitError( void );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Each task maintains its own interrupt status in the critical nesting
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
variable. */
|
* variable. */
|
||||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The number of SysTick increments that make up one tick period.
|
* The number of SysTick increments that make up one tick period.
|
||||||
*/
|
*/
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static uint32_t ulTimerCountsForOneTick = 0;
|
static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
|
@ -112,7 +112,7 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
* The maximum number of tick periods that can be suppressed is limited by the
|
* The maximum number of tick periods that can be suppressed is limited by the
|
||||||
* 24 bit resolution of the SysTick timer.
|
* 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
|
@ -120,7 +120,7 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
||||||
* power functionality only.
|
* power functionality only.
|
||||||
*/
|
*/
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
static uint32_t ulStoppedTimerCompensation = 0;
|
static uint32_t ulStoppedTimerCompensation = 0;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
|
|
||||||
|
|
@ -129,10 +129,12 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters )
|
||||||
{
|
{
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
interrupt. */
|
* interrupt. */
|
||||||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
@ -149,25 +151,26 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||||
|
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulDummy = 0UL;
|
volatile uint32_t ulDummy = 0UL;
|
||||||
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* 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
|
* its caller as there is nothing to return to. If a task wants to exit it
|
||||||
should instead call vTaskDelete( NULL ).
|
* should instead call vTaskDelete( NULL ).
|
||||||
|
*
|
||||||
Artificially force an assert() to be triggered if configASSERT() is
|
* Artificially force an assert() to be triggered if configASSERT() is
|
||||||
defined, then stop here so application writers can catch the error. */
|
* defined, then stop here so application writers can catch the error. */
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
configASSERT( uxCriticalNesting == ~0UL );
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
while( ulDummy == 0 )
|
while( ulDummy == 0 )
|
||||||
{
|
{
|
||||||
/* This file calls prvTaskExitError() after the scheduler has been
|
/* This file calls prvTaskExitError() after the scheduler has been
|
||||||
started to remove a compiler warning about the function being defined
|
* started to remove a compiler warning about the function being defined
|
||||||
but never called. ulDummy is used purely to quieten other warnings
|
* but never called. ulDummy is used purely to quieten other warnings
|
||||||
about code appearing after this function is called - making ulDummy
|
* about code appearing after this function is called - making ulDummy
|
||||||
volatile makes the compiler think the function could return and
|
* volatile makes the compiler think the function could return and
|
||||||
therefore not output an 'unreachable code' warning for code that appears
|
* therefore not output an 'unreachable code' warning for code that appears
|
||||||
after it. */
|
* after it. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -175,31 +178,31 @@ volatile uint32_t ulDummy = 0UL;
|
||||||
void vPortSVCHandler( void )
|
void vPortSVCHandler( void )
|
||||||
{
|
{
|
||||||
/* This function is no longer used, but retained for backward
|
/* This function is no longer used, but retained for backward
|
||||||
compatibility. */
|
* compatibility. */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortStartFirstTask( void )
|
void vPortStartFirstTask( void )
|
||||||
{
|
{
|
||||||
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
|
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
|
||||||
table offset register that can be used to locate the initial stack value.
|
* table offset register that can be used to locate the initial stack value.
|
||||||
Not all M0 parts have the application vector table at address 0. */
|
* Not all M0 parts have the application vector table at address 0. */
|
||||||
__asm volatile(
|
__asm volatile (
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Obtain location of pxCurrentTCB. */
|
" ldr r2, pxCurrentTCBConst2 \n"/* Obtain location of pxCurrentTCB. */
|
||||||
" ldr r3, [r2] \n"
|
" ldr r3, [r2] \n"
|
||||||
" ldr r0, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||||
" movs r0, #2 \n" /* Switch to the psp stack. */
|
" movs r0, #2 \n"/* Switch to the psp stack. */
|
||||||
" msr CONTROL, r0 \n"
|
" msr CONTROL, r0 \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" pop {r0-r5} \n" /* Pop the registers that are saved automatically. */
|
" pop {r0-r5} \n"/* Pop the registers that are saved automatically. */
|
||||||
" mov lr, r5 \n" /* lr is now in r5. */
|
" mov lr, r5 \n"/* lr is now in r5. */
|
||||||
" pop {r3} \n" /* Return address is now in r3. */
|
" pop {r3} \n"/* Return address is now in r3. */
|
||||||
" pop {r2} \n" /* Pop and discard XPSR. */
|
" pop {r2} \n"/* Pop and discard XPSR. */
|
||||||
" cpsie i \n" /* The first task has its context and interrupts can be enabled. */
|
" cpsie i \n"/* The first task has its context and interrupts can be enabled. */
|
||||||
" bx r3 \n" /* Finally, jump to the user defined task code. */
|
" bx r3 \n"/* Finally, jump to the user defined task code. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB "
|
"pxCurrentTCBConst2: .word pxCurrentTCB "
|
||||||
|
|
@ -217,7 +220,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
here already. */
|
* here already. */
|
||||||
vPortSetupTimerInterrupt();
|
vPortSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Initialise the critical nesting count ready for the first task. */
|
/* Initialise the critical nesting count ready for the first task. */
|
||||||
|
|
@ -227,11 +230,11 @@ BaseType_t xPortStartScheduler( void )
|
||||||
vPortStartFirstTask();
|
vPortStartFirstTask();
|
||||||
|
|
||||||
/* Should never get here as the tasks will now be executing! Call the task
|
/* 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
|
* exit error function to prevent compiler warnings about a static function
|
||||||
not being called in the case that the application writer overrides this
|
* not being called in the case that the application writer overrides this
|
||||||
functionality by defining configTASK_RETURN_ADDRESS. Call
|
* functionality by defining configTASK_RETURN_ADDRESS. Call
|
||||||
vTaskSwitchContext() so link time optimisation does not remove the
|
* vTaskSwitchContext() so link time optimisation does not remove the
|
||||||
symbol. */
|
* symbol. */
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
prvTaskExitError();
|
prvTaskExitError();
|
||||||
|
|
||||||
|
|
@ -243,7 +246,7 @@ BaseType_t xPortStartScheduler( void )
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
/* Not implemented in ports where there is nothing to return to.
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
Artificially force an assert. */
|
* Artificially force an assert. */
|
||||||
configASSERT( uxCriticalNesting == 1000UL );
|
configASSERT( uxCriticalNesting == 1000UL );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -254,9 +257,9 @@ void vPortYield( void )
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is completely
|
/* Barriers are normally not required but do ensure the code is completely
|
||||||
within the specified behaviour for the architecture. */
|
* within the specified behaviour for the architecture. */
|
||||||
__asm volatile( "dsb" ::: "memory" );
|
__asm volatile ( "dsb" ::: "memory" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -264,8 +267,8 @@ void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
uxCriticalNesting++;
|
uxCriticalNesting++;
|
||||||
__asm volatile( "dsb" ::: "memory" );
|
__asm volatile ( "dsb" ::: "memory" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -273,6 +276,7 @@ void vPortExitCritical( void )
|
||||||
{
|
{
|
||||||
configASSERT( uxCriticalNesting );
|
configASSERT( uxCriticalNesting );
|
||||||
uxCriticalNesting--;
|
uxCriticalNesting--;
|
||||||
|
|
||||||
if( uxCriticalNesting == 0 )
|
if( uxCriticalNesting == 0 )
|
||||||
{
|
{
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
@ -282,7 +286,7 @@ void vPortExitCritical( void )
|
||||||
|
|
||||||
uint32_t ulSetInterruptMaskFromISR( void )
|
uint32_t ulSetInterruptMaskFromISR( void )
|
||||||
{
|
{
|
||||||
__asm volatile(
|
__asm volatile (
|
||||||
" mrs r0, PRIMASK \n"
|
" mrs r0, PRIMASK \n"
|
||||||
" cpsid i \n"
|
" cpsid i \n"
|
||||||
" bx lr "
|
" bx lr "
|
||||||
|
|
@ -293,7 +297,7 @@ uint32_t ulSetInterruptMaskFromISR( void )
|
||||||
|
|
||||||
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask )
|
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask )
|
||||||
{
|
{
|
||||||
__asm volatile(
|
__asm volatile (
|
||||||
" msr PRIMASK, r0 \n"
|
" msr PRIMASK, r0 \n"
|
||||||
" bx lr "
|
" bx lr "
|
||||||
::: "memory"
|
::: "memory"
|
||||||
|
|
@ -310,13 +314,13 @@ void xPortPendSVHandler( void )
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" mrs r0, psp \n"
|
" mrs r0, psp \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
" ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */
|
||||||
" ldr r2, [r3] \n"
|
" ldr r2, [r3] \n"
|
||||||
" \n"
|
" \n"
|
||||||
" subs r0, r0, #32 \n" /* Make space for the remaining low registers. */
|
" subs r0, r0, #32 \n"/* Make space for the remaining low registers. */
|
||||||
" str r0, [r2] \n" /* Save the new top of stack. */
|
" str r0, [r2] \n"/* Save the new top of stack. */
|
||||||
" stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */
|
" stmia r0!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */
|
||||||
" mov r4, r8 \n" /* Store the high registers. */
|
" mov r4, r8 \n"/* Store the high registers. */
|
||||||
" mov r5, r9 \n"
|
" mov r5, r9 \n"
|
||||||
" mov r6, r10 \n"
|
" mov r6, r10 \n"
|
||||||
" mov r7, r11 \n"
|
" mov r7, r11 \n"
|
||||||
|
|
@ -326,21 +330,21 @@ void xPortPendSVHandler( void )
|
||||||
" cpsid i \n"
|
" cpsid i \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" cpsie i \n"
|
" cpsie i \n"
|
||||||
" pop {r2, r3} \n" /* lr goes in r3. r2 now holds tcb pointer. */
|
" pop {r2, r3} \n"/* lr goes in r3. r2 now holds tcb pointer. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r1, [r2] \n"
|
" ldr r1, [r2] \n"
|
||||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" adds r0, r0, #16 \n" /* Move to the high registers. */
|
" adds r0, r0, #16 \n"/* Move to the high registers. */
|
||||||
" ldmia r0!, {r4-r7} \n" /* Pop the high registers. */
|
" ldmia r0!, {r4-r7} \n"/* Pop the high registers. */
|
||||||
" mov r8, r4 \n"
|
" mov r8, r4 \n"
|
||||||
" mov r9, r5 \n"
|
" mov r9, r5 \n"
|
||||||
" mov r10, r6 \n"
|
" mov r10, r6 \n"
|
||||||
" mov r11, r7 \n"
|
" mov r11, r7 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
||||||
" \n"
|
" \n"
|
||||||
" subs r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */
|
" subs r0, r0, #32 \n"/* Go back for the low registers that are not automatically restored. */
|
||||||
" ldmia r0!, {r4-r7} \n" /* Pop low registers. */
|
" ldmia r0!, {r4-r7} \n"/* Pop low registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" bx r3 \n"
|
" bx r3 \n"
|
||||||
" \n"
|
" \n"
|
||||||
|
|
@ -352,7 +356,7 @@ void xPortPendSVHandler( void )
|
||||||
|
|
||||||
void xPortSysTickHandler( void )
|
void xPortSysTickHandler( void )
|
||||||
{
|
{
|
||||||
uint32_t ulPreviousMask;
|
uint32_t ulPreviousMask;
|
||||||
|
|
||||||
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
|
|
@ -371,10 +375,10 @@ uint32_t ulPreviousMask;
|
||||||
* Setup the systick timer to generate the tick interrupts at the required
|
* Setup the systick timer to generate the tick interrupts at the required
|
||||||
* frequency.
|
* frequency.
|
||||||
*/
|
*/
|
||||||
__attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
/* Calculate the constants required to configure the tick interrupt. */
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
{
|
{
|
||||||
ulTimerCountsForOneTick = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );
|
ulTimerCountsForOneTick = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||||
|
|
@ -392,9 +396,9 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
|
|
||||||
__attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
__attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
||||||
TickType_t xModifiableIdleTime;
|
TickType_t xModifiableIdleTime;
|
||||||
|
|
@ -406,44 +410,45 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop the SysTick momentarily. The time the SysTick is stopped for
|
/* 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
|
* 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
|
* inevitably result in some tiny drift of the time maintained by the
|
||||||
kernel with respect to calendar time. */
|
* kernel with respect to calendar time. */
|
||||||
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||||
tick periods. -1 is used because this code will execute part way
|
* tick periods. -1 is used because this code will execute part way
|
||||||
through one of the tick periods. */
|
* through one of the tick periods. */
|
||||||
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
||||||
|
|
||||||
if( ulReloadValue > ulStoppedTimerCompensation )
|
if( ulReloadValue > ulStoppedTimerCompensation )
|
||||||
{
|
{
|
||||||
ulReloadValue -= ulStoppedTimerCompensation;
|
ulReloadValue -= ulStoppedTimerCompensation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||||
method as that will mask interrupts that should exit sleep mode. */
|
* method as that will mask interrupts that should exit sleep mode. */
|
||||||
__asm volatile( "cpsid i" ::: "memory" );
|
__asm volatile ( "cpsid i" ::: "memory" );
|
||||||
__asm volatile( "dsb" );
|
__asm volatile ( "dsb" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
|
|
||||||
/* If a context switch is pending or a task is waiting for the scheduler
|
/* If a context switch is pending or a task is waiting for the scheduler
|
||||||
to be unsuspended then abandon the low power entry. */
|
* to be unsuspended then abandon the low power entry. */
|
||||||
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
||||||
{
|
{
|
||||||
/* Restart from whatever is left in the count register to complete
|
/* Restart from whatever is left in the count register to complete
|
||||||
this tick period. */
|
* this tick period. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Reset the reload register to the value required for normal tick
|
/* Reset the reload register to the value required for normal tick
|
||||||
periods. */
|
* periods. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
above. */
|
* above. */
|
||||||
__asm volatile( "cpsie i" ::: "memory" );
|
__asm volatile ( "cpsie i" ::: "memory" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -451,69 +456,71 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
||||||
|
|
||||||
/* Clear the SysTick count flag and set the count value back to
|
/* Clear the SysTick count flag and set the count value back to
|
||||||
zero. */
|
* zero. */
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Restart SysTick. */
|
/* Restart SysTick. */
|
||||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
|
|
||||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||||
set its parameter to 0 to indicate that its implementation contains
|
* set its parameter to 0 to indicate that its implementation contains
|
||||||
its own wait for interrupt or wait for event instruction, and so wfi
|
* its own wait for interrupt or wait for event instruction, and so wfi
|
||||||
should not be executed again. However, the original expected idle
|
* should not be executed again. However, the original expected idle
|
||||||
time variable must remain unmodified, so a copy is taken. */
|
* time variable must remain unmodified, so a copy is taken. */
|
||||||
xModifiableIdleTime = xExpectedIdleTime;
|
xModifiableIdleTime = xExpectedIdleTime;
|
||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||||
|
|
||||||
if( xModifiableIdleTime > 0 )
|
if( xModifiableIdleTime > 0 )
|
||||||
{
|
{
|
||||||
__asm volatile( "dsb" ::: "memory" );
|
__asm volatile ( "dsb" ::: "memory" );
|
||||||
__asm volatile( "wfi" );
|
__asm volatile ( "wfi" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
}
|
}
|
||||||
|
|
||||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
|
||||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||||
out of sleep mode to execute immediately. see comments above
|
* out of sleep mode to execute immediately. see comments above
|
||||||
__disable_interrupt() call above. */
|
* __disable_interrupt() call above. */
|
||||||
__asm volatile( "cpsie i" ::: "memory" );
|
__asm volatile ( "cpsie i" ::: "memory" );
|
||||||
__asm volatile( "dsb" );
|
__asm volatile ( "dsb" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
|
|
||||||
/* Disable interrupts again because the clock is about to be stopped
|
/* Disable interrupts again because the clock is about to be stopped
|
||||||
and interrupts that execute while the clock is stopped will increase
|
* and interrupts that execute while the clock is stopped will increase
|
||||||
any slippage between the time maintained by the RTOS and calendar
|
* any slippage between the time maintained by the RTOS and calendar
|
||||||
time. */
|
* time. */
|
||||||
__asm volatile( "cpsid i" ::: "memory" );
|
__asm volatile ( "cpsid i" ::: "memory" );
|
||||||
__asm volatile( "dsb" );
|
__asm volatile ( "dsb" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
|
|
||||||
/* Disable the SysTick clock without reading the
|
/* Disable the SysTick clock without reading the
|
||||||
portNVIC_SYSTICK_CTRL_REG register to ensure the
|
* portNVIC_SYSTICK_CTRL_REG register to ensure the
|
||||||
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
|
* portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
|
||||||
the time the SysTick is stopped for is accounted for as best it can
|
* 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
|
* be, but using the tickless mode will inevitably result in some tiny
|
||||||
drift of the time maintained by the kernel with respect to calendar
|
* drift of the time maintained by the kernel with respect to calendar
|
||||||
time*/
|
* time*/
|
||||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
|
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
|
||||||
|
|
||||||
/* Determine if the SysTick clock has already counted to zero and
|
/* Determine if the SysTick clock has already counted to zero and
|
||||||
been set back to the current reload value (the reload back being
|
* been set back to the current reload value (the reload back being
|
||||||
correct for the entire expected idle time) or if the SysTick is yet
|
* correct for the entire expected idle time) or if the SysTick is yet
|
||||||
to count to zero (in which case an interrupt other than the SysTick
|
* to count to zero (in which case an interrupt other than the SysTick
|
||||||
must have brought the system out of sleep mode). */
|
* must have brought the system out of sleep mode). */
|
||||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||||
{
|
{
|
||||||
uint32_t ulCalculatedLoadValue;
|
uint32_t ulCalculatedLoadValue;
|
||||||
|
|
||||||
/* The tick interrupt is already pending, and the SysTick count
|
/* The tick interrupt is already pending, and the SysTick count
|
||||||
reloaded with ulReloadValue. Reset the
|
* reloaded with ulReloadValue. Reset the
|
||||||
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
* portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
||||||
period. */
|
* period. */
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
||||||
|
|
||||||
/* Don't allow a tiny value, or values that have somehow
|
/* Don't allow a tiny value, or values that have somehow
|
||||||
underflowed because the post sleep hook did something
|
* underflowed because the post sleep hook did something
|
||||||
that took too long. */
|
* that took too long. */
|
||||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
||||||
{
|
{
|
||||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
||||||
|
|
@ -522,37 +529,37 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
||||||
|
|
||||||
/* As the pending tick will be processed as soon as this
|
/* As the pending tick will be processed as soon as this
|
||||||
function exits, the tick value maintained by the tick is stepped
|
* function exits, the tick value maintained by the tick is stepped
|
||||||
forward by one less than the time spent waiting. */
|
* forward by one less than the time spent waiting. */
|
||||||
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Something other than the tick interrupt ended the sleep.
|
/* Something other than the tick interrupt ended the sleep.
|
||||||
Work out how long the sleep lasted rounded to complete tick
|
* Work out how long the sleep lasted rounded to complete tick
|
||||||
periods (not the ulReload value which accounted for part
|
* periods (not the ulReload value which accounted for part
|
||||||
ticks). */
|
* ticks). */
|
||||||
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||||
|
|
||||||
/* How many complete tick periods passed while the processor
|
/* How many complete tick periods passed while the processor
|
||||||
was waiting? */
|
* was waiting? */
|
||||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
||||||
|
|
||||||
/* The reload value is set to whatever fraction of a single tick
|
/* The reload value is set to whatever fraction of a single tick
|
||||||
period remains. */
|
* period remains. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
||||||
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
* again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
||||||
value. */
|
* value. */
|
||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||||
vTaskStepTick( ulCompleteTickPeriods );
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
|
|
||||||
/* Exit with interrpts enabled. */
|
/* Exit with interrpts enabled. */
|
||||||
__asm volatile( "cpsie i" ::: "memory" );
|
__asm volatile ( "cpsie i" ::: "memory" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -43,82 +43,81 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Type definitions. */
|
/* Type definitions. */
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specifics. */
|
/* Architecture specifics. */
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portDONT_DISCARD __attribute__(( used ))
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
extern void vPortYield( void );
|
extern void vPortYield( void );
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
extern uint32_t ulSetInterruptMaskFromISR( void ) __attribute__((naked));
|
extern uint32_t ulSetInterruptMaskFromISR( void ) __attribute__( ( naked ) );
|
||||||
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__((naked));
|
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x )
|
||||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
/* Tickless idle/low power functionality. */
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
|
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
/* Portasm includes. */
|
/* Portasm includes. */
|
||||||
#include "portasm.h"
|
#include "portasm.h"
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/* Secure components includes. */
|
/* Secure components includes. */
|
||||||
#include "secure_context.h"
|
#include "secure_context.h"
|
||||||
#include "secure_init.h"
|
#include "secure_init.h"
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
* 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support:
|
* 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support:
|
||||||
* configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0
|
* configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0
|
||||||
*/
|
*/
|
||||||
#if( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) )
|
#if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) )
|
||||||
#error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side.
|
#error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -70,10 +70,10 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
|
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||||
#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) )
|
#define portNVIC_SYSPRI2_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||||
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||||
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
||||||
|
|
@ -85,7 +85,8 @@
|
||||||
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
#else
|
#else
|
||||||
/* The way the SysTick is clocked is not modified in case it is not the
|
|
||||||
|
/* The way the SysTick is clocked is not modified in case it is not the
|
||||||
* same a the core. */
|
* same a the core. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -94,7 +95,7 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( * ( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -117,24 +118,24 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the MPU.
|
* @brief Constants required to manipulate the MPU.
|
||||||
*/
|
*/
|
||||||
#define portMPU_TYPE_REG ( * ( ( volatile uint32_t * ) 0xe000ed90 ) )
|
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
|
||||||
#define portMPU_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed94 ) )
|
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
|
||||||
#define portMPU_RNR_REG ( * ( ( volatile uint32_t * ) 0xe000ed98 ) )
|
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_REG ( * ( ( volatile uint32_t * ) 0xe000ed9c ) )
|
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
|
||||||
#define portMPU_RLAR_REG ( * ( ( volatile uint32_t * ) 0xe000eda0 ) )
|
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_A1_REG ( * ( ( volatile uint32_t * ) 0xe000eda4 ) )
|
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
|
||||||
#define portMPU_RLAR_A1_REG ( * ( ( volatile uint32_t * ) 0xe000eda8 ) )
|
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_A2_REG ( * ( ( volatile uint32_t * ) 0xe000edac ) )
|
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
|
||||||
#define portMPU_RLAR_A2_REG ( * ( ( volatile uint32_t * ) 0xe000edb0 ) )
|
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_A3_REG ( * ( ( volatile uint32_t * ) 0xe000edb4 ) )
|
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
|
||||||
#define portMPU_RLAR_A3_REG ( * ( ( volatile uint32_t * ) 0xe000edb8 ) )
|
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
|
||||||
|
|
||||||
#define portMPU_MAIR0_REG ( * ( ( volatile uint32_t * ) 0xe000edc0 ) )
|
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
|
||||||
#define portMPU_MAIR1_REG ( * ( ( volatile uint32_t * ) 0xe000edc4 ) )
|
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
||||||
#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
||||||
|
|
@ -204,8 +205,9 @@
|
||||||
*/
|
*/
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
|
|
||||||
#if( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -221,7 +223,8 @@
|
||||||
*/
|
*/
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -284,15 +287,17 @@
|
||||||
*/
|
*/
|
||||||
static void prvTaskExitError( void );
|
static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -337,7 +342,7 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION;
|
||||||
/**
|
/**
|
||||||
* @brief C part of SVC handler.
|
* @brief C part of SVC handler.
|
||||||
*/
|
*/
|
||||||
portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVILEGED_FUNCTION;
|
portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -346,27 +351,29 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVI
|
||||||
*/
|
*/
|
||||||
static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT;
|
portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief The number of SysTick increments that make up one tick period.
|
* @brief The number of SysTick increments that make up one tick period.
|
||||||
*/
|
*/
|
||||||
static uint32_t ulTimerCountsForOneTick = 0;
|
static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -374,8 +381,8 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
__attribute__(( weak )) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
__attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
||||||
TickType_t xModifiableIdleTime;
|
TickType_t xModifiableIdleTime;
|
||||||
|
|
@ -396,6 +403,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
* tick periods. -1 is used because this code will execute part way
|
* tick periods. -1 is used because this code will execute part way
|
||||||
* through one of the tick periods. */
|
* through one of the tick periods. */
|
||||||
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
||||||
|
|
||||||
if( ulReloadValue > ulStoppedTimerCompensation )
|
if( ulReloadValue > ulStoppedTimerCompensation )
|
||||||
{
|
{
|
||||||
ulReloadValue -= ulStoppedTimerCompensation;
|
ulReloadValue -= ulStoppedTimerCompensation;
|
||||||
|
|
@ -403,9 +411,9 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||||
* method as that will mask interrupts that should exit sleep mode. */
|
* method as that will mask interrupts that should exit sleep mode. */
|
||||||
__asm volatile( "cpsid i" ::: "memory" );
|
__asm volatile ( "cpsid i" ::: "memory" );
|
||||||
__asm volatile( "dsb" );
|
__asm volatile ( "dsb" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
|
|
||||||
/* If a context switch is pending or a task is waiting for the scheduler
|
/* If a context switch is pending or a task is waiting for the scheduler
|
||||||
* to be un-suspended then abandon the low power entry. */
|
* to be un-suspended then abandon the low power entry. */
|
||||||
|
|
@ -424,7 +432,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
* above. */
|
* above. */
|
||||||
__asm volatile( "cpsie i" ::: "memory" );
|
__asm volatile ( "cpsie i" ::: "memory" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -446,28 +454,30 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
* so a copy is taken. */
|
* so a copy is taken. */
|
||||||
xModifiableIdleTime = xExpectedIdleTime;
|
xModifiableIdleTime = xExpectedIdleTime;
|
||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||||
|
|
||||||
if( xModifiableIdleTime > 0 )
|
if( xModifiableIdleTime > 0 )
|
||||||
{
|
{
|
||||||
__asm volatile( "dsb" ::: "memory" );
|
__asm volatile ( "dsb" ::: "memory" );
|
||||||
__asm volatile( "wfi" );
|
__asm volatile ( "wfi" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
}
|
}
|
||||||
|
|
||||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
|
||||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||||
* out of sleep mode to execute immediately. See comments above
|
* out of sleep mode to execute immediately. See comments above
|
||||||
* the cpsid instruction above. */
|
* the cpsid instruction above. */
|
||||||
__asm volatile( "cpsie i" ::: "memory" );
|
__asm volatile ( "cpsie i" ::: "memory" );
|
||||||
__asm volatile( "dsb" );
|
__asm volatile ( "dsb" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
|
|
||||||
/* Disable interrupts again because the clock is about to be stopped
|
/* Disable interrupts again because the clock is about to be stopped
|
||||||
* and interrupts that execute while the clock is stopped will
|
* and interrupts that execute while the clock is stopped will
|
||||||
* increase any slippage between the time maintained by the RTOS and
|
* increase any slippage between the time maintained by the RTOS and
|
||||||
* calendar time. */
|
* calendar time. */
|
||||||
__asm volatile( "cpsid i" ::: "memory" );
|
__asm volatile ( "cpsid i" ::: "memory" );
|
||||||
__asm volatile( "dsb" );
|
__asm volatile ( "dsb" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
|
|
||||||
/* Disable the SysTick clock without reading the
|
/* Disable the SysTick clock without reading the
|
||||||
* portNVIC_SYSTICK_CTRL_REG register to ensure the
|
* portNVIC_SYSTICK_CTRL_REG register to ensure the
|
||||||
|
|
@ -534,16 +544,16 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
|
|
||||||
/* Exit with interrupts enabled. */
|
/* Exit with interrupts enabled. */
|
||||||
__asm volatile( "cpsie i" ::: "memory" );
|
__asm volatile ( "cpsie i" ::: "memory" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
|
__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
/* Calculate the constants required to configure the tick interrupt. */
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
{
|
{
|
||||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||||
|
|
@ -563,7 +573,7 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNC
|
||||||
|
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulDummy = 0UL;
|
volatile uint32_t ulDummy = 0UL;
|
||||||
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* 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
|
* its caller as there is nothing to return to. If a task wants to exit it
|
||||||
|
|
@ -586,10 +596,11 @@ volatile uint32_t ulDummy = 0UL;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */
|
static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* Declaration when these variable are defined in code instead of being
|
||||||
* exported from linker scripts. */
|
* exported from linker scripts. */
|
||||||
extern uint32_t * __privileged_functions_start__;
|
extern uint32_t * __privileged_functions_start__;
|
||||||
|
|
@ -600,7 +611,7 @@ volatile uint32_t ulDummy = 0UL;
|
||||||
extern uint32_t * __unprivileged_flash_end__;
|
extern uint32_t * __unprivileged_flash_end__;
|
||||||
extern uint32_t * __privileged_sram_start__;
|
extern uint32_t * __privileged_sram_start__;
|
||||||
extern uint32_t * __privileged_sram_end__;
|
extern uint32_t * __privileged_sram_end__;
|
||||||
#else
|
#else /* if defined( __ARMCC_VERSION ) */
|
||||||
/* Declaration when these variable are exported from linker scripts. */
|
/* Declaration when these variable are exported from linker scripts. */
|
||||||
extern uint32_t __privileged_functions_start__[];
|
extern uint32_t __privileged_functions_start__[];
|
||||||
extern uint32_t __privileged_functions_end__[];
|
extern uint32_t __privileged_functions_end__[];
|
||||||
|
|
@ -671,10 +682,10 @@ volatile uint32_t ulDummy = 0UL;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */
|
static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
{
|
{
|
||||||
/* Enable non-secure access to the FPU. */
|
/* Enable non-secure access to the FPU. */
|
||||||
SecureInit_EnableNSFPUAccess();
|
SecureInit_EnableNSFPUAccess();
|
||||||
|
|
@ -703,8 +714,8 @@ void vPortYield( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is
|
/* Barriers are normally not required but do ensure the code is
|
||||||
* completely within the specified behaviour for the architecture. */
|
* completely within the specified behaviour for the architecture. */
|
||||||
__asm volatile( "dsb" ::: "memory" );
|
__asm volatile ( "dsb" ::: "memory" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -715,8 +726,8 @@ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is
|
/* Barriers are normally not required but do ensure the code is
|
||||||
* completely within the specified behaviour for the architecture. */
|
* completely within the specified behaviour for the architecture. */
|
||||||
__asm volatile( "dsb" ::: "memory" );
|
__asm volatile ( "dsb" ::: "memory" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -734,7 +745,7 @@ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
|
void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
uint32_t ulPreviousMask;
|
uint32_t ulPreviousMask;
|
||||||
|
|
||||||
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
|
|
@ -749,10 +760,11 @@ uint32_t ulPreviousMask;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */
|
void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */
|
||||||
{
|
{
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* Declaration when these variable are defined in code instead of being
|
||||||
* exported from linker scripts. */
|
* exported from linker scripts. */
|
||||||
extern uint32_t * __syscalls_flash_start__;
|
extern uint32_t * __syscalls_flash_start__;
|
||||||
|
|
@ -762,33 +774,33 @@ void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION
|
||||||
extern uint32_t __syscalls_flash_start__[];
|
extern uint32_t __syscalls_flash_start__[];
|
||||||
extern uint32_t __syscalls_flash_end__[];
|
extern uint32_t __syscalls_flash_end__[];
|
||||||
#endif /* defined( __ARMCC_VERSION ) */
|
#endif /* defined( __ARMCC_VERSION ) */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
uint32_t ulPC;
|
uint32_t ulPC;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
uint32_t ulR0;
|
uint32_t ulR0;
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
uint32_t ulControl, ulIsTaskPrivileged;
|
uint32_t ulControl, ulIsTaskPrivileged;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
uint8_t ucSVCNumber;
|
uint8_t ucSVCNumber;
|
||||||
|
|
||||||
/* Register are stored on the stack in the following order - R0, R1, R2, R3,
|
/* Register are stored on the stack in the following order - R0, R1, R2, R3,
|
||||||
* R12, LR, PC, xPSR. */
|
* R12, LR, PC, xPSR. */
|
||||||
ulPC = pulCallerStackAddress[ 6 ];
|
ulPC = pulCallerStackAddress[ 6 ];
|
||||||
ucSVCNumber = ( ( uint8_t *) ulPC )[ -2 ];
|
ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ];
|
||||||
|
|
||||||
switch( ucSVCNumber )
|
switch( ucSVCNumber )
|
||||||
{
|
{
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
case portSVC_ALLOCATE_SECURE_CONTEXT:
|
case portSVC_ALLOCATE_SECURE_CONTEXT:
|
||||||
{
|
|
||||||
/* R0 contains the stack size passed as parameter to the
|
/* R0 contains the stack size passed as parameter to the
|
||||||
* vPortAllocateSecureContext function. */
|
* vPortAllocateSecureContext function. */
|
||||||
ulR0 = pulCallerStackAddress[ 0 ];
|
ulR0 = pulCallerStackAddress[ 0 ];
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
/* Read the CONTROL register value. */
|
/* Read the CONTROL register value. */
|
||||||
__asm volatile ( "mrs %0, control" : "=r" ( ulControl ) );
|
__asm volatile ( "mrs %0, control" : "=r" ( ulControl ) );
|
||||||
|
|
@ -800,7 +812,7 @@ uint8_t ucSVCNumber;
|
||||||
/* Allocate and load a context for the secure task. */
|
/* Allocate and load a context for the secure task. */
|
||||||
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
|
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
|
||||||
}
|
}
|
||||||
#else
|
#else /* if ( configENABLE_MPU == 1 ) */
|
||||||
{
|
{
|
||||||
/* Allocate and load a context for the secure task. */
|
/* Allocate and load a context for the secure task. */
|
||||||
xSecureContext = SecureContext_AllocateContext( ulR0 );
|
xSecureContext = SecureContext_AllocateContext( ulR0 );
|
||||||
|
|
@ -809,23 +821,19 @@ uint8_t ucSVCNumber;
|
||||||
|
|
||||||
configASSERT( xSecureContext != NULL );
|
configASSERT( xSecureContext != NULL );
|
||||||
SecureContext_LoadContext( xSecureContext );
|
SecureContext_LoadContext( xSecureContext );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case portSVC_FREE_SECURE_CONTEXT:
|
case portSVC_FREE_SECURE_CONTEXT:
|
||||||
{
|
|
||||||
/* R0 contains the secure context handle to be freed. */
|
/* R0 contains the secure context handle to be freed. */
|
||||||
ulR0 = pulCallerStackAddress[ 0 ];
|
ulR0 = pulCallerStackAddress[ 0 ];
|
||||||
|
|
||||||
/* Free the secure context. */
|
/* Free the secure context. */
|
||||||
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 );
|
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
case portSVC_START_SCHEDULER:
|
case portSVC_START_SCHEDULER:
|
||||||
{
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
|
||||||
{
|
{
|
||||||
/* De-prioritize the non-secure exceptions so that the
|
/* De-prioritize the non-secure exceptions so that the
|
||||||
* non-secure pendSV runs at the lowest priority. */
|
* non-secure pendSV runs at the lowest priority. */
|
||||||
|
|
@ -836,7 +844,7 @@ uint8_t ucSVCNumber;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
{
|
{
|
||||||
/* Setup the Floating Point Unit (FPU). */
|
/* Setup the Floating Point Unit (FPU). */
|
||||||
prvSetupFPU();
|
prvSetupFPU();
|
||||||
|
|
@ -846,41 +854,44 @@ uint8_t ucSVCNumber;
|
||||||
/* Setup the context of the first task so that the first task starts
|
/* Setup the context of the first task so that the first task starts
|
||||||
* executing. */
|
* executing. */
|
||||||
vRestoreContextOfFirstTask();
|
vRestoreContextOfFirstTask();
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
case portSVC_RAISE_PRIVILEGE:
|
case portSVC_RAISE_PRIVILEGE:
|
||||||
{
|
|
||||||
/* Only raise the privilege, if the svc was raised from any of
|
/* Only raise the privilege, if the svc was raised from any of
|
||||||
* the system calls. */
|
* the system calls. */
|
||||||
if( ulPC >= ( uint32_t ) __syscalls_flash_start__ &&
|
if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) &&
|
||||||
ulPC <= ( uint32_t ) __syscalls_flash_end__ )
|
( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) )
|
||||||
{
|
{
|
||||||
vRaisePrivilege();
|
vRaisePrivilege();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
|
||||||
/* Incorrect SVC call. */
|
/* Incorrect SVC call. */
|
||||||
configASSERT( pdFALSE );
|
configASSERT( pdFALSE );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
StackType_t * pxEndOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters,
|
||||||
|
BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */
|
||||||
#else
|
#else
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) /* PRIVILEGED_FUNCTION */
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
StackType_t * pxEndOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters ) /* PRIVILEGED_FUNCTION */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
{
|
{
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
* interrupt. */
|
* interrupt. */
|
||||||
#if( portPRELOAD_REGISTERS == 0 )
|
#if ( portPRELOAD_REGISTERS == 0 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||||
|
|
@ -893,9 +904,10 @@ uint8_t ucSVCNumber;
|
||||||
pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */
|
pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */
|
||||||
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
if( xRunPrivileged == pdTRUE )
|
if( xRunPrivileged == pdTRUE )
|
||||||
{
|
{
|
||||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||||
|
|
@ -910,7 +922,7 @@ uint8_t ucSVCNumber;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
||||||
|
|
@ -954,9 +966,10 @@ uint8_t ucSVCNumber;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */
|
*pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
if( xRunPrivileged == pdTRUE )
|
if( xRunPrivileged == pdTRUE )
|
||||||
{
|
{
|
||||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||||
|
|
@ -971,7 +984,7 @@ uint8_t ucSVCNumber;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
||||||
|
|
@ -990,7 +1003,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
/* Setup the Memory Protection Unit (MPU). */
|
/* Setup the Memory Protection Unit (MPU). */
|
||||||
prvSetupMPU();
|
prvSetupMPU();
|
||||||
|
|
@ -1029,8 +1042,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )
|
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||||
|
const struct xMEMORY_REGION * const xRegions,
|
||||||
|
StackType_t * pxBottomOfStack,
|
||||||
|
uint32_t ulStackDepth )
|
||||||
{
|
{
|
||||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||||
int32_t lIndex = 0;
|
int32_t lIndex = 0;
|
||||||
|
|
@ -1126,13 +1142,13 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
BaseType_t xPortIsInsideInterrupt( void )
|
BaseType_t xPortIsInsideInterrupt( void )
|
||||||
{
|
{
|
||||||
uint32_t ulCurrentInterrupt;
|
uint32_t ulCurrentInterrupt;
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
/* Obtain the number of the currently executing interrupt. Interrupt Program
|
/* Obtain the number of the currently executing interrupt. Interrupt Program
|
||||||
* Status Register (IPSR) holds the exception number of the currently-executing
|
* Status Register (IPSR) holds the exception number of the currently-executing
|
||||||
* exception or zero for Thread mode.*/
|
* exception or zero for Thread mode.*/
|
||||||
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
|
||||||
|
|
||||||
if( ulCurrentInterrupt == 0 )
|
if( ulCurrentInterrupt == 0 )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
* header files. */
|
* header files. */
|
||||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -48,80 +48,80 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r3, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n"/* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r5, #1 \n" /* r5 = 1. */
|
" movs r5, #1 \n"/* r5 = 1. */
|
||||||
" bics r4, r5 \n" /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
|
" bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Disable MPU. */
|
" str r4, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
||||||
" ldr r4, [r3] \n" /* r4 = *r3 i.e. r4 = MAIR0. */
|
" ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r4, [r2] \n" /* Program MAIR0. */
|
" str r4, [r2] \n"/* Program MAIR0. */
|
||||||
" ldr r2, xRNRConst2 \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
" ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */
|
||||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||||
" movs r5, #4 \n" /* r5 = 4. */
|
" movs r5, #4 \n"/* r5 = 4. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 4. */
|
" str r5, [r2] \n"/* Program RNR = 4. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read first set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst2 \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write first set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */
|
||||||
" movs r5, #5 \n" /* r5 = 5. */
|
" movs r5, #5 \n"/* r5 = 5. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 5. */
|
" str r5, [r2] \n"/* Program RNR = 5. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read second set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst2 \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write second set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */
|
||||||
" movs r5, #6 \n" /* r5 = 6. */
|
" movs r5, #6 \n"/* r5 = 6. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 6. */
|
" str r5, [r2] \n"/* Program RNR = 6. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read third set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst2 \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write third set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */
|
||||||
" movs r5, #7 \n" /* r5 = 7. */
|
" movs r5, #7 \n"/* r5 = 7. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 7. */
|
" str r5, [r2] \n"/* Program RNR = 7. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read fourth set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst2 \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write fourth set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r5, #1 \n" /* r5 = 1. */
|
" movs r5, #1 \n"/* r5 = 1. */
|
||||||
" orrs r4, r5 \n" /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
|
" orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Enable MPU. */
|
" str r4, [r2] \n"/* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n"/* Force memory writes before continuing. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" ldm r0!, {r1-r4} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */
|
" ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */
|
||||||
" ldr r5, xSecureContextConst2 \n"
|
" ldr r5, xSecureContextConst2 \n"
|
||||||
" str r1, [r5] \n" /* Set xSecureContext to this task's value for the same. */
|
" str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */
|
||||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
" msr psplim, r2 \n"/* Set this task's PSPLIM value. */
|
||||||
" msr control, r3 \n" /* Set this task's CONTROL value. */
|
" msr control, r3 \n"/* Set this task's CONTROL value. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r4 \n" /* Finally, branch to EXC_RETURN. */
|
" bx r4 \n"/* Finally, branch to EXC_RETURN. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
" ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||||
" ldr r4, xSecureContextConst2 \n"
|
" ldr r4, xSecureContextConst2 \n"
|
||||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
" str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */
|
||||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
" msr psplim, r2 \n"/* Set this task's PSPLIM value. */
|
||||||
" movs r1, #2 \n" /* r1 = 2. */
|
" movs r1, #2 \n"/* r1 = 2. */
|
||||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
" msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
" bx r3 \n"/* Finally, branch to EXC_RETURN. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
"xSecureContextConst2: .word xSecureContext \n"
|
"xSecureContextConst2: .word xSecureContext \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||||
"xMAIR0Const2: .word 0xe000edc0 \n"
|
"xMAIR0Const2: .word 0xe000edc0 \n"
|
||||||
"xRNRConst2: .word 0xe000ed98 \n"
|
"xRNRConst2: .word 0xe000ed98 \n"
|
||||||
|
|
@ -135,15 +135,15 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||||
" movs r1, #1 \n" /* r1 = 1. */
|
" movs r1, #1 \n"/* r1 = 1. */
|
||||||
" tst r0, r1 \n" /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
" tst r0, r1 \n"/* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
||||||
" beq running_privileged \n" /* If the result of previous AND operation was 0, branch. */
|
" beq running_privileged \n"/* If the result of previous AND operation was 0, branch. */
|
||||||
" movs r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
" movs r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
" running_privileged: \n"
|
" running_privileged: \n"
|
||||||
" movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
" movs r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
|
|
@ -155,11 +155,11 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||||
" movs r1, #1 \n" /* r1 = 1. */
|
" movs r1, #1 \n"/* r1 = 1. */
|
||||||
" bics r0, r1 \n" /* Clear the bit 0. */
|
" bics r0, r1 \n"/* Clear the bit 0. */
|
||||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||||
" bx lr \n" /* Return to the caller. */
|
" bx lr \n"/* Return to the caller. */
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -169,12 +169,12 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||||
" movs r1, #1 \n" /* r1 = 1. */
|
" movs r1, #1 \n"/* r1 = 1. */
|
||||||
" orrs r0, r1 \n" /* r0 = r0 | r1. */
|
" orrs r0, r1 \n"/* r0 = r0 | r1. */
|
||||||
" msr control, r0 \n" /* CONTROL = r0. */
|
" msr control, r0 \n"/* CONTROL = r0. */
|
||||||
" bx lr \n" /* Return to the caller. */
|
" bx lr \n"/* Return to the caller. */
|
||||||
:::"r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -183,19 +183,19 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||||
" cpsie i \n" /* Globally enable interrupts. */
|
" cpsie i \n"/* Globally enable interrupts. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" svc %0 \n" /* System call to start the first task. */
|
" svc %0 \n"/* System call to start the first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"xVTORConst: .word 0xe000ed08 \n"
|
"xVTORConst: .word 0xe000ed08 \n"
|
||||||
:: "i" ( portSVC_START_SCHEDULER ) : "memory"
|
::"i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -231,64 +231,64 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
" .extern SecureContext_SaveContext \n"
|
" .extern SecureContext_SaveContext \n"
|
||||||
" .extern SecureContext_LoadContext \n"
|
" .extern SecureContext_LoadContext \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r1, psp \n" /* Read PSP in r1. */
|
" mrs r1, psp \n"/* Read PSP in r1. */
|
||||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" ldr r0, [r2] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
" ldr r0, [r2] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||||
" \n"
|
" \n"
|
||||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
" cbz r0, save_ns_context \n"/* No secure context to save. */
|
||||||
" push {r0-r2, r14} \n"
|
" push {r0-r2, r14} \n"
|
||||||
" bl SecureContext_SaveContext \n"
|
" bl SecureContext_SaveContext \n"
|
||||||
" pop {r0-r3} \n" /* LR is now in r3. */
|
" pop {r0-r3} \n"/* LR is now in r3. */
|
||||||
" mov lr, r3 \n" /* LR = r3. */
|
" mov lr, r3 \n"/* LR = r3. */
|
||||||
" lsls r2, r3, #25 \n" /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
" lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
" bpl save_ns_context \n" /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
" bpl save_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r2, [r3] \n" /* Read pxCurrentTCB. */
|
" ldr r2, [r3] \n"/* Read pxCurrentTCB. */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" subs r1, r1, #16 \n" /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
" subs r1, r1, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||||
" str r1, [r2] \n" /* Save the new top of stack in TCB. */
|
" str r1, [r2] \n"/* Save the new top of stack in TCB. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mrs r3, control \n" /* r3 = CONTROL. */
|
" mrs r3, control \n"/* r3 = CONTROL. */
|
||||||
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
|
" mov r4, lr \n"/* r4 = LR/EXC_RETURN. */
|
||||||
" stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
" stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" subs r1, r1, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
" subs r1, r1, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */
|
||||||
" str r1, [r2] \n" /* Save the new top of stack in TCB. */
|
" str r1, [r2] \n"/* Save the new top of stack in TCB. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||||
" stmia r1!, {r0, r2-r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
" stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" b select_next_task \n"
|
" b select_next_task \n"
|
||||||
" \n"
|
" \n"
|
||||||
" save_ns_context: \n"
|
" save_ns_context: \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r2, [r3] \n" /* Read pxCurrentTCB. */
|
" ldr r2, [r3] \n"/* Read pxCurrentTCB. */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" subs r1, r1, #48 \n" /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
|
" subs r1, r1, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
|
||||||
" str r1, [r2] \n" /* Save the new top of stack in TCB. */
|
" str r1, [r2] \n"/* Save the new top of stack in TCB. */
|
||||||
" adds r1, r1, #16 \n" /* r1 = r1 + 16. */
|
" adds r1, r1, #16 \n"/* r1 = r1 + 16. */
|
||||||
" stmia r1!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */
|
" stmia r1!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */
|
||||||
" mov r4, r8 \n" /* r4 = r8. */
|
" mov r4, r8 \n"/* r4 = r8. */
|
||||||
" mov r5, r9 \n" /* r5 = r9. */
|
" mov r5, r9 \n"/* r5 = r9. */
|
||||||
" mov r6, r10 \n" /* r6 = r10. */
|
" mov r6, r10 \n"/* r6 = r10. */
|
||||||
" mov r7, r11 \n" /* r7 = r11. */
|
" mov r7, r11 \n"/* r7 = r11. */
|
||||||
" stmia r1!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
" stmia r1!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mrs r3, control \n" /* r3 = CONTROL. */
|
" mrs r3, control \n"/* r3 = CONTROL. */
|
||||||
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
|
" mov r4, lr \n"/* r4 = LR/EXC_RETURN. */
|
||||||
" subs r1, r1, #48 \n" /* r1 = r1 - 48. */
|
" subs r1, r1, #48 \n"/* r1 = r1 - 48. */
|
||||||
" stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
" stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" subs r1, r1, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
" subs r1, r1, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
|
||||||
" str r1, [r2] \n" /* Save the new top of stack in TCB. */
|
" str r1, [r2] \n"/* Save the new top of stack in TCB. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||||
" stmia r1!, {r0, r2-r7} \n" /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */
|
" stmia r1!, {r0, r2-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */
|
||||||
" mov r4, r8 \n" /* r4 = r8. */
|
" mov r4, r8 \n"/* r4 = r8. */
|
||||||
" mov r5, r9 \n" /* r5 = r9. */
|
" mov r5, r9 \n"/* r5 = r9. */
|
||||||
" mov r6, r10 \n" /* r6 = r10. */
|
" mov r6, r10 \n"/* r6 = r10. */
|
||||||
" mov r7, r11 \n" /* r7 = r11. */
|
" mov r7, r11 \n"/* r7 = r11. */
|
||||||
" stmia r1!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
" stmia r1!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" select_next_task: \n"
|
" select_next_task: \n"
|
||||||
|
|
@ -296,102 +296,102 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" cpsie i \n"
|
" cpsie i \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r3, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
" ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */
|
" ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n"/* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r5, #1 \n" /* r5 = 1. */
|
" movs r5, #1 \n"/* r5 = 1. */
|
||||||
" bics r4, r5 \n" /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
|
" bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Disable MPU. */
|
" str r4, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
||||||
" ldr r4, [r3] \n" /* r4 = *r3 i.e. r4 = MAIR0. */
|
" ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r4, [r2] \n" /* Program MAIR0. */
|
" str r4, [r2] \n"/* Program MAIR0. */
|
||||||
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
" ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */
|
||||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||||
" movs r5, #4 \n" /* r5 = 4. */
|
" movs r5, #4 \n"/* r5 = 4. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 4. */
|
" str r5, [r2] \n"/* Program RNR = 4. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read first set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write first set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */
|
||||||
" movs r5, #5 \n" /* r5 = 5. */
|
" movs r5, #5 \n"/* r5 = 5. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 5. */
|
" str r5, [r2] \n"/* Program RNR = 5. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read second set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write second set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */
|
||||||
" movs r5, #6 \n" /* r5 = 6. */
|
" movs r5, #6 \n"/* r5 = 6. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 6. */
|
" str r5, [r2] \n"/* Program RNR = 6. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read third set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write third set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */
|
||||||
" movs r5, #7 \n" /* r5 = 7. */
|
" movs r5, #7 \n"/* r5 = 7. */
|
||||||
" str r5, [r2] \n" /* Program RNR = 7. */
|
" str r5, [r2] \n"/* Program RNR = 7. */
|
||||||
" ldmia r3!, {r6,r7} \n" /* Read fourth set of RBAR/RLAR from TCB. */
|
" ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */
|
||||||
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r4!, {r6,r7} \n" /* Write fourth set of RBAR/RLAR registers. */
|
" stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r5, #1 \n" /* r5 = 1. */
|
" movs r5, #1 \n"/* r5 = 1. */
|
||||||
" orrs r4, r5 \n" /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
|
" orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
|
||||||
" str r4, [r2] \n" /* Enable MPU. */
|
" str r4, [r2] \n"/* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n"/* Force memory writes before continuing. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" ldmia r1!, {r0, r2-r4} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */
|
" ldmia r1!, {r0, r2-r4} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */
|
||||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
||||||
" msr control, r3 \n" /* Restore the CONTROL register value for the task. */
|
" msr control, r3 \n"/* Restore the CONTROL register value for the task. */
|
||||||
" mov lr, r4 \n" /* LR = r4. */
|
" mov lr, r4 \n"/* LR = r4. */
|
||||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" str r0, [r2] \n" /* Restore the task's xSecureContext. */
|
" str r0, [r2] \n"/* Restore the task's xSecureContext. */
|
||||||
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
|
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
|
||||||
" push {r1,r4} \n"
|
" push {r1,r4} \n"
|
||||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. */
|
" bl SecureContext_LoadContext \n"/* Restore the secure context. */
|
||||||
" pop {r1,r4} \n"
|
" pop {r1,r4} \n"
|
||||||
" mov lr, r4 \n" /* LR = r4. */
|
" mov lr, r4 \n"/* LR = r4. */
|
||||||
" lsls r2, r4, #25 \n" /* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
" lsls r2, r4, #25 \n"/* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
" bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||||
" msr psp, r1 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r1 \n"/* Remember the new top of stack for the task. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" ldmia r1!, {r0, r2-r3} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */
|
" ldmia r1!, {r0, r2-r3} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */
|
||||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
||||||
" mov lr, r3 \n" /* LR = r3. */
|
" mov lr, r3 \n"/* LR = r3. */
|
||||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
" str r0, [r2] \n" /* Restore the task's xSecureContext. */
|
" str r0, [r2] \n"/* Restore the task's xSecureContext. */
|
||||||
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
|
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
|
||||||
" push {r1,r3} \n"
|
" push {r1,r3} \n"
|
||||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. */
|
" bl SecureContext_LoadContext \n"/* Restore the secure context. */
|
||||||
" pop {r1,r3} \n"
|
" pop {r1,r3} \n"
|
||||||
" mov lr, r3 \n" /* LR = r3. */
|
" mov lr, r3 \n"/* LR = r3. */
|
||||||
" lsls r2, r3, #25 \n" /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
" lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
" bpl restore_ns_context \n" /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
|
||||||
" msr psp, r1 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r1 \n"/* Remember the new top of stack for the task. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" restore_ns_context: \n"
|
" restore_ns_context: \n"
|
||||||
" adds r1, r1, #16 \n" /* Move to the high registers. */
|
" adds r1, r1, #16 \n"/* Move to the high registers. */
|
||||||
" ldmia r1!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
|
" ldmia r1!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */
|
||||||
" mov r8, r4 \n" /* r8 = r4. */
|
" mov r8, r4 \n"/* r8 = r4. */
|
||||||
" mov r9, r5 \n" /* r9 = r5. */
|
" mov r9, r5 \n"/* r9 = r5. */
|
||||||
" mov r10, r6 \n" /* r10 = r6. */
|
" mov r10, r6 \n"/* r10 = r6. */
|
||||||
" mov r11, r7 \n" /* r11 = r7. */
|
" mov r11, r7 \n"/* r11 = r7. */
|
||||||
" msr psp, r1 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r1 \n"/* Remember the new top of stack for the task. */
|
||||||
" subs r1, r1, #32 \n" /* Go back to the low registers. */
|
" subs r1, r1, #32 \n"/* Go back to the low registers. */
|
||||||
" ldmia r1!, {r4-r7} \n" /* Restore the low registers that are not automatically restored. */
|
" ldmia r1!, {r4-r7} \n"/* Restore the low registers that are not automatically restored. */
|
||||||
" bx lr \n"
|
" bx lr \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
"xSecureContextConst: .word xSecureContext \n"
|
"xSecureContextConst: .word xSecureContext \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||||
"xMAIR0Const: .word 0xe000edc0 \n"
|
"xMAIR0Const: .word 0xe000edc0 \n"
|
||||||
"xRNRConst: .word 0xe000ed98 \n"
|
"xRNRConst: .word 0xe000ed98 \n"
|
||||||
|
|
@ -427,26 +427,26 @@ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
|
" svc %0 \n"/* Secure context is allocated in the supervisor call. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
:: "i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" ldr r1, [r0] \n" /* The first item in the TCB is the top of the stack. */
|
" ldr r1, [r0] \n"/* The first item in the TCB is the top of the stack. */
|
||||||
" ldr r0, [r1] \n" /* The first item on the stack is the task's xSecureContext. */
|
" ldr r0, [r1] \n"/* The first item on the stack is the task's xSecureContext. */
|
||||||
" cmp r0, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
|
" cmp r0, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */
|
||||||
" beq free_secure_context \n"
|
" beq free_secure_context \n"
|
||||||
" bx lr \n" /* There is no secure context (xSecureContext is NULL). */
|
" bx lr \n"/* There is no secure context (xSecureContext is NULL). */
|
||||||
" free_secure_context: \n"
|
" free_secure_context: \n"
|
||||||
" svc %0 \n" /* Secure context is freed in the supervisor call. */
|
" svc %0 \n"/* Secure context is freed in the supervisor call. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
:: "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
||||||
|
|
@ -37,14 +37,14 @@
|
||||||
* @brief Restore the context of the first task so that the first task starts
|
* @brief Restore the context of the first task so that the first task starts
|
||||||
* executing.
|
* executing.
|
||||||
*/
|
*/
|
||||||
void vRestoreContextOfFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
BaseType_t xIsPrivileged( void ) __attribute__ (( naked ));
|
BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raises the privilege level by clearing the bit 0 of the CONTROL
|
* @brief Raises the privilege level by clearing the bit 0 of the CONTROL
|
||||||
|
|
@ -57,7 +57,7 @@ BaseType_t xIsPrivileged( void ) __attribute__ (( naked ));
|
||||||
* Bit[0] = 0 --> The processor is running privileged
|
* Bit[0] = 0 --> The processor is running privileged
|
||||||
* Bit[0] = 1 --> The processor is running unprivileged.
|
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||||
*/
|
*/
|
||||||
void vRaisePrivilege( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
|
|
@ -67,32 +67,32 @@ void vRaisePrivilege( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
||||||
* Bit[0] = 0 --> The processor is running privileged
|
* Bit[0] = 0 --> The processor is running privileged
|
||||||
* Bit[0] = 1 --> The processor is running unprivileged.
|
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||||
*/
|
*/
|
||||||
void vResetPrivilege( void ) __attribute__ (( naked ));
|
void vResetPrivilege( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Starts the first task.
|
* @brief Starts the first task.
|
||||||
*/
|
*/
|
||||||
void vStartFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disables interrupts.
|
* @brief Disables interrupts.
|
||||||
*/
|
*/
|
||||||
uint32_t ulSetInterruptMask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
|
uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables interrupts.
|
* @brief Enables interrupts.
|
||||||
*/
|
*/
|
||||||
void vClearInterruptMask( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
|
void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief PendSV Exception handler.
|
* @brief PendSV Exception handler.
|
||||||
*/
|
*/
|
||||||
void PendSV_Handler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SVC Handler.
|
* @brief SVC Handler.
|
||||||
*/
|
*/
|
||||||
void SVC_Handler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocate a Secure context for the calling task.
|
* @brief Allocate a Secure context for the calling task.
|
||||||
|
|
@ -100,13 +100,13 @@ void SVC_Handler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
||||||
* @param[in] ulSecureStackSize The size of the stack to be allocated on the
|
* @param[in] ulSecureStackSize The size of the stack to be allocated on the
|
||||||
* secure side for the calling task.
|
* secure side for the calling task.
|
||||||
*/
|
*/
|
||||||
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__ (( naked ));
|
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Free the task's secure context.
|
* @brief Free the task's secure context.
|
||||||
*
|
*
|
||||||
* @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task.
|
* @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task.
|
||||||
*/
|
*/
|
||||||
void vPortFreeSecureContext( uint32_t *pulTCB ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
#endif /* __PORT_ASM_H__ */
|
#endif /* __PORT_ASM_H__ */
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
|
@ -41,109 +41,109 @@ extern "C" {
|
||||||
*------------------------------------------------------------------------------
|
*------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef configENABLE_FPU
|
#ifndef configENABLE_FPU
|
||||||
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
#endif /* configENABLE_FPU */
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
#ifndef configENABLE_MPU
|
#ifndef configENABLE_MPU
|
||||||
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
#ifndef configENABLE_TRUSTZONE
|
#ifndef configENABLE_TRUSTZONE
|
||||||
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type definitions.
|
* @brief Type definitions.
|
||||||
*/
|
*/
|
||||||
#define portCHAR char
|
#define portCHAR char
|
||||||
#define portFLOAT float
|
#define portFLOAT float
|
||||||
#define portDOUBLE double
|
#define portDOUBLE double
|
||||||
#define portLONG long
|
#define portLONG long
|
||||||
#define portSHORT short
|
#define portSHORT short
|
||||||
#define portSTACK_TYPE uint32_t
|
#define portSTACK_TYPE uint32_t
|
||||||
#define portBASE_TYPE long
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
typedef portSTACK_TYPE StackType_t;
|
typedef portSTACK_TYPE StackType_t;
|
||||||
typedef long BaseType_t;
|
typedef long BaseType_t;
|
||||||
typedef unsigned long UBaseType_t;
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
* not need to be guarded with a critical section. */
|
* not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Architecture specifics.
|
* Architecture specifics.
|
||||||
*/
|
*/
|
||||||
#define portARCH_NAME "Cortex-M23"
|
#define portARCH_NAME "Cortex-M23"
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
#endif
|
#endif
|
||||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
#define portDONT_DISCARD __attribute__(( used ))
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extern declarations.
|
* @brief Extern declarations.
|
||||||
*/
|
*/
|
||||||
extern BaseType_t xPortIsInsideInterrupt( void );
|
extern BaseType_t xPortIsInsideInterrupt( void );
|
||||||
|
|
||||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU specific constants.
|
* @brief MPU specific constants.
|
||||||
*/
|
*/
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
#define portUSING_MPU_WRAPPERS 1
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
#else
|
#else
|
||||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
|
||||||
/* MPU regions. */
|
/* MPU regions. */
|
||||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
#define portSTACK_REGION ( 4UL )
|
#define portSTACK_REGION ( 4UL )
|
||||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||||
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
/* Device memory attributes used in MPU_MAIR registers.
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
*
|
*
|
||||||
|
|
@ -155,95 +155,96 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
|
||||||
* 11 --> Device-GRE
|
* 11 --> Device-GRE
|
||||||
* Bit[1:0] - 00, Reserved.
|
* Bit[1:0] - 00, Reserved.
|
||||||
*/
|
*/
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
/* Attributes used in MPU_RBAR registers. */
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Settings to define an MPU region.
|
* @brief Settings to define an MPU region.
|
||||||
*/
|
*/
|
||||||
typedef struct MPURegionSettings
|
typedef struct MPURegionSettings
|
||||||
{
|
{
|
||||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
} MPURegionSettings_t;
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief MPU settings as stored in the TCB.
|
* @brief MPU settings as stored in the TCB.
|
||||||
*/
|
*/
|
||||||
typedef struct MPU_SETTINGS
|
typedef struct MPU_SETTINGS
|
||||||
{
|
{
|
||||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
} xMPU_SETTINGS;
|
} xMPU_SETTINGS;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SVC numbers.
|
* @brief SVC numbers.
|
||||||
*/
|
*/
|
||||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||||
#define portSVC_START_SCHEDULER 2
|
#define portSVC_START_SCHEDULER 2
|
||||||
#define portSVC_RAISE_PRIVILEGE 3
|
#define portSVC_RAISE_PRIVILEGE 3
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Scheduler utilities.
|
* @brief Scheduler utilities.
|
||||||
*/
|
*/
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Critical section management.
|
* @brief Critical section management.
|
||||||
*/
|
*/
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tickless idle/low power functionality.
|
* @brief Tickless idle/low power functionality.
|
||||||
*/
|
*/
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||||
*/
|
*/
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Allocate a secure context for the task.
|
* @brief Allocate a secure context for the task.
|
||||||
*
|
*
|
||||||
* Tasks are not created with a secure context. Any task that is going to call
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
|
@ -254,56 +255,57 @@ typedef struct MPU_SETTINGS
|
||||||
*/
|
*/
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a task is deleted to delete the task's secure context,
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
* if it has one.
|
* if it has one.
|
||||||
*
|
*
|
||||||
* @param[in] pxTCB The TCB of the task being deleted.
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
*/
|
*/
|
||||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
#else
|
#else
|
||||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||||
#define portCLEAN_UP_TCB( pxTCB )
|
#define portCLEAN_UP_TCB( pxTCB )
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Checks whether or not the processor is privileged.
|
* @brief Checks whether or not the processor is privileged.
|
||||||
*
|
*
|
||||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raise an SVC request to raise privilege.
|
* @brief Raise an SVC request to raise privilege.
|
||||||
*
|
*
|
||||||
* The SVC handler checks that the SVC was raised from a system call and only
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
* then it raises the privilege. If this is called from any other place,
|
* then it raises the privilege. If this is called from any other place,
|
||||||
* the privilege is not raised.
|
* the privilege is not raised.
|
||||||
*/
|
*/
|
||||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
* register.
|
* register.
|
||||||
*/
|
*/
|
||||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
#else
|
#else
|
||||||
#define portIS_PRIVILEGED()
|
#define portIS_PRIVILEGED()
|
||||||
#define portRAISE_PRIVILEGE()
|
#define portRAISE_PRIVILEGE()
|
||||||
#define portRESET_PRIVILEGE()
|
#define portRESET_PRIVILEGE()
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Barriers.
|
* @brief Barriers.
|
||||||
*/
|
*/
|
||||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* PORTMACRO_H */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
|
||||||
|
|
@ -58,9 +58,9 @@
|
||||||
*/
|
*/
|
||||||
typedef struct SecureContext
|
typedef struct SecureContext
|
||||||
{
|
{
|
||||||
uint8_t *pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
|
uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
|
||||||
uint8_t *pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
|
uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
|
||||||
uint8_t *pucStackStart; /**< First location of the stack memory. */
|
uint8_t * pucStackStart; /**< First location of the stack memory. */
|
||||||
} SecureContext_t;
|
} SecureContext_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -79,7 +79,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
secureportSET_PSPLIM( securecontextNO_STACK );
|
secureportSET_PSPLIM( securecontextNO_STACK );
|
||||||
secureportSET_PSP( securecontextNO_STACK );
|
secureportSET_PSP( securecontextNO_STACK );
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||||
|
|
@ -94,17 +94,19 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged )
|
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
uint32_t ulIsTaskPrivileged )
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
|
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
{
|
{
|
||||||
uint8_t *pucStackMemory = NULL;
|
uint8_t * pucStackMemory = NULL;
|
||||||
uint32_t ulIPSR;
|
uint32_t ulIPSR;
|
||||||
SecureContextHandle_t xSecureContextHandle = NULL;
|
SecureContextHandle_t xSecureContextHandle = NULL;
|
||||||
#if( configENABLE_MPU == 1 )
|
|
||||||
uint32_t *pulCurrentStackPointer = NULL;
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
uint32_t * pulCurrentStackPointer = NULL;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
/* Read the Interrupt Program Status Register (IPSR) value. */
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
|
@ -136,13 +138,14 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
* programmed in the PSPLIM register on context switch.*/
|
* programmed in the PSPLIM register on context switch.*/
|
||||||
xSecureContextHandle->pucStackLimit = pucStackMemory;
|
xSecureContextHandle->pucStackLimit = pucStackMemory;
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
/* Store the correct CONTROL value for the task on the stack.
|
/* Store the correct CONTROL value for the task on the stack.
|
||||||
* This value is programmed in the CONTROL register on
|
* This value is programmed in the CONTROL register on
|
||||||
* context switch. */
|
* context switch. */
|
||||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
|
pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
|
||||||
pulCurrentStackPointer--;
|
pulCurrentStackPointer--;
|
||||||
|
|
||||||
if( ulIsTaskPrivileged )
|
if( ulIsTaskPrivileged )
|
||||||
{
|
{
|
||||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||||
|
|
@ -161,7 +164,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
/* Current SP is set to the starting of the stack. This
|
/* Current SP is set to the starting of the stack. This
|
||||||
* value programmed in the PSP register on context switch. */
|
* value programmed in the PSP register on context switch. */
|
||||||
xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
|
xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
* @brief Opaque handle.
|
* @brief Opaque handle.
|
||||||
*/
|
*/
|
||||||
struct SecureContext;
|
struct SecureContext;
|
||||||
typedef struct SecureContext* SecureContextHandle_t;
|
typedef struct SecureContext * SecureContextHandle_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -68,8 +68,9 @@ void SecureContext_Init( void );
|
||||||
* @return Opaque context handle if context is successfully allocated, NULL
|
* @return Opaque context handle if context is successfully allocated, NULL
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged );
|
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
uint32_t ulIsTaskPrivileged );
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
|
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
/* Secure port macros. */
|
/* Secure port macros. */
|
||||||
#include "secure_port_macros.h"
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -41,20 +41,20 @@ secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandl
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
" mrs r1, ipsr \n"/* r1 = IPSR. */
|
||||||
" cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
" cbz r1, load_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
|
||||||
" ldmia r0!, {r1, r2} \n" /* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
|
" ldmia r0!, {r1, r2} \n"/* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
" ldmia r1!, {r3} \n"/* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
||||||
" msr control, r3 \n" /* CONTROL = r3. */
|
" msr control, r3 \n"/* CONTROL = r3. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" msr psplim, r2 \n" /* PSPLIM = r2. */
|
" msr psplim, r2 \n"/* PSPLIM = r2. */
|
||||||
" msr psp, r1 \n" /* PSP = r1. */
|
" msr psp, r1 \n"/* PSP = r1. */
|
||||||
" \n"
|
" \n"
|
||||||
" load_ctx_therad_mode: \n"
|
" load_ctx_therad_mode: \n"
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
:::"r0", "r1", "r2"
|
::: "r0", "r1", "r2"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -66,25 +66,25 @@ secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandl
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
" mrs r1, ipsr \n"/* r1 = IPSR. */
|
||||||
" cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
" cbz r1, save_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
|
||||||
" mrs r1, psp \n" /* r1 = PSP. */
|
" mrs r1, psp \n"/* r1 = PSP. */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" mrs r2, control \n" /* r2 = CONTROL. */
|
" mrs r2, control \n"/* r2 = CONTROL. */
|
||||||
" subs r1, r1, #4 \n" /* Make space for the CONTROL value on the stack. */
|
" subs r1, r1, #4 \n"/* Make space for the CONTROL value on the stack. */
|
||||||
" str r1, [r0] \n" /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
" str r1, [r0] \n"/* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
||||||
" stmia r1!, {r2} \n" /* Store CONTROL value on the stack. */
|
" stmia r1!, {r2} \n"/* Store CONTROL value on the stack. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" str r1, [r0] \n" /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
" str r1, [r0] \n"/* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" movs r1, %0 \n" /* r1 = securecontextNO_STACK. */
|
" movs r1, %0 \n"/* r1 = securecontextNO_STACK. */
|
||||||
" msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */
|
" msr psplim, r1 \n"/* PSPLIM = securecontextNO_STACK. */
|
||||||
" msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
|
" msr psp, r1 \n"/* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
|
||||||
" \n"
|
" \n"
|
||||||
" save_ctx_therad_mode: \n"
|
" save_ctx_therad_mode: \n"
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
:: "i" ( securecontextNO_STACK ) : "r1", "memory"
|
::"i" ( securecontextNO_STACK ) : "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,10 @@
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Allocate the memory for the heap. */
|
/* Allocate the memory for the heap. */
|
||||||
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
|
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
|
||||||
/* The application writer has already defined the array used for the RTOS
|
|
||||||
* heap - probably so it can be placed in a special segment or address. */
|
/* The application writer has already defined the array used for the RTOS
|
||||||
|
* heap - probably so it can be placed in a special segment or address. */
|
||||||
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||||
#else /* configAPPLICATION_ALLOCATED_HEAP */
|
#else /* configAPPLICATION_ALLOCATED_HEAP */
|
||||||
static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||||
|
|
@ -76,7 +77,7 @@
|
||||||
*/
|
*/
|
||||||
typedef struct A_BLOCK_LINK
|
typedef struct A_BLOCK_LINK
|
||||||
{
|
{
|
||||||
struct A_BLOCK_LINK *pxNextFreeBlock; /**< The next free block in the list. */
|
struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */
|
||||||
size_t xBlockSize; /**< The size of the free block. */
|
size_t xBlockSize; /**< The size of the free block. */
|
||||||
} BlockLink_t;
|
} BlockLink_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -96,7 +97,7 @@ static void prvHeapInit( void );
|
||||||
*
|
*
|
||||||
* @param[in] pxBlockToInsert The block being freed.
|
* @param[in] pxBlockToInsert The block being freed.
|
||||||
*/
|
*/
|
||||||
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert );
|
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -108,7 +109,7 @@ static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( s
|
||||||
/**
|
/**
|
||||||
* @brief Create a couple of list links to mark the start and end of the list.
|
* @brief Create a couple of list links to mark the start and end of the list.
|
||||||
*/
|
*/
|
||||||
static BlockLink_t xStart, *pxEnd = NULL;
|
static BlockLink_t xStart, * pxEnd = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Keeps track of the number of free bytes remaining, but says nothing
|
* @brief Keeps track of the number of free bytes remaining, but says nothing
|
||||||
|
|
@ -129,10 +130,10 @@ static size_t xBlockAllocatedBit = 0;
|
||||||
|
|
||||||
static void prvHeapInit( void )
|
static void prvHeapInit( void )
|
||||||
{
|
{
|
||||||
BlockLink_t *pxFirstFreeBlock;
|
BlockLink_t * pxFirstFreeBlock;
|
||||||
uint8_t *pucAlignedHeap;
|
uint8_t * pucAlignedHeap;
|
||||||
size_t uxAddress;
|
size_t uxAddress;
|
||||||
size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE;
|
size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE;
|
||||||
|
|
||||||
/* Ensure the heap starts on a correctly aligned boundary. */
|
/* Ensure the heap starts on a correctly aligned boundary. */
|
||||||
uxAddress = ( size_t ) ucHeap;
|
uxAddress = ( size_t ) ucHeap;
|
||||||
|
|
@ -175,10 +176,10 @@ size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert )
|
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert )
|
||||||
{
|
{
|
||||||
BlockLink_t *pxIterator;
|
BlockLink_t * pxIterator;
|
||||||
uint8_t *puc;
|
uint8_t * puc;
|
||||||
|
|
||||||
/* Iterate through the list until a block is found that has a higher address
|
/* Iterate through the list until a block is found that has a higher address
|
||||||
* than the block being inserted. */
|
* than the block being inserted. */
|
||||||
|
|
@ -190,6 +191,7 @@ uint8_t *puc;
|
||||||
/* Do the block being inserted, and the block it is being inserted after
|
/* Do the block being inserted, and the block it is being inserted after
|
||||||
* make a contiguous block of memory? */
|
* make a contiguous block of memory? */
|
||||||
puc = ( uint8_t * ) pxIterator;
|
puc = ( uint8_t * ) pxIterator;
|
||||||
|
|
||||||
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
|
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
|
||||||
{
|
{
|
||||||
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
|
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
|
||||||
|
|
@ -203,6 +205,7 @@ uint8_t *puc;
|
||||||
/* Do the block being inserted, and the block it is being inserted before
|
/* Do the block being inserted, and the block it is being inserted before
|
||||||
* make a contiguous block of memory? */
|
* make a contiguous block of memory? */
|
||||||
puc = ( uint8_t * ) pxBlockToInsert;
|
puc = ( uint8_t * ) pxBlockToInsert;
|
||||||
|
|
||||||
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
|
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
|
||||||
{
|
{
|
||||||
if( pxIterator->pxNextFreeBlock != pxEnd )
|
if( pxIterator->pxNextFreeBlock != pxEnd )
|
||||||
|
|
@ -236,10 +239,10 @@ uint8_t *puc;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void *pvPortMalloc( size_t xWantedSize )
|
void * pvPortMalloc( size_t xWantedSize )
|
||||||
{
|
{
|
||||||
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
|
BlockLink_t * pxBlock, * pxPreviousBlock, * pxNewBlockLink;
|
||||||
void *pvReturn = NULL;
|
void * pvReturn = NULL;
|
||||||
|
|
||||||
/* If this is the first call to malloc then the heap will require
|
/* If this is the first call to malloc then the heap will require
|
||||||
* initialisation to setup the list of free blocks. */
|
* initialisation to setup the list of free blocks. */
|
||||||
|
|
@ -288,6 +291,7 @@ void *pvReturn = NULL;
|
||||||
* one of adequate size is found. */
|
* one of adequate size is found. */
|
||||||
pxPreviousBlock = &xStart;
|
pxPreviousBlock = &xStart;
|
||||||
pxBlock = xStart.pxNextFreeBlock;
|
pxBlock = xStart.pxNextFreeBlock;
|
||||||
|
|
||||||
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
|
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
|
||||||
{
|
{
|
||||||
pxPreviousBlock = pxBlock;
|
pxPreviousBlock = pxBlock;
|
||||||
|
|
@ -363,7 +367,7 @@ void *pvReturn = NULL;
|
||||||
|
|
||||||
traceMALLOC( pvReturn, xWantedSize );
|
traceMALLOC( pvReturn, xWantedSize );
|
||||||
|
|
||||||
#if( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||||
{
|
{
|
||||||
if( pvReturn == NULL )
|
if( pvReturn == NULL )
|
||||||
{
|
{
|
||||||
|
|
@ -375,17 +379,17 @@ void *pvReturn = NULL;
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||||
|
|
||||||
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
return pvReturn;
|
return pvReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortFree( void *pv )
|
void vPortFree( void * pv )
|
||||||
{
|
{
|
||||||
uint8_t *puc = ( uint8_t * ) pv;
|
uint8_t * puc = ( uint8_t * ) pv;
|
||||||
BlockLink_t *pxLink;
|
BlockLink_t * pxLink;
|
||||||
|
|
||||||
if( pv != NULL )
|
if( pv != NULL )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,13 @@
|
||||||
* @return Pointer to the memory region if the allocation is successful, NULL
|
* @return Pointer to the memory region if the allocation is successful, NULL
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
void *pvPortMalloc( size_t xWantedSize );
|
void * pvPortMalloc( size_t xWantedSize );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Frees the previously allocated memory.
|
* @brief Frees the previously allocated memory.
|
||||||
*
|
*
|
||||||
* @param[in] pv Pointer to the memory to be freed.
|
* @param[in] pv Pointer to the memory to be freed.
|
||||||
*/
|
*/
|
||||||
void vPortFree( void *pv );
|
void vPortFree( void * pv );
|
||||||
|
|
||||||
#endif /* __SECURE_HEAP_H__ */
|
#endif /* __SECURE_HEAP_H__ */
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
|
||||||
|
|
||||||
/* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures
|
/* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures
|
||||||
* that we can enable/disable lazy stacking in port.c file. */
|
* that we can enable/disable lazy stacking in port.c file. */
|
||||||
*( secureinitFPCCR ) &= ~ ( secureinitFPCCR_LSPENS_MASK );
|
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
||||||
|
|
||||||
/* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP
|
/* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP
|
||||||
* registers (S16-S31) are also pushed to stack on exception entry and
|
* registers (S16-S31) are also pushed to stack on exception entry and
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
#if defined( __IAR_SYSTEMS_ICC__ )
|
#if defined( __IAR_SYSTEMS_ICC__ )
|
||||||
#define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root
|
#define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root
|
||||||
#else
|
#else
|
||||||
#define secureportNON_SECURE_CALLABLE __attribute__((cmse_nonsecure_entry)) __attribute__((used))
|
#define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -126,7 +126,7 @@
|
||||||
{ \
|
{ \
|
||||||
secureportDISABLE_SECURE_INTERRUPTS(); \
|
secureportDISABLE_SECURE_INTERRUPTS(); \
|
||||||
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
|
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
|
||||||
for( ;; ); \
|
for( ; ; ) {; } \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __SECURE_PORT_MACROS_H__ */
|
#endif /* __SECURE_PORT_MACROS_H__ */
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
/* Portasm includes. */
|
/* Portasm includes. */
|
||||||
#include "portasm.h"
|
#include "portasm.h"
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/* Secure components includes. */
|
/* Secure components includes. */
|
||||||
#include "secure_context.h"
|
#include "secure_context.h"
|
||||||
#include "secure_init.h"
|
#include "secure_init.h"
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
* 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support:
|
* 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support:
|
||||||
* configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0
|
* configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0
|
||||||
*/
|
*/
|
||||||
#if( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) )
|
#if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) )
|
||||||
#error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side.
|
#error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side.
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -70,10 +70,10 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the NVIC.
|
* @brief Constants required to manipulate the NVIC.
|
||||||
*/
|
*/
|
||||||
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
|
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||||
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
|
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
|
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||||
#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) )
|
#define portNVIC_SYSPRI2_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||||
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||||
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||||
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
||||||
|
|
@ -85,7 +85,8 @@
|
||||||
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
#else
|
#else
|
||||||
/* The way the SysTick is clocked is not modified in case it is not the
|
|
||||||
|
/* The way the SysTick is clocked is not modified in case it is not the
|
||||||
* same a the core. */
|
* same a the core. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -94,7 +95,7 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the SCB.
|
* @brief Constants required to manipulate the SCB.
|
||||||
*/
|
*/
|
||||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( * ( volatile uint32_t * ) 0xe000ed24 )
|
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( volatile uint32_t * ) 0xe000ed24 )
|
||||||
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -117,24 +118,24 @@
|
||||||
/**
|
/**
|
||||||
* @brief Constants required to manipulate the MPU.
|
* @brief Constants required to manipulate the MPU.
|
||||||
*/
|
*/
|
||||||
#define portMPU_TYPE_REG ( * ( ( volatile uint32_t * ) 0xe000ed90 ) )
|
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
|
||||||
#define portMPU_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed94 ) )
|
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
|
||||||
#define portMPU_RNR_REG ( * ( ( volatile uint32_t * ) 0xe000ed98 ) )
|
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_REG ( * ( ( volatile uint32_t * ) 0xe000ed9c ) )
|
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
|
||||||
#define portMPU_RLAR_REG ( * ( ( volatile uint32_t * ) 0xe000eda0 ) )
|
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_A1_REG ( * ( ( volatile uint32_t * ) 0xe000eda4 ) )
|
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
|
||||||
#define portMPU_RLAR_A1_REG ( * ( ( volatile uint32_t * ) 0xe000eda8 ) )
|
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_A2_REG ( * ( ( volatile uint32_t * ) 0xe000edac ) )
|
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
|
||||||
#define portMPU_RLAR_A2_REG ( * ( ( volatile uint32_t * ) 0xe000edb0 ) )
|
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_A3_REG ( * ( ( volatile uint32_t * ) 0xe000edb4 ) )
|
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
|
||||||
#define portMPU_RLAR_A3_REG ( * ( ( volatile uint32_t * ) 0xe000edb8 ) )
|
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
|
||||||
|
|
||||||
#define portMPU_MAIR0_REG ( * ( ( volatile uint32_t * ) 0xe000edc0 ) )
|
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
|
||||||
#define portMPU_MAIR1_REG ( * ( ( volatile uint32_t * ) 0xe000edc4 ) )
|
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
|
||||||
|
|
||||||
#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
||||||
#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
||||||
|
|
@ -204,8 +205,9 @@
|
||||||
*/
|
*/
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
|
|
||||||
#if( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF FD
|
* FF FF FF FD
|
||||||
|
|
@ -221,7 +223,8 @@
|
||||||
*/
|
*/
|
||||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||||
#else
|
#else
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Initial EXC_RETURN value.
|
* @brief Initial EXC_RETURN value.
|
||||||
*
|
*
|
||||||
* FF FF FF BC
|
* FF FF FF BC
|
||||||
|
|
@ -284,15 +287,17 @@
|
||||||
*/
|
*/
|
||||||
static void prvTaskExitError( void );
|
static void prvTaskExitError( void );
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Setup the Memory Protection Unit (MPU).
|
* @brief Setup the Memory Protection Unit (MPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Setup the Floating Point Unit (FPU).
|
* @brief Setup the Floating Point Unit (FPU).
|
||||||
*/
|
*/
|
||||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
@ -337,7 +342,7 @@ void SysTick_Handler( void ) PRIVILEGED_FUNCTION;
|
||||||
/**
|
/**
|
||||||
* @brief C part of SVC handler.
|
* @brief C part of SVC handler.
|
||||||
*/
|
*/
|
||||||
portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVILEGED_FUNCTION;
|
portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -346,27 +351,29 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVI
|
||||||
*/
|
*/
|
||||||
static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief Saved as part of the task context to indicate which context the
|
* @brief Saved as part of the task context to indicate which context the
|
||||||
* task is using on the secure side.
|
* task is using on the secure side.
|
||||||
*/
|
*/
|
||||||
portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT;
|
portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* @brief The number of SysTick increments that make up one tick period.
|
* @brief The number of SysTick increments that make up one tick period.
|
||||||
*/
|
*/
|
||||||
static uint32_t ulTimerCountsForOneTick = 0;
|
static uint32_t ulTimerCountsForOneTick = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The maximum number of tick periods that can be suppressed is
|
* @brief The maximum number of tick periods that can be suppressed is
|
||||||
* limited by the 24 bit resolution of the SysTick timer.
|
* limited by the 24 bit resolution of the SysTick timer.
|
||||||
*/
|
*/
|
||||||
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
* @brief Compensate for the CPU cycles that pass while the SysTick is
|
||||||
* stopped (low power functionality only).
|
* stopped (low power functionality only).
|
||||||
*/
|
*/
|
||||||
|
|
@ -374,8 +381,8 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
__attribute__(( weak )) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
__attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
||||||
TickType_t xModifiableIdleTime;
|
TickType_t xModifiableIdleTime;
|
||||||
|
|
@ -396,6 +403,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
* tick periods. -1 is used because this code will execute part way
|
* tick periods. -1 is used because this code will execute part way
|
||||||
* through one of the tick periods. */
|
* through one of the tick periods. */
|
||||||
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
||||||
|
|
||||||
if( ulReloadValue > ulStoppedTimerCompensation )
|
if( ulReloadValue > ulStoppedTimerCompensation )
|
||||||
{
|
{
|
||||||
ulReloadValue -= ulStoppedTimerCompensation;
|
ulReloadValue -= ulStoppedTimerCompensation;
|
||||||
|
|
@ -403,9 +411,9 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||||
* method as that will mask interrupts that should exit sleep mode. */
|
* method as that will mask interrupts that should exit sleep mode. */
|
||||||
__asm volatile( "cpsid i" ::: "memory" );
|
__asm volatile ( "cpsid i" ::: "memory" );
|
||||||
__asm volatile( "dsb" );
|
__asm volatile ( "dsb" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
|
|
||||||
/* If a context switch is pending or a task is waiting for the scheduler
|
/* If a context switch is pending or a task is waiting for the scheduler
|
||||||
* to be un-suspended then abandon the low power entry. */
|
* to be un-suspended then abandon the low power entry. */
|
||||||
|
|
@ -424,7 +432,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
* above. */
|
* above. */
|
||||||
__asm volatile( "cpsie i" ::: "memory" );
|
__asm volatile ( "cpsie i" ::: "memory" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -446,28 +454,30 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
* so a copy is taken. */
|
* so a copy is taken. */
|
||||||
xModifiableIdleTime = xExpectedIdleTime;
|
xModifiableIdleTime = xExpectedIdleTime;
|
||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||||
|
|
||||||
if( xModifiableIdleTime > 0 )
|
if( xModifiableIdleTime > 0 )
|
||||||
{
|
{
|
||||||
__asm volatile( "dsb" ::: "memory" );
|
__asm volatile ( "dsb" ::: "memory" );
|
||||||
__asm volatile( "wfi" );
|
__asm volatile ( "wfi" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
}
|
}
|
||||||
|
|
||||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
|
||||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||||
* out of sleep mode to execute immediately. See comments above
|
* out of sleep mode to execute immediately. See comments above
|
||||||
* the cpsid instruction above. */
|
* the cpsid instruction above. */
|
||||||
__asm volatile( "cpsie i" ::: "memory" );
|
__asm volatile ( "cpsie i" ::: "memory" );
|
||||||
__asm volatile( "dsb" );
|
__asm volatile ( "dsb" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
|
|
||||||
/* Disable interrupts again because the clock is about to be stopped
|
/* Disable interrupts again because the clock is about to be stopped
|
||||||
* and interrupts that execute while the clock is stopped will
|
* and interrupts that execute while the clock is stopped will
|
||||||
* increase any slippage between the time maintained by the RTOS and
|
* increase any slippage between the time maintained by the RTOS and
|
||||||
* calendar time. */
|
* calendar time. */
|
||||||
__asm volatile( "cpsid i" ::: "memory" );
|
__asm volatile ( "cpsid i" ::: "memory" );
|
||||||
__asm volatile( "dsb" );
|
__asm volatile ( "dsb" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
|
|
||||||
/* Disable the SysTick clock without reading the
|
/* Disable the SysTick clock without reading the
|
||||||
* portNVIC_SYSTICK_CTRL_REG register to ensure the
|
* portNVIC_SYSTICK_CTRL_REG register to ensure the
|
||||||
|
|
@ -534,16 +544,16 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||||
|
|
||||||
/* Exit with interrupts enabled. */
|
/* Exit with interrupts enabled. */
|
||||||
__asm volatile( "cpsie i" ::: "memory" );
|
__asm volatile ( "cpsie i" ::: "memory" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
|
__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
/* Calculate the constants required to configure the tick interrupt. */
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||||
{
|
{
|
||||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||||
|
|
@ -563,7 +573,7 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNC
|
||||||
|
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError( void )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulDummy = 0UL;
|
volatile uint32_t ulDummy = 0UL;
|
||||||
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* 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
|
* its caller as there is nothing to return to. If a task wants to exit it
|
||||||
|
|
@ -586,10 +596,11 @@ volatile uint32_t ulDummy = 0UL;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */
|
static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* Declaration when these variable are defined in code instead of being
|
||||||
* exported from linker scripts. */
|
* exported from linker scripts. */
|
||||||
extern uint32_t * __privileged_functions_start__;
|
extern uint32_t * __privileged_functions_start__;
|
||||||
|
|
@ -600,7 +611,7 @@ volatile uint32_t ulDummy = 0UL;
|
||||||
extern uint32_t * __unprivileged_flash_end__;
|
extern uint32_t * __unprivileged_flash_end__;
|
||||||
extern uint32_t * __privileged_sram_start__;
|
extern uint32_t * __privileged_sram_start__;
|
||||||
extern uint32_t * __privileged_sram_end__;
|
extern uint32_t * __privileged_sram_end__;
|
||||||
#else
|
#else /* if defined( __ARMCC_VERSION ) */
|
||||||
/* Declaration when these variable are exported from linker scripts. */
|
/* Declaration when these variable are exported from linker scripts. */
|
||||||
extern uint32_t __privileged_functions_start__[];
|
extern uint32_t __privileged_functions_start__[];
|
||||||
extern uint32_t __privileged_functions_end__[];
|
extern uint32_t __privileged_functions_end__[];
|
||||||
|
|
@ -671,10 +682,10 @@ volatile uint32_t ulDummy = 0UL;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */
|
static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
{
|
{
|
||||||
/* Enable non-secure access to the FPU. */
|
/* Enable non-secure access to the FPU. */
|
||||||
SecureInit_EnableNSFPUAccess();
|
SecureInit_EnableNSFPUAccess();
|
||||||
|
|
@ -703,8 +714,8 @@ void vPortYield( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is
|
/* Barriers are normally not required but do ensure the code is
|
||||||
* completely within the specified behaviour for the architecture. */
|
* completely within the specified behaviour for the architecture. */
|
||||||
__asm volatile( "dsb" ::: "memory" );
|
__asm volatile ( "dsb" ::: "memory" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -715,8 +726,8 @@ void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is
|
/* Barriers are normally not required but do ensure the code is
|
||||||
* completely within the specified behaviour for the architecture. */
|
* completely within the specified behaviour for the architecture. */
|
||||||
__asm volatile( "dsb" ::: "memory" );
|
__asm volatile ( "dsb" ::: "memory" );
|
||||||
__asm volatile( "isb" );
|
__asm volatile ( "isb" );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -734,7 +745,7 @@ void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
|
void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
uint32_t ulPreviousMask;
|
uint32_t ulPreviousMask;
|
||||||
|
|
||||||
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
|
|
@ -749,10 +760,11 @@ uint32_t ulPreviousMask;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */
|
void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */
|
||||||
{
|
{
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
#if defined( __ARMCC_VERSION )
|
#if defined( __ARMCC_VERSION )
|
||||||
|
|
||||||
/* Declaration when these variable are defined in code instead of being
|
/* Declaration when these variable are defined in code instead of being
|
||||||
* exported from linker scripts. */
|
* exported from linker scripts. */
|
||||||
extern uint32_t * __syscalls_flash_start__;
|
extern uint32_t * __syscalls_flash_start__;
|
||||||
|
|
@ -762,33 +774,33 @@ void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION
|
||||||
extern uint32_t __syscalls_flash_start__[];
|
extern uint32_t __syscalls_flash_start__[];
|
||||||
extern uint32_t __syscalls_flash_end__[];
|
extern uint32_t __syscalls_flash_end__[];
|
||||||
#endif /* defined( __ARMCC_VERSION ) */
|
#endif /* defined( __ARMCC_VERSION ) */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
uint32_t ulPC;
|
uint32_t ulPC;
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
uint32_t ulR0;
|
uint32_t ulR0;
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
uint32_t ulControl, ulIsTaskPrivileged;
|
uint32_t ulControl, ulIsTaskPrivileged;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
uint8_t ucSVCNumber;
|
uint8_t ucSVCNumber;
|
||||||
|
|
||||||
/* Register are stored on the stack in the following order - R0, R1, R2, R3,
|
/* Register are stored on the stack in the following order - R0, R1, R2, R3,
|
||||||
* R12, LR, PC, xPSR. */
|
* R12, LR, PC, xPSR. */
|
||||||
ulPC = pulCallerStackAddress[ 6 ];
|
ulPC = pulCallerStackAddress[ 6 ];
|
||||||
ucSVCNumber = ( ( uint8_t *) ulPC )[ -2 ];
|
ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ];
|
||||||
|
|
||||||
switch( ucSVCNumber )
|
switch( ucSVCNumber )
|
||||||
{
|
{
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
case portSVC_ALLOCATE_SECURE_CONTEXT:
|
case portSVC_ALLOCATE_SECURE_CONTEXT:
|
||||||
{
|
|
||||||
/* R0 contains the stack size passed as parameter to the
|
/* R0 contains the stack size passed as parameter to the
|
||||||
* vPortAllocateSecureContext function. */
|
* vPortAllocateSecureContext function. */
|
||||||
ulR0 = pulCallerStackAddress[ 0 ];
|
ulR0 = pulCallerStackAddress[ 0 ];
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
/* Read the CONTROL register value. */
|
/* Read the CONTROL register value. */
|
||||||
__asm volatile ( "mrs %0, control" : "=r" ( ulControl ) );
|
__asm volatile ( "mrs %0, control" : "=r" ( ulControl ) );
|
||||||
|
|
@ -800,7 +812,7 @@ uint8_t ucSVCNumber;
|
||||||
/* Allocate and load a context for the secure task. */
|
/* Allocate and load a context for the secure task. */
|
||||||
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
|
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
|
||||||
}
|
}
|
||||||
#else
|
#else /* if ( configENABLE_MPU == 1 ) */
|
||||||
{
|
{
|
||||||
/* Allocate and load a context for the secure task. */
|
/* Allocate and load a context for the secure task. */
|
||||||
xSecureContext = SecureContext_AllocateContext( ulR0 );
|
xSecureContext = SecureContext_AllocateContext( ulR0 );
|
||||||
|
|
@ -809,23 +821,19 @@ uint8_t ucSVCNumber;
|
||||||
|
|
||||||
configASSERT( xSecureContext != NULL );
|
configASSERT( xSecureContext != NULL );
|
||||||
SecureContext_LoadContext( xSecureContext );
|
SecureContext_LoadContext( xSecureContext );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case portSVC_FREE_SECURE_CONTEXT:
|
case portSVC_FREE_SECURE_CONTEXT:
|
||||||
{
|
|
||||||
/* R0 contains the secure context handle to be freed. */
|
/* R0 contains the secure context handle to be freed. */
|
||||||
ulR0 = pulCallerStackAddress[ 0 ];
|
ulR0 = pulCallerStackAddress[ 0 ];
|
||||||
|
|
||||||
/* Free the secure context. */
|
/* Free the secure context. */
|
||||||
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 );
|
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
case portSVC_START_SCHEDULER:
|
case portSVC_START_SCHEDULER:
|
||||||
{
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
|
||||||
{
|
{
|
||||||
/* De-prioritize the non-secure exceptions so that the
|
/* De-prioritize the non-secure exceptions so that the
|
||||||
* non-secure pendSV runs at the lowest priority. */
|
* non-secure pendSV runs at the lowest priority. */
|
||||||
|
|
@ -836,7 +844,7 @@ uint8_t ucSVCNumber;
|
||||||
}
|
}
|
||||||
#endif /* configENABLE_TRUSTZONE */
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
{
|
{
|
||||||
/* Setup the Floating Point Unit (FPU). */
|
/* Setup the Floating Point Unit (FPU). */
|
||||||
prvSetupFPU();
|
prvSetupFPU();
|
||||||
|
|
@ -846,41 +854,44 @@ uint8_t ucSVCNumber;
|
||||||
/* Setup the context of the first task so that the first task starts
|
/* Setup the context of the first task so that the first task starts
|
||||||
* executing. */
|
* executing. */
|
||||||
vRestoreContextOfFirstTask();
|
vRestoreContextOfFirstTask();
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
case portSVC_RAISE_PRIVILEGE:
|
case portSVC_RAISE_PRIVILEGE:
|
||||||
{
|
|
||||||
/* Only raise the privilege, if the svc was raised from any of
|
/* Only raise the privilege, if the svc was raised from any of
|
||||||
* the system calls. */
|
* the system calls. */
|
||||||
if( ulPC >= ( uint32_t ) __syscalls_flash_start__ &&
|
if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) &&
|
||||||
ulPC <= ( uint32_t ) __syscalls_flash_end__ )
|
( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) )
|
||||||
{
|
{
|
||||||
vRaisePrivilege();
|
vRaisePrivilege();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
|
||||||
/* Incorrect SVC call. */
|
/* Incorrect SVC call. */
|
||||||
configASSERT( pdFALSE );
|
configASSERT( pdFALSE );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
StackType_t * pxEndOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters,
|
||||||
|
BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */
|
||||||
#else
|
#else
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) /* PRIVILEGED_FUNCTION */
|
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
StackType_t * pxEndOfStack,
|
||||||
|
TaskFunction_t pxCode,
|
||||||
|
void * pvParameters ) /* PRIVILEGED_FUNCTION */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
{
|
{
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
* interrupt. */
|
* interrupt. */
|
||||||
#if( portPRELOAD_REGISTERS == 0 )
|
#if ( portPRELOAD_REGISTERS == 0 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||||
|
|
@ -893,9 +904,10 @@ uint8_t ucSVCNumber;
|
||||||
pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */
|
pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */
|
||||||
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
if( xRunPrivileged == pdTRUE )
|
if( xRunPrivileged == pdTRUE )
|
||||||
{
|
{
|
||||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||||
|
|
@ -910,7 +922,7 @@ uint8_t ucSVCNumber;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
||||||
|
|
@ -954,9 +966,10 @@ uint8_t ucSVCNumber;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */
|
*pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
|
|
||||||
if( xRunPrivileged == pdTRUE )
|
if( xRunPrivileged == pdTRUE )
|
||||||
{
|
{
|
||||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||||
|
|
@ -971,7 +984,7 @@ uint8_t ucSVCNumber;
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
||||||
|
|
||||||
#if( configENABLE_TRUSTZONE == 1 )
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
{
|
{
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
||||||
|
|
@ -990,7 +1003,7 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
{
|
{
|
||||||
/* Setup the Memory Protection Unit (MPU). */
|
/* Setup the Memory Protection Unit (MPU). */
|
||||||
prvSetupMPU();
|
prvSetupMPU();
|
||||||
|
|
@ -1029,8 +1042,11 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )
|
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||||
|
const struct xMEMORY_REGION * const xRegions,
|
||||||
|
StackType_t * pxBottomOfStack,
|
||||||
|
uint32_t ulStackDepth )
|
||||||
{
|
{
|
||||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||||
int32_t lIndex = 0;
|
int32_t lIndex = 0;
|
||||||
|
|
@ -1126,13 +1142,13 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||||
|
|
||||||
BaseType_t xPortIsInsideInterrupt( void )
|
BaseType_t xPortIsInsideInterrupt( void )
|
||||||
{
|
{
|
||||||
uint32_t ulCurrentInterrupt;
|
uint32_t ulCurrentInterrupt;
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
/* Obtain the number of the currently executing interrupt. Interrupt Program
|
/* Obtain the number of the currently executing interrupt. Interrupt Program
|
||||||
* Status Register (IPSR) holds the exception number of the currently-executing
|
* Status Register (IPSR) holds the exception number of the currently-executing
|
||||||
* exception or zero for Thread mode.*/
|
* exception or zero for Thread mode.*/
|
||||||
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
|
||||||
|
|
||||||
if( ulCurrentInterrupt == 0 )
|
if( ulCurrentInterrupt == 0 )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
* header files. */
|
* header files. */
|
||||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
#if( configENABLE_FPU == 1 )
|
#if ( configENABLE_FPU == 1 )
|
||||||
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -48,75 +48,75 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst2 \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r1] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n"/* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r4, #1 \n" /* r4 = 1. */
|
" movs r4, #1 \n"/* r4 = 1. */
|
||||||
" bics r3, r4 \n" /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
|
" bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
|
||||||
" str r3, [r2] \n" /* Disable MPU. */
|
" str r3, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
||||||
" ldr r4, [r1] \n" /* r4 = *r1 i.e. r4 = MAIR0. */
|
" ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r4, [r2] \n" /* Program MAIR0. */
|
" str r4, [r2] \n"/* Program MAIR0. */
|
||||||
" ldr r2, xRNRConst2 \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
" ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */
|
||||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||||
" movs r4, #4 \n" /* r4 = 4. */
|
" movs r4, #4 \n"/* r4 = 4. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 4. */
|
" str r4, [r2] \n"/* Program RNR = 4. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read first set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst2 \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write first set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */
|
||||||
" movs r4, #5 \n" /* r4 = 5. */
|
" movs r4, #5 \n"/* r4 = 5. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 5. */
|
" str r4, [r2] \n"/* Program RNR = 5. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read second set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst2 \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write second set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */
|
||||||
" movs r4, #6 \n" /* r4 = 6. */
|
" movs r4, #6 \n"/* r4 = 6. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 6. */
|
" str r4, [r2] \n"/* Program RNR = 6. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read third set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst2 \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write third set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */
|
||||||
" movs r4, #7 \n" /* r4 = 7. */
|
" movs r4, #7 \n"/* r4 = 7. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 7. */
|
" str r4, [r2] \n"/* Program RNR = 7. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read fourth set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst2 \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst2 \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write fourth set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r4, #1 \n" /* r4 = 1. */
|
" movs r4, #1 \n"/* r4 = 1. */
|
||||||
" orrs r3, r4 \n" /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
|
" orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
|
||||||
" str r3, [r2] \n" /* Enable MPU. */
|
" str r3, [r2] \n"/* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n"/* Force memory writes before continuing. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */
|
" ldm r0!, {r1-r3} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */
|
||||||
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
" msr psplim, r1 \n"/* Set this task's PSPLIM value. */
|
||||||
" msr control, r2 \n" /* Set this task's CONTROL value. */
|
" msr control, r2 \n"/* Set this task's CONTROL value. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
" bx r3 \n"/* Finally, branch to EXC_RETURN. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
" ldm r0!, {r1-r2} \n"/* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||||
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
" msr psplim, r1 \n"/* Set this task's PSPLIM value. */
|
||||||
" movs r1, #2 \n" /* r1 = 2. */
|
" movs r1, #2 \n"/* r1 = 2. */
|
||||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
" msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */
|
||||||
" adds r0, #32 \n" /* Discard everything up to r0. */
|
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||||
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r2 \n" /* Finally, branch to EXC_RETURN. */
|
" bx r2 \n"/* Finally, branch to EXC_RETURN. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||||
"xMAIR0Const2: .word 0xe000edc0 \n"
|
"xMAIR0Const2: .word 0xe000edc0 \n"
|
||||||
"xRNRConst2: .word 0xe000ed98 \n"
|
"xRNRConst2: .word 0xe000ed98 \n"
|
||||||
|
|
@ -130,15 +130,15 @@ BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||||
" movs r1, #1 \n" /* r1 = 1. */
|
" movs r1, #1 \n"/* r1 = 1. */
|
||||||
" tst r0, r1 \n" /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
" tst r0, r1 \n"/* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
|
||||||
" beq running_privileged \n" /* If the result of previous AND operation was 0, branch. */
|
" beq running_privileged \n"/* If the result of previous AND operation was 0, branch. */
|
||||||
" movs r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
" movs r0, #0 \n"/* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
" running_privileged: \n"
|
" running_privileged: \n"
|
||||||
" movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
" movs r0, #1 \n"/* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||||
" bx lr \n" /* Return. */
|
" bx lr \n"/* Return. */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
|
|
@ -150,11 +150,11 @@ void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
" mrs r0, control \n"/* Read the CONTROL register. */
|
||||||
" movs r1, #1 \n" /* r1 = 1. */
|
" movs r1, #1 \n"/* r1 = 1. */
|
||||||
" bics r0, r1 \n" /* Clear the bit 0. */
|
" bics r0, r1 \n"/* Clear the bit 0. */
|
||||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
" msr control, r0 \n"/* Write back the new CONTROL value. */
|
||||||
" bx lr \n" /* Return to the caller. */
|
" bx lr \n"/* Return to the caller. */
|
||||||
::: "r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -164,12 +164,12 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
" mrs r0, control \n"/* r0 = CONTROL. */
|
||||||
" movs r1, #1 \n" /* r1 = 1. */
|
" movs r1, #1 \n"/* r1 = 1. */
|
||||||
" orrs r0, r1 \n" /* r0 = r0 | r1. */
|
" orrs r0, r1 \n"/* r0 = r0 | r1. */
|
||||||
" msr control, r0 \n" /* CONTROL = r0. */
|
" msr control, r0 \n"/* CONTROL = r0. */
|
||||||
" bx lr \n" /* Return to the caller. */
|
" bx lr \n"/* Return to the caller. */
|
||||||
:::"r0", "r1", "memory"
|
::: "r0", "r1", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -178,19 +178,19 @@ void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
{
|
{
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" ldr r0, xVTORConst \n" /* Use the NVIC offset register to locate the stack. */
|
" ldr r0, xVTORConst \n"/* Use the NVIC offset register to locate the stack. */
|
||||||
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
" ldr r0, [r0] \n"/* Read the VTOR register which gives the address of vector table. */
|
||||||
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
" ldr r0, [r0] \n"/* The first entry in vector table is stack pointer. */
|
||||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
" msr msp, r0 \n"/* Set the MSP back to the start of the stack. */
|
||||||
" cpsie i \n" /* Globally enable interrupts. */
|
" cpsie i \n"/* Globally enable interrupts. */
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" svc %0 \n" /* System call to start the first task. */
|
" svc %0 \n"/* System call to start the first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"xVTORConst: .word 0xe000ed08 \n"
|
"xVTORConst: .word 0xe000ed08 \n"
|
||||||
:: "i" ( portSVC_START_SCHEDULER ) : "memory"
|
::"i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
@ -224,115 +224,115 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
(
|
(
|
||||||
" .syntax unified \n"
|
" .syntax unified \n"
|
||||||
" \n"
|
" \n"
|
||||||
" mrs r0, psp \n" /* Read PSP in r0. */
|
" mrs r0, psp \n"/* Read PSP in r0. */
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" subs r0, r0, #44 \n" /* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */
|
" subs r0, r0, #44 \n"/* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */
|
||||||
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
" str r0, [r1] \n"/* Save the new top of stack in TCB. */
|
||||||
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
" mrs r1, psplim \n"/* r1 = PSPLIM. */
|
||||||
" mrs r2, control \n" /* r2 = CONTROL. */
|
" mrs r2, control \n"/* r2 = CONTROL. */
|
||||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||||
" stmia r0!, {r1-r7} \n" /* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */
|
" stmia r0!, {r1-r7} \n"/* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */
|
||||||
" mov r4, r8 \n" /* r4 = r8. */
|
" mov r4, r8 \n"/* r4 = r8. */
|
||||||
" mov r5, r9 \n" /* r5 = r9. */
|
" mov r5, r9 \n"/* r5 = r9. */
|
||||||
" mov r6, r10 \n" /* r6 = r10. */
|
" mov r6, r10 \n"/* r6 = r10. */
|
||||||
" mov r7, r11 \n" /* r7 = r11. */
|
" mov r7, r11 \n"/* r7 = r11. */
|
||||||
" stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
" stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" subs r0, r0, #40 \n" /* Make space for PSPLIM, LR and the remaining registers on the stack. */
|
" subs r0, r0, #40 \n"/* Make space for PSPLIM, LR and the remaining registers on the stack. */
|
||||||
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
" str r0, [r1] \n"/* Save the new top of stack in TCB. */
|
||||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
" mrs r2, psplim \n"/* r2 = PSPLIM. */
|
||||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
|
||||||
" stmia r0!, {r2-r7} \n" /* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
|
" stmia r0!, {r2-r7} \n"/* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
|
||||||
" mov r4, r8 \n" /* r4 = r8. */
|
" mov r4, r8 \n"/* r4 = r8. */
|
||||||
" mov r5, r9 \n" /* r5 = r9. */
|
" mov r5, r9 \n"/* r5 = r9. */
|
||||||
" mov r6, r10 \n" /* r6 = r10. */
|
" mov r6, r10 \n"/* r6 = r10. */
|
||||||
" mov r7, r11 \n" /* r7 = r11. */
|
" mov r7, r11 \n"/* r7 = r11. */
|
||||||
" stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
" stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" cpsid i \n"
|
" cpsid i \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" cpsie i \n"
|
" cpsie i \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */
|
||||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
" dmb \n"/* Complete outstanding transfers before disabling MPU. */
|
||||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r4, #1 \n" /* r4 = 1. */
|
" movs r4, #1 \n"/* r4 = 1. */
|
||||||
" bics r3, r4 \n" /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
|
" bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
|
||||||
" str r3, [r2] \n" /* Disable MPU. */
|
" str r3, [r2] \n"/* Disable MPU. */
|
||||||
" \n"
|
" \n"
|
||||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
||||||
" ldr r4, [r1] \n" /* r4 = *r1 i.e. r4 = MAIR0. */
|
" ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */
|
||||||
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
" ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
" str r4, [r2] \n" /* Program MAIR0. */
|
" str r4, [r2] \n"/* Program MAIR0. */
|
||||||
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
" ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */
|
||||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||||
" movs r4, #4 \n" /* r4 = 4. */
|
" movs r4, #4 \n"/* r4 = 4. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 4. */
|
" str r4, [r2] \n"/* Program RNR = 4. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read first set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write first set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */
|
||||||
" movs r4, #5 \n" /* r4 = 5. */
|
" movs r4, #5 \n"/* r4 = 5. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 5. */
|
" str r4, [r2] \n"/* Program RNR = 5. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read second set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write second set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */
|
||||||
" movs r4, #6 \n" /* r4 = 6. */
|
" movs r4, #6 \n"/* r4 = 6. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 6. */
|
" str r4, [r2] \n"/* Program RNR = 6. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read third set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write third set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */
|
||||||
" movs r4, #7 \n" /* r4 = 7. */
|
" movs r4, #7 \n"/* r4 = 7. */
|
||||||
" str r4, [r2] \n" /* Program RNR = 7. */
|
" str r4, [r2] \n"/* Program RNR = 7. */
|
||||||
" ldmia r1!, {r5,r6} \n" /* Read fourth set of RBAR/RLAR from TCB. */
|
" ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */
|
||||||
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
" ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||||
" stmia r3!, {r5,r6} \n" /* Write fourth set of RBAR/RLAR registers. */
|
" stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
|
" ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */
|
||||||
" movs r4, #1 \n" /* r4 = 1. */
|
" movs r4, #1 \n"/* r4 = 1. */
|
||||||
" orrs r3, r4 \n" /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
|
" orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
|
||||||
" str r3, [r2] \n" /* Enable MPU. */
|
" str r3, [r2] \n"/* Enable MPU. */
|
||||||
" dsb \n" /* Force memory writes before continuing. */
|
" dsb \n"/* Force memory writes before continuing. */
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
" adds r0, r0, #28 \n" /* Move to the high registers. */
|
" adds r0, r0, #28 \n"/* Move to the high registers. */
|
||||||
" ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
|
" ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */
|
||||||
" mov r8, r4 \n" /* r8 = r4. */
|
" mov r8, r4 \n"/* r8 = r4. */
|
||||||
" mov r9, r5 \n" /* r9 = r5. */
|
" mov r9, r5 \n"/* r9 = r5. */
|
||||||
" mov r10, r6 \n" /* r10 = r6. */
|
" mov r10, r6 \n"/* r10 = r6. */
|
||||||
" mov r11, r7 \n" /* r11 = r7. */
|
" mov r11, r7 \n"/* r11 = r7. */
|
||||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
||||||
" subs r0, r0, #44 \n" /* Move to the starting of the saved context. */
|
" subs r0, r0, #44 \n"/* Move to the starting of the saved context. */
|
||||||
" ldmia r0!, {r1-r7} \n" /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */
|
" ldmia r0!, {r1-r7} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */
|
||||||
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */
|
" msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */
|
||||||
" msr control, r2 \n" /* Restore the CONTROL register value for the task. */
|
" msr control, r2 \n"/* Restore the CONTROL register value for the task. */
|
||||||
" bx r3 \n"
|
" bx r3 \n"
|
||||||
#else /* configENABLE_MPU */
|
#else /* configENABLE_MPU */
|
||||||
" adds r0, r0, #24 \n" /* Move to the high registers. */
|
" adds r0, r0, #24 \n"/* Move to the high registers. */
|
||||||
" ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
|
" ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */
|
||||||
" mov r8, r4 \n" /* r8 = r4. */
|
" mov r8, r4 \n"/* r8 = r4. */
|
||||||
" mov r9, r5 \n" /* r9 = r5. */
|
" mov r9, r5 \n"/* r9 = r5. */
|
||||||
" mov r10, r6 \n" /* r10 = r6. */
|
" mov r10, r6 \n"/* r10 = r6. */
|
||||||
" mov r11, r7 \n" /* r11 = r7. */
|
" mov r11, r7 \n"/* r11 = r7. */
|
||||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
||||||
" subs r0, r0, #40 \n" /* Move to the starting of the saved context. */
|
" subs r0, r0, #40 \n"/* Move to the starting of the saved context. */
|
||||||
" ldmia r0!, {r2-r7} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
|
" ldmia r0!, {r2-r7} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
|
||||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
|
||||||
" bx r3 \n"
|
" bx r3 \n"
|
||||||
#endif /* configENABLE_MPU */
|
#endif /* configENABLE_MPU */
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
#if( configENABLE_MPU == 1 )
|
#if ( configENABLE_MPU == 1 )
|
||||||
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||||
"xMAIR0Const: .word 0xe000edc0 \n"
|
"xMAIR0Const: .word 0xe000edc0 \n"
|
||||||
"xRNRConst: .word 0xe000ed98 \n"
|
"xRNRConst: .word 0xe000ed98 \n"
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue