Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Jon Snow 2020-02-18 19:21:29 -05:00
commit abc46d833a
515 changed files with 185768 additions and 182906 deletions

File diff suppressed because it is too large Load diff

18
LICENSE Normal file
View file

@ -0,0 +1,18 @@
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
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
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,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
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
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.

31
README.md Normal file
View file

@ -0,0 +1,31 @@
## Getting started
This repository contains FreeRTOS kernel source/header files and kernel ports only. This repository is referenced as a submodule in [FreeRTOS/FreeRTOS](https://github.com/FreeRTOS/FreeRTOS) repository, which contains pre-configured demo application projects under ```FreeRTOS/Demo``` directory.
The easiest way to use FreeRTOS is to start with one of the pre-configured demo application projects. That way you will have the correct FreeRTOS source files included, and the correct include paths configured. Once a demo application is building and executing you can remove the demo application files, and start to add in your own application source files. See the [FreeRTOS Kernel Quick Start Guide](https://www.freertos.org/FreeRTOS-quick-start-guide.html) for detailed instructions and other useful links.
Additionally, for FreeRTOS kernel feature information refer to the [Developer Documentation](https://www.freertos.org/features.html), and [API Reference](https://www.freertos.org/a00106.html).
### Getting help
If you have any questions or need assistance troubleshooting your FreeRTOS project, we have an active community that can help on the [FreeRTOS Community Support Forum](https://forums.freertos.org).
## Cloning this repository
To clone using HTTPS:
```
git clone https://github.com/FreeRTOS/FreeRTOS-Kernel.git
```
Using SSH:
```
git clone git@github.com:FreeRTOS/FreeRTOS-Kernel.git
```
## Repository structure
- The root of this repository contains the three files that are common to
every port - list.c, queue.c and tasks.c. The kernel is contained within these
three files. croutine.c implements the optional co-routine functionality - which
is normally only used on very memory limited systems.
- The ```./portable``` directory contains the files that are specific to a particular microcontroller and/or compiler.
See the readme file in the ```./portable``` directory for more information.
- The ```./include``` directory contains the real time kernel header files.

View file

@ -1,353 +1,353 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
#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; /*< Points to the delayed co-routine list currently being used. */ static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */
static List_t * pxOverflowDelayedCoRoutineList; /*< 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; /*< 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
* for the priority. It is inserted at the end of the list. * for the priority. It is inserted at the end of the list.
* *
* 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
* the ready lists (there is no mutual exclusion). Instead they are placed in * the ready lists (there is no mutual exclusion). Instead they are placed in
* 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
* see if any require waking. * see if any require waking.
* *
* Co-routines are stored in the queue in the order of their wake time - * Co-routines are stored in the queue in the order of their wake time -
* 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, UBaseType_t uxIndex )
{ {
BaseType_t xReturn; BaseType_t xReturn;
CRCB_t *pxCoRoutine; 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;
prvInitialiseCoRoutineLists(); prvInitialiseCoRoutineLists();
} }
/* Check the priority is within limits. */ /* Check the priority is within limits. */
if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
{ {
uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
} }
/* Fill out the co-routine control block from the function parameters. */ /* Fill out the co-routine control block from the function parameters. */
pxCoRoutine->uxState = corINITIAL_STATE; pxCoRoutine->uxState = corINITIAL_STATE;
pxCoRoutine->uxPriority = uxPriority; pxCoRoutine->uxPriority = uxPriority;
pxCoRoutine->uxIndex = uxIndex; pxCoRoutine->uxIndex = uxIndex;
pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
/* Initialise all the other co-routine control block parameters. */ /* Initialise all the other co-routine control block parameters. */
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
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 );
/* Event lists are always in priority order. */ /* Event lists are always in priority order. */
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;
} }
else else
{ {
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
} }
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. */
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), 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();
( 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++;
xPassedTicks--; xPassedTicks--;
/* If the tick count has overflowed we need to swap the ready lists. */ /* If the tick count has overflowed we need to swap the ready lists. */
if( xCoRoutineTickCount == 0 ) if( xCoRoutineTickCount == 0 )
{ {
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;
} }
/* See if this tick has made a timeout expire. */ /* See if this tick has made a timeout expire. */
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
{ {
pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
{ {
/* Timeout not yet expired. */ /* Timeout not yet expired. */
break; break;
} }
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? */
if( pxCRCB->xEventListItem.pxContainer ) if( pxCRCB->xEventListItem.pxContainer )
{ {
( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); ( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
} }
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
prvAddCoRoutineToReadyQueue( pxCRCB ); prvAddCoRoutineToReadyQueue( pxCRCB );
} }
} }
xLastTickCount = xCoRoutineTickCount; xLastTickCount = xCoRoutineTickCount;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vCoRoutineSchedule( void ) void vCoRoutineSchedule( void )
{ {
/* 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. */
prvCheckPendingReadyList(); prvCheckPendingReadyList();
/* See if any delayed co-routines have timed out. */ /* See if any delayed co-routines have timed out. */
prvCheckDelayedList(); prvCheckDelayedList();
/* Find the highest priority queue that contains ready co-routines. */ /* Find the highest priority queue that contains ready co-routines. */
while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
{ {
if( uxTopCoRoutineReadyPriority == 0 ) if( uxTopCoRoutineReadyPriority == 0 )
{ {
/* 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; 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++ )
{ {
vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
} }
vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 );
vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 );
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 ) );
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
{ {
xReturn = pdTRUE; xReturn = pdTRUE;
} }
else else
{ {
xReturn = pdFALSE; xReturn = pdFALSE;
} }
return xReturn; return xReturn;
} }
#endif /* configUSE_CO_ROUTINES == 0 */ #endif /* configUSE_CO_ROUTINES == 0 */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,133 +1,133 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef STACK_MACROS_H #ifndef STACK_MACROS_H
#define STACK_MACROS_H #define STACK_MACROS_H
#ifndef _MSC_VER /* Visual Studio doesn't support #warning. */ #ifndef _MSC_VER /* Visual Studio doesn't support #warning. */
#warning The name of this file has changed to stack_macros.h. Please update your code accordingly. This source file (which has the original name) will be removed in future released. #warning The name of this file has changed to stack_macros.h. Please update your code accordingly. This source file (which has the original name) will be removed in future released.
#endif #endif
/* /*
* Call the stack overflow hook function if the stack of the task being swapped * Call the stack overflow hook function if the stack of the task being swapped
* out is currently overflowed, or looks like it might have overflowed in the * out is currently overflowed, or looks like it might have overflowed in the
* past. * past.
* *
* Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
* the current stack state only - comparing the current top of stack value to * the current stack state only - comparing the current top of stack value to
* the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
* will also cause the last few stack bytes to be checked to ensure the value * will also cause the last few stack bytes to be checked to ensure the value
* to which the bytes were set when the task was created have not been * to which the bytes were set when the task was created have not been
* overwritten. Note this second test does not guarantee that an overflowed * overwritten. Note this second test does not guarantee that an overflowed
* stack will always be recognised. * stack will always be recognised.
*/ */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#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? */ \
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
{ \ { \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \ } \
} }
#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() \
{ \ { \
\ \
/* Is the currently saved stack pointer within the stack limit? */ \ /* Is the currently saved stack pointer within the stack limit? */ \
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
{ \ { \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \ } \
} }
#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() \
{ \ { \
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \
\ \
if( ( pulStack[ 0 ] != ulCheckValue ) || \ if( ( pulStack[ 0 ] != ulCheckValue ) || \
( pulStack[ 1 ] != ulCheckValue ) || \ ( pulStack[ 1 ] != ulCheckValue ) || \
( pulStack[ 2 ] != ulCheckValue ) || \ ( pulStack[ 2 ] != ulCheckValue ) || \
( pulStack[ 3 ] != ulCheckValue ) ) \ ( pulStack[ 3 ] != ulCheckValue ) ) \
{ \ { \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \ } \
} }
#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, \
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 }; \
\ \
\ \
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
\ \
/* Has the extremity of the task stack ever been written over? */ \ /* Has the extremity of the task stack ever been written over? */ \
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
{ \ { \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \ } \
} }
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Remove stack overflow macro if not being used. */ /* Remove stack overflow macro if not being used. */
#ifndef taskCHECK_FOR_STACK_OVERFLOW #ifndef taskCHECK_FOR_STACK_OVERFLOW
#define taskCHECK_FOR_STACK_OVERFLOW() #define taskCHECK_FOR_STACK_OVERFLOW()
#endif #endif
#endif /* STACK_MACROS_H */ #endif /* STACK_MACROS_H */

View file

@ -1,418 +1,414 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/** /**
* @file atomic.h * @file atomic.h
* @brief FreeRTOS atomic operation support. * @brief FreeRTOS atomic operation support.
* *
* This file implements atomic by disabling interrupts globally. * This file implements atomic functions by disabling interrupts globally.
* Implementation with architecture specific atomic instructions * Implementations with architecture specific atomic instructions can be
* are to be provided under each compiler directory. * provided under each compiler directory.
*/ */
#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. /*
* Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h * Port specific definitions -- entering/exiting critical section.
* * Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h
* Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with *
* ATOMIC_ENTER_CRITICAL(). * Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with
* */ * ATOMIC_ENTER_CRITICAL().
#if defined( portSET_INTERRUPT_MASK_FROM_ISR ) *
*/
/* Nested interrupt scheme is supported in this port. */ #if defined( portSET_INTERRUPT_MASK_FROM_ISR )
#define ATOMIC_ENTER_CRITICAL() \
UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR() /* Nested interrupt scheme is supported in this port. */
#define ATOMIC_ENTER_CRITICAL() \
#define ATOMIC_EXIT_CRITICAL() \ UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
#define ATOMIC_EXIT_CRITICAL() \
#else portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
/* Nested interrupt scheme is NOT supported in this port. */ #else
#define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
#define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL() /* Nested interrupt scheme is NOT supported in this port. */
#define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */ #define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL()
/* Port specific definition -- "always inline". #endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
* Inline is compiler specific, and may not always get inlined depending on your optimization level.
* Also, inline is considerred as performance optimization for atomic. /*
* Thus, if portFORCE_INLINE is not provided by portmacro.h, instead of resulting error, * Port specific definition -- "always inline".
* simply define it. * Inline is compiler specific, and may not always get inlined depending on your
*/ * optimization level. Also, inline is considered as performance optimization
#ifndef portFORCE_INLINE * for atomic. Thus, if portFORCE_INLINE is not provided by portmacro.h,
#define portFORCE_INLINE * instead of resulting error, simply define it away.
#endif */
#ifndef portFORCE_INLINE
#define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U /**< Compare and swap succeeded, swapped. */ #define portFORCE_INLINE
#define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U /**< Compare and swap failed, did not swap. */ #endif
/*----------------------------- Swap && CAS ------------------------------*/ #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. */
/**
* Atomic compare-and-swap /*----------------------------- Swap && CAS ------------------------------*/
*
* @brief Performs an atomic compare-and-swap operation on the specified values. /**
* * Atomic compare-and-swap
* @param[in, out] pDestination Pointer to memory location from where value is *
* to be loaded and checked. * @brief Performs an atomic compare-and-swap operation on the specified values.
* @param[in] ulExchange If condition meets, write this value to memory. *
* @param[in] ulComparand Swap condition. * @param[in, out] pulDestination Pointer to memory location from where value is
* * to be loaded and checked.
* @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped. * @param[in] ulExchange If condition meets, write this value to memory.
* * @param[in] ulComparand Swap condition.
* @note This function only swaps *pDestination with ulExchange, if previous *
* *pDestination value equals ulComparand. * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
*/ *
static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( * @note This function only swaps *pulDestination with ulExchange, if previous
uint32_t volatile * pDestination, * *pulDestination value equals ulComparand.
uint32_t ulExchange, */
uint32_t ulComparand ) static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination,
{ uint32_t ulExchange,
uint32_t ulComparand )
uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE; {
uint32_t ulReturnValue;
ATOMIC_ENTER_CRITICAL();
ATOMIC_ENTER_CRITICAL();
if ( *pDestination == ulComparand ) {
{ if( *pulDestination == ulComparand )
*pDestination = ulExchange; {
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; *pulDestination = ulExchange;
} ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
}
ATOMIC_EXIT_CRITICAL(); else
{
return ulReturnValue; ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
}
} }
ATOMIC_EXIT_CRITICAL();
/**
* Atomic swap (pointers) return ulReturnValue;
* }
* @brief Atomically sets the address pointed to by *ppDestination to the value /*-----------------------------------------------------------*/
* of *pExchange.
* /**
* @param[in, out] ppDestination Pointer to memory location from where a pointer * Atomic swap (pointers)
* value is to be loaded and written back to. *
* @param[in] pExchange Pointer value to be written to *ppDestination. * @brief Atomically sets the address pointed to by *ppvDestination to the value
* * of *pvExchange.
* @return The initial value of *ppDestination. *
*/ * @param[in, out] ppvDestination Pointer to memory location from where a pointer
static portFORCE_INLINE void * Atomic_SwapPointers_p32( * value is to be loaded and written back to.
void * volatile * ppDestination, * @param[in] pvExchange Pointer value to be written to *ppvDestination.
void * pExchange ) *
{ * @return The initial value of *ppvDestination.
void * pReturnValue; */
static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination,
ATOMIC_ENTER_CRITICAL(); void * pvExchange )
{
pReturnValue = *ppDestination; void * pReturnValue;
*ppDestination = pExchange; ATOMIC_ENTER_CRITICAL();
{
ATOMIC_EXIT_CRITICAL(); pReturnValue = *ppvDestination;
*ppvDestination = pvExchange;
return pReturnValue; }
} ATOMIC_EXIT_CRITICAL();
/** return pReturnValue;
* Atomic compare-and-swap (pointers) }
* /*-----------------------------------------------------------*/
* @brief Performs an atomic compare-and-swap operation on the specified pointer
* values. /**
* * Atomic compare-and-swap (pointers)
* @param[in, out] ppDestination Pointer to memory location from where a pointer *
* value is to be loaded and checked. * @brief Performs an atomic compare-and-swap operation on the specified pointer
* @param[in] pExchange If condition meets, write this value to memory. * values.
* @param[in] pComparand Swap condition. *
* * @param[in, out] ppvDestination Pointer to memory location from where a pointer
* @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped. * value is to be loaded and checked.
* * @param[in] pvExchange If condition meets, write this value to memory.
* @note This function only swaps *ppDestination with pExchange, if previous * @param[in] pvComparand Swap condition.
* *ppDestination value equals pComparand. *
*/ * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( *
void * volatile * ppDestination, * @note This function only swaps *ppvDestination with pvExchange, if previous
void * pExchange, void * pComparand ) * *ppvDestination value equals pvComparand.
{ */
uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE; static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination,
void * pvExchange,
ATOMIC_ENTER_CRITICAL(); void * pvComparand )
{
if ( *ppDestination == pComparand ) uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
{
*ppDestination = pExchange; ATOMIC_ENTER_CRITICAL();
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; {
} if( *ppvDestination == pvComparand )
{
ATOMIC_EXIT_CRITICAL(); *ppvDestination = pvExchange;
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
return ulReturnValue; }
} }
ATOMIC_EXIT_CRITICAL();
/*----------------------------- Arithmetic ------------------------------*/ return ulReturnValue;
}
/**
* Atomic add
* /*----------------------------- Arithmetic ------------------------------*/
* @brief Atomically adds count to the value of the specified pointer points to.
* /**
* @param[in,out] pAddend Pointer to memory location from where value is to be * Atomic add
* loaded and written back to. *
* @param[in] ulCount Value to be added to *pAddend. * @brief Atomically adds count to the value of the specified pointer points to.
* *
* @return previous *pAddend value. * @param[in,out] pulAddend Pointer to memory location from where value is to be
*/ * loaded and written back to.
static portFORCE_INLINE uint32_t Atomic_Add_u32( * @param[in] ulCount Value to be added to *pulAddend.
uint32_t volatile * pAddend, *
uint32_t ulCount ) * @return previous *pulAddend value.
{ */
uint32_t ulCurrent; static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend,
uint32_t ulCount )
ATOMIC_ENTER_CRITICAL(); {
uint32_t ulCurrent;
ulCurrent = *pAddend;
ATOMIC_ENTER_CRITICAL();
*pAddend += ulCount; {
ulCurrent = *pulAddend;
ATOMIC_EXIT_CRITICAL(); *pulAddend += ulCount;
}
return ulCurrent; ATOMIC_EXIT_CRITICAL();
}
return ulCurrent;
/** }
* Atomic subtract /*-----------------------------------------------------------*/
*
* @brief Atomically subtracts count from the value of the specified pointer /**
* pointers to. * Atomic subtract
* *
* @param[in,out] pAddend Pointer to memory location from where value is to be * @brief Atomically subtracts count from the value of the specified pointer
* loaded and written back to. * pointers to.
* @param[in] ulCount Value to be subtract from *pAddend. *
* * @param[in,out] pulAddend Pointer to memory location from where value is to be
* @return previous *pAddend value. * loaded and written back to.
*/ * @param[in] ulCount Value to be subtract from *pulAddend.
static portFORCE_INLINE uint32_t Atomic_Subtract_u32( *
uint32_t volatile * pAddend, * @return previous *pulAddend value.
uint32_t ulCount ) */
{ static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend,
uint32_t ulCurrent; uint32_t ulCount )
{
ATOMIC_ENTER_CRITICAL(); uint32_t ulCurrent;
ulCurrent = *pAddend; ATOMIC_ENTER_CRITICAL();
{
*pAddend -= ulCount; ulCurrent = *pulAddend;
*pulAddend -= ulCount;
ATOMIC_EXIT_CRITICAL(); }
ATOMIC_EXIT_CRITICAL();
return ulCurrent;
} return ulCurrent;
}
/** /*-----------------------------------------------------------*/
* Atomic increment
* /**
* @brief Atomically increments the value of the specified pointer points to. * Atomic increment
* *
* @param[in,out] pAddend Pointer to memory location from where value is to be * @brief Atomically increments the value of the specified pointer points to.
* loaded and written back to. *
* * @param[in,out] pulAddend Pointer to memory location from where value is to be
* @return *pAddend value before increment. * loaded and written back to.
*/ *
static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pAddend ) * @return *pulAddend value before increment.
{ */
uint32_t ulCurrent; static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend )
{
ATOMIC_ENTER_CRITICAL(); uint32_t ulCurrent;
ulCurrent = *pAddend; ATOMIC_ENTER_CRITICAL();
{
*pAddend += 1; ulCurrent = *pulAddend;
*pulAddend += 1;
ATOMIC_EXIT_CRITICAL(); }
ATOMIC_EXIT_CRITICAL();
return ulCurrent;
} return ulCurrent;
}
/** /*-----------------------------------------------------------*/
* Atomic decrement
* /**
* @brief Atomically decrements the value of the specified pointer points to * Atomic decrement
* *
* @param[in,out] pAddend Pointer to memory location from where value is to be * @brief Atomically decrements the value of the specified pointer points to
* loaded and written back to. *
* * @param[in,out] pulAddend Pointer to memory location from where value is to be
* @return *pAddend value before decrement. * loaded and written back to.
*/ *
static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pAddend ) * @return *pulAddend value before decrement.
{ */
uint32_t ulCurrent; static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend )
{
ATOMIC_ENTER_CRITICAL(); uint32_t ulCurrent;
ulCurrent = *pAddend; ATOMIC_ENTER_CRITICAL();
{
*pAddend -= 1; ulCurrent = *pulAddend;
*pulAddend -= 1;
ATOMIC_EXIT_CRITICAL(); }
ATOMIC_EXIT_CRITICAL();
return ulCurrent;
} return ulCurrent;
}
/*----------------------------- Bitwise Logical ------------------------------*/
/*----------------------------- Bitwise Logical ------------------------------*/
/**
* Atomic OR /**
* * Atomic OR
* @brief Performs an atomic OR operation on the specified values. *
* * @brief Performs an atomic OR operation on the specified values.
* @param [in, out] pDestination Pointer to memory location from where value is *
* to be loaded and written back to. * @param [in, out] pulDestination Pointer to memory location from where value is
* @param [in] ulValue Value to be ORed with *pDestination. * to be loaded and written back to.
* * @param [in] ulValue Value to be ORed with *pulDestination.
* @return The original value of *pDestination. *
*/ * @return The original value of *pulDestination.
static portFORCE_INLINE uint32_t Atomic_OR_u32( */
uint32_t volatile * pDestination, 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();
{
ulCurrent = *pDestination; ulCurrent = *pulDestination;
*pulDestination |= ulValue;
*pDestination |= ulValue; }
ATOMIC_EXIT_CRITICAL();
ATOMIC_EXIT_CRITICAL();
return ulCurrent;
return ulCurrent; }
} /*-----------------------------------------------------------*/
/** /**
* Atomic AND * Atomic AND
* *
* @brief Performs an atomic AND operation on the specified values. * @brief Performs an atomic AND operation on the specified values.
* *
* @param [in, out] pDestination Pointer to memory location from where value is * @param [in, out] pulDestination Pointer to memory location from where value is
* to be loaded and written back to. * to be loaded and written back to.
* @param [in] ulValue Value to be ANDed with *pDestination. * @param [in] ulValue Value to be ANDed with *pulDestination.
* *
* @return The original value of *pDestination. * @return The original value of *pulDestination.
*/ */
static portFORCE_INLINE uint32_t Atomic_AND_u32( static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination,
uint32_t volatile * pDestination, uint32_t ulValue )
uint32_t ulValue ) {
{ uint32_t ulCurrent;
uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL();
ATOMIC_ENTER_CRITICAL(); {
ulCurrent = *pulDestination;
ulCurrent = *pDestination; *pulDestination &= ulValue;
}
*pDestination &= ulValue; ATOMIC_EXIT_CRITICAL();
ATOMIC_EXIT_CRITICAL(); return ulCurrent;
}
return ulCurrent; /*-----------------------------------------------------------*/
}
/**
/** * Atomic NAND
* Atomic NAND *
* * @brief Performs an atomic NAND operation on the specified values.
* @brief Performs an atomic NAND operation on the specified values. *
* * @param [in, out] pulDestination Pointer to memory location from where value is
* @param [in, out] pDestination Pointer to memory location from where value is * to be loaded and written back to.
* to be loaded and written back to. * @param [in] ulValue Value to be NANDed with *pulDestination.
* @param [in] ulValue Value to be NANDed with *pDestination. *
* * @return The original value of *pulDestination.
* @return The original value of *pDestination. */
*/ static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination,
static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t ulValue )
uint32_t volatile * pDestination, {
uint32_t ulValue ) uint32_t ulCurrent;
{
uint32_t ulCurrent; ATOMIC_ENTER_CRITICAL();
{
ATOMIC_ENTER_CRITICAL(); ulCurrent = *pulDestination;
*pulDestination = ~( ulCurrent & ulValue );
ulCurrent = *pDestination; }
ATOMIC_EXIT_CRITICAL();
*pDestination = ~(ulCurrent & ulValue);
return ulCurrent;
ATOMIC_EXIT_CRITICAL(); }
/*-----------------------------------------------------------*/
return ulCurrent;
} /**
* Atomic XOR
/** *
* Atomic XOR * @brief Performs an atomic XOR operation on the specified values.
* *
* @brief Performs an atomic XOR operation on the specified values. * @param [in, out] pulDestination Pointer to memory location from where value is
* * to be loaded and written back to.
* @param [in, out] pDestination Pointer to memory location from where value is * @param [in] ulValue Value to be XORed with *pulDestination.
* to be loaded and written back to. *
* @param [in] ulValue Value to be XORed with *pDestination. * @return The original value of *pulDestination.
* */
* @return The original value of *pDestination. static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination,
*/ uint32_t ulValue )
static portFORCE_INLINE uint32_t Atomic_XOR_u32( {
uint32_t volatile * pDestination, uint32_t ulCurrent;
uint32_t ulValue )
{ ATOMIC_ENTER_CRITICAL();
uint32_t ulCurrent; {
ulCurrent = *pulDestination;
ATOMIC_ENTER_CRITICAL(); *pulDestination ^= ulValue;
}
ulCurrent = *pDestination; ATOMIC_EXIT_CRITICAL();
*pDestination ^= ulValue; return ulCurrent;
}
ATOMIC_EXIT_CRITICAL();
#ifdef __cplusplus
return ulCurrent; }
} #endif
#ifdef __cplusplus #endif /* ATOMIC_H */
}
#endif
#endif /* ATOMIC_H */

File diff suppressed because it is too large Load diff

View file

@ -1,279 +1,279 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef DEPRECATED_DEFINITIONS_H #ifndef DEPRECATED_DEFINITIONS_H
#define DEPRECATED_DEFINITIONS_H #define DEPRECATED_DEFINITIONS_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. 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
#include "../portable/GCC/ATMega323/portmacro.h" #include "../portable/GCC/ATMega323/portmacro.h"
#endif #endif
#ifdef IAR_MEGA_AVR #ifdef IAR_MEGA_AVR
#include "../portable/IAR/ATMega323/portmacro.h" #include "../portable/IAR/ATMega323/portmacro.h"
#endif #endif
#ifdef MPLAB_PIC24_PORT #ifdef MPLAB_PIC24_PORT
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
#endif #endif
#ifdef MPLAB_DSPIC_PORT #ifdef MPLAB_DSPIC_PORT
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
#endif #endif
#ifdef MPLAB_PIC18F_PORT #ifdef MPLAB_PIC18F_PORT
#include "../../Source/portable/MPLAB/PIC18F/portmacro.h" #include "../../Source/portable/MPLAB/PIC18F/portmacro.h"
#endif #endif
#ifdef MPLAB_PIC32MX_PORT #ifdef MPLAB_PIC32MX_PORT
#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"
#endif #endif
#ifdef _FEDPICC #ifdef _FEDPICC
#include "libFreeRTOS/Include/portmacro.h" #include "libFreeRTOS/Include/portmacro.h"
#endif #endif
#ifdef SDCC_CYGNAL #ifdef SDCC_CYGNAL
#include "../../Source/portable/SDCC/Cygnal/portmacro.h" #include "../../Source/portable/SDCC/Cygnal/portmacro.h"
#endif #endif
#ifdef GCC_ARM7 #ifdef GCC_ARM7
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
#endif #endif
#ifdef GCC_ARM7_ECLIPSE #ifdef GCC_ARM7_ECLIPSE
#include "portmacro.h" #include "portmacro.h"
#endif #endif
#ifdef ROWLEY_LPC23xx #ifdef ROWLEY_LPC23xx
#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
#endif #endif
#ifdef IAR_MSP430 #ifdef IAR_MSP430
#include "..\..\Source\portable\IAR\MSP430\portmacro.h" #include "..\..\Source\portable\IAR\MSP430\portmacro.h"
#endif #endif
#ifdef GCC_MSP430 #ifdef GCC_MSP430
#include "../../Source/portable/GCC/MSP430F449/portmacro.h" #include "../../Source/portable/GCC/MSP430F449/portmacro.h"
#endif #endif
#ifdef ROWLEY_MSP430 #ifdef ROWLEY_MSP430
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h" #include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
#endif #endif
#ifdef ARM7_LPC21xx_KEIL_RVDS #ifdef ARM7_LPC21xx_KEIL_RVDS
#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
#endif #endif
#ifdef SAM7_GCC #ifdef SAM7_GCC
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
#endif #endif
#ifdef SAM7_IAR #ifdef SAM7_IAR
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
#endif #endif
#ifdef SAM9XE_IAR #ifdef SAM9XE_IAR
#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
#endif #endif
#ifdef LPC2000_IAR #ifdef LPC2000_IAR
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h" #include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
#endif #endif
#ifdef STR71X_IAR #ifdef STR71X_IAR
#include "..\..\Source\portable\IAR\STR71x\portmacro.h" #include "..\..\Source\portable\IAR\STR71x\portmacro.h"
#endif #endif
#ifdef STR75X_IAR #ifdef STR75X_IAR
#include "..\..\Source\portable\IAR\STR75x\portmacro.h" #include "..\..\Source\portable\IAR\STR75x\portmacro.h"
#endif #endif
#ifdef STR75X_GCC #ifdef STR75X_GCC
#include "..\..\Source\portable\GCC\STR75x\portmacro.h" #include "..\..\Source\portable\GCC\STR75x\portmacro.h"
#endif #endif
#ifdef STR91X_IAR #ifdef STR91X_IAR
#include "..\..\Source\portable\IAR\STR91x\portmacro.h" #include "..\..\Source\portable\IAR\STR91x\portmacro.h"
#endif #endif
#ifdef GCC_H8S #ifdef GCC_H8S
#include "../../Source/portable/GCC/H8S2329/portmacro.h" #include "../../Source/portable/GCC/H8S2329/portmacro.h"
#endif #endif
#ifdef GCC_AT91FR40008 #ifdef GCC_AT91FR40008
#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
#endif #endif
#ifdef RVDS_ARMCM3_LM3S102 #ifdef RVDS_ARMCM3_LM3S102
#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
#endif #endif
#ifdef GCC_ARMCM3_LM3S102 #ifdef GCC_ARMCM3_LM3S102
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h" #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
#endif #endif
#ifdef GCC_ARMCM3 #ifdef GCC_ARMCM3
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h" #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
#endif #endif
#ifdef IAR_ARM_CM3 #ifdef IAR_ARM_CM3
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h" #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
#endif #endif
#ifdef IAR_ARMCM3_LM #ifdef IAR_ARMCM3_LM
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h" #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
#endif #endif
#ifdef HCS12_CODE_WARRIOR #ifdef HCS12_CODE_WARRIOR
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
#endif #endif
#ifdef MICROBLAZE_GCC #ifdef MICROBLAZE_GCC
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h" #include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
#endif #endif
#ifdef TERN_EE #ifdef TERN_EE
#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
#endif #endif
#ifdef GCC_HCS12 #ifdef GCC_HCS12
#include "../../Source/portable/GCC/HCS12/portmacro.h" #include "../../Source/portable/GCC/HCS12/portmacro.h"
#endif #endif
#ifdef GCC_MCF5235 #ifdef GCC_MCF5235
#include "../../Source/portable/GCC/MCF5235/portmacro.h" #include "../../Source/portable/GCC/MCF5235/portmacro.h"
#endif #endif
#ifdef COLDFIRE_V2_GCC #ifdef COLDFIRE_V2_GCC
#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
#endif #endif
#ifdef COLDFIRE_V2_CODEWARRIOR #ifdef COLDFIRE_V2_CODEWARRIOR
#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
#endif #endif
#ifdef GCC_PPC405 #ifdef GCC_PPC405
#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
#endif #endif
#ifdef GCC_PPC440 #ifdef GCC_PPC440
#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
#endif #endif
#ifdef _16FX_SOFTUNE #ifdef _16FX_SOFTUNE
#include "..\..\Source\portable\Softune\MB96340\portmacro.h" #include "..\..\Source\portable\Softune\MB96340\portmacro.h"
#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 /* A short file name has to be used in place of the normal
FreeRTOSConfig.h when using the Borland compiler. */ 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 /* A short file name has to be used in place of the normal
FreeRTOSConfig.h when using the Borland compiler. */ 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__
#ifdef __AVR32_AVR32A__ #ifdef __AVR32_AVR32A__
#include "portmacro.h" #include "portmacro.h"
#endif #endif
#endif #endif
#ifdef __ICCAVR32__ #ifdef __ICCAVR32__
#ifdef __CORE__ #ifdef __CORE__
#if __CORE__ == __AVR32A__ #if __CORE__ == __AVR32A__
#include "portmacro.h" #include "portmacro.h"
#endif #endif
#endif #endif
#endif #endif
#ifdef __91467D #ifdef __91467D
#include "portmacro.h" #include "portmacro.h"
#endif #endif
#ifdef __96340 #ifdef __96340
#include "portmacro.h" #include "portmacro.h"
#endif #endif
#ifdef __IAR_V850ES_Fx3__ #ifdef __IAR_V850ES_Fx3__
#include "../../Source/portable/IAR/V850ES/portmacro.h" #include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif #endif
#ifdef __IAR_V850ES_Jx3__ #ifdef __IAR_V850ES_Jx3__
#include "../../Source/portable/IAR/V850ES/portmacro.h" #include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif #endif
#ifdef __IAR_V850ES_Jx3_L__ #ifdef __IAR_V850ES_Jx3_L__
#include "../../Source/portable/IAR/V850ES/portmacro.h" #include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif #endif
#ifdef __IAR_V850ES_Jx2__ #ifdef __IAR_V850ES_Jx2__
#include "../../Source/portable/IAR/V850ES/portmacro.h" #include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif #endif
#ifdef __IAR_V850ES_Hx2__ #ifdef __IAR_V850ES_Hx2__
#include "../../Source/portable/IAR/V850ES/portmacro.h" #include "../../Source/portable/IAR/V850ES/portmacro.h"
#endif #endif
#ifdef __IAR_78K0R_Kx3__ #ifdef __IAR_78K0R_Kx3__
#include "../../Source/portable/IAR/78K0R/portmacro.h" #include "../../Source/portable/IAR/78K0R/portmacro.h"
#endif #endif
#ifdef __IAR_78K0R_Kx3L__ #ifdef __IAR_78K0R_Kx3L__
#include "../../Source/portable/IAR/78K0R/portmacro.h" #include "../../Source/portable/IAR/78K0R/portmacro.h"
#endif #endif
#endif /* DEPRECATED_DEFINITIONS_H */ #endif /* DEPRECATED_DEFINITIONS_H */

File diff suppressed because it is too large Load diff

View file

@ -1,412 +1,412 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* /*
* This is the list implementation used by the scheduler. While it is tailored * This is the list implementation used by the scheduler. While it is tailored
* heavily for the schedulers needs, it is also available for use by * heavily for the schedulers needs, it is also available for use by
* application code. * application code.
* *
* list_ts can only store pointers to list_item_ts. Each ListItem_t contains a * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a
* numeric value (xItemValue). Most of the time the lists are sorted in * numeric value (xItemValue). Most of the time the lists are sorted in
* descending item value order. * descending item value order.
* *
* Lists are created already containing one list item. The value of this * Lists are created already containing one list item. The value of this
* item is the maximum possible that can be stored, it is therefore always at * item is the maximum possible that can be stored, it is therefore always at
* the end of the list and acts as a marker. The list member pxHead always * the end of the list and acts as a marker. The list member pxHead always
* points to this marker - even though it is at the tail of the list. This * points to this marker - even though it is at the tail of the list. This
* is because the tail contains a wrap back pointer to the true head of * is because the tail contains a wrap back pointer to the true head of
* the list. * the list.
* *
* In addition to it's value, each list item contains a pointer to the next * In addition to it's value, each list item contains a pointer to the next
* item in the list (pxNext), a pointer to the list it is in (pxContainer) * item in the list (pxNext), a pointer to the list it is in (pxContainer)
* and a pointer to back to the object that contains it. These later two * and a pointer to back to the object that contains it. These later two
* pointers are included for efficiency of list manipulation. There is * pointers are included for efficiency of list manipulation. There is
* effectively a two way link between the object containing the list item and * effectively a two way link between the object containing the list item and
* the list item itself. * the list item itself.
* *
* *
* \page ListIntroduction List Implementation * \page ListIntroduction List Implementation
* \ingroup FreeRTOSIntro * \ingroup FreeRTOSIntro
*/ */
#ifndef INC_FREERTOS_H #ifndef INC_FREERTOS_H
#error FreeRTOS.h must be included before list.h #error FreeRTOS.h must be included before list.h
#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
* by rights should be declared volatile. However, they are only modified in a * by rights should be declared volatile. However, they are only modified in a
* functionally atomic way (within critical sections of with the scheduler * functionally atomic way (within critical sections of with the scheduler
* suspended) and are either passed by reference into a function or indexed via * suspended) and are either passed by reference into a function or indexed via
* a volatile variable. Therefore, in all use cases tested so far, the volatile * a volatile variable. Therefore, in all use cases tested so far, the volatile
* qualifier can be omitted in order to provide a moderate performance * qualifier can be omitted in order to provide a moderate performance
* improvement without adversely affecting functional behaviour. The assembly * improvement without adversely affecting functional behaviour. The assembly
* instructions generated by the IAR, ARM and GCC compilers when the respective * instructions generated by the IAR, ARM and GCC compilers when the respective
* compiler's options were set for maximum optimisation has been inspected and * compiler's options were set for maximum optimisation has been inspected and
* deemed to be as intended. That said, as compiler technology advances, and * deemed to be as intended. That said, as compiler technology advances, and
* especially if aggressive cross module optimisation is used (a use case that * especially if aggressive cross module optimisation is used (a use case that
* has not been exercised to any great extend) then it is feasible that the * has not been exercised to any great extend) then it is feasible that the
* volatile qualifier will be needed for correct optimisation. It is expected * volatile qualifier will be needed for correct optimisation. It is expected
* that a compiler removing essential code because, without the volatile * that a compiler removing essential code because, without the volatile
* qualifier on the list structure members and with aggressive cross module * qualifier on the list structure members and with aggressive cross module
* optimisation, the compiler deemed the code unnecessary will result in * optimisation, the compiler deemed the code unnecessary will result in
* complete and obvious failure of the scheduler. If this is ever experienced * complete and obvious failure of the scheduler. If this is ever experienced
* then the volatile qualifier can be inserted in the relevant places within the * then the volatile qualifier can be inserted in the relevant places within the
* list structures by simply defining configLIST_VOLATILE to volatile in * list structures by simply defining configLIST_VOLATILE to volatile in
* FreeRTOSConfig.h (as per the example at the bottom of this comment block). * FreeRTOSConfig.h (as per the example at the bottom of this comment block).
* If configLIST_VOLATILE is not defined then the preprocessor directives below * If configLIST_VOLATILE is not defined then the preprocessor directives below
* will simply #define configLIST_VOLATILE away completely. * will simply #define configLIST_VOLATILE away completely.
* *
* To use volatile list structure members then add the following line to * To use volatile list structure members then add the following line to
* 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
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE #define listFIRST_LIST_INTEGRITY_CHECK_VALUE
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE #define listSECOND_LIST_INTEGRITY_CHECK_VALUE
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )
#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
/* 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. */
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */
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
* is the object (usually a TCB) that contains the list item. * is the object (usually a TCB) that contains the list item.
* *
* \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
* is the object (usually a TCB) that contains the list item. * is the object (usually a TCB) that contains the list item.
* *
* \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
* used to sort the list in descending order. * used to sort the list in descending order.
* *
* \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
* represent anything - for example the priority of a task, or the time at * represent anything - for example the priority of a task, or the time at
* which a task should be unblocked. * which a task should be unblocked.
* *
* \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
* list. * list.
* *
* \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.
* *
* \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.
* *
* \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
* *
* \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
* only have the value true if the list is empty. * only have the value true if the list is empty.
* *
* \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.
* *
* The list member pxIndex is used to walk through a list. Calling * The list member pxIndex is used to walk through a list. Calling
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
* and returns that entry's pxOwner parameter. Using multiple calls to this * and returns that entry's pxOwner parameter. Using multiple calls to this
* function it is therefore possible to move through every item contained in * function it is therefore possible to move through every item contained in
* a list. * a list.
* *
* The pxOwner parameter of a list item is a pointer to the object that owns * The pxOwner parameter of a list item is a pointer to the object that owns
* the list item. In the scheduler this is normally a task control block. * the list item. In the scheduler this is normally a task control block.
* The pxOwner parameter effectively creates a two way link between the list * The pxOwner parameter effectively creates a two way link between the list
* item and its owner. * item and its owner.
* *
* @param pxTCB pxTCB is set to the address of the owner of the next list item. * @param pxTCB pxTCB is set to the address of the owner of the next list item.
* @param pxList The list from which the next item owner is to be returned. * @param pxList The list from which the next item owner is to be returned.
* *
* \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; \
if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
{ \ { \
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
} \ } \
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
} }
/* /*
* Access function to obtain the owner of the first entry in a list. Lists * Access function to obtain the owner of the first entry in a list. Lists
* are normally sorted in ascending item value order. * are normally sorted in ascending item value order.
* *
* This function returns the pxOwner member of the first item in the list. * This function returns the pxOwner member of the first item in the list.
* The pxOwner parameter of a list item is a pointer to the object that owns * The pxOwner parameter of a list item is a pointer to the object that owns
* the list item. In the scheduler this is normally a task control block. * the list item. In the scheduler this is normally a task control block.
* The pxOwner parameter effectively creates a two way link between the list * The pxOwner parameter effectively creates a two way link between the list
* item and its owner. * item and its owner.
* *
* @param pxList The list from which the owner of the head item is to be * @param pxList The list from which the owner of the head item is to be
* returned. * returned.
* *
* \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
* "container" pointer that points to the list it is in. All this macro does * "container" pointer that points to the list it is in. All this macro does
* is check to see if the container and the list match. * is check to see if the container and the list match.
* *
* @param pxList The list we want to know if the list item is within. * @param pxList The list we want to know if the list item is within.
* @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).
* *
* @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
* of the list structure and inserts the xListEnd item into the list as a * of the list structure and inserts the xListEnd item into the list as a
* marker to the back of the list. * marker to the back of the list.
* *
* @param pxList Pointer to the list being initialised. * @param pxList Pointer to the list being initialised.
* *
* \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
* null so the item does not think that it is already contained in a list. * null so the item does not think that it is already contained in a list.
* *
* @param pxItem Pointer to the list item being initialised. * @param pxItem Pointer to the list item being initialised.
* *
* \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
* a position determined by its item value (descending item value order). * a position determined by its item value (descending item value order).
* *
* @param pxList The list into which the item is to be inserted. * @param pxList The list into which the item is to be inserted.
* *
* @param pxNewListItem The item that is to be placed in the list. * @param pxNewListItem The item that is to be placed in the list.
* *
* \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
* such that it will be the last item within the list returned by multiple * such that it will be the last item within the list returned by multiple
* calls to listGET_OWNER_OF_NEXT_ENTRY. * calls to listGET_OWNER_OF_NEXT_ENTRY.
* *
* The list member pxIndex is used to walk through a list. Calling * The list member pxIndex is used to walk through a list. Calling
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.
* Placing an item in a list using vListInsertEnd effectively places the item * Placing an item in a list using vListInsertEnd effectively places the item
* in the list position pointed to by pxIndex. This means that every other * in the list position pointed to by pxIndex. This means that every other
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
* the pxIndex parameter again points to the item being inserted. * the pxIndex parameter again points to the item being inserted.
* *
* @param pxList The list into which the item is to be inserted. * @param pxList The list into which the item is to be inserted.
* *
* @param pxNewListItem The list item to be inserted into the list. * @param pxNewListItem The list item to be inserted into the list.
* *
* \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
* it is in, so only the list item need be passed into the function. * it is in, so only the list item need be passed into the function.
* *
* @param uxListRemove The item to be removed. The item will remove itself from * @param uxListRemove The item to be removed. The item will remove itself from
* the list pointed to by it's pxContainer parameter. * the list pointed to by it's pxContainer parameter.
* *
* @return The number of items that remain in the list after the list item has * @return The number of items that remain in the list after the list item has
* been removed. * been removed.
* *
* \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

File diff suppressed because it is too large Load diff

View file

@ -1,158 +1,160 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* /*
* When the MPU is used the standard (non MPU) API functions are mapped to * When the MPU is used the standard (non MPU) API functions are mapped to
* equivalents that start "MPU_", the prototypes for which are defined in this * equivalents that start "MPU_", the prototypes for which are defined in this
* header files. This will cause the application code to call the MPU_ version * header files. This will cause the application code to call the MPU_ version
* which wraps the non-MPU version with privilege promoting then demoting code, * which wraps the non-MPU version with privilege promoting then demoting code,
* so the kernel code always runs will full privileges. * so the kernel code always runs will full privileges.
*/ */
#ifndef MPU_PROTOTYPES_H #ifndef MPU_PROTOTYPES_H
#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, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, 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; 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_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; 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_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, 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_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;
void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL; 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, BaseType_t xIndex, void *pvValue ) FREERTOS_SYSTEM_CALL;
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) 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; 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, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL; uint32_t MPU_ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL;
/* 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; /* MPU versions of queue.h API functions. */
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueReceive( 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; BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, 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;
TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) FREERTOS_SYSTEM_CALL;
const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; void MPU_vQueueUnregisterQueue( 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; const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) 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; QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) 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;
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, 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, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL; QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL;
uint8_t MPU_ucQueueGetQueueType( 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;
/* 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; /* MPU versions of timers.h API functions. */
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; 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;
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) 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_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) FREERTOS_SYSTEM_CALL; void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL;
const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL;
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) 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; TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL;
/* MPU versions of event_group.h API functions. */ 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;
EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL;
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; /* MPU versions of event_group.h API functions. */
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; EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) 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_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL;
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ) 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;
/* MPU versions of message/stream_buffer.h API functions. */ UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, 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; /* MPU versions of message/stream_buffer.h API functions. */
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) 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; BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) 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 */

View file

@ -1,187 +1,189 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef MPU_WRAPPERS_H #ifndef MPU_WRAPPERS_H
#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
* then demoting code, so the kernel code always runs will full * then demoting code, so the kernel code always runs will full
* 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
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
#define vTaskDelete MPU_vTaskDelete #define vTaskDelete MPU_vTaskDelete
#define vTaskDelay MPU_vTaskDelay #define vTaskDelay MPU_vTaskDelay
#define vTaskDelayUntil MPU_vTaskDelayUntil #define vTaskDelayUntil MPU_vTaskDelayUntil
#define xTaskAbortDelay MPU_xTaskAbortDelay #define xTaskAbortDelay MPU_xTaskAbortDelay
#define uxTaskPriorityGet MPU_uxTaskPriorityGet #define uxTaskPriorityGet MPU_uxTaskPriorityGet
#define eTaskGetState MPU_eTaskGetState #define eTaskGetState MPU_eTaskGetState
#define vTaskGetInfo MPU_vTaskGetInfo #define vTaskGetInfo MPU_vTaskGetInfo
#define vTaskPrioritySet MPU_vTaskPrioritySet #define vTaskPrioritySet MPU_vTaskPrioritySet
#define vTaskSuspend MPU_vTaskSuspend #define vTaskSuspend MPU_vTaskSuspend
#define vTaskResume MPU_vTaskResume #define vTaskResume MPU_vTaskResume
#define vTaskSuspendAll MPU_vTaskSuspendAll #define vTaskSuspendAll MPU_vTaskSuspendAll
#define xTaskResumeAll MPU_xTaskResumeAll #define xTaskResumeAll MPU_xTaskResumeAll
#define xTaskGetTickCount MPU_xTaskGetTickCount #define xTaskGetTickCount MPU_xTaskGetTickCount
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
#define pcTaskGetName MPU_pcTaskGetName #define pcTaskGetName MPU_pcTaskGetName
#define xTaskGetHandle MPU_xTaskGetHandle #define xTaskGetHandle MPU_xTaskGetHandle
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
#define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 #define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
#define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer
#define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
#define uxTaskGetSystemState MPU_uxTaskGetSystemState #define uxTaskGetSystemState MPU_uxTaskGetSystemState
#define vTaskList MPU_vTaskList #define vTaskList MPU_vTaskList
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
#define ulTaskGetIdleRunTimeCounter MPU_ulTaskGetIdleRunTimeCounter #define ulTaskGetIdleRunTimeCounter MPU_ulTaskGetIdleRunTimeCounter
#define xTaskGenericNotify MPU_xTaskGenericNotify #define xTaskGenericNotify MPU_xTaskGenericNotify
#define xTaskNotifyWait MPU_xTaskNotifyWait #define xTaskNotifyWait MPU_xTaskNotifyWait
#define ulTaskNotifyTake MPU_ulTaskNotifyTake #define ulTaskNotifyTake MPU_ulTaskNotifyTake
#define xTaskNotifyStateClear MPU_xTaskNotifyStateClear #define xTaskNotifyStateClear MPU_xTaskNotifyStateClear
#define xTaskCatchUpTicks MPU_xTaskCatchUpTicks #define ulTaskNotifyValueClear MPU_ulTaskNotifyValueClear
#define xTaskCatchUpTicks MPU_xTaskCatchUpTicks
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
#define vTaskSetTimeOutState MPU_vTaskSetTimeOutState #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
#define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
/* Map standard queue.h API functions to the MPU equivalents. */
#define xQueueGenericSend MPU_xQueueGenericSend /* Map standard queue.h API functions to the MPU equivalents. */
#define xQueueReceive MPU_xQueueReceive #define xQueueGenericSend MPU_xQueueGenericSend
#define xQueuePeek MPU_xQueuePeek #define xQueueReceive MPU_xQueueReceive
#define xQueueSemaphoreTake MPU_xQueueSemaphoreTake #define xQueuePeek MPU_xQueuePeek
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake
#define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
#define vQueueDelete MPU_vQueueDelete #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable
#define xQueueCreateMutex MPU_xQueueCreateMutex #define vQueueDelete MPU_vQueueDelete
#define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic #define xQueueCreateMutex MPU_xQueueCreateMutex
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic
#define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
#define xQueueGetMutexHolder MPU_xQueueGetMutexHolder #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
#define xQueueGenericCreate MPU_xQueueGenericCreate #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic #define xQueueGenericCreate MPU_xQueueGenericCreate
#define xQueueCreateSet MPU_xQueueCreateSet #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic
#define xQueueAddToSet MPU_xQueueAddToSet #define xQueueCreateSet MPU_xQueueCreateSet
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet #define xQueueAddToSet MPU_xQueueAddToSet
#define xQueueSelectFromSet MPU_xQueueSelectFromSet #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
#define xQueueGenericReset MPU_xQueueGenericReset #define xQueueSelectFromSet MPU_xQueueSelectFromSet
#define xQueueGenericReset MPU_xQueueGenericReset
#if( configQUEUE_REGISTRY_SIZE > 0 )
#define vQueueAddToRegistry MPU_vQueueAddToRegistry #if( configQUEUE_REGISTRY_SIZE > 0 )
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue #define vQueueAddToRegistry MPU_vQueueAddToRegistry
#define pcQueueGetName MPU_pcQueueGetName #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
#endif #define pcQueueGetName MPU_pcQueueGetName
#endif
/* Map standard timer.h API functions to the MPU equivalents. */
#define xTimerCreate MPU_xTimerCreate /* Map standard timer.h API functions to the MPU equivalents. */
#define xTimerCreateStatic MPU_xTimerCreateStatic #define xTimerCreate MPU_xTimerCreate
#define pvTimerGetTimerID MPU_pvTimerGetTimerID #define xTimerCreateStatic MPU_xTimerCreateStatic
#define vTimerSetTimerID MPU_vTimerSetTimerID #define pvTimerGetTimerID MPU_pvTimerGetTimerID
#define xTimerIsTimerActive MPU_xTimerIsTimerActive #define vTimerSetTimerID MPU_vTimerSetTimerID
#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle #define xTimerIsTimerActive MPU_xTimerIsTimerActive
#define xTimerPendFunctionCall MPU_xTimerPendFunctionCall #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle
#define pcTimerGetName MPU_pcTimerGetName #define xTimerPendFunctionCall MPU_xTimerPendFunctionCall
#define vTimerSetReloadMode MPU_vTimerSetReloadMode #define pcTimerGetName MPU_pcTimerGetName
#define xTimerGetPeriod MPU_xTimerGetPeriod #define vTimerSetReloadMode MPU_vTimerSetReloadMode
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime #define uxTimerGetReloadMode MPU_uxTimerGetReloadMode
#define xTimerGenericCommand MPU_xTimerGenericCommand #define xTimerGetPeriod MPU_xTimerGetPeriod
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
/* Map standard event_group.h API functions to the MPU equivalents. */ #define xTimerGenericCommand MPU_xTimerGenericCommand
#define xEventGroupCreate MPU_xEventGroupCreate
#define xEventGroupCreateStatic MPU_xEventGroupCreateStatic /* Map standard event_group.h API functions to the MPU equivalents. */
#define xEventGroupWaitBits MPU_xEventGroupWaitBits #define xEventGroupCreate MPU_xEventGroupCreate
#define xEventGroupClearBits MPU_xEventGroupClearBits #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic
#define xEventGroupSetBits MPU_xEventGroupSetBits #define xEventGroupWaitBits MPU_xEventGroupWaitBits
#define xEventGroupSync MPU_xEventGroupSync #define xEventGroupClearBits MPU_xEventGroupClearBits
#define vEventGroupDelete MPU_vEventGroupDelete #define xEventGroupSetBits MPU_xEventGroupSetBits
#define xEventGroupSync MPU_xEventGroupSync
/* Map standard message/stream_buffer.h API functions to the MPU #define vEventGroupDelete MPU_vEventGroupDelete
equivalents. */
#define xStreamBufferSend MPU_xStreamBufferSend /* Map standard message/stream_buffer.h API functions to the MPU
#define xStreamBufferReceive MPU_xStreamBufferReceive equivalents. */
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes #define xStreamBufferSend MPU_xStreamBufferSend
#define vStreamBufferDelete MPU_vStreamBufferDelete #define xStreamBufferReceive MPU_xStreamBufferReceive
#define xStreamBufferIsFull MPU_xStreamBufferIsFull #define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
#define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty #define vStreamBufferDelete MPU_vStreamBufferDelete
#define xStreamBufferReset MPU_xStreamBufferReset #define xStreamBufferIsFull MPU_xStreamBufferIsFull
#define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable #define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty
#define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable #define xStreamBufferReset MPU_xStreamBufferReset
#define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel #define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable
#define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate #define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable
#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic #define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel
#define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate
#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic
/* Remove the privileged function macro, but keep the PRIVILEGED_DATA
macro so applications can place data in privileged access sections
(useful when using statically allocated objects). */ /* Remove the privileged function macro, but keep the PRIVILEGED_DATA
#define PRIVILEGED_FUNCTION macro so applications can place data in privileged access sections
#define PRIVILEGED_DATA __attribute__((section("privileged_data"))) (useful when using statically allocated objects). */
#define FREERTOS_SYSTEM_CALL #define PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ #define FREERTOS_SYSTEM_CALL
/* Ensure API functions go in the privileged execution section. */ #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
#define PRIVILEGED_DATA __attribute__((section("privileged_data"))) /* Ensure API functions go in the privileged execution section. */
#define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls"))) #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ #define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls")))
#else /* portUSING_MPU_WRAPPERS */ #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
#define PRIVILEGED_FUNCTION #else /* portUSING_MPU_WRAPPERS */
#define PRIVILEGED_DATA
#define FREERTOS_SYSTEM_CALL #define PRIVILEGED_FUNCTION
#define portUSING_MPU_WRAPPERS 0 #define PRIVILEGED_DATA
#define FREERTOS_SYSTEM_CALL
#endif /* portUSING_MPU_WRAPPERS */ #define portUSING_MPU_WRAPPERS 0
#endif /* portUSING_MPU_WRAPPERS */
#endif /* MPU_WRAPPERS_H */
#endif /* MPU_WRAPPERS_H */

View file

@ -1,199 +1,199 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
* 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
* scheduler control. The registers have to be placed on the stack in * scheduler control. The registers have to be placed on the stack in
* 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( 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
/* 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. */
size_t xNumberOfFreeBlocks; /* The number of free memory blocks within the heap at the time vPortGetHeapStats() is called. */ size_t xNumberOfFreeBlocks; /* The number of free memory blocks within the heap at the time vPortGetHeapStats() is called. */
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
* must be called before any calls to pvPortMalloc() - not creating a task, * must be called before any calls to pvPortMalloc() - not creating a task,
* queue, semaphore, mutex, software timer, event group, etc. will result in * queue, semaphore, mutex, software timer, event group, etc. will result in
* pvPortMalloc being called. * pvPortMalloc being called.
* *
* pxHeapRegions passes in an array of HeapRegion_t structures - each of which * pxHeapRegions passes in an array of HeapRegion_t structures - each of which
* defines a region of memory that can be used as the heap. The array is * defines a region of memory that can be used as the heap. The array is
* 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
* port layer. * port layer.
* *
* 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, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION;
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* PORTABLE_H */ #endif /* PORTABLE_H */

View file

@ -1,124 +1,124 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef PROJDEFS_H #ifndef PROJDEFS_H
#define PROJDEFS_H #define PROJDEFS_H
/* /*
* 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
#define pdFALSE ( ( BaseType_t ) 0 ) #define pdFALSE ( ( BaseType_t ) 0 )
#define pdTRUE ( ( BaseType_t ) 1 ) #define pdTRUE ( ( BaseType_t ) 1 )
#define pdPASS ( pdTRUE ) #define pdPASS ( pdTRUE )
#define pdFAIL ( pdFALSE ) #define pdFAIL ( pdFALSE )
#define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) #define errQUEUE_EMPTY ( ( BaseType_t ) 0 )
#define errQUEUE_FULL ( ( BaseType_t ) 0 ) #define errQUEUE_FULL ( ( BaseType_t ) 0 )
/* FreeRTOS error definitions. */ /* FreeRTOS error definitions. */
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) #define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
#define errQUEUE_BLOCKED ( -4 ) #define errQUEUE_BLOCKED ( -4 )
#define errQUEUE_YIELD ( -5 ) #define errQUEUE_YIELD ( -5 )
/* Macros used for basic data corruption checks. */ /* Macros used for basic data corruption checks. */
#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES #ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES
#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 */
#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ #define pdFREERTOS_ERRNO_EIO 5 /* I/O error */
#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ #define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */
#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ #define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */
#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ #define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */
#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ #define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */
#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ #define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */
#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ #define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */
#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ #define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */
#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ #define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */
#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ #define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */
#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ #define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */
#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ #define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */
#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ #define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */
#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ #define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */
#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ #define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */
#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ #define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */
#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ #define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */
#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ #define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */
#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ #define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */
#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ #define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */
#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ #define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */
#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ #define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */
#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ #define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */
#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ #define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */
#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ #define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ #define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */
#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ #define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */
#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ #define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */
#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ #define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */
#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ #define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */
#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ #define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */
#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ #define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */
#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ #define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */
#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ #define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */
#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ #define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */
#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ #define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */
#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
/* Re-defining endian values for generic naming. */ /* Re-defining endian values for generic naming. */
#define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN #define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN
#define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN #define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN
#endif /* PROJDEFS_H */ #endif /* PROJDEFS_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,129 +1,129 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef STACK_MACROS_H #ifndef STACK_MACROS_H
#define STACK_MACROS_H #define STACK_MACROS_H
/* /*
* Call the stack overflow hook function if the stack of the task being swapped * Call the stack overflow hook function if the stack of the task being swapped
* out is currently overflowed, or looks like it might have overflowed in the * out is currently overflowed, or looks like it might have overflowed in the
* past. * past.
* *
* Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
* the current stack state only - comparing the current top of stack value to * the current stack state only - comparing the current top of stack value to
* the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
* will also cause the last few stack bytes to be checked to ensure the value * will also cause the last few stack bytes to be checked to ensure the value
* to which the bytes were set when the task was created have not been * to which the bytes were set when the task was created have not been
* overwritten. Note this second test does not guarantee that an overflowed * overwritten. Note this second test does not guarantee that an overflowed
* stack will always be recognised. * stack will always be recognised.
*/ */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#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? */ \
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
{ \ { \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \ } \
} }
#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() \
{ \ { \
\ \
/* Is the currently saved stack pointer within the stack limit? */ \ /* Is the currently saved stack pointer within the stack limit? */ \
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
{ \ { \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \ } \
} }
#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() \
{ \ { \
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \
\ \
if( ( pulStack[ 0 ] != ulCheckValue ) || \ if( ( pulStack[ 0 ] != ulCheckValue ) || \
( pulStack[ 1 ] != ulCheckValue ) || \ ( pulStack[ 1 ] != ulCheckValue ) || \
( pulStack[ 2 ] != ulCheckValue ) || \ ( pulStack[ 2 ] != ulCheckValue ) || \
( pulStack[ 3 ] != ulCheckValue ) ) \ ( pulStack[ 3 ] != ulCheckValue ) ) \
{ \ { \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \ } \
} }
#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, \
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 }; \
\ \
\ \
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
\ \
/* Has the extremity of the task stack ever been written over? */ \ /* Has the extremity of the task stack ever been written over? */ \
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
{ \ { \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
} \ } \
} }
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Remove stack overflow macro if not being used. */ /* Remove stack overflow macro if not being used. */
#ifndef taskCHECK_FOR_STACK_OVERFLOW #ifndef taskCHECK_FOR_STACK_OVERFLOW
#define taskCHECK_FOR_STACK_OVERFLOW() #define taskCHECK_FOR_STACK_OVERFLOW()
#endif #endif
#endif /* STACK_MACROS_H */ #endif /* STACK_MACROS_H */

View file

@ -1,27 +1,27 @@
#ifndef FREERTOS_STDINT #ifndef FREERTOS_STDINT
#define FREERTOS_STDINT #define FREERTOS_STDINT
/******************************************************************************* /*******************************************************************************
* THIS IS NOT A FULL stdint.h IMPLEMENTATION - It only contains the definitions * THIS IS NOT A FULL stdint.h IMPLEMENTATION - It only contains the definitions
* necessary to build the FreeRTOS code. It is provided to allow FreeRTOS to be * necessary to build the FreeRTOS code. It is provided to allow FreeRTOS to be
* built using compilers that do not provide their own stdint.h definition. * built using compilers that do not provide their own stdint.h definition.
* *
* To use this file: * To use this file:
* *
* 1) Copy this file into the directory that contains your FreeRTOSConfig.h * 1) Copy this file into the directory that contains your FreeRTOSConfig.h
* header file, as that directory will already be in the compilers include * header file, as that directory will already be in the compilers include
* path. * path.
* *
* 2) Rename the copied file stdint.h. * 2) Rename the copied file stdint.h.
* *
*/ */
typedef signed char int8_t; typedef signed char int8_t;
typedef unsigned char uint8_t; typedef unsigned char uint8_t;
typedef short int16_t; typedef short int16_t;
typedef unsigned short uint16_t; typedef unsigned short uint16_t;
typedef long int32_t; typedef long int32_t;
typedef unsigned long uint32_t; typedef unsigned long uint32_t;
#endif /* FREERTOS_STDINT */ #endif /* FREERTOS_STDINT */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

396
list.c
View file

@ -1,198 +1,198 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#include <stdlib.h> #include <stdlib.h>
#include "FreeRTOS.h" #include "FreeRTOS.h"
#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 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vListInitialiseItem( ListItem_t * const pxItem ) void vListInitialiseItem( ListItem_t * const pxItem )
{ {
/* Make sure the list item is not recorded as being on a list. */ /* Make sure the list item is not recorded as being on a list. */
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;
/* Only used during decision coverage testing. */ /* Only used during decision coverage testing. */
mtCOVERAGE_TEST_DELAY(); mtCOVERAGE_TEST_DELAY();
pxIndex->pxPrevious->pxNext = pxNewListItem; pxIndex->pxPrevious->pxNext = pxNewListItem;
pxIndex->pxPrevious = pxNewListItem; pxIndex->pxPrevious = pxNewListItem;
/* Remember which list the item is in. */ /* Remember which list the item is in. */
pxNewListItem->pxContainer = pxList; pxNewListItem->pxContainer = pxList;
( pxList->uxNumberOfItems )++; ( pxList->uxNumberOfItems )++;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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;
} }
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. */
} }
} }
pxNewListItem->pxNext = pxIterator->pxNext; pxNewListItem->pxNext = pxIterator->pxNext;
pxNewListItem->pxNext->pxPrevious = pxNewListItem; pxNewListItem->pxNext->pxPrevious = pxNewListItem;
pxNewListItem->pxPrevious = pxIterator; pxNewListItem->pxPrevious = pxIterator;
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 )++;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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;
/* Only used during decision coverage testing. */ /* Only used during decision coverage testing. */
mtCOVERAGE_TEST_DELAY(); mtCOVERAGE_TEST_DELAY();
/* Make sure the index is left pointing to a valid item. */ /* Make sure the index is left pointing to a valid item. */
if( pxList->pxIndex == pxItemToRemove ) if( pxList->pxIndex == pxItemToRemove )
{ {
pxList->pxIndex = pxItemToRemove->pxPrevious; pxList->pxIndex = pxItemToRemove->pxPrevious;
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
pxItemToRemove->pxContainer = NULL; pxItemToRemove->pxContainer = NULL;
( pxList->uxNumberOfItems )--; ( pxList->uxNumberOfItems )--;
return pxList->uxNumberOfItems; return pxList->uxNumberOfItems;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -0,0 +1,2 @@
The FreeRTOS GCC port layer also builds and works with the ARMClang compiler.
To use the ARMClang compiler build the port files from FreeRTOS/Source/portable/GCC.

View file

@ -1,10 +1,10 @@
This directory tree contains the master copy of the FreeeRTOS Cortex-M33 port. This directory tree contains the master copy of the FreeeRTOS Cortex-M33 port.
Do not use the files located here! These file are copied into separate Do not use the files located here! These file are copied into separate
FreeRTOS/Source/portable/[compiler]/ARM_CM33_NNN directories prior to each FreeRTOS/Source/portable/[compiler]/ARM_CM33_NNN directories prior to each
FreeRTOS release. FreeRTOS release.
If your Cortex-M33 application uses TrustZone then use the files from the If your Cortex-M33 application uses TrustZone then use the files from the
FreeRTOS/Source/portable/[compiler]/ARM_CM33 directories. FreeRTOS/Source/portable/[compiler]/ARM_CM33 directories.
If your Cortex-M33 application does not use TrustZone then use the files from If your Cortex-M33 application does not use TrustZone then use the files from
the FreeRTOS/Source/portable/[compiler]/ARM_CM33_NTZ directories. the FreeRTOS/Source/portable/[compiler]/ARM_CM33_NTZ directories.

View file

@ -1,103 +1,103 @@
#/* #/*
# * FreeRTOS Kernel V10.2.1 # * FreeRTOS Kernel V10.3.0
# * Copyright (C) 2019 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
# * # *
# * 1 tab == 4 spaces! # * 1 tab == 4 spaces!
# */ # */
import os import os
import shutil import shutil
_THIS_FILE_DIRECTORY_ = os.path.dirname(os.path.realpath(__file__)) _THIS_FILE_DIRECTORY_ = os.path.dirname(os.path.realpath(__file__))
_FREERTOS_PORTABLE_DIRECTORY_ = os.path.dirname(_THIS_FILE_DIRECTORY_) _FREERTOS_PORTABLE_DIRECTORY_ = os.path.dirname(_THIS_FILE_DIRECTORY_)
_COMPILERS_ = ['GCC', 'IAR'] _COMPILERS_ = ['GCC', 'IAR']
_ARCH_NS_ = ['ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ'] _ARCH_NS_ = ['ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ']
_ARCH_S_ = ['ARM_CM33', 'ARM_CM23'] _ARCH_S_ = ['ARM_CM33', 'ARM_CM23']
_SUPPORTED_CONFIGS_ = { _SUPPORTED_CONFIGS_ = {
'GCC' : ['ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ'], 'GCC' : ['ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ'],
'IAR' : ['ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ'] 'IAR' : ['ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ']
} }
# Files to be complied in the Secure Project # Files to be complied in the Secure Project
_SECURE_FILE_PATHS_ = [ _SECURE_FILE_PATHS_ = [
os.path.join('secure', 'context'), os.path.join('secure', 'context'),
os.path.join('secure', 'context', 'portable', '_COMPILER_ARCH_'), os.path.join('secure', 'context', 'portable', '_COMPILER_ARCH_'),
os.path.join('secure', 'heap'), os.path.join('secure', 'heap'),
os.path.join('secure', 'init'), os.path.join('secure', 'init'),
os.path.join('secure', 'macros') os.path.join('secure', 'macros')
] ]
# Files to be complied in the Non-Secure Project # Files to be complied in the Non-Secure Project
_NONSECURE_FILE_PATHS_ = [ _NONSECURE_FILE_PATHS_ = [
'non_secure', 'non_secure',
os.path.join('non_secure', 'portable', '_COMPILER_ARCH_') os.path.join('non_secure', 'portable', '_COMPILER_ARCH_')
] ]
def is_supported_config(compiler, arch): def is_supported_config(compiler, arch):
return arch in _SUPPORTED_CONFIGS_[compiler] return arch in _SUPPORTED_CONFIGS_[compiler]
def copy_files_in_dir(src_abs_path, dst_abs_path): def copy_files_in_dir(src_abs_path, dst_abs_path):
for src_file in os.listdir(src_abs_path): for src_file in os.listdir(src_abs_path):
src_file_abs_path = os.path.join(src_abs_path, src_file) src_file_abs_path = os.path.join(src_abs_path, src_file)
if os.path.isfile(src_file_abs_path) and src_file != 'ReadMe.txt': if os.path.isfile(src_file_abs_path) and src_file != 'ReadMe.txt':
if not os.path.exists(dst_abs_path): if not os.path.exists(dst_abs_path):
os.makedirs(dst_abs_path) os.makedirs(dst_abs_path)
print('Copying {}...'.format(os.path.basename(src_file_abs_path))) print('Copying {}...'.format(os.path.basename(src_file_abs_path)))
shutil.copy2(src_file_abs_path, dst_abs_path) shutil.copy2(src_file_abs_path, dst_abs_path)
def copy_files_for_compiler_and_arch(compiler, arch, src_paths, dst_path): def copy_files_for_compiler_and_arch(compiler, arch, src_paths, dst_path):
_COMPILER_ARCH_ = os.path.join(compiler, arch) _COMPILER_ARCH_ = os.path.join(compiler, arch)
for src_path in src_paths: for src_path in src_paths:
src_path_sanitized = src_path.replace('_COMPILER_ARCH_', _COMPILER_ARCH_ ) src_path_sanitized = src_path.replace('_COMPILER_ARCH_', _COMPILER_ARCH_ )
src_abs_path = os.path.join(_THIS_FILE_DIRECTORY_, src_path_sanitized) src_abs_path = os.path.join(_THIS_FILE_DIRECTORY_, src_path_sanitized)
dst_abs_path = os.path.join(_FREERTOS_PORTABLE_DIRECTORY_, _COMPILER_ARCH_, dst_path) dst_abs_path = os.path.join(_FREERTOS_PORTABLE_DIRECTORY_, _COMPILER_ARCH_, dst_path)
copy_files_in_dir(src_abs_path, dst_abs_path) copy_files_in_dir(src_abs_path, dst_abs_path)
def copy_files(): def copy_files():
# Copy Secure Files # Copy Secure Files
for compiler in _COMPILERS_: for compiler in _COMPILERS_:
for arch in _ARCH_S_: for arch in _ARCH_S_:
if is_supported_config(compiler, arch): if is_supported_config(compiler, arch):
copy_files_for_compiler_and_arch(compiler, arch, _SECURE_FILE_PATHS_, 'secure') copy_files_for_compiler_and_arch(compiler, arch, _SECURE_FILE_PATHS_, 'secure')
# Copy Non-Secure Files # Copy Non-Secure Files
for compiler in _COMPILERS_: for compiler in _COMPILERS_:
for arch in _ARCH_NS_: for arch in _ARCH_NS_:
if is_supported_config(compiler, arch): if is_supported_config(compiler, arch):
copy_files_for_compiler_and_arch(compiler, arch, _NONSECURE_FILE_PATHS_, 'non_secure') copy_files_for_compiler_and_arch(compiler, arch, _NONSECURE_FILE_PATHS_, 'non_secure')
def main(): def main():
copy_files() copy_files()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View file

@ -1,11 +1,11 @@
This directory tree contains the master copy of the FreeeRTOS Cortex-M33 port. This directory tree contains the master copy of the FreeeRTOS Cortex-M33 port.
Do not use the files located here! These file are copied into separate Do not use the files located here! These file are copied into separate
FreeRTOS/Source/portable/[compiler]/ARM_CM33_NNN directories prior to each FreeRTOS/Source/portable/[compiler]/ARM_CM33_NNN directories prior to each
FreeRTOS release. FreeRTOS release.
If your Cortex-M33 application uses TrustZone then use the files from the If your Cortex-M33 application uses TrustZone then use the files from the
FreeRTOS/Source/portable/[compiler]/ARM_CM33 directories. FreeRTOS/Source/portable/[compiler]/ARM_CM33 directories.
If your Cortex-M33 application does not use TrustZone then use the files from If your Cortex-M33 application does not use TrustZone then use the files from
the FreeRTOS/Source/portable/[compiler]/ARM_CM33_NTZ directories. the FreeRTOS/Source/portable/[compiler]/ARM_CM33_NTZ directories.

File diff suppressed because it is too large Load diff

View file

@ -1,468 +1,453 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Standard includes. */ /* Standard includes. */
#include <stdint.h> #include <stdint.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION
* is defined correctly and privileged functions are placed in correct sections. */ * is defined correctly and privileged functions are placed in correct sections. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* Portasm includes. */ /* Portasm includes. */
#include "portasm.h" #include "portasm.h"
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the
* 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
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" .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"
"xRBARConst2: .word 0xe000ed9c \n" "xRBARConst2: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vResetPrivilege( void ) /* __attribute__ (( naked )) */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" mrs r0, PRIMASK \n" " mrs r0, PRIMASK \n"
" cpsid i \n" " cpsid i \n"
" bx lr \n" " bx lr \n"
::: "memory" ::: "memory"
); );
}
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /*-----------------------------------------------------------*/
/* To avoid compiler warnings. The return statement will never be reached,
* but some compilers warn if it is not included, while others won't compile void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
* if it is. */ {
return 0; __asm volatile
#endif (
} " msr PRIMASK, r0 \n"
/*-----------------------------------------------------------*/ " bx lr \n"
::: "memory"
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ );
{ }
__asm volatile /*-----------------------------------------------------------*/
(
" msr PRIMASK, r0 \n" void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
" bx lr \n" {
::: "memory" __asm volatile
); (
" .syntax unified \n"
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) " .extern SecureContext_SaveContext \n"
/* Just to avoid compiler warning. ulMask is used from the asm code but " .extern SecureContext_LoadContext \n"
* the compiler can't see that. Some compilers generate warnings without " \n"
* the following line, while others generate warnings if the line is " mrs r1, psp \n" /* Read PSP in r1. */
* included. */ " ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
( void ) ulMask; " ldr r0, [r2] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
#endif " \n"
} " cbz r0, save_ns_context \n" /* No secure context to save. */
/*-----------------------------------------------------------*/ " push {r0-r2, r14} \n"
" bl SecureContext_SaveContext \n"
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " pop {r0-r3} \n" /* LR is now in r3. */
{ " mov lr, r3 \n" /* LR = r3. */
__asm volatile " 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. */
" .syntax unified \n" " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" .extern SecureContext_SaveContext \n" " ldr r2, [r3] \n" /* Read pxCurrentTCB. */
" .extern SecureContext_LoadContext \n" #if( configENABLE_MPU == 1 )
" \n" " subs r1, r1, #16 \n" /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
" mrs r1, psp \n" /* Read PSP in r1. */ " str r1, [r2] \n" /* Save the new top of stack in TCB. */
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " mrs r2, psplim \n" /* r2 = PSPLIM. */
" ldr r0, [r2] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ " mrs r3, control \n" /* r3 = CONTROL. */
" \n" " mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
" cbz r0, save_ns_context \n" /* No secure context to save. */ " stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
" push {r0-r2, r14} \n" #else /* configENABLE_MPU */
" bl SecureContext_SaveContext \n" " subs r1, r1, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
" pop {r0-r3} \n" /* LR is now in r3. */ " str r1, [r2] \n" /* Save the new top of stack in TCB. */
" mov lr, r3 \n" /* LR = r3. */ " mrs r2, psplim \n" /* r2 = PSPLIM. */
" 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. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
" 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. */ " stmia r1!, {r0, r2-r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ #endif /* configENABLE_MPU */
" ldr r2, [r3] \n" /* Read pxCurrentTCB. */ " b select_next_task \n"
#if( configENABLE_MPU == 1 ) " \n"
" subs r1, r1, #16 \n" /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " save_ns_context: \n"
" str r1, [r2] \n" /* Save the new top of stack in TCB. */ " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" mrs r2, psplim \n" /* r2 = PSPLIM. */ " ldr r2, [r3] \n" /* Read pxCurrentTCB. */
" mrs r3, control \n" /* r3 = CONTROL. */ #if( configENABLE_MPU == 1 )
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */ " subs r1, r1, #48 \n" /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
" stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " str r1, [r2] \n" /* Save the new top of stack in TCB. */
#else /* configENABLE_MPU */ " adds r1, r1, #16 \n" /* r1 = r1 + 16. */
" subs r1, r1, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ " stmia r1!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */
" str r1, [r2] \n" /* Save the new top of stack in TCB. */ " mov r4, r8 \n" /* r4 = r8. */
" mrs r2, psplim \n" /* r2 = PSPLIM. */ " mov r5, r9 \n" /* r5 = r9. */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " mov r6, r10 \n" /* r6 = r10. */
" stmia r1!, {r0, r2-r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " mov r7, r11 \n" /* r7 = r11. */
#endif /* configENABLE_MPU */ " stmia r1!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
" b select_next_task \n" " mrs r2, psplim \n" /* r2 = PSPLIM. */
" \n" " mrs r3, control \n" /* r3 = CONTROL. */
" save_ns_context: \n" " mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " subs r1, r1, #48 \n" /* r1 = r1 - 48. */
" ldr r2, [r3] \n" /* Read pxCurrentTCB. */ " stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
#if( configENABLE_MPU == 1 ) #else /* configENABLE_MPU */
" subs r1, r1, #48 \n" /* Make space for xSecureContext, PSPLIM, CONTROL, 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, #16 \n" /* r1 = r1 + 16. */ " mrs r2, psplim \n" /* r2 = PSPLIM. */
" stmia r1!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
" mov r4, r8 \n" /* r4 = r8. */ " stmia r1!, {r0, r2-r7} \n" /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */
" mov r5, r9 \n" /* r5 = r9. */ " mov r4, r8 \n" /* r4 = r8. */
" mov r6, r10 \n" /* r6 = r10. */ " mov r5, r9 \n" /* r5 = r9. */
" mov r7, r11 \n" /* r7 = r11. */ " mov r6, r10 \n" /* r6 = r10. */
" stmia r1!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */ " mov r7, r11 \n" /* r7 = r11. */
" mrs r2, psplim \n" /* r2 = PSPLIM. */ " stmia r1!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
" mrs r3, control \n" /* r3 = CONTROL. */ #endif /* configENABLE_MPU */
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */ " \n"
" subs r1, r1, #48 \n" /* r1 = r1 - 48. */ " select_next_task: \n"
" stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " cpsid i \n"
#else /* configENABLE_MPU */ " bl vTaskSwitchContext \n"
" subs r1, r1, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ " cpsie i \n"
" str r1, [r2] \n" /* Save the new top of stack in TCB. */ " \n"
" mrs r2, psplim \n" /* r2 = PSPLIM. */ " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */
" stmia r1!, {r0, r2-r7} \n" /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */
" mov r4, r8 \n" /* r4 = r8. */ " \n"
" mov r5, r9 \n" /* r5 = r9. */ #if( configENABLE_MPU == 1 )
" mov r6, r10 \n" /* r6 = r10. */ " dmb \n" /* Complete outstanding transfers before disabling MPU. */
" mov r7, r11 \n" /* r7 = r11. */ " ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" stmia r1!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */ " ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
#endif /* configENABLE_MPU */ " movs r5, #1 \n" /* r5 = 1. */
" \n" " bics r4, r5 \n" /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
" select_next_task: \n" " str r4, [r2] \n" /* Disable MPU. */
" cpsid i \n" " \n"
" bl vTaskSwitchContext \n" " adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
" cpsie i \n" " ldr r4, [r3] \n" /* r4 = *r3 i.e. r4 = MAIR0. */
" \n" " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " str r4, [r2] \n" /* Program MAIR0. */
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
" ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ " adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
" \n" " movs r5, #4 \n" /* r5 = 4. */
#if( configENABLE_MPU == 1 ) " str r5, [r2] \n" /* Program RNR = 4. */
" dmb \n" /* Complete outstanding transfers before disabling MPU. */ " ldmia r3!, {r6,r7} \n" /* Read first set of RBAR/RLAR from TCB. */
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */ " stmia r4!, {r6,r7} \n" /* Write first set of RBAR/RLAR registers. */
" movs r5, #1 \n" /* r5 = 1. */ " movs r5, #5 \n" /* r5 = 5. */
" bics r4, r5 \n" /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ " str r5, [r2] \n" /* Program RNR = 5. */
" str r4, [r2] \n" /* Disable MPU. */ " ldmia r3!, {r6,r7} \n" /* Read second set of RBAR/RLAR from TCB. */
" \n" " ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ " stmia r4!, {r6,r7} \n" /* Write second set of RBAR/RLAR registers. */
" ldr r4, [r3] \n" /* r4 = *r3 i.e. r4 = MAIR0. */ " movs r5, #6 \n" /* r5 = 6. */
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r5, [r2] \n" /* Program RNR = 6. */
" str r4, [r2] \n" /* Program MAIR0. */ " ldmia r3!, {r6,r7} \n" /* Read third set of RBAR/RLAR from TCB. */
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */ " ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ " stmia r4!, {r6,r7} \n" /* Write third set of RBAR/RLAR registers. */
" movs r5, #4 \n" /* r5 = 4. */ " movs r5, #7 \n" /* r5 = 7. */
" str r5, [r2] \n" /* Program RNR = 4. */ " str r5, [r2] \n" /* Program RNR = 7. */
" ldmia r3!, {r6,r7} \n" /* Read first 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 first set of RBAR/RLAR registers. */ " stmia r4!, {r6,r7} \n" /* Write fourth set of RBAR/RLAR registers. */
" movs r5, #5 \n" /* r5 = 5. */ " \n"
" str r5, [r2] \n" /* Program RNR = 5. */ " ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldmia r3!, {r6,r7} \n" /* Read second set of RBAR/RLAR from TCB. */ " ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */ " movs r5, #1 \n" /* r5 = 1. */
" stmia r4!, {r6,r7} \n" /* Write second set of RBAR/RLAR registers. */ " orrs r4, r5 \n" /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
" movs r5, #6 \n" /* r5 = 6. */ " str r4, [r2] \n" /* Enable MPU. */
" str r5, [r2] \n" /* Program RNR = 6. */ " dsb \n" /* Force memory writes before continuing. */
" ldmia r3!, {r6,r7} \n" /* Read third set of RBAR/RLAR from TCB. */ #endif /* configENABLE_MPU */
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */ " \n"
" stmia r4!, {r6,r7} \n" /* Write third set of RBAR/RLAR registers. */ #if( configENABLE_MPU == 1 )
" movs r5, #7 \n" /* r5 = 7. */ " ldmia r1!, {r0, r2-r4} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */
" str r5, [r2] \n" /* Program RNR = 7. */ " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
" ldmia r3!, {r6,r7} \n" /* Read fourth set of RBAR/RLAR from TCB. */ " msr control, r3 \n" /* Restore the CONTROL register value for the task. */
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */ " mov lr, r4 \n" /* LR = r4. */
" stmia r4!, {r6,r7} \n" /* Write fourth set of RBAR/RLAR registers. */ " ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
" \n" " str r0, [r2] \n" /* Restore the task's xSecureContext. */
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */ " push {r1,r4} \n"
" movs r5, #1 \n" /* r5 = 1. */ " bl SecureContext_LoadContext \n" /* Restore the secure context. */
" orrs r4, r5 \n" /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ " pop {r1,r4} \n"
" str r4, [r2] \n" /* Enable MPU. */ " mov lr, r4 \n" /* LR = r4. */
" dsb \n" /* Force memory writes before continuing. */ " 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. */
#endif /* configENABLE_MPU */ " 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. */
" \n" " msr psp, r1 \n" /* Remember the new top of stack for the task. */
#if( configENABLE_MPU == 1 ) " bx lr \n"
" ldmia r1!, {r0, r2-r4} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ #else /* configENABLE_MPU */
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " ldmia r1!, {r0, r2-r3} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */
" msr control, r3 \n" /* Restore the CONTROL register value for the task. */ " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
" mov lr, r4 \n" /* LR = r4. */ " 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,r4} \n" " push {r1,r3} \n"
" bl SecureContext_LoadContext \n" /* Restore the secure context. */ " bl SecureContext_LoadContext \n" /* Restore the secure context. */
" pop {r1,r4} \n" " pop {r1,r3} \n"
" mov lr, r4 \n" /* LR = r4. */ " mov lr, r3 \n" /* LR = r3. */
" 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, 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"
#else /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" ldmia r1!, {r0, r2-r3} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ " \n"
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " restore_ns_context: \n"
" mov lr, r3 \n" /* LR = r3. */ " adds r1, r1, #16 \n" /* Move to the high registers. */
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldmia r1!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
" str r0, [r2] \n" /* Restore the task's xSecureContext. */ " mov r8, r4 \n" /* r8 = r4. */
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ " mov r9, r5 \n" /* r9 = r5. */
" push {r1,r3} \n" " mov r10, r6 \n" /* r10 = r6. */
" bl SecureContext_LoadContext \n" /* Restore the secure context. */ " mov r11, r7 \n" /* r11 = r7. */
" pop {r1,r3} \n" " msr psp, r1 \n" /* Remember the new top of stack for the task. */
" mov lr, r3 \n" /* LR = r3. */ " subs r1, r1, #32 \n" /* Go back to the low registers. */
" 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. */ " ldmia r1!, {r4-r7} \n" /* Restore the low registers that are not automatically restored. */
" 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. */ " bx lr \n"
" msr psp, r1 \n" /* Remember the new top of stack for the task. */ " \n"
" bx lr \n" " .align 4 \n"
#endif /* configENABLE_MPU */ "pxCurrentTCBConst: .word pxCurrentTCB \n"
" \n" "xSecureContextConst: .word xSecureContext \n"
" restore_ns_context: \n" #if( configENABLE_MPU == 1 )
" adds r1, r1, #16 \n" /* Move to the high registers. */ "xMPUCTRLConst: .word 0xe000ed94 \n"
" ldmia r1!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */ "xMAIR0Const: .word 0xe000edc0 \n"
" mov r8, r4 \n" /* r8 = r4. */ "xRNRConst: .word 0xe000ed98 \n"
" mov r9, r5 \n" /* r9 = r5. */ "xRBARConst: .word 0xe000ed9c \n"
" mov r10, r6 \n" /* r10 = r6. */ #endif /* configENABLE_MPU */
" mov r11, r7 \n" /* r11 = r7. */ );
" msr psp, r1 \n" /* Remember the new top of stack for the task. */ }
" 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. */
" bx lr \n" void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
" \n" {
" .align 4 \n" __asm volatile
"pxCurrentTCBConst: .word pxCurrentTCB \n" (
"xSecureContextConst: .word xSecureContext \n" " movs r0, #4 \n"
#if( configENABLE_MPU == 1 ) " mov r1, lr \n"
"xMPUCTRLConst: .word 0xe000ed94 \n" " tst r0, r1 \n"
"xMAIR0Const: .word 0xe000edc0 \n" " beq stacking_used_msp \n"
"xRNRConst: .word 0xe000ed98 \n" " mrs r0, psp \n"
"xRBARConst: .word 0xe000ed9c \n" " ldr r2, svchandler_address_const \n"
#endif /* configENABLE_MPU */ " bx r2 \n"
); " stacking_used_msp: \n"
} " mrs r0, msp \n"
/*-----------------------------------------------------------*/ " ldr r2, svchandler_address_const \n"
" bx r2 \n"
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " \n"
{ " .align 4 \n"
__asm volatile "svchandler_address_const: .word vPortSVCHandler_C \n"
( );
" movs r0, #4 \n" }
" mov r1, lr \n" /*-----------------------------------------------------------*/
" tst r0, r1 \n"
" beq stacking_used_msp \n" void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */
" mrs r0, psp \n" {
" ldr r2, svchandler_address_const \n" __asm volatile
" bx r2 \n" (
" stacking_used_msp: \n" " svc %0 \n" /* Secure context is allocated in the supervisor call. */
" mrs r0, msp \n" " bx lr \n" /* Return. */
" ldr r2, svchandler_address_const \n" :: "i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
" bx r2 \n" );
" \n" }
" .align 4 \n" /*-----------------------------------------------------------*/
"svchandler_address_const: .word vPortSVCHandler_C \n"
); void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
} {
/*-----------------------------------------------------------*/ __asm volatile
(
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ " 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. */
__asm volatile " cmp r0, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
( " beq free_secure_context \n"
" svc %0 \n" /* Secure context is allocated in the supervisor call. */ " bx lr \n" /* There is no secure context (xSecureContext is NULL). */
" bx lr \n" /* Return. */ " free_secure_context: \n"
:: "i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory" " svc %0 \n" /* Secure context is freed in the supervisor call. */
); " bx lr \n" /* Return. */
} :: "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
/*-----------------------------------------------------------*/ );
}
void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ /*-----------------------------------------------------------*/
{
__asm volatile
(
" 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. */
" cmp r0, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
" beq free_secure_context \n"
" bx lr \n" /* There is no secure context (xSecureContext is NULL). */
" free_secure_context: \n"
" svc %0 \n" /* Secure context is freed in the supervisor call. */
" bx lr \n" /* Return. */
:: "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
);
}
/*-----------------------------------------------------------*/

View file

@ -1,299 +1,301 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#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.
* *
* The settings in this file configure FreeRTOS correctly for the given hardware * The settings in this file configure FreeRTOS correctly for the given hardware
* and compiler. * and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
*/ */
#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 void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #if( configENABLE_TRUSTZONE == 1 )
#endif /* configENABLE_TRUSTZONE */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_MPU == 1 ) #endif /* configENABLE_TRUSTZONE */
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #if( configENABLE_MPU == 1 )
#endif /* configENABLE_MPU */ extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
/*-----------------------------------------------------------*/ extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief MPU specific constants.
*/ /**
#if( configENABLE_MPU == 1 ) * @brief MPU specific constants.
#define portUSING_MPU_WRAPPERS 1 */
#define portPRIVILEGE_BIT ( 0x80000000UL ) #if( configENABLE_MPU == 1 )
#else #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#endif /* configENABLE_MPU */ #else
#define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */
/* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) /* MPU regions. */
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portSTACK_REGION ( 4UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portSTACK_REGION ( 4UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
/* Device memory attributes used in MPU_MAIR registers. #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
*
* 8-bit values encoded as follows: /* Device memory attributes used in MPU_MAIR registers.
* Bit[7:4] - 0000 - Device Memory *
* Bit[3:2] - 00 --> Device-nGnRnE * 8-bit values encoded as follows:
* 01 --> Device-nGnRE * Bit[7:4] - 0000 - Device Memory
* 10 --> Device-nGRE * Bit[3:2] - 00 --> Device-nGnRnE
* 11 --> Device-GRE * 01 --> Device-nGnRE
* Bit[1:0] - 00, Reserved. * 10 --> Device-nGRE
*/ * 11 --> Device-GRE
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ * Bit[1:0] - 00, Reserved.
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
/* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
#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. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
/* Attributes used in MPU_RBAR registers. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
/*-----------------------------------------------------------*/
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/** /*-----------------------------------------------------------*/
* @brief Settings to define an MPU region.
*/ /**
typedef struct MPURegionSettings * @brief Settings to define an MPU region.
{ */
uint32_t ulRBAR; /**< RBAR for the region. */ typedef struct MPURegionSettings
uint32_t ulRLAR; /**< RLAR for the region. */ {
} MPURegionSettings_t; uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */
/** } MPURegionSettings_t;
* @brief MPU settings as stored in the TCB.
*/ /**
typedef struct MPU_SETTINGS * @brief MPU settings as stored in the TCB.
{ */
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ typedef struct MPU_SETTINGS
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ {
} xMPU_SETTINGS; 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. */
} xMPU_SETTINGS;
/** /*-----------------------------------------------------------*/
* @brief SVC numbers.
*/ /**
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 * @brief SVC numbers.
#define portSVC_FREE_SECURE_CONTEXT 1 */
#define portSVC_START_SCHEDULER 2 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_FREE_SECURE_CONTEXT 1
/*-----------------------------------------------------------*/ #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3
/** /*-----------------------------------------------------------*/
* @brief Scheduler utilities.
*/ /**
#define portYIELD() vPortYield() * @brief Scheduler utilities.
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) */
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portYIELD() vPortYield()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
/*-----------------------------------------------------------*/ #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/** /*-----------------------------------------------------------*/
* @brief Critical section management.
*/ /**
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() * @brief Critical section management.
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) */
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portENTER_CRITICAL() vPortEnterCritical() #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portEXIT_CRITICAL() vPortExitCritical() #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
/*-----------------------------------------------------------*/ #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/** /*-----------------------------------------------------------*/
* @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ /**
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) * @brief Task function macros as described on the FreeRTOS.org WEB site.
#define portTASK_FUNCTION( 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 )
#if( configENABLE_TRUSTZONE == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Allocate a secure context for the task. #if( configENABLE_TRUSTZONE == 1 )
* /**
* Tasks are not created with a secure context. Any task that is going to call * @brief Allocate a secure context for the task.
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a *
* secure context before it calls any secure function. * Tasks are not created with a secure context. Any task that is going to call
* * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * secure context before it calls any secure function.
*/ *
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/
/** #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
* @brief Called when a task is deleted to delete the task's secure context,
* if it has one. /**
* * @brief Called when a task is deleted to delete the task's secure context,
* @param[in] pxTCB The TCB of the task being deleted. * if it has one.
*/ *
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) * @param[in] pxTCB The TCB of the task being deleted.
#else */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#define portCLEAN_UP_TCB( pxTCB ) #else
#endif /* configENABLE_TRUSTZONE */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
/*-----------------------------------------------------------*/ #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */
#if( configENABLE_MPU == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Checks whether or not the processor is privileged. #if( configENABLE_MPU == 1 )
* /**
* @return 1 if the processor is already privileged, 0 otherwise. * @brief Checks whether or not the processor is privileged.
*/ *
#define portIS_PRIVILEGED() xIsPrivileged() * @return 1 if the processor is already privileged, 0 otherwise.
*/
/** #define portIS_PRIVILEGED() xIsPrivileged()
* @brief Raise an SVC request to raise privilege.
* /**
* The SVC handler checks that the SVC was raised from a system call and only * @brief Raise an SVC request to raise privilege.
* then it raises the privilege. If this is called from any other place, *
* the privilege is not raised. * 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,
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); * the privilege is not raised.
*/
/** #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
* register. /**
*/ * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
#define portRESET_PRIVILEGE() vResetPrivilege() * register.
#else */
#define portIS_PRIVILEGED() #define portRESET_PRIVILEGE() vResetPrivilege()
#define portRAISE_PRIVILEGE() #else
#define portRESET_PRIVILEGE() #define portIS_PRIVILEGED()
#endif /* configENABLE_MPU */ #define portRAISE_PRIVILEGE()
/*-----------------------------------------------------------*/ #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief Barriers.
*/ /**
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) * @brief Barriers.
/*-----------------------------------------------------------*/ */
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
#ifdef __cplusplus /*-----------------------------------------------------------*/
}
#endif #ifdef __cplusplus
}
#endif /* PORTMACRO_H */ #endif
#endif /* PORTMACRO_H */

View file

@ -1,381 +1,366 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Standard includes. */ /* Standard includes. */
#include <stdint.h> #include <stdint.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION
* is defined correctly and privileged functions are placed in correct sections. */ * is defined correctly and privileged functions are placed in correct sections. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* Portasm includes. */ /* Portasm includes. */
#include "portasm.h" #include "portasm.h"
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the
* 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
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" .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"
"xRBARConst2: .word 0xe000ed9c \n" "xRBARConst2: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vResetPrivilege( void ) /* __attribute__ (( naked )) */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" mrs r0, PRIMASK \n" " mrs r0, PRIMASK \n"
" cpsid i \n" " cpsid i \n"
" bx lr \n" " bx lr \n"
::: "memory" ::: "memory"
); );
}
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /*-----------------------------------------------------------*/
/* To avoid compiler warnings. The return statement will never be reached,
* but some compilers warn if it is not included, while others won't compile void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
* if it is. */ {
return 0; __asm volatile
#endif (
} " msr PRIMASK, r0 \n"
/*-----------------------------------------------------------*/ " bx lr \n"
::: "memory"
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ );
{ }
__asm volatile /*-----------------------------------------------------------*/
(
" msr PRIMASK, r0 \n" void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
" bx lr \n" {
::: "memory" __asm volatile
); (
" .syntax unified \n"
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) " \n"
/* Just to avoid compiler warning. ulMask is used from the asm code but " mrs r0, psp \n" /* Read PSP in r0. */
* the compiler can't see that. Some compilers generate warnings without " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
* the following line, while others generate warnings if the line is " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
* included. */ #if( configENABLE_MPU == 1 )
( void ) ulMask; " subs r0, r0, #44 \n" /* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */
#endif " str r0, [r1] \n" /* Save the new top of stack in TCB. */
} " mrs r1, psplim \n" /* r1 = PSPLIM. */
/*-----------------------------------------------------------*/ " mrs r2, control \n" /* r2 = CONTROL. */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " 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. */
__asm volatile " mov r5, r9 \n" /* r5 = r9. */
( " mov r6, r10 \n" /* r6 = r10. */
" .syntax unified \n" " mov r7, r11 \n" /* r7 = r11. */
" \n" " stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
" mrs r0, psp \n" /* Read PSP in r0. */ #else /* configENABLE_MPU */
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " subs r0, r0, #40 \n" /* Make space for PSPLIM, LR and the remaining registers on the stack. */
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */
#if( configENABLE_MPU == 1 ) " mrs r2, psplim \n" /* r2 = PSPLIM. */
" subs r0, r0, #44 \n" /* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
" str r0, [r1] \n" /* Save the new top of stack in TCB. */ " stmia r0!, {r2-r7} \n" /* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
" mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r4, r8 \n" /* r4 = r8. */
" mrs r2, control \n" /* r2 = CONTROL. */ " mov r5, r9 \n" /* r5 = r9. */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " mov r6, r10 \n" /* r6 = r10. */
" stmia r0!, {r1-r7} \n" /* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */ " mov r7, r11 \n" /* r7 = r11. */
" mov r4, r8 \n" /* r4 = r8. */ " stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
" mov r5, r9 \n" /* r5 = r9. */ #endif /* configENABLE_MPU */
" mov r6, r10 \n" /* r6 = r10. */ " \n"
" mov r7, r11 \n" /* r7 = r11. */ " cpsid i \n"
" stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */ " bl vTaskSwitchContext \n"
#else /* configENABLE_MPU */ " cpsie i \n"
" subs r0, r0, #40 \n" /* Make space for PSPLIM, LR and the remaining registers on the stack. */ " \n"
" str r0, [r1] \n" /* Save the new top of stack in TCB. */ " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" mrs r2, psplim \n" /* r2 = PSPLIM. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
" stmia r0!, {r2-r7} \n" /* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */ " \n"
" mov r4, r8 \n" /* r4 = r8. */ #if( configENABLE_MPU == 1 )
" mov r5, r9 \n" /* r5 = r9. */ " dmb \n" /* Complete outstanding transfers before disabling MPU. */
" mov r6, r10 \n" /* r6 = r10. */ " ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" mov r7, r11 \n" /* r7 = r11. */ " ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
" stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */ " movs r4, #1 \n" /* r4 = 1. */
#endif /* configENABLE_MPU */ " bics r3, r4 \n" /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
" \n" " str r3, [r2] \n" /* Disable MPU. */
" cpsid i \n" " \n"
" bl vTaskSwitchContext \n" " adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
" cpsie i \n" " ldr r4, [r1] \n" /* r4 = *r1 i.e. r4 = MAIR0. */
" \n" " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " str r4, [r2] \n" /* Program MAIR0. */
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
" \n" " movs r4, #4 \n" /* r4 = 4. */
#if( configENABLE_MPU == 1 ) " str r4, [r2] \n" /* Program RNR = 4. */
" dmb \n" /* Complete outstanding transfers before disabling MPU. */ " ldmia r1!, {r5,r6} \n" /* Read first set of RBAR/RLAR from TCB. */
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */ " stmia r3!, {r5,r6} \n" /* Write first set of RBAR/RLAR registers. */
" movs r4, #1 \n" /* r4 = 1. */ " movs r4, #5 \n" /* r4 = 5. */
" bics r3, r4 \n" /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ " str r4, [r2] \n" /* Program RNR = 5. */
" str r3, [r2] \n" /* Disable MPU. */ " ldmia r1!, {r5,r6} \n" /* Read second set of RBAR/RLAR from TCB. */
" \n" " ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " stmia r3!, {r5,r6} \n" /* Write second set of RBAR/RLAR registers. */
" ldr r4, [r1] \n" /* r4 = *r1 i.e. r4 = MAIR0. */ " movs r4, #6 \n" /* r4 = 6. */
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " str r4, [r2] \n" /* Program RNR = 6. */
" str r4, [r2] \n" /* Program MAIR0. */ " ldmia r1!, {r5,r6} \n" /* Read third set of RBAR/RLAR from TCB. */
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */ " ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " stmia r3!, {r5,r6} \n" /* Write third set of RBAR/RLAR registers. */
" movs r4, #4 \n" /* r4 = 4. */ " movs r4, #7 \n" /* r4 = 7. */
" str r4, [r2] \n" /* Program RNR = 4. */ " str r4, [r2] \n" /* Program RNR = 7. */
" ldmia r1!, {r5,r6} \n" /* Read first 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 first set of RBAR/RLAR registers. */ " stmia r3!, {r5,r6} \n" /* Write fourth set of RBAR/RLAR registers. */
" movs r4, #5 \n" /* r4 = 5. */ " \n"
" str r4, [r2] \n" /* Program RNR = 5. */ " ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldmia r1!, {r5,r6} \n" /* Read second set of RBAR/RLAR from TCB. */ " ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */ " movs r4, #1 \n" /* r4 = 1. */
" stmia r3!, {r5,r6} \n" /* Write second set of RBAR/RLAR registers. */ " orrs r3, r4 \n" /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
" movs r4, #6 \n" /* r4 = 6. */ " str r3, [r2] \n" /* Enable MPU. */
" str r4, [r2] \n" /* Program RNR = 6. */ " dsb \n" /* Force memory writes before continuing. */
" ldmia r1!, {r5,r6} \n" /* Read third set of RBAR/RLAR from TCB. */ #endif /* configENABLE_MPU */
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */ " \n"
" stmia r3!, {r5,r6} \n" /* Write third set of RBAR/RLAR registers. */ #if( configENABLE_MPU == 1 )
" movs r4, #7 \n" /* r4 = 7. */ " adds r0, r0, #28 \n" /* Move to the high registers. */
" str r4, [r2] \n" /* Program RNR = 7. */ " ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
" ldmia r1!, {r5,r6} \n" /* Read fourth set of RBAR/RLAR from TCB. */ " mov r8, r4 \n" /* r8 = r4. */
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */ " mov r9, r5 \n" /* r9 = r5. */
" stmia r3!, {r5,r6} \n" /* Write fourth set of RBAR/RLAR registers. */ " mov r10, r6 \n" /* r10 = r6. */
" \n" " mov r11, r7 \n" /* r11 = r7. */
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */ " subs r0, r0, #44 \n" /* Move to the starting of the saved context. */
" movs r4, #1 \n" /* r4 = 1. */ " ldmia r0!, {r1-r7} \n" /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */
" orrs r3, r4 \n" /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */
" str r3, [r2] \n" /* Enable MPU. */ " msr control, r2 \n" /* Restore the CONTROL register value for the task. */
" dsb \n" /* Force memory writes before continuing. */ " bx r3 \n"
#endif /* configENABLE_MPU */ #else /* configENABLE_MPU */
" \n" " adds r0, r0, #24 \n" /* Move to the high registers. */
#if( configENABLE_MPU == 1 ) " ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
" adds r0, r0, #28 \n" /* Move to the high registers. */ " mov r8, r4 \n" /* r8 = r4. */
" ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */ " mov r9, r5 \n" /* r9 = r5. */
" mov r8, r4 \n" /* r8 = r4. */ " mov r10, r6 \n" /* r10 = r6. */
" mov r9, r5 \n" /* r9 = r5. */ " mov r11, r7 \n" /* r11 = r7. */
" mov r10, r6 \n" /* r10 = r6. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */
" mov r11, r7 \n" /* r11 = r7. */ " subs r0, r0, #40 \n" /* Move to the starting of the saved context. */
" msr psp, r0 \n" /* Remember the new top of stack for the task. */ " ldmia r0!, {r2-r7} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
" subs r0, r0, #44 \n" /* Move to the starting of the saved context. */ " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
" ldmia r0!, {r1-r7} \n" /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */ " bx r3 \n"
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ #endif /* configENABLE_MPU */
" msr control, r2 \n" /* Restore the CONTROL register value for the task. */ " \n"
" bx r3 \n" " .align 4 \n"
#else /* configENABLE_MPU */ "pxCurrentTCBConst: .word pxCurrentTCB \n"
" adds r0, r0, #24 \n" /* Move to the high registers. */ #if( configENABLE_MPU == 1 )
" ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */ "xMPUCTRLConst: .word 0xe000ed94 \n"
" mov r8, r4 \n" /* r8 = r4. */ "xMAIR0Const: .word 0xe000edc0 \n"
" mov r9, r5 \n" /* r9 = r5. */ "xRNRConst: .word 0xe000ed98 \n"
" mov r10, r6 \n" /* r10 = r6. */ "xRBARConst: .word 0xe000ed9c \n"
" mov r11, r7 \n" /* r11 = r7. */ #endif /* configENABLE_MPU */
" 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. */ }
" 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. */
" bx r3 \n" void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
#endif /* configENABLE_MPU */ {
" \n" __asm volatile
" .align 4 \n" (
"pxCurrentTCBConst: .word pxCurrentTCB \n" " movs r0, #4 \n"
#if( configENABLE_MPU == 1 ) " mov r1, lr \n"
"xMPUCTRLConst: .word 0xe000ed94 \n" " tst r0, r1 \n"
"xMAIR0Const: .word 0xe000edc0 \n" " beq stacking_used_msp \n"
"xRNRConst: .word 0xe000ed98 \n" " mrs r0, psp \n"
"xRBARConst: .word 0xe000ed9c \n" " ldr r2, svchandler_address_const \n"
#endif /* configENABLE_MPU */ " bx r2 \n"
); " stacking_used_msp: \n"
} " mrs r0, msp \n"
/*-----------------------------------------------------------*/ " ldr r2, svchandler_address_const \n"
" bx r2 \n"
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " \n"
{ " .align 4 \n"
__asm volatile "svchandler_address_const: .word vPortSVCHandler_C \n"
( );
" movs r0, #4 \n" }
" mov r1, lr \n" /*-----------------------------------------------------------*/
" tst r0, r1 \n"
" beq stacking_used_msp \n"
" mrs r0, psp \n"
" ldr r2, svchandler_address_const \n"
" bx r2 \n"
" stacking_used_msp: \n"
" mrs r0, msp \n"
" ldr r2, svchandler_address_const \n"
" bx r2 \n"
" \n"
" .align 4 \n"
"svchandler_address_const: .word vPortSVCHandler_C \n"
);
}
/*-----------------------------------------------------------*/

View file

@ -1,299 +1,301 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#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.
* *
* The settings in this file configure FreeRTOS correctly for the given hardware * The settings in this file configure FreeRTOS correctly for the given hardware
* and compiler. * and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
*/ */
#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 void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #if( configENABLE_TRUSTZONE == 1 )
#endif /* configENABLE_TRUSTZONE */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_MPU == 1 ) #endif /* configENABLE_TRUSTZONE */
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #if( configENABLE_MPU == 1 )
#endif /* configENABLE_MPU */ extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
/*-----------------------------------------------------------*/ extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief MPU specific constants.
*/ /**
#if( configENABLE_MPU == 1 ) * @brief MPU specific constants.
#define portUSING_MPU_WRAPPERS 1 */
#define portPRIVILEGE_BIT ( 0x80000000UL ) #if( configENABLE_MPU == 1 )
#else #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#endif /* configENABLE_MPU */ #else
#define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */
/* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) /* MPU regions. */
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portSTACK_REGION ( 4UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portSTACK_REGION ( 4UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
/* Device memory attributes used in MPU_MAIR registers. #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
*
* 8-bit values encoded as follows: /* Device memory attributes used in MPU_MAIR registers.
* Bit[7:4] - 0000 - Device Memory *
* Bit[3:2] - 00 --> Device-nGnRnE * 8-bit values encoded as follows:
* 01 --> Device-nGnRE * Bit[7:4] - 0000 - Device Memory
* 10 --> Device-nGRE * Bit[3:2] - 00 --> Device-nGnRnE
* 11 --> Device-GRE * 01 --> Device-nGnRE
* Bit[1:0] - 00, Reserved. * 10 --> Device-nGRE
*/ * 11 --> Device-GRE
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ * Bit[1:0] - 00, Reserved.
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
/* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
#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. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
/* Attributes used in MPU_RBAR registers. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
/*-----------------------------------------------------------*/
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/** /*-----------------------------------------------------------*/
* @brief Settings to define an MPU region.
*/ /**
typedef struct MPURegionSettings * @brief Settings to define an MPU region.
{ */
uint32_t ulRBAR; /**< RBAR for the region. */ typedef struct MPURegionSettings
uint32_t ulRLAR; /**< RLAR for the region. */ {
} MPURegionSettings_t; uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */
/** } MPURegionSettings_t;
* @brief MPU settings as stored in the TCB.
*/ /**
typedef struct MPU_SETTINGS * @brief MPU settings as stored in the TCB.
{ */
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ typedef struct MPU_SETTINGS
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ {
} xMPU_SETTINGS; 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. */
} xMPU_SETTINGS;
/** /*-----------------------------------------------------------*/
* @brief SVC numbers.
*/ /**
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 * @brief SVC numbers.
#define portSVC_FREE_SECURE_CONTEXT 1 */
#define portSVC_START_SCHEDULER 2 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_FREE_SECURE_CONTEXT 1
/*-----------------------------------------------------------*/ #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3
/** /*-----------------------------------------------------------*/
* @brief Scheduler utilities.
*/ /**
#define portYIELD() vPortYield() * @brief Scheduler utilities.
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) */
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portYIELD() vPortYield()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
/*-----------------------------------------------------------*/ #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/** /*-----------------------------------------------------------*/
* @brief Critical section management.
*/ /**
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() * @brief Critical section management.
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) */
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portENTER_CRITICAL() vPortEnterCritical() #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portEXIT_CRITICAL() vPortExitCritical() #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
/*-----------------------------------------------------------*/ #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/** /*-----------------------------------------------------------*/
* @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ /**
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) * @brief Task function macros as described on the FreeRTOS.org WEB site.
#define portTASK_FUNCTION( 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 )
#if( configENABLE_TRUSTZONE == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Allocate a secure context for the task. #if( configENABLE_TRUSTZONE == 1 )
* /**
* Tasks are not created with a secure context. Any task that is going to call * @brief Allocate a secure context for the task.
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a *
* secure context before it calls any secure function. * Tasks are not created with a secure context. Any task that is going to call
* * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * secure context before it calls any secure function.
*/ *
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/
/** #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
* @brief Called when a task is deleted to delete the task's secure context,
* if it has one. /**
* * @brief Called when a task is deleted to delete the task's secure context,
* @param[in] pxTCB The TCB of the task being deleted. * if it has one.
*/ *
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) * @param[in] pxTCB The TCB of the task being deleted.
#else */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#define portCLEAN_UP_TCB( pxTCB ) #else
#endif /* configENABLE_TRUSTZONE */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
/*-----------------------------------------------------------*/ #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */
#if( configENABLE_MPU == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Checks whether or not the processor is privileged. #if( configENABLE_MPU == 1 )
* /**
* @return 1 if the processor is already privileged, 0 otherwise. * @brief Checks whether or not the processor is privileged.
*/ *
#define portIS_PRIVILEGED() xIsPrivileged() * @return 1 if the processor is already privileged, 0 otherwise.
*/
/** #define portIS_PRIVILEGED() xIsPrivileged()
* @brief Raise an SVC request to raise privilege.
* /**
* The SVC handler checks that the SVC was raised from a system call and only * @brief Raise an SVC request to raise privilege.
* then it raises the privilege. If this is called from any other place, *
* the privilege is not raised. * 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,
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); * the privilege is not raised.
*/
/** #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
* register. /**
*/ * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
#define portRESET_PRIVILEGE() vResetPrivilege() * register.
#else */
#define portIS_PRIVILEGED() #define portRESET_PRIVILEGE() vResetPrivilege()
#define portRAISE_PRIVILEGE() #else
#define portRESET_PRIVILEGE() #define portIS_PRIVILEGED()
#endif /* configENABLE_MPU */ #define portRAISE_PRIVILEGE()
/*-----------------------------------------------------------*/ #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief Barriers.
*/ /**
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) * @brief Barriers.
/*-----------------------------------------------------------*/ */
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
#ifdef __cplusplus /*-----------------------------------------------------------*/
}
#endif #ifdef __cplusplus
}
#endif /* PORTMACRO_H */ #endif
#endif /* PORTMACRO_H */

View file

@ -1,415 +1,410 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Standard includes. */ /* Standard includes. */
#include <stdint.h> #include <stdint.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION
* is defined correctly and privileged functions are placed in correct sections. */ * is defined correctly and privileged functions are placed in correct sections. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* Portasm includes. */ /* Portasm includes. */
#include "portasm.h" #include "portasm.h"
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the
* header files. */ * header files. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" .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"
"xRBARConst2: .word 0xe000ed9c \n" "xRBARConst2: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vResetPrivilege( void ) /* __attribute__ (( naked )) */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" mrs r0, PRIMASK \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
" cpsid i \n" " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" bx lr \n" " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
::: "memory" " dsb \n"
); " isb \n"
" bx lr \n" /* Return. */
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) :: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
/* To avoid compiler warnings. The return statement will never be reached, );
* but some compilers warn if it is not included, while others won't compile }
* if it is. */ /*-----------------------------------------------------------*/
return 0;
#endif void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
} {
/*-----------------------------------------------------------*/ __asm volatile
(
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ " msr basepri, r0 \n" /* basepri = ulMask. */
{ " dsb \n"
__asm volatile " isb \n"
( " bx lr \n" /* Return. */
" msr PRIMASK, r0 \n" ::: "memory"
" bx lr \n" );
::: "memory" }
); /*-----------------------------------------------------------*/
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
/* Just to avoid compiler warning. ulMask is used from the asm code but {
* the compiler can't see that. Some compilers generate warnings without __asm volatile
* the following line, while others generate warnings if the line is (
* included. */ " .syntax unified \n"
( void ) ulMask; " .extern SecureContext_SaveContext \n"
#endif " .extern SecureContext_LoadContext \n"
} " \n"
/*-----------------------------------------------------------*/ " mrs r1, psp \n" /* Read PSP in r1. */
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ldr r0, [r2] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
{ " \n"
__asm volatile " cbz r0, save_ns_context \n" /* No secure context to save. */
( " push {r0-r2, r14} \n"
" .syntax unified \n" " bl SecureContext_SaveContext \n"
" .extern SecureContext_SaveContext \n" " pop {r0-r3} \n" /* LR is now in r3. */
" .extern SecureContext_LoadContext \n" " mov lr, r3 \n" /* LR = r3. */
" \n" " 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. */
" mrs r1, psp \n" /* Read PSP in r1. */ " 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 r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r0, [r2] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ " ldr r2, [r3] \n" /* Read pxCurrentTCB. */
" \n" #if( configENABLE_MPU == 1 )
" cbz r0, save_ns_context \n" /* No secure context to save. */ " subs r1, r1, #16 \n" /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
" push {r0-r2, r14} \n" " str r1, [r2] \n" /* Save the new top of stack in TCB. */
" bl SecureContext_SaveContext \n" " mrs r2, psplim \n" /* r2 = PSPLIM. */
" pop {r0-r3} \n" /* LR is now in r3. */ " mrs r3, control \n" /* r3 = CONTROL. */
" mov lr, r3 \n" /* LR = r3. */ " mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
" 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. */ " stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
" 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. */ #else /* configENABLE_MPU */
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " subs r1, r1, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
" ldr r2, [r3] \n" /* Read pxCurrentTCB. */ " str r1, [r2] \n" /* Save the new top of stack in TCB. */
#if( configENABLE_MPU == 1 ) " mrs r2, psplim \n" /* r2 = PSPLIM. */
" subs r1, r1, #16 \n" /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
" str r1, [r2] \n" /* Save the new top of stack in TCB. */ " stmia r1!, {r0, r2-r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
" mrs r2, psplim \n" /* r2 = PSPLIM. */ #endif /* configENABLE_MPU */
" mrs r3, control \n" /* r3 = CONTROL. */ " b select_next_task \n"
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */ " \n"
" stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " save_ns_context: \n"
#else /* configENABLE_MPU */ " ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" subs r1, r1, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ " ldr r2, [r3] \n" /* Read pxCurrentTCB. */
" str r1, [r2] \n" /* Save the new top of stack in TCB. */ #if( configENABLE_FPU == 1 )
" mrs r2, psplim \n" /* r2 = PSPLIM. */ " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " it eq \n"
" stmia r1!, {r0, r2-r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " vstmdbeq r1!, {s16-s31} \n" /* Store the FPU registers which are not saved automatically. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_FPU */
" b select_next_task \n" #if( configENABLE_MPU == 1 )
" \n" " subs r1, r1, #48 \n" /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
" save_ns_context: \n" " str r1, [r2] \n" /* Save the new top of stack in TCB. */
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " adds r1, r1, #16 \n" /* r1 = r1 + 16. */
" ldr r2, [r3] \n" /* Read pxCurrentTCB. */ " stm r1, {r4-r11} \n" /* Store the registers that are not saved automatically. */
#if( configENABLE_FPU == 1 ) " mrs r2, psplim \n" /* r2 = PSPLIM. */
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ " mrs r3, control \n" /* r3 = CONTROL. */
" it eq \n" " mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
" vstmdbeq r1!, {s16-s31} \n" /* Store the FPU registers which are not saved automatically. */ " subs r1, r1, #16 \n" /* r1 = r1 - 16. */
#endif /* configENABLE_FPU */ " stm r1, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
#if( configENABLE_MPU == 1 ) #else /* configENABLE_MPU */
" subs r1, r1, #48 \n" /* Make space for xSecureContext, PSPLIM, CONTROL, 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, #16 \n" /* r1 = r1 + 16. */ " 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. */
" mrs r3, control \n" /* r3 = CONTROL. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */ " subs r1, r1, #12 \n" /* r1 = r1 - 12. */
" subs r1, r1, #16 \n" /* r1 = r1 - 16. */ " stmia r1!, {r0, r2-r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
" stm r1, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #endif /* configENABLE_MPU */
#else /* configENABLE_MPU */ " \n"
" subs r1, r1, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ " select_next_task: \n"
" str r1, [r2] \n" /* Save the new top of stack in TCB. */ " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
" adds r1, r1, #12 \n" /* r1 = r1 + 12. */ " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" stm r1, {r4-r11} \n" /* Store the registers that are not saved automatically. */ " dsb \n"
" mrs r2, psplim \n" /* r2 = PSPLIM. */ " isb \n"
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " bl vTaskSwitchContext \n"
" subs r1, r1, #12 \n" /* r1 = r1 - 12. */ " mov r0, #0 \n" /* r0 = 0. */
" stmia r1!, {r0, r2-r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " msr basepri, r0 \n" /* Enable interrupts. */
#endif /* configENABLE_MPU */ " \n"
" \n" " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" select_next_task: \n" " ldr r3, [r2] \n" /* Read pxCurrentTCB. */
" cpsid i \n" " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */
" bl vTaskSwitchContext \n" " \n"
" cpsie i \n" #if( configENABLE_MPU == 1 )
" \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
" ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ " bic r4, #1 \n" /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
" \n" " str r4, [r2] \n" /* Disable MPU. */
#if( configENABLE_MPU == 1 ) " \n"
" dmb \n" /* Complete outstanding transfers before disabling MPU. */ " adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r4, [r3] \n" /* r4 = *r3 i.e. r4 = MAIR0. */
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */ " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
" bic r4, #1 \n" /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r4, [r2] \n" /* Program MAIR0. */
" str r4, [r2] \n" /* Disable MPU. */ " ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
" \n" " movs r4, #4 \n" /* r4 = 4. */
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ " str r4, [r2] \n" /* Program RNR = 4. */
" ldr r4, [r3] \n" /* r4 = *r3 i.e. r4 = MAIR0. */ " adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
" str r4, [r2] \n" /* Program MAIR0. */ " ldmia r3!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */ " stmia r2!, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r4, #4 \n" /* r4 = 4. */ " \n"
" str r4, [r2] \n" /* Program RNR = 4. */ " ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ " ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " orr r4, #1 \n" /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
" ldmia r3!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " str r4, [r2] \n" /* Enable MPU. */
" stmia r2!, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " dsb \n" /* Force memory writes before continuing. */
" \n" #endif /* configENABLE_MPU */
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " \n"
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */ #if( configENABLE_MPU == 1 )
" orr r4, #1 \n" /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " ldmia r1!, {r0, r2-r4} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */
" str r4, [r2] \n" /* Enable MPU. */ " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
" dsb \n" /* Force memory writes before continuing. */ " msr control, r3 \n" /* Restore the CONTROL register value for the task. */
#endif /* configENABLE_MPU */ " mov lr, r4 \n" /* LR = r4. */
" \n" " ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
#if( configENABLE_MPU == 1 ) " str r0, [r2] \n" /* Restore the task's xSecureContext. */
" ldmia r1!, {r0, r2-r4} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " push {r1,r4} \n"
" msr control, r3 \n" /* Restore the CONTROL register value for the task. */ " bl SecureContext_LoadContext \n" /* Restore the secure context. */
" mov lr, r4 \n" /* LR = r4. */ " pop {r1,r4} \n"
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " mov lr, r4 \n" /* LR = r4. */
" str r0, [r2] \n" /* Restore the task's xSecureContext. */ " 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. */
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ " 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. */
" push {r1,r4} \n" " msr psp, r1 \n" /* Remember the new top of stack for the task. */
" bl SecureContext_LoadContext \n" /* Restore the secure context. */ " bx lr \n"
" pop {r1,r4} \n" #else /* configENABLE_MPU */
" mov lr, r4 \n" /* LR = r4. */ " ldmia r1!, {r0, r2-r3} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */
" 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. */ " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
" 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. */ " mov lr, r3 \n" /* LR = r3. */
" msr psp, r1 \n" /* Remember the new top of stack for the task. */ " ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
" bx lr \n" " str r0, [r2] \n" /* Restore the task's xSecureContext. */
#else /* configENABLE_MPU */ " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
" ldmia r1!, {r0, r2-r3} \n" /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ " push {r1,r3} \n"
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " bl SecureContext_LoadContext \n" /* Restore the secure context. */
" mov lr, r3 \n" /* LR = r3. */ " pop {r1,r3} \n"
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " mov lr, r3 \n" /* LR = r3. */
" str r0, [r2] \n" /* Restore the task's xSecureContext. */ " 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. */
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ " 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. */
" push {r1,r3} \n" " msr psp, r1 \n" /* Remember the new top of stack for the task. */
" bl SecureContext_LoadContext \n" /* Restore the secure context. */ " bx lr \n"
" pop {r1,r3} \n" #endif /* configENABLE_MPU */
" mov lr, r3 \n" /* LR = r3. */ " \n"
" 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. */ " restore_ns_context: \n"
" 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. */ " ldmia r1!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */
" msr psp, r1 \n" /* Remember the new top of stack for the task. */ #if( configENABLE_FPU == 1 )
" bx lr \n" " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
#endif /* configENABLE_MPU */ " it eq \n"
" \n" " vldmiaeq r1!, {s16-s31} \n" /* Restore the FPU registers which are not restored automatically. */
" restore_ns_context: \n" #endif /* configENABLE_FPU */
" ldmia r1!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ " msr psp, r1 \n" /* Remember the new top of stack for the task. */
#if( configENABLE_FPU == 1 ) " bx lr \n"
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ " \n"
" it eq \n" " .align 4 \n"
" vldmiaeq r1!, {s16-s31} \n" /* Restore the FPU registers which are not restored automatically. */ "pxCurrentTCBConst: .word pxCurrentTCB \n"
#endif /* configENABLE_FPU */ "xSecureContextConst: .word xSecureContext \n"
" msr psp, r1 \n" /* Remember the new top of stack for the task. */ #if( configENABLE_MPU == 1 )
" bx lr \n" "xMPUCTRLConst: .word 0xe000ed94 \n"
" \n" "xMAIR0Const: .word 0xe000edc0 \n"
" .align 4 \n" "xRNRConst: .word 0xe000ed98 \n"
"pxCurrentTCBConst: .word pxCurrentTCB \n" "xRBARConst: .word 0xe000ed9c \n"
"xSecureContextConst: .word xSecureContext \n" #endif /* configENABLE_MPU */
#if( configENABLE_MPU == 1 ) :: "i"( configMAX_SYSCALL_INTERRUPT_PRIORITY )
"xMPUCTRLConst: .word 0xe000ed94 \n" );
"xMAIR0Const: .word 0xe000edc0 \n" }
"xRNRConst: .word 0xe000ed98 \n" /*-----------------------------------------------------------*/
"xRBARConst: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
); {
} __asm volatile
/*-----------------------------------------------------------*/ (
" tst lr, #4 \n"
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ite eq \n"
{ " mrseq r0, msp \n"
__asm volatile " mrsne r0, psp \n"
( " ldr r1, svchandler_address_const \n"
" tst lr, #4 \n" " bx r1 \n"
" ite eq \n" " \n"
" mrseq r0, msp \n" " .align 4 \n"
" mrsne r0, psp \n" "svchandler_address_const: .word vPortSVCHandler_C \n"
" ldr r1, svchandler_address_const \n" );
" bx r1 \n" }
" \n" /*-----------------------------------------------------------*/
" .align 4 \n"
"svchandler_address_const: .word vPortSVCHandler_C \n" void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */
); {
} __asm volatile
/*-----------------------------------------------------------*/ (
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ " bx lr \n" /* Return. */
{ :: "i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
__asm volatile );
( }
" svc %0 \n" /* Secure context is allocated in the supervisor call. */ /*-----------------------------------------------------------*/
" bx lr \n" /* Return. */
:: "i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory" void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
); {
} __asm volatile
/*-----------------------------------------------------------*/ (
" ldr r1, [r0] \n" /* The first item in the TCB is the top of the stack. */
void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " 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. */
__asm volatile " it ne \n"
( " svcne %0 \n" /* Secure context is freed in the supervisor call. */
" ldr r1, [r0] \n" /* The first item in the TCB is the top of the stack. */ " bx lr \n" /* Return. */
" ldr r0, [r1] \n" /* The first item on the stack is the task's xSecureContext. */ :: "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
" cmp r0, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */ );
" it ne \n" }
" svcne %0 \n" /* Secure context is freed in the supervisor call. */ /*-----------------------------------------------------------*/
" bx lr \n" /* Return. */
:: "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
);
}
/*-----------------------------------------------------------*/

View file

@ -1,299 +1,301 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#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.
* *
* The settings in this file configure FreeRTOS correctly for the given hardware * The settings in this file configure FreeRTOS correctly for the given hardware
* and compiler. * and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
*/ */
#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 void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #if( configENABLE_TRUSTZONE == 1 )
#endif /* configENABLE_TRUSTZONE */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_MPU == 1 ) #endif /* configENABLE_TRUSTZONE */
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #if( configENABLE_MPU == 1 )
#endif /* configENABLE_MPU */ extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
/*-----------------------------------------------------------*/ extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief MPU specific constants.
*/ /**
#if( configENABLE_MPU == 1 ) * @brief MPU specific constants.
#define portUSING_MPU_WRAPPERS 1 */
#define portPRIVILEGE_BIT ( 0x80000000UL ) #if( configENABLE_MPU == 1 )
#else #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#endif /* configENABLE_MPU */ #else
#define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */
/* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) /* MPU regions. */
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portSTACK_REGION ( 4UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portSTACK_REGION ( 4UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
/* Device memory attributes used in MPU_MAIR registers. #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
*
* 8-bit values encoded as follows: /* Device memory attributes used in MPU_MAIR registers.
* Bit[7:4] - 0000 - Device Memory *
* Bit[3:2] - 00 --> Device-nGnRnE * 8-bit values encoded as follows:
* 01 --> Device-nGnRE * Bit[7:4] - 0000 - Device Memory
* 10 --> Device-nGRE * Bit[3:2] - 00 --> Device-nGnRnE
* 11 --> Device-GRE * 01 --> Device-nGnRE
* Bit[1:0] - 00, Reserved. * 10 --> Device-nGRE
*/ * 11 --> Device-GRE
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ * Bit[1:0] - 00, Reserved.
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
/* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
#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. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
/* Attributes used in MPU_RBAR registers. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
/*-----------------------------------------------------------*/
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/** /*-----------------------------------------------------------*/
* @brief Settings to define an MPU region.
*/ /**
typedef struct MPURegionSettings * @brief Settings to define an MPU region.
{ */
uint32_t ulRBAR; /**< RBAR for the region. */ typedef struct MPURegionSettings
uint32_t ulRLAR; /**< RLAR for the region. */ {
} MPURegionSettings_t; uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */
/** } MPURegionSettings_t;
* @brief MPU settings as stored in the TCB.
*/ /**
typedef struct MPU_SETTINGS * @brief MPU settings as stored in the TCB.
{ */
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ typedef struct MPU_SETTINGS
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ {
} xMPU_SETTINGS; 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. */
} xMPU_SETTINGS;
/** /*-----------------------------------------------------------*/
* @brief SVC numbers.
*/ /**
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 * @brief SVC numbers.
#define portSVC_FREE_SECURE_CONTEXT 1 */
#define portSVC_START_SCHEDULER 2 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_FREE_SECURE_CONTEXT 1
/*-----------------------------------------------------------*/ #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3
/** /*-----------------------------------------------------------*/
* @brief Scheduler utilities.
*/ /**
#define portYIELD() vPortYield() * @brief Scheduler utilities.
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) */
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portYIELD() vPortYield()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
/*-----------------------------------------------------------*/ #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/** /*-----------------------------------------------------------*/
* @brief Critical section management.
*/ /**
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() * @brief Critical section management.
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) */
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
#define portENTER_CRITICAL() vPortEnterCritical() #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portEXIT_CRITICAL() vPortExitCritical() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
/*-----------------------------------------------------------*/ #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/** /*-----------------------------------------------------------*/
* @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ /**
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) * @brief Task function macros as described on the FreeRTOS.org WEB site.
#define portTASK_FUNCTION( 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 )
#if( configENABLE_TRUSTZONE == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Allocate a secure context for the task. #if( configENABLE_TRUSTZONE == 1 )
* /**
* Tasks are not created with a secure context. Any task that is going to call * @brief Allocate a secure context for the task.
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a *
* secure context before it calls any secure function. * Tasks are not created with a secure context. Any task that is going to call
* * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * secure context before it calls any secure function.
*/ *
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/
/** #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
* @brief Called when a task is deleted to delete the task's secure context,
* if it has one. /**
* * @brief Called when a task is deleted to delete the task's secure context,
* @param[in] pxTCB The TCB of the task being deleted. * if it has one.
*/ *
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) * @param[in] pxTCB The TCB of the task being deleted.
#else */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#define portCLEAN_UP_TCB( pxTCB ) #else
#endif /* configENABLE_TRUSTZONE */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
/*-----------------------------------------------------------*/ #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */
#if( configENABLE_MPU == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Checks whether or not the processor is privileged. #if( configENABLE_MPU == 1 )
* /**
* @return 1 if the processor is already privileged, 0 otherwise. * @brief Checks whether or not the processor is privileged.
*/ *
#define portIS_PRIVILEGED() xIsPrivileged() * @return 1 if the processor is already privileged, 0 otherwise.
*/
/** #define portIS_PRIVILEGED() xIsPrivileged()
* @brief Raise an SVC request to raise privilege.
* /**
* The SVC handler checks that the SVC was raised from a system call and only * @brief Raise an SVC request to raise privilege.
* then it raises the privilege. If this is called from any other place, *
* the privilege is not raised. * 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,
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); * the privilege is not raised.
*/
/** #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
* register. /**
*/ * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
#define portRESET_PRIVILEGE() vResetPrivilege() * register.
#else */
#define portIS_PRIVILEGED() #define portRESET_PRIVILEGE() vResetPrivilege()
#define portRAISE_PRIVILEGE() #else
#define portRESET_PRIVILEGE() #define portIS_PRIVILEGED()
#endif /* configENABLE_MPU */ #define portRAISE_PRIVILEGE()
/*-----------------------------------------------------------*/ #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief Barriers.
*/ /**
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) * @brief Barriers.
/*-----------------------------------------------------------*/ */
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
#ifdef __cplusplus /*-----------------------------------------------------------*/
}
#endif #ifdef __cplusplus
}
#endif /* PORTMACRO_H */ #endif
#endif /* PORTMACRO_H */

View file

@ -1,321 +1,316 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Standard includes. */ /* Standard includes. */
#include <stdint.h> #include <stdint.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION
* is defined correctly and privileged functions are placed in correct sections. */ * is defined correctly and privileged functions are placed in correct sections. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* Portasm includes. */ /* Portasm includes. */
#include "portasm.h" #include "portasm.h"
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the
* header files. */ * header files. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" .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"
"xRBARConst2: .word 0xe000ed9c \n" "xRBARConst2: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vResetPrivilege( void ) /* __attribute__ (( naked )) */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" mrs r0, PRIMASK \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
" cpsid i \n" " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" bx lr \n" " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
::: "memory" " dsb \n"
); " isb \n"
" bx lr \n" /* Return. */
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) :: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
/* To avoid compiler warnings. The return statement will never be reached, );
* but some compilers warn if it is not included, while others won't compile }
* if it is. */ /*-----------------------------------------------------------*/
return 0;
#endif void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
} {
/*-----------------------------------------------------------*/ __asm volatile
(
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ " msr basepri, r0 \n" /* basepri = ulMask. */
{ " dsb \n"
__asm volatile " isb \n"
( " bx lr \n" /* Return. */
" msr PRIMASK, r0 \n" ::: "memory"
" bx lr \n" );
::: "memory" }
); /*-----------------------------------------------------------*/
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
/* Just to avoid compiler warning. ulMask is used from the asm code but {
* the compiler can't see that. Some compilers generate warnings without __asm volatile
* the following line, while others generate warnings if the line is (
* included. */ " .syntax unified \n"
( void ) ulMask; " \n"
#endif " mrs r0, psp \n" /* Read PSP in r0. */
} #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. */
" it eq \n"
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " vstmdbeq r0!, {s16-s31} \n" /* Store the FPU registers which are not saved automatically. */
{ #endif /* configENABLE_FPU */
__asm volatile #if( configENABLE_MPU == 1 )
( " mrs r1, psplim \n" /* r1 = PSPLIM. */
" .syntax unified \n" " mrs r2, control \n" /* r2 = CONTROL. */
" \n" " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
" mrs r0, psp \n" /* Read PSP in r0. */ " stmdb r0!, {r1-r11} \n" /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */
#if( configENABLE_FPU == 1 ) #else /* configENABLE_MPU */
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ " mrs r2, psplim \n" /* r2 = PSPLIM. */
" it eq \n" " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
" vstmdbeq r0!, {s16-s31} \n" /* Store the FPU registers which are not saved automatically. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
#endif /* configENABLE_FPU */ #endif /* configENABLE_MPU */
#if( configENABLE_MPU == 1 ) " \n"
" mrs r1, psplim \n" /* r1 = PSPLIM. */ " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" mrs r2, control \n" /* r2 = CONTROL. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */
" stmdb r0!, {r1-r11} \n" /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ " \n"
#else /* configENABLE_MPU */ " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
" mrs r2, psplim \n" /* r2 = PSPLIM. */ " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " dsb \n"
" stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " isb \n"
#endif /* configENABLE_MPU */ " bl vTaskSwitchContext \n"
" \n" " mov r0, #0 \n" /* r0 = 0. */
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " msr basepri, r0 \n" /* Enable interrupts. */
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " \n"
" str r0, [r1] \n" /* Save the new top of stack in TCB. */ " ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" \n" " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" cpsid i \n" " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
" bl vTaskSwitchContext \n" " \n"
" cpsie i \n" #if( configENABLE_MPU == 1 )
" \n" " dmb \n" /* Complete outstanding transfers before disabling MPU. */
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " bic r4, #1 \n" /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
" \n" " str r4, [r2] \n" /* Disable MPU. */
#if( configENABLE_MPU == 1 ) " \n"
" dmb \n" /* Complete outstanding transfers before disabling MPU. */ " adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r3, [r1] \n" /* r3 = *r1 i.e. r3 = MAIR0. */
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */ " ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
" bic r4, #1 \n" /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " str r3, [r2] \n" /* Program MAIR0. */
" str r4, [r2] \n" /* Disable MPU. */ " ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
" \n" " movs r3, #4 \n" /* r3 = 4. */
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " str r3, [r2] \n" /* Program RNR = 4. */
" ldr r3, [r1] \n" /* r3 = *r1 i.e. r3 = MAIR0. */ " adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
" ldr r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */ " ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
" str r3, [r2] \n" /* Program MAIR0. */ " ldmia r1!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */ " stmia r2!, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #4 \n" /* r3 = 4. */ " \n"
" str r3, [r2] \n" /* Program RNR = 4. */ " ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */ " orr r4, #1 \n" /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
" ldmia r1!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " str r4, [r2] \n" /* Enable MPU. */
" stmia r2!, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " dsb \n" /* Force memory writes before continuing. */
" \n" #endif /* configENABLE_MPU */
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " \n"
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */ #if( configENABLE_MPU == 1 )
" orr r4, #1 \n" /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " ldmia r0!, {r1-r11} \n" /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */
" str r4, [r2] \n" /* Enable MPU. */ #else /* configENABLE_MPU */
" dsb \n" /* Force memory writes before continuing. */ " 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_MPU == 1 ) #if( configENABLE_FPU == 1 )
" ldmia r0!, {r1-r11} \n" /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
#else /* configENABLE_MPU */ " it eq \n"
" ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " vldmiaeq r0!, {s16-s31} \n" /* Restore the FPU registers which are not restored automatically. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_FPU */
" \n" " \n"
#if( configENABLE_FPU == 1 ) #if( configENABLE_MPU == 1 )
" tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */
" it eq \n" " msr control, r2 \n" /* Restore the CONTROL register value for the task. */
" vldmiaeq r0!, {s16-s31} \n" /* Restore the FPU registers which are not restored automatically. */ #else /* configENABLE_MPU */
#endif /* configENABLE_FPU */ " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
" \n" #endif /* configENABLE_MPU */
#if( configENABLE_MPU == 1 ) " msr psp, r0 \n" /* Remember the new top of stack for the task. */
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ " bx r3 \n"
" msr control, r2 \n" /* Restore the CONTROL register value for the task. */ " \n"
#else /* configENABLE_MPU */ " .align 4 \n"
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ "pxCurrentTCBConst: .word pxCurrentTCB \n"
#endif /* configENABLE_MPU */ #if( configENABLE_MPU == 1 )
" msr psp, r0 \n" /* Remember the new top of stack for the task. */ "xMPUCTRLConst: .word 0xe000ed94 \n"
" bx r3 \n" "xMAIR0Const: .word 0xe000edc0 \n"
" \n" "xRNRConst: .word 0xe000ed98 \n"
" .align 4 \n" "xRBARConst: .word 0xe000ed9c \n"
"pxCurrentTCBConst: .word pxCurrentTCB \n" #endif /* configENABLE_MPU */
#if( configENABLE_MPU == 1 ) :: "i"( configMAX_SYSCALL_INTERRUPT_PRIORITY )
"xMPUCTRLConst: .word 0xe000ed94 \n" );
"xMAIR0Const: .word 0xe000edc0 \n" }
"xRNRConst: .word 0xe000ed98 \n" /*-----------------------------------------------------------*/
"xRBARConst: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
); {
} __asm volatile
/*-----------------------------------------------------------*/ (
" tst lr, #4 \n"
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " ite eq \n"
{ " mrseq r0, msp \n"
__asm volatile " mrsne r0, psp \n"
( " ldr r1, svchandler_address_const \n"
" tst lr, #4 \n" " bx r1 \n"
" ite eq \n" " \n"
" mrseq r0, msp \n" " .align 4 \n"
" mrsne r0, psp \n" "svchandler_address_const: .word vPortSVCHandler_C \n"
" ldr r1, svchandler_address_const \n" );
" bx r1 \n" }
" \n" /*-----------------------------------------------------------*/
" .align 4 \n"
"svchandler_address_const: .word vPortSVCHandler_C \n"
);
}
/*-----------------------------------------------------------*/

View file

@ -1,299 +1,301 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#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.
* *
* The settings in this file configure FreeRTOS correctly for the given hardware * The settings in this file configure FreeRTOS correctly for the given hardware
* and compiler. * and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
*/ */
#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 void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #if( configENABLE_TRUSTZONE == 1 )
#endif /* configENABLE_TRUSTZONE */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_MPU == 1 ) #endif /* configENABLE_TRUSTZONE */
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #if( configENABLE_MPU == 1 )
#endif /* configENABLE_MPU */ extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
/*-----------------------------------------------------------*/ extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief MPU specific constants.
*/ /**
#if( configENABLE_MPU == 1 ) * @brief MPU specific constants.
#define portUSING_MPU_WRAPPERS 1 */
#define portPRIVILEGE_BIT ( 0x80000000UL ) #if( configENABLE_MPU == 1 )
#else #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#endif /* configENABLE_MPU */ #else
#define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */
/* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) /* MPU regions. */
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portSTACK_REGION ( 4UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portSTACK_REGION ( 4UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
/* Device memory attributes used in MPU_MAIR registers. #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
*
* 8-bit values encoded as follows: /* Device memory attributes used in MPU_MAIR registers.
* Bit[7:4] - 0000 - Device Memory *
* Bit[3:2] - 00 --> Device-nGnRnE * 8-bit values encoded as follows:
* 01 --> Device-nGnRE * Bit[7:4] - 0000 - Device Memory
* 10 --> Device-nGRE * Bit[3:2] - 00 --> Device-nGnRnE
* 11 --> Device-GRE * 01 --> Device-nGnRE
* Bit[1:0] - 00, Reserved. * 10 --> Device-nGRE
*/ * 11 --> Device-GRE
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ * Bit[1:0] - 00, Reserved.
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
/* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
#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. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
/* Attributes used in MPU_RBAR registers. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
/*-----------------------------------------------------------*/
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/** /*-----------------------------------------------------------*/
* @brief Settings to define an MPU region.
*/ /**
typedef struct MPURegionSettings * @brief Settings to define an MPU region.
{ */
uint32_t ulRBAR; /**< RBAR for the region. */ typedef struct MPURegionSettings
uint32_t ulRLAR; /**< RLAR for the region. */ {
} MPURegionSettings_t; uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */
/** } MPURegionSettings_t;
* @brief MPU settings as stored in the TCB.
*/ /**
typedef struct MPU_SETTINGS * @brief MPU settings as stored in the TCB.
{ */
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ typedef struct MPU_SETTINGS
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ {
} xMPU_SETTINGS; 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. */
} xMPU_SETTINGS;
/** /*-----------------------------------------------------------*/
* @brief SVC numbers.
*/ /**
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 * @brief SVC numbers.
#define portSVC_FREE_SECURE_CONTEXT 1 */
#define portSVC_START_SCHEDULER 2 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_FREE_SECURE_CONTEXT 1
/*-----------------------------------------------------------*/ #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3
/** /*-----------------------------------------------------------*/
* @brief Scheduler utilities.
*/ /**
#define portYIELD() vPortYield() * @brief Scheduler utilities.
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) */
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portYIELD() vPortYield()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
/*-----------------------------------------------------------*/ #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/** /*-----------------------------------------------------------*/
* @brief Critical section management.
*/ /**
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() * @brief Critical section management.
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) */
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portENTER_CRITICAL() vPortEnterCritical() #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portEXIT_CRITICAL() vPortExitCritical() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
/*-----------------------------------------------------------*/ #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/** /*-----------------------------------------------------------*/
* @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ /**
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) * @brief Task function macros as described on the FreeRTOS.org WEB site.
#define portTASK_FUNCTION( 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 )
#if( configENABLE_TRUSTZONE == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Allocate a secure context for the task. #if( configENABLE_TRUSTZONE == 1 )
* /**
* Tasks are not created with a secure context. Any task that is going to call * @brief Allocate a secure context for the task.
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a *
* secure context before it calls any secure function. * Tasks are not created with a secure context. Any task that is going to call
* * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * secure context before it calls any secure function.
*/ *
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/
/** #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
* @brief Called when a task is deleted to delete the task's secure context,
* if it has one. /**
* * @brief Called when a task is deleted to delete the task's secure context,
* @param[in] pxTCB The TCB of the task being deleted. * if it has one.
*/ *
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) * @param[in] pxTCB The TCB of the task being deleted.
#else */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#define portCLEAN_UP_TCB( pxTCB ) #else
#endif /* configENABLE_TRUSTZONE */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
/*-----------------------------------------------------------*/ #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */
#if( configENABLE_MPU == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Checks whether or not the processor is privileged. #if( configENABLE_MPU == 1 )
* /**
* @return 1 if the processor is already privileged, 0 otherwise. * @brief Checks whether or not the processor is privileged.
*/ *
#define portIS_PRIVILEGED() xIsPrivileged() * @return 1 if the processor is already privileged, 0 otherwise.
*/
/** #define portIS_PRIVILEGED() xIsPrivileged()
* @brief Raise an SVC request to raise privilege.
* /**
* The SVC handler checks that the SVC was raised from a system call and only * @brief Raise an SVC request to raise privilege.
* then it raises the privilege. If this is called from any other place, *
* the privilege is not raised. * 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,
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); * the privilege is not raised.
*/
/** #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
* register. /**
*/ * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
#define portRESET_PRIVILEGE() vResetPrivilege() * register.
#else */
#define portIS_PRIVILEGED() #define portRESET_PRIVILEGE() vResetPrivilege()
#define portRAISE_PRIVILEGE() #else
#define portRESET_PRIVILEGE() #define portIS_PRIVILEGED()
#endif /* configENABLE_MPU */ #define portRAISE_PRIVILEGE()
/*-----------------------------------------------------------*/ #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief Barriers.
*/ /**
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) * @brief Barriers.
/*-----------------------------------------------------------*/ */
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
#ifdef __cplusplus /*-----------------------------------------------------------*/
}
#endif #ifdef __cplusplus
}
#endif /* PORTMACRO_H */ #endif
#endif /* PORTMACRO_H */

View file

@ -1,377 +1,377 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
EXTERN pxCurrentTCB EXTERN pxCurrentTCB
EXTERN xSecureContext EXTERN xSecureContext
EXTERN vTaskSwitchContext EXTERN vTaskSwitchContext
EXTERN vPortSVCHandler_C EXTERN vPortSVCHandler_C
EXTERN SecureContext_SaveContext EXTERN SecureContext_SaveContext
EXTERN SecureContext_LoadContext EXTERN SecureContext_LoadContext
PUBLIC xIsPrivileged PUBLIC xIsPrivileged
PUBLIC vResetPrivilege PUBLIC vResetPrivilege
PUBLIC vPortAllocateSecureContext PUBLIC vPortAllocateSecureContext
PUBLIC vRestoreContextOfFirstTask PUBLIC vRestoreContextOfFirstTask
PUBLIC vRaisePrivilege PUBLIC vRaisePrivilege
PUBLIC vStartFirstTask PUBLIC vStartFirstTask
PUBLIC ulSetInterruptMaskFromISR PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMaskFromISR PUBLIC vClearInterruptMask
PUBLIC PendSV_Handler PUBLIC PendSV_Handler
PUBLIC SVC_Handler PUBLIC SVC_Handler
PUBLIC vPortFreeSecureContext PUBLIC vPortFreeSecureContext
#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
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*---------------- Unprivileged Functions -------------------*/ /*---------------- Unprivileged Functions -------------------*/
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
SECTION .text:CODE:NOROOT(2) SECTION .text:CODE:NOROOT(2)
THUMB THUMB
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
xIsPrivileged: xIsPrivileged:
mrs r0, control /* r0 = CONTROL. */ mrs r0, control /* r0 = CONTROL. */
movs r1, #1 /* r1 = 1. */ movs r1, #1 /* r1 = 1. */
tst r0, r1 /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */ tst r0, r1 /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
beq running_privileged /* If the result of previous AND operation was 0, branch. */ beq running_privileged /* If the result of previous AND operation was 0, branch. */
movs r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ movs r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
bx lr /* Return. */ bx lr /* Return. */
running_privileged: running_privileged:
movs r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ movs r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
bx lr /* Return. */ bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vResetPrivilege: vResetPrivilege:
mrs r0, control /* r0 = CONTROL. */ mrs r0, control /* r0 = CONTROL. */
movs r1, #1 /* r1 = 1. */ movs r1, #1 /* r1 = 1. */
orrs r0, r1 /* r0 = r0 | r1. */ orrs r0, r1 /* r0 = r0 | r1. */
msr control, r0 /* CONTROL = r0. */ msr control, r0 /* CONTROL = r0. */
bx lr /* Return to the caller. */ bx lr /* Return to the caller. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vPortAllocateSecureContext: vPortAllocateSecureContext:
svc 0 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 0. */ svc 0 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 0. */
bx lr /* Return. */ bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*----------------- Privileged Functions --------------------*/ /*----------------- Privileged Functions --------------------*/
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
SECTION privileged_functions:CODE:NOROOT(2) SECTION privileged_functions:CODE:NOROOT(2)
THUMB THUMB
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vRestoreContextOfFirstTask: vRestoreContextOfFirstTask:
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r3, [r2] /* Read pxCurrentTCB. */
ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
dmb /* Complete outstanding transfers before disabling MPU. */ dmb /* Complete outstanding transfers before disabling MPU. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r4, [r2] /* Read the value of MPU_CTRL. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */
movs r5, #1 /* r5 = 1. */ movs r5, #1 /* r5 = 1. */
bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
str r4, [r2] /* Disable MPU. */ str r4, [r2] /* Disable MPU. */
adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
str r4, [r2] /* Program MAIR0. */ str r4, [r2] /* Program MAIR0. */
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
movs r5, #4 /* r5 = 4. */ movs r5, #4 /* r5 = 4. */
str r5, [r2] /* Program RNR = 4. */ str r5, [r2] /* Program RNR = 4. */
ldmia r3!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ ldmia r3!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
stmia r4!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ stmia r4!, {r6,r7} /* Write first set of RBAR/RLAR registers. */
movs r5, #5 /* r5 = 5. */ movs r5, #5 /* r5 = 5. */
str r5, [r2] /* Program RNR = 5. */ str r5, [r2] /* Program RNR = 5. */
ldmia r3!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ ldmia r3!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
stmia r4!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ stmia r4!, {r6,r7} /* Write second set of RBAR/RLAR registers. */
movs r5, #6 /* r5 = 6. */ movs r5, #6 /* r5 = 6. */
str r5, [r2] /* Program RNR = 6. */ str r5, [r2] /* Program RNR = 6. */
ldmia r3!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ ldmia r3!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
stmia r4!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ stmia r4!, {r6,r7} /* Write third set of RBAR/RLAR registers. */
movs r5, #7 /* r5 = 7. */ movs r5, #7 /* r5 = 7. */
str r5, [r2] /* Program RNR = 7. */ str r5, [r2] /* Program RNR = 7. */
ldmia r3!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ ldmia r3!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
stmia r4!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ stmia r4!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r4, [r2] /* Read the value of MPU_CTRL. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */
movs r5, #1 /* r5 = 1. */ movs r5, #1 /* r5 = 1. */
orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
str r4, [r2] /* Enable MPU. */ str r4, [r2] /* Enable MPU. */
dsb /* Force memory writes before continuing. */ dsb /* Force memory writes before continuing. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */
ldr r5, =xSecureContext ldr r5, =xSecureContext
str r1, [r5] /* Set xSecureContext to this task's value for the same. */ str r1, [r5] /* Set xSecureContext to this task's value for the same. */
msr psplim, r2 /* Set this task's PSPLIM value. */ msr psplim, r2 /* Set this task's PSPLIM value. */
msr control, r3 /* Set this task's CONTROL value. */ msr control, r3 /* Set this task's CONTROL value. */
adds r0, #32 /* Discard everything up to r0. */ adds r0, #32 /* Discard everything up to r0. */
msr psp, r0 /* This is now the new top of stack to use in the task. */ msr psp, r0 /* This is now the new top of stack to use in the task. */
isb isb
bx r4 /* Finally, branch to EXC_RETURN. */ bx r4 /* Finally, branch to EXC_RETURN. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
ldr r4, =xSecureContext ldr r4, =xSecureContext
str r1, [r4] /* Set xSecureContext to this task's value for the same. */ str r1, [r4] /* Set xSecureContext to this task's value for the same. */
msr psplim, r2 /* Set this task's PSPLIM value. */ msr psplim, r2 /* Set this task's PSPLIM value. */
movs r1, #2 /* r1 = 2. */ movs r1, #2 /* r1 = 2. */
msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */
adds r0, #32 /* Discard everything up to r0. */ adds r0, #32 /* Discard everything up to r0. */
msr psp, r0 /* This is now the new top of stack to use in the task. */ msr psp, r0 /* This is now the new top of stack to use in the task. */
isb isb
bx r3 /* Finally, branch to EXC_RETURN. */ bx r3 /* Finally, branch to EXC_RETURN. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vRaisePrivilege: vRaisePrivilege:
mrs r0, control /* Read the CONTROL register. */ mrs r0, control /* Read the CONTROL register. */
movs r1, #1 /* r1 = 1. */ movs r1, #1 /* r1 = 1. */
bics r0, r1 /* Clear the bit 0. */ bics r0, r1 /* Clear the bit 0. */
msr control, r0 /* Write back the new CONTROL value. */ msr control, r0 /* Write back the new CONTROL value. */
bx lr /* Return to the caller. */ bx lr /* Return to the caller. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vStartFirstTask: vStartFirstTask:
ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */
ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */
ldr r0, [r0] /* The first entry in vector table is stack pointer. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */
msr msp, r0 /* Set the MSP back to the start of the stack. */ msr msp, r0 /* Set the MSP back to the start of the stack. */
cpsie i /* Globally enable interrupts. */ cpsie i /* Globally enable interrupts. */
dsb dsb
isb isb
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMaskFromISR: ulSetInterruptMask:
mrs r0, PRIMASK mrs r0, PRIMASK
cpsid i cpsid i
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMaskFromISR: vClearInterruptMask:
msr PRIMASK, r0 msr PRIMASK, r0
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
PendSV_Handler: PendSV_Handler:
mrs r1, psp /* Read PSP in r1. */ mrs r1, psp /* Read PSP in r1. */
ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
ldr r0, [r2] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ ldr r0, [r2] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
cbz r0, save_ns_context /* No secure context to save. */ cbz r0, save_ns_context /* No secure context to save. */
push {r0-r2, r14} push {r0-r2, r14}
bl SecureContext_SaveContext bl SecureContext_SaveContext
pop {r0-r3} /* LR is now in r3. */ pop {r0-r3} /* LR is now in r3. */
mov lr, r3 /* LR = r3. */ mov lr, r3 /* LR = r3. */
lsls r2, r3, #25 /* 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 /* 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 /* 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 /* 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, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r2, [r3] /* Read pxCurrentTCB. */ ldr r2, [r3] /* Read pxCurrentTCB. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
subs r1, r1, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ subs r1, r1, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
str r1, [r2] /* Save the new top of stack in TCB. */ str r1, [r2] /* Save the new top of stack in TCB. */
mrs r2, psplim /* r2 = PSPLIM. */ mrs r2, psplim /* r2 = PSPLIM. */
mrs r3, control /* r3 = CONTROL. */ mrs r3, control /* r3 = CONTROL. */
mov r4, lr /* r4 = LR/EXC_RETURN. */ mov r4, lr /* r4 = LR/EXC_RETURN. */
stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
subs r1, r1, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ subs r1, r1, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */
str r1, [r2] /* Save the new top of stack in TCB. */ str r1, [r2] /* Save the new top of stack in TCB. */
mrs r2, psplim /* r2 = PSPLIM. */ mrs r2, psplim /* r2 = PSPLIM. */
mov r3, lr /* r3 = LR/EXC_RETURN. */ mov r3, lr /* r3 = LR/EXC_RETURN. */
stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
b select_next_task b select_next_task
save_ns_context: save_ns_context:
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r2, [r3] /* Read pxCurrentTCB. */ ldr r2, [r3] /* Read pxCurrentTCB. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
subs r1, r1, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ subs r1, r1, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
str r1, [r2] /* Save the new top of stack in TCB. */ str r1, [r2] /* Save the new top of stack in TCB. */
adds r1, r1, #16 /* r1 = r1 + 16. */ adds r1, r1, #16 /* r1 = r1 + 16. */
stmia r1!, {r4-r7} /* Store the low registers that are not saved automatically. */ stmia r1!, {r4-r7} /* Store the low registers that are not saved automatically. */
mov r4, r8 /* r4 = r8. */ mov r4, r8 /* r4 = r8. */
mov r5, r9 /* r5 = r9. */ mov r5, r9 /* r5 = r9. */
mov r6, r10 /* r6 = r10. */ mov r6, r10 /* r6 = r10. */
mov r7, r11 /* r7 = r11. */ mov r7, r11 /* r7 = r11. */
stmia r1!, {r4-r7} /* Store the high registers that are not saved automatically. */ stmia r1!, {r4-r7} /* Store the high registers that are not saved automatically. */
mrs r2, psplim /* r2 = PSPLIM. */ mrs r2, psplim /* r2 = PSPLIM. */
mrs r3, control /* r3 = CONTROL. */ mrs r3, control /* r3 = CONTROL. */
mov r4, lr /* r4 = LR/EXC_RETURN. */ mov r4, lr /* r4 = LR/EXC_RETURN. */
subs r1, r1, #48 /* r1 = r1 - 48. */ subs r1, r1, #48 /* r1 = r1 - 48. */
stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
subs r1, r1, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ subs r1, r1, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
str r1, [r2] /* Save the new top of stack in TCB. */ str r1, [r2] /* Save the new top of stack in TCB. */
mrs r2, psplim /* r2 = PSPLIM. */ mrs r2, psplim /* r2 = PSPLIM. */
mov r3, lr /* r3 = LR/EXC_RETURN. */ mov r3, lr /* r3 = LR/EXC_RETURN. */
stmia r1!, {r0, r2-r7} /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ stmia r1!, {r0, r2-r7} /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */
mov r4, r8 /* r4 = r8. */ mov r4, r8 /* r4 = r8. */
mov r5, r9 /* r5 = r9. */ mov r5, r9 /* r5 = r9. */
mov r6, r10 /* r6 = r10. */ mov r6, r10 /* r6 = r10. */
mov r7, r11 /* r7 = r11. */ mov r7, r11 /* r7 = r11. */
stmia r1!, {r4-r7} /* Store the high registers that are not saved automatically. */ stmia r1!, {r4-r7} /* Store the high registers that are not saved automatically. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
select_next_task: select_next_task:
cpsid i cpsid i
bl vTaskSwitchContext bl vTaskSwitchContext
cpsie i cpsie i
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r3, [r2] /* Read pxCurrentTCB. */
ldr r1, [r3] /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ ldr r1, [r3] /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
dmb /* Complete outstanding transfers before disabling MPU. */ dmb /* Complete outstanding transfers before disabling MPU. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r4, [r2] /* Read the value of MPU_CTRL. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */
movs r5, #1 /* r5 = 1. */ movs r5, #1 /* r5 = 1. */
bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
str r4, [r2] /* Disable MPU. */ str r4, [r2] /* Disable MPU. */
adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
str r4, [r2] /* Program MAIR0. */ str r4, [r2] /* Program MAIR0. */
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
movs r5, #4 /* r5 = 4. */ movs r5, #4 /* r5 = 4. */
str r5, [r2] /* Program RNR = 4. */ str r5, [r2] /* Program RNR = 4. */
ldmia r3!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ ldmia r3!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
stmia r4!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ stmia r4!, {r6,r7} /* Write first set of RBAR/RLAR registers. */
movs r5, #5 /* r5 = 5. */ movs r5, #5 /* r5 = 5. */
str r5, [r2] /* Program RNR = 5. */ str r5, [r2] /* Program RNR = 5. */
ldmia r3!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ ldmia r3!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
stmia r4!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ stmia r4!, {r6,r7} /* Write second set of RBAR/RLAR registers. */
movs r5, #6 /* r5 = 6. */ movs r5, #6 /* r5 = 6. */
str r5, [r2] /* Program RNR = 6. */ str r5, [r2] /* Program RNR = 6. */
ldmia r3!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ ldmia r3!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
stmia r4!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ stmia r4!, {r6,r7} /* Write third set of RBAR/RLAR registers. */
movs r5, #7 /* r5 = 7. */ movs r5, #7 /* r5 = 7. */
str r5, [r2] /* Program RNR = 7. */ str r5, [r2] /* Program RNR = 7. */
ldmia r3!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ ldmia r3!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
stmia r4!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ stmia r4!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r4, [r2] /* Read the value of MPU_CTRL. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */
movs r5, #1 /* r5 = 1. */ movs r5, #1 /* r5 = 1. */
orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
str r4, [r2] /* Enable MPU. */ str r4, [r2] /* Enable MPU. */
dsb /* Force memory writes before continuing. */ dsb /* Force memory writes before continuing. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
ldmia r1!, {r0, r2-r4} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ ldmia r1!, {r0, r2-r4} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */
msr psplim, r2 /* Restore the PSPLIM register value for the task. */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */
msr control, r3 /* Restore the CONTROL register value for the task. */ msr control, r3 /* Restore the CONTROL register value for the task. */
mov lr, r4 /* LR = r4. */ mov lr, r4 /* LR = r4. */
ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
str r0, [r2] /* Restore the task's xSecureContext. */ str r0, [r2] /* Restore the task's xSecureContext. */
cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */
push {r1,r4} push {r1,r4}
bl SecureContext_LoadContext /* Restore the secure context. */ bl SecureContext_LoadContext /* Restore the secure context. */
pop {r1,r4} pop {r1,r4}
mov lr, r4 /* LR = r4. */ mov lr, r4 /* LR = r4. */
lsls r2, r4, #25 /* 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 /* 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 /* 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 /* 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 /* Remember the new top of stack for the task. */ msr psp, r1 /* Remember the new top of stack for the task. */
bx lr bx lr
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
ldmia r1!, {r0, r2-r3} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ ldmia r1!, {r0, r2-r3} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */
msr psplim, r2 /* Restore the PSPLIM register value for the task. */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */
mov lr, r3 /* LR = r3. */ mov lr, r3 /* LR = r3. */
ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
str r0, [r2] /* Restore the task's xSecureContext. */ str r0, [r2] /* Restore the task's xSecureContext. */
cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */
push {r1,r3} push {r1,r3}
bl SecureContext_LoadContext /* Restore the secure context. */ bl SecureContext_LoadContext /* Restore the secure context. */
pop {r1,r3} pop {r1,r3}
mov lr, r3 /* LR = r3. */ mov lr, r3 /* LR = r3. */
lsls r2, r3, #25 /* 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 /* 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 /* 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 /* 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 /* Remember the new top of stack for the task. */ msr psp, r1 /* Remember the new top of stack for the task. */
bx lr bx lr
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
restore_ns_context: restore_ns_context:
adds r1, r1, #16 /* Move to the high registers. */ adds r1, r1, #16 /* Move to the high registers. */
ldmia r1!, {r4-r7} /* Restore the high registers that are not automatically restored. */ ldmia r1!, {r4-r7} /* Restore the high registers that are not automatically restored. */
mov r8, r4 /* r8 = r4. */ mov r8, r4 /* r8 = r4. */
mov r9, r5 /* r9 = r5. */ mov r9, r5 /* r9 = r5. */
mov r10, r6 /* r10 = r6. */ mov r10, r6 /* r10 = r6. */
mov r11, r7 /* r11 = r7. */ mov r11, r7 /* r11 = r7. */
msr psp, r1 /* Remember the new top of stack for the task. */ msr psp, r1 /* Remember the new top of stack for the task. */
subs r1, r1, #32 /* Go back to the low registers. */ subs r1, r1, #32 /* Go back to the low registers. */
ldmia r1!, {r4-r7} /* Restore the low registers that are not automatically restored. */ ldmia r1!, {r4-r7} /* Restore the low registers that are not automatically restored. */
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
SVC_Handler: SVC_Handler:
movs r0, #4 movs r0, #4
mov r1, lr mov r1, lr
tst r0, r1 tst r0, r1
beq stacking_used_msp beq stacking_used_msp
mrs r0, psp mrs r0, psp
b vPortSVCHandler_C b vPortSVCHandler_C
stacking_used_msp: stacking_used_msp:
mrs r0, msp mrs r0, msp
b vPortSVCHandler_C b vPortSVCHandler_C
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vPortFreeSecureContext: vPortFreeSecureContext:
ldr r1, [r0] /* The first item in the TCB is the top of the stack. */ ldr r1, [r0] /* The first item in the TCB is the top of the stack. */
ldr r0, [r1] /* The first item on the stack is the task's xSecureContext. */ ldr r0, [r1] /* The first item on the stack is the task's xSecureContext. */
cmp r0, #0 /* Raise svc if task's xSecureContext is not NULL. */ cmp r0, #0 /* Raise svc if task's xSecureContext is not NULL. */
beq free_secure_context beq free_secure_context
bx lr /* There is no secure context (xSecureContext is NULL). */ bx lr /* There is no secure context (xSecureContext is NULL). */
free_secure_context: free_secure_context:
svc 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */ svc 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */
bx lr /* Return. */ bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
END END

View file

@ -1,299 +1,308 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#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.
* *
* The settings in this file configure FreeRTOS correctly for the given hardware * The settings in this file configure FreeRTOS correctly for the given hardware
* and compiler. * and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
*/ */
#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 void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #if( configENABLE_TRUSTZONE == 1 )
#endif /* configENABLE_TRUSTZONE */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_MPU == 1 ) #endif /* configENABLE_TRUSTZONE */
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #if( configENABLE_MPU == 1 )
#endif /* configENABLE_MPU */ extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
/*-----------------------------------------------------------*/ extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief MPU specific constants.
*/ /**
#if( configENABLE_MPU == 1 ) * @brief MPU specific constants.
#define portUSING_MPU_WRAPPERS 1 */
#define portPRIVILEGE_BIT ( 0x80000000UL ) #if( configENABLE_MPU == 1 )
#else #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#endif /* configENABLE_MPU */ #else
#define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */
/* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) /* MPU regions. */
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portSTACK_REGION ( 4UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portSTACK_REGION ( 4UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
/* Device memory attributes used in MPU_MAIR registers. #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
*
* 8-bit values encoded as follows: /* Device memory attributes used in MPU_MAIR registers.
* Bit[7:4] - 0000 - Device Memory *
* Bit[3:2] - 00 --> Device-nGnRnE * 8-bit values encoded as follows:
* 01 --> Device-nGnRE * Bit[7:4] - 0000 - Device Memory
* 10 --> Device-nGRE * Bit[3:2] - 00 --> Device-nGnRnE
* 11 --> Device-GRE * 01 --> Device-nGnRE
* Bit[1:0] - 00, Reserved. * 10 --> Device-nGRE
*/ * 11 --> Device-GRE
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ * Bit[1:0] - 00, Reserved.
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
/* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
#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. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
/* Attributes used in MPU_RBAR registers. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
/*-----------------------------------------------------------*/
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/** /*-----------------------------------------------------------*/
* @brief Settings to define an MPU region.
*/ /**
typedef struct MPURegionSettings * @brief Settings to define an MPU region.
{ */
uint32_t ulRBAR; /**< RBAR for the region. */ typedef struct MPURegionSettings
uint32_t ulRLAR; /**< RLAR for the region. */ {
} MPURegionSettings_t; uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */
/** } MPURegionSettings_t;
* @brief MPU settings as stored in the TCB.
*/ /**
typedef struct MPU_SETTINGS * @brief MPU settings as stored in the TCB.
{ */
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ typedef struct MPU_SETTINGS
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ {
} xMPU_SETTINGS; 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. */
} xMPU_SETTINGS;
/** /*-----------------------------------------------------------*/
* @brief SVC numbers.
*/ /**
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 * @brief SVC numbers.
#define portSVC_FREE_SECURE_CONTEXT 1 */
#define portSVC_START_SCHEDULER 2 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_FREE_SECURE_CONTEXT 1
/*-----------------------------------------------------------*/ #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3
/** /*-----------------------------------------------------------*/
* @brief Scheduler utilities.
*/ /**
#define portYIELD() vPortYield() * @brief Scheduler utilities.
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) */
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portYIELD() vPortYield()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
/*-----------------------------------------------------------*/ #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/** /*-----------------------------------------------------------*/
* @brief Critical section management.
*/ /**
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() * @brief Critical section management.
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) */
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portENTER_CRITICAL() vPortEnterCritical() #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portEXIT_CRITICAL() vPortExitCritical() #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
/*-----------------------------------------------------------*/ #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/** /*-----------------------------------------------------------*/
* @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ /**
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) * @brief Task function macros as described on the FreeRTOS.org WEB site.
#define portTASK_FUNCTION( 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 )
#if( configENABLE_TRUSTZONE == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Allocate a secure context for the task. #if( configENABLE_TRUSTZONE == 1 )
* /**
* Tasks are not created with a secure context. Any task that is going to call * @brief Allocate a secure context for the task.
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a *
* secure context before it calls any secure function. * Tasks are not created with a secure context. Any task that is going to call
* * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * secure context before it calls any secure function.
*/ *
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/
/** #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
* @brief Called when a task is deleted to delete the task's secure context,
* if it has one. /**
* * @brief Called when a task is deleted to delete the task's secure context,
* @param[in] pxTCB The TCB of the task being deleted. * if it has one.
*/ *
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) * @param[in] pxTCB The TCB of the task being deleted.
#else */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#define portCLEAN_UP_TCB( pxTCB ) #else
#endif /* configENABLE_TRUSTZONE */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
/*-----------------------------------------------------------*/ #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */
#if( configENABLE_MPU == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Checks whether or not the processor is privileged. #if( configENABLE_MPU == 1 )
* /**
* @return 1 if the processor is already privileged, 0 otherwise. * @brief Checks whether or not the processor is privileged.
*/ *
#define portIS_PRIVILEGED() xIsPrivileged() * @return 1 if the processor is already privileged, 0 otherwise.
*/
/** #define portIS_PRIVILEGED() xIsPrivileged()
* @brief Raise an SVC request to raise privilege.
* /**
* The SVC handler checks that the SVC was raised from a system call and only * @brief Raise an SVC request to raise privilege.
* then it raises the privilege. If this is called from any other place, *
* the privilege is not raised. * 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,
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); * the privilege is not raised.
*/
/** #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
* register. /**
*/ * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
#define portRESET_PRIVILEGE() vResetPrivilege() * register.
#else */
#define portIS_PRIVILEGED() #define portRESET_PRIVILEGE() vResetPrivilege()
#define portRAISE_PRIVILEGE() #else
#define portRESET_PRIVILEGE() #define portIS_PRIVILEGED()
#endif /* configENABLE_MPU */ #define portRAISE_PRIVILEGE()
/*-----------------------------------------------------------*/ #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief Barriers.
*/ /**
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) * @brief Barriers.
/*-----------------------------------------------------------*/ */
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
#ifdef __cplusplus /*-----------------------------------------------------------*/
}
#endif /* 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
#endif /* PORTMACRO_H */ * warnings. */
#pragma diag_suppress=Be006
#pragma diag_suppress=Pa082
/*-----------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -1,303 +1,303 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
EXTERN pxCurrentTCB EXTERN pxCurrentTCB
EXTERN vTaskSwitchContext EXTERN vTaskSwitchContext
EXTERN vPortSVCHandler_C EXTERN vPortSVCHandler_C
PUBLIC xIsPrivileged PUBLIC xIsPrivileged
PUBLIC vResetPrivilege PUBLIC vResetPrivilege
PUBLIC vRestoreContextOfFirstTask PUBLIC vRestoreContextOfFirstTask
PUBLIC vRaisePrivilege PUBLIC vRaisePrivilege
PUBLIC vStartFirstTask PUBLIC vStartFirstTask
PUBLIC ulSetInterruptMaskFromISR PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMaskFromISR PUBLIC vClearInterruptMask
PUBLIC PendSV_Handler PUBLIC PendSV_Handler
PUBLIC SVC_Handler PUBLIC SVC_Handler
#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
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*---------------- Unprivileged Functions -------------------*/ /*---------------- Unprivileged Functions -------------------*/
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
SECTION .text:CODE:NOROOT(2) SECTION .text:CODE:NOROOT(2)
THUMB THUMB
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
xIsPrivileged: xIsPrivileged:
mrs r0, control /* r0 = CONTROL. */ mrs r0, control /* r0 = CONTROL. */
movs r1, #1 /* r1 = 1. */ movs r1, #1 /* r1 = 1. */
tst r0, r1 /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */ tst r0, r1 /* Perform r0 & r1 (bitwise AND) and update the conditions flag. */
beq running_privileged /* If the result of previous AND operation was 0, branch. */ beq running_privileged /* If the result of previous AND operation was 0, branch. */
movs r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ movs r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
bx lr /* Return. */ bx lr /* Return. */
running_privileged: running_privileged:
movs r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */ movs r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
bx lr /* Return. */ bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vResetPrivilege: vResetPrivilege:
mrs r0, control /* r0 = CONTROL. */ mrs r0, control /* r0 = CONTROL. */
movs r1, #1 /* r1 = 1. */ movs r1, #1 /* r1 = 1. */
orrs r0, r1 /* r0 = r0 | r1. */ orrs r0, r1 /* r0 = r0 | r1. */
msr control, r0 /* CONTROL = r0. */ msr control, r0 /* CONTROL = r0. */
bx lr /* Return to the caller. */ bx lr /* Return to the caller. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*----------------- Privileged Functions --------------------*/ /*----------------- Privileged Functions --------------------*/
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
SECTION privileged_functions:CODE:NOROOT(2) SECTION privileged_functions:CODE:NOROOT(2)
THUMB THUMB
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vRestoreContextOfFirstTask: vRestoreContextOfFirstTask:
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
dmb /* Complete outstanding transfers before disabling MPU. */ dmb /* Complete outstanding transfers before disabling MPU. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r3, [r2] /* Read the value of MPU_CTRL. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */
movs r4, #1 /* r4 = 1. */ movs r4, #1 /* r4 = 1. */
bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
str r3, [r2] /* Disable MPU. */ str r3, [r2] /* Disable MPU. */
adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
str r4, [r2] /* Program MAIR0. */ str r4, [r2] /* Program MAIR0. */
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
movs r4, #4 /* r4 = 4. */ movs r4, #4 /* r4 = 4. */
str r4, [r2] /* Program RNR = 4. */ str r4, [r2] /* Program RNR = 4. */
ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */ ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */ stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */
movs r4, #5 /* r4 = 5. */ movs r4, #5 /* r4 = 5. */
str r4, [r2] /* Program RNR = 5. */ str r4, [r2] /* Program RNR = 5. */
ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */ ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */ stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */
movs r4, #6 /* r4 = 6. */ movs r4, #6 /* r4 = 6. */
str r4, [r2] /* Program RNR = 6. */ str r4, [r2] /* Program RNR = 6. */
ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */ ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */ stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */
movs r4, #7 /* r4 = 7. */ movs r4, #7 /* r4 = 7. */
str r4, [r2] /* Program RNR = 7. */ str r4, [r2] /* Program RNR = 7. */
ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */ ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */ stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r3, [r2] /* Read the value of MPU_CTRL. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */
movs r4, #1 /* r4 = 1. */ movs r4, #1 /* r4 = 1. */
orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
str r3, [r2] /* Enable MPU. */ str r3, [r2] /* Enable MPU. */
dsb /* Force memory writes before continuing. */ dsb /* Force memory writes before continuing. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */
msr psplim, r1 /* Set this task's PSPLIM value. */ msr psplim, r1 /* Set this task's PSPLIM value. */
msr control, r2 /* Set this task's CONTROL value. */ msr control, r2 /* Set this task's CONTROL value. */
adds r0, #32 /* Discard everything up to r0. */ adds r0, #32 /* Discard everything up to r0. */
msr psp, r0 /* This is now the new top of stack to use in the task. */ msr psp, r0 /* This is now the new top of stack to use in the task. */
isb isb
bx r3 /* Finally, branch to EXC_RETURN. */ bx r3 /* Finally, branch to EXC_RETURN. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
msr psplim, r1 /* Set this task's PSPLIM value. */ msr psplim, r1 /* Set this task's PSPLIM value. */
movs r1, #2 /* r1 = 2. */ movs r1, #2 /* r1 = 2. */
msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */
adds r0, #32 /* Discard everything up to r0. */ adds r0, #32 /* Discard everything up to r0. */
msr psp, r0 /* This is now the new top of stack to use in the task. */ msr psp, r0 /* This is now the new top of stack to use in the task. */
isb isb
bx r2 /* Finally, branch to EXC_RETURN. */ bx r2 /* Finally, branch to EXC_RETURN. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vRaisePrivilege: vRaisePrivilege:
mrs r0, control /* Read the CONTROL register. */ mrs r0, control /* Read the CONTROL register. */
movs r1, #1 /* r1 = 1. */ movs r1, #1 /* r1 = 1. */
bics r0, r1 /* Clear the bit 0. */ bics r0, r1 /* Clear the bit 0. */
msr control, r0 /* Write back the new CONTROL value. */ msr control, r0 /* Write back the new CONTROL value. */
bx lr /* Return to the caller. */ bx lr /* Return to the caller. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vStartFirstTask: vStartFirstTask:
ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */
ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */
ldr r0, [r0] /* The first entry in vector table is stack pointer. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */
msr msp, r0 /* Set the MSP back to the start of the stack. */ msr msp, r0 /* Set the MSP back to the start of the stack. */
cpsie i /* Globally enable interrupts. */ cpsie i /* Globally enable interrupts. */
dsb dsb
isb isb
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
nop nop
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMaskFromISR: ulSetInterruptMask:
mrs r0, PRIMASK mrs r0, PRIMASK
cpsid i cpsid i
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMaskFromISR: vClearInterruptMask:
msr PRIMASK, r0 msr PRIMASK, r0
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
PendSV_Handler: PendSV_Handler:
mrs r0, psp /* Read PSP in r0. */ mrs r0, psp /* Read PSP in r0. */
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
subs r0, r0, #44 /* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */ subs r0, r0, #44 /* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */
str r0, [r1] /* Save the new top of stack in TCB. */ str r0, [r1] /* Save the new top of stack in TCB. */
mrs r1, psplim /* r1 = PSPLIM. */ mrs r1, psplim /* r1 = PSPLIM. */
mrs r2, control /* r2 = CONTROL. */ mrs r2, control /* r2 = CONTROL. */
mov r3, lr /* r3 = LR/EXC_RETURN. */ mov r3, lr /* r3 = LR/EXC_RETURN. */
stmia r0!, {r1-r7} /* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */ stmia r0!, {r1-r7} /* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */
mov r4, r8 /* r4 = r8. */ mov r4, r8 /* r4 = r8. */
mov r5, r9 /* r5 = r9. */ mov r5, r9 /* r5 = r9. */
mov r6, r10 /* r6 = r10. */ mov r6, r10 /* r6 = r10. */
mov r7, r11 /* r7 = r11. */ mov r7, r11 /* r7 = r11. */
stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */ stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
subs r0, r0, #40 /* Make space for PSPLIM, LR and the remaining registers on the stack. */ subs r0, r0, #40 /* Make space for PSPLIM, LR and the remaining registers on the stack. */
str r0, [r1] /* Save the new top of stack in TCB. */ str r0, [r1] /* Save the new top of stack in TCB. */
mrs r2, psplim /* r2 = PSPLIM. */ mrs r2, psplim /* r2 = PSPLIM. */
mov r3, lr /* r3 = LR/EXC_RETURN. */ mov r3, lr /* r3 = LR/EXC_RETURN. */
stmia r0!, {r2-r7} /* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */ stmia r0!, {r2-r7} /* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
mov r4, r8 /* r4 = r8. */ mov r4, r8 /* r4 = r8. */
mov r5, r9 /* r5 = r9. */ mov r5, r9 /* r5 = r9. */
mov r6, r10 /* r6 = r10. */ mov r6, r10 /* r6 = r10. */
mov r7, r11 /* r7 = r11. */ mov r7, r11 /* r7 = r11. */
stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */ stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
cpsid i cpsid i
bl vTaskSwitchContext bl vTaskSwitchContext
cpsie i cpsie i
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
dmb /* Complete outstanding transfers before disabling MPU. */ dmb /* Complete outstanding transfers before disabling MPU. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r3, [r2] /* Read the value of MPU_CTRL. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */
movs r4, #1 /* r4 = 1. */ movs r4, #1 /* r4 = 1. */
bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
str r3, [r2] /* Disable MPU. */ str r3, [r2] /* Disable MPU. */
adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
str r4, [r2] /* Program MAIR0. */ str r4, [r2] /* Program MAIR0. */
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
movs r4, #4 /* r4 = 4. */ movs r4, #4 /* r4 = 4. */
str r4, [r2] /* Program RNR = 4. */ str r4, [r2] /* Program RNR = 4. */
ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */ ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */ stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */
movs r4, #5 /* r4 = 5. */ movs r4, #5 /* r4 = 5. */
str r4, [r2] /* Program RNR = 5. */ str r4, [r2] /* Program RNR = 5. */
ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */ ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */ stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */
movs r4, #6 /* r4 = 6. */ movs r4, #6 /* r4 = 6. */
str r4, [r2] /* Program RNR = 6. */ str r4, [r2] /* Program RNR = 6. */
ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */ ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */ stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */
movs r4, #7 /* r4 = 7. */ movs r4, #7 /* r4 = 7. */
str r4, [r2] /* Program RNR = 7. */ str r4, [r2] /* Program RNR = 7. */
ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */ ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */ stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r3, [r2] /* Read the value of MPU_CTRL. */ ldr r3, [r2] /* Read the value of MPU_CTRL. */
movs r4, #1 /* r4 = 1. */ movs r4, #1 /* r4 = 1. */
orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
str r3, [r2] /* Enable MPU. */ str r3, [r2] /* Enable MPU. */
dsb /* Force memory writes before continuing. */ dsb /* Force memory writes before continuing. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
adds r0, r0, #28 /* Move to the high registers. */ adds r0, r0, #28 /* Move to the high registers. */
ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */ ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */
mov r8, r4 /* r8 = r4. */ mov r8, r4 /* r8 = r4. */
mov r9, r5 /* r9 = r5. */ mov r9, r5 /* r9 = r5. */
mov r10, r6 /* r10 = r6. */ mov r10, r6 /* r10 = r6. */
mov r11, r7 /* r11 = r7. */ mov r11, r7 /* r11 = r7. */
msr psp, r0 /* Remember the new top of stack for the task. */ msr psp, r0 /* Remember the new top of stack for the task. */
subs r0, r0, #44 /* Move to the starting of the saved context. */ subs r0, r0, #44 /* Move to the starting of the saved context. */
ldmia r0!, {r1-r7} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */ ldmia r0!, {r1-r7} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */
msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */
msr control, r2 /* Restore the CONTROL register value for the task. */ msr control, r2 /* Restore the CONTROL register value for the task. */
bx r3 bx r3
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
adds r0, r0, #24 /* Move to the high registers. */ adds r0, r0, #24 /* Move to the high registers. */
ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */ ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */
mov r8, r4 /* r8 = r4. */ mov r8, r4 /* r8 = r4. */
mov r9, r5 /* r9 = r5. */ mov r9, r5 /* r9 = r5. */
mov r10, r6 /* r10 = r6. */ mov r10, r6 /* r10 = r6. */
mov r11, r7 /* r11 = r7. */ mov r11, r7 /* r11 = r7. */
msr psp, r0 /* Remember the new top of stack for the task. */ msr psp, r0 /* Remember the new top of stack for the task. */
subs r0, r0, #40 /* Move to the starting of the saved context. */ subs r0, r0, #40 /* Move to the starting of the saved context. */
ldmia r0!, {r2-r7} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */ ldmia r0!, {r2-r7} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
msr psplim, r2 /* Restore the PSPLIM register value for the task. */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */
bx r3 bx r3
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
SVC_Handler: SVC_Handler:
movs r0, #4 movs r0, #4
mov r1, lr mov r1, lr
tst r0, r1 tst r0, r1
beq stacking_used_msp beq stacking_used_msp
mrs r0, psp mrs r0, psp
b vPortSVCHandler_C b vPortSVCHandler_C
stacking_used_msp: stacking_used_msp:
mrs r0, msp mrs r0, msp
b vPortSVCHandler_C b vPortSVCHandler_C
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
END END

View file

@ -1,299 +1,308 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#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.
* *
* The settings in this file configure FreeRTOS correctly for the given hardware * The settings in this file configure FreeRTOS correctly for the given hardware
* and compiler. * and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
*/ */
#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 void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #if( configENABLE_TRUSTZONE == 1 )
#endif /* configENABLE_TRUSTZONE */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_MPU == 1 ) #endif /* configENABLE_TRUSTZONE */
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #if( configENABLE_MPU == 1 )
#endif /* configENABLE_MPU */ extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
/*-----------------------------------------------------------*/ extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief MPU specific constants.
*/ /**
#if( configENABLE_MPU == 1 ) * @brief MPU specific constants.
#define portUSING_MPU_WRAPPERS 1 */
#define portPRIVILEGE_BIT ( 0x80000000UL ) #if( configENABLE_MPU == 1 )
#else #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#endif /* configENABLE_MPU */ #else
#define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */
/* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) /* MPU regions. */
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portSTACK_REGION ( 4UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portSTACK_REGION ( 4UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
/* Device memory attributes used in MPU_MAIR registers. #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
*
* 8-bit values encoded as follows: /* Device memory attributes used in MPU_MAIR registers.
* Bit[7:4] - 0000 - Device Memory *
* Bit[3:2] - 00 --> Device-nGnRnE * 8-bit values encoded as follows:
* 01 --> Device-nGnRE * Bit[7:4] - 0000 - Device Memory
* 10 --> Device-nGRE * Bit[3:2] - 00 --> Device-nGnRnE
* 11 --> Device-GRE * 01 --> Device-nGnRE
* Bit[1:0] - 00, Reserved. * 10 --> Device-nGRE
*/ * 11 --> Device-GRE
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ * Bit[1:0] - 00, Reserved.
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
/* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
#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. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
/* Attributes used in MPU_RBAR registers. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
/*-----------------------------------------------------------*/
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/** /*-----------------------------------------------------------*/
* @brief Settings to define an MPU region.
*/ /**
typedef struct MPURegionSettings * @brief Settings to define an MPU region.
{ */
uint32_t ulRBAR; /**< RBAR for the region. */ typedef struct MPURegionSettings
uint32_t ulRLAR; /**< RLAR for the region. */ {
} MPURegionSettings_t; uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */
/** } MPURegionSettings_t;
* @brief MPU settings as stored in the TCB.
*/ /**
typedef struct MPU_SETTINGS * @brief MPU settings as stored in the TCB.
{ */
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ typedef struct MPU_SETTINGS
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ {
} xMPU_SETTINGS; 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. */
} xMPU_SETTINGS;
/** /*-----------------------------------------------------------*/
* @brief SVC numbers.
*/ /**
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 * @brief SVC numbers.
#define portSVC_FREE_SECURE_CONTEXT 1 */
#define portSVC_START_SCHEDULER 2 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_FREE_SECURE_CONTEXT 1
/*-----------------------------------------------------------*/ #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3
/** /*-----------------------------------------------------------*/
* @brief Scheduler utilities.
*/ /**
#define portYIELD() vPortYield() * @brief Scheduler utilities.
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) */
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portYIELD() vPortYield()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
/*-----------------------------------------------------------*/ #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/** /*-----------------------------------------------------------*/
* @brief Critical section management.
*/ /**
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() * @brief Critical section management.
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) */
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portENTER_CRITICAL() vPortEnterCritical() #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portEXIT_CRITICAL() vPortExitCritical() #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
/*-----------------------------------------------------------*/ #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/** /*-----------------------------------------------------------*/
* @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ /**
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) * @brief Task function macros as described on the FreeRTOS.org WEB site.
#define portTASK_FUNCTION( 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 )
#if( configENABLE_TRUSTZONE == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Allocate a secure context for the task. #if( configENABLE_TRUSTZONE == 1 )
* /**
* Tasks are not created with a secure context. Any task that is going to call * @brief Allocate a secure context for the task.
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a *
* secure context before it calls any secure function. * Tasks are not created with a secure context. Any task that is going to call
* * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * secure context before it calls any secure function.
*/ *
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/
/** #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
* @brief Called when a task is deleted to delete the task's secure context,
* if it has one. /**
* * @brief Called when a task is deleted to delete the task's secure context,
* @param[in] pxTCB The TCB of the task being deleted. * if it has one.
*/ *
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) * @param[in] pxTCB The TCB of the task being deleted.
#else */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#define portCLEAN_UP_TCB( pxTCB ) #else
#endif /* configENABLE_TRUSTZONE */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
/*-----------------------------------------------------------*/ #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */
#if( configENABLE_MPU == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Checks whether or not the processor is privileged. #if( configENABLE_MPU == 1 )
* /**
* @return 1 if the processor is already privileged, 0 otherwise. * @brief Checks whether or not the processor is privileged.
*/ *
#define portIS_PRIVILEGED() xIsPrivileged() * @return 1 if the processor is already privileged, 0 otherwise.
*/
/** #define portIS_PRIVILEGED() xIsPrivileged()
* @brief Raise an SVC request to raise privilege.
* /**
* The SVC handler checks that the SVC was raised from a system call and only * @brief Raise an SVC request to raise privilege.
* then it raises the privilege. If this is called from any other place, *
* the privilege is not raised. * 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,
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); * the privilege is not raised.
*/
/** #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
* register. /**
*/ * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
#define portRESET_PRIVILEGE() vResetPrivilege() * register.
#else */
#define portIS_PRIVILEGED() #define portRESET_PRIVILEGE() vResetPrivilege()
#define portRAISE_PRIVILEGE() #else
#define portRESET_PRIVILEGE() #define portIS_PRIVILEGED()
#endif /* configENABLE_MPU */ #define portRAISE_PRIVILEGE()
/*-----------------------------------------------------------*/ #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief Barriers.
*/ /**
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) * @brief Barriers.
/*-----------------------------------------------------------*/ */
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
#ifdef __cplusplus /*-----------------------------------------------------------*/
}
#endif /* 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
#endif /* PORTMACRO_H */ * warnings. */
#pragma diag_suppress=Be006
#pragma diag_suppress=Pa082
/*-----------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -1,326 +1,341 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Including FreeRTOSConfig.h here will cause build errors if the header file
EXTERN pxCurrentTCB contains code not understood by the assembler - for example the 'extern' keyword.
EXTERN xSecureContext To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
EXTERN vTaskSwitchContext the code is included in C files but excluded by the preprocessor in assembly
EXTERN vPortSVCHandler_C files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
EXTERN SecureContext_SaveContext #include "FreeRTOSConfig.h"
EXTERN SecureContext_LoadContext
EXTERN pxCurrentTCB
PUBLIC xIsPrivileged EXTERN xSecureContext
PUBLIC vResetPrivilege EXTERN vTaskSwitchContext
PUBLIC vPortAllocateSecureContext EXTERN vPortSVCHandler_C
PUBLIC vRestoreContextOfFirstTask EXTERN SecureContext_SaveContext
PUBLIC vRaisePrivilege EXTERN SecureContext_LoadContext
PUBLIC vStartFirstTask
PUBLIC ulSetInterruptMaskFromISR PUBLIC xIsPrivileged
PUBLIC vClearInterruptMaskFromISR PUBLIC vResetPrivilege
PUBLIC PendSV_Handler PUBLIC vPortAllocateSecureContext
PUBLIC SVC_Handler PUBLIC vRestoreContextOfFirstTask
PUBLIC vPortFreeSecureContext PUBLIC vRaisePrivilege
/*-----------------------------------------------------------*/ PUBLIC vStartFirstTask
PUBLIC ulSetInterruptMask
/*---------------- Unprivileged Functions -------------------*/ PUBLIC vClearInterruptMask
PUBLIC PendSV_Handler
/*-----------------------------------------------------------*/ PUBLIC SVC_Handler
PUBLIC vPortFreeSecureContext
SECTION .text:CODE:NOROOT(2) /*-----------------------------------------------------------*/
THUMB
/*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/
xIsPrivileged: /*-----------------------------------------------------------*/
mrs r0, control /* r0 = CONTROL. */
tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ SECTION .text:CODE:NOROOT(2)
ite ne THUMB
movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ /*-----------------------------------------------------------*/
moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */
bx lr /* Return. */ xIsPrivileged:
/*-----------------------------------------------------------*/ mrs r0, control /* r0 = CONTROL. */
tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
vResetPrivilege: ite ne
mrs r0, control /* r0 = CONTROL. */ movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
orr r0, r0, #1 /* r0 = r0 | 1. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */
msr control, r0 /* CONTROL = r0. */ bx lr /* Return. */
bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
vResetPrivilege:
vPortAllocateSecureContext: mrs r0, control /* r0 = CONTROL. */
svc 0 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 0. */ orr r0, r0, #1 /* r0 = r0 | 1. */
bx lr /* Return. */ msr control, r0 /* CONTROL = r0. */
/*-----------------------------------------------------------*/ bx lr /* Return to the caller. */
/*-----------------------------------------------------------*/
/*----------------- Privileged Functions --------------------*/
vPortAllocateSecureContext:
/*-----------------------------------------------------------*/ svc 0 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 0. */
bx lr /* Return. */
SECTION privileged_functions:CODE:NOROOT(2) /*-----------------------------------------------------------*/
THUMB
/*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/
vRestoreContextOfFirstTask: /*-----------------------------------------------------------*/
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r3, [r2] /* Read pxCurrentTCB. */ SECTION privileged_functions:CODE:NOROOT(2)
ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ THUMB
/*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 )
dmb /* Complete outstanding transfers before disabling MPU. */ vRestoreContextOfFirstTask:
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r4, [r2] /* Read the value of MPU_CTRL. */ ldr r3, [r2] /* Read pxCurrentTCB. */
bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
str r4, [r2] /* Disable MPU. */
#if ( configENABLE_MPU == 1 )
adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ dmb /* Complete outstanding transfers before disabling MPU. */
ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */
str r4, [r2] /* Program MAIR0. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ str r4, [r2] /* Disable MPU. */
movs r4, #4 /* r4 = 4. */
str r4, [r2] /* Program RNR = 4. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ str r4, [r2] /* Program MAIR0. */
stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
movs r4, #4 /* r4 = 4. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ str r4, [r2] /* Program RNR = 4. */
ldr r4, [r2] /* Read the value of MPU_CTRL. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
str r4, [r2] /* Enable MPU. */ ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */
dsb /* Force memory writes before continuing. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configENABLE_MPU */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
#if ( configENABLE_MPU == 1 ) ldr r4, [r2] /* Read the value of MPU_CTRL. */
ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
ldr r5, =xSecureContext str r4, [r2] /* Enable MPU. */
str r1, [r5] /* Set xSecureContext to this task's value for the same. */ dsb /* Force memory writes before continuing. */
msr psplim, r2 /* Set this task's PSPLIM value. */ #endif /* configENABLE_MPU */
msr control, r3 /* Set this task's CONTROL value. */
adds r0, #32 /* Discard everything up to r0. */ #if ( configENABLE_MPU == 1 )
msr psp, r0 /* This is now the new top of stack to use in the task. */ ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */
isb ldr r5, =xSecureContext
bx r4 /* Finally, branch to EXC_RETURN. */ str r1, [r5] /* Set xSecureContext to this task's value for the same. */
#else /* configENABLE_MPU */ msr psplim, r2 /* Set this task's PSPLIM value. */
ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ msr control, r3 /* Set this task's CONTROL value. */
ldr r4, =xSecureContext adds r0, #32 /* Discard everything up to r0. */
str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psp, r0 /* This is now the new top of stack to use in the task. */
msr psplim, r2 /* Set this task's PSPLIM value. */ isb
movs r1, #2 /* r1 = 2. */ bx r4 /* Finally, branch to EXC_RETURN. */
msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ #else /* configENABLE_MPU */
adds r0, #32 /* Discard everything up to r0. */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
msr psp, r0 /* This is now the new top of stack to use in the task. */ ldr r4, =xSecureContext
isb str r1, [r4] /* Set xSecureContext to this task's value for the same. */
bx r3 /* Finally, branch to EXC_RETURN. */ msr psplim, r2 /* Set this task's PSPLIM value. */
#endif /* configENABLE_MPU */ movs r1, #2 /* r1 = 2. */
/*-----------------------------------------------------------*/ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */
adds r0, #32 /* Discard everything up to r0. */
vRaisePrivilege: msr psp, r0 /* This is now the new top of stack to use in the task. */
mrs r0, control /* Read the CONTROL register. */ isb
bic r0, r0, #1 /* Clear the bit 0. */ bx r3 /* Finally, branch to EXC_RETURN. */
msr control, r0 /* Write back the new CONTROL value. */ #endif /* configENABLE_MPU */
bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
vRaisePrivilege:
vStartFirstTask: mrs r0, control /* Read the CONTROL register. */
ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ bic r0, r0, #1 /* Clear the bit 0. */
ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ msr control, r0 /* Write back the new CONTROL value. */
ldr r0, [r0] /* The first entry in vector table is stack pointer. */ bx lr /* Return to the caller. */
msr msp, r0 /* Set the MSP back to the start of the stack. */ /*-----------------------------------------------------------*/
cpsie i /* Globally enable interrupts. */
cpsie f vStartFirstTask:
dsb ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */
isb ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */
/*-----------------------------------------------------------*/ msr msp, r0 /* Set the MSP back to the start of the stack. */
cpsie i /* Globally enable interrupts. */
ulSetInterruptMaskFromISR: cpsie f
mrs r0, PRIMASK dsb
cpsid i isb
bx lr svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMaskFromISR: ulSetInterruptMask:
msr PRIMASK, r0 mrs r0, basepri /* r0 = basepri. Return original basepri value. */
bx lr mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
/*-----------------------------------------------------------*/ msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb
PendSV_Handler: isb
mrs r1, psp /* Read PSP in r1. */ bx lr /* Return. */
ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ /*-----------------------------------------------------------*/
ldr r0, [r2] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
vClearInterruptMask:
cbz r0, save_ns_context /* No secure context to save. */ msr basepri, r0 /* basepri = ulMask. */
push {r0-r2, r14} dsb
bl SecureContext_SaveContext isb
pop {r0-r3} /* LR is now in r3. */ bx lr /* Return. */
mov lr, r3 /* LR = r3. */ /*-----------------------------------------------------------*/
lsls r2, r3, #25 /* 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 /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ PendSV_Handler:
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ mrs r1, psp /* Read PSP in r1. */
ldr r2, [r3] /* Read pxCurrentTCB. */ ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
#if ( configENABLE_MPU == 1 ) ldr r0, [r2] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
subs r1, r1, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
str r1, [r2] /* Save the new top of stack in TCB. */ cbz r0, save_ns_context /* No secure context to save. */
mrs r2, psplim /* r2 = PSPLIM. */ push {r0-r2, r14}
mrs r3, control /* r3 = CONTROL. */ bl SecureContext_SaveContext
mov r4, lr /* r4 = LR/EXC_RETURN. */ pop {r0-r3} /* LR is now in r3. */
stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ mov lr, r3 /* LR = r3. */
#else /* configENABLE_MPU */ lsls r2, r3, #25 /* 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. */
subs r1, r1, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ bpl save_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
str r1, [r2] /* Save the new top of stack in TCB. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
mrs r2, psplim /* r2 = PSPLIM. */ ldr r2, [r3] /* Read pxCurrentTCB. */
mov r3, lr /* r3 = LR/EXC_RETURN. */ #if ( configENABLE_MPU == 1 )
stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ subs r1, r1, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
#endif /* configENABLE_MPU */ str r1, [r2] /* Save the new top of stack in TCB. */
b select_next_task mrs r2, psplim /* r2 = PSPLIM. */
mrs r3, control /* r3 = CONTROL. */
save_ns_context: mov r4, lr /* r4 = LR/EXC_RETURN. */
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
ldr r2, [r3] /* Read pxCurrentTCB. */ #else /* configENABLE_MPU */
#if ( configENABLE_FPU == 1 ) subs r1, r1, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */
tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ str r1, [r2] /* Save the new top of stack in TCB. */
it eq mrs r2, psplim /* r2 = PSPLIM. */
vstmdbeq r1!, {s16-s31} /* Store the FPU registers which are not saved automatically. */ mov r3, lr /* r3 = LR/EXC_RETURN. */
#endif /* configENABLE_FPU */ stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
#if ( configENABLE_MPU == 1 ) #endif /* configENABLE_MPU */
subs r1, r1, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ b select_next_task
str r1, [r2] /* Save the new top of stack in TCB. */
adds r1, r1, #16 /* r1 = r1 + 16. */ save_ns_context:
stm r1, {r4-r11} /* Store the registers that are not saved automatically. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
mrs r2, psplim /* r2 = PSPLIM. */ ldr r2, [r3] /* Read pxCurrentTCB. */
mrs r3, control /* r3 = CONTROL. */ #if ( configENABLE_FPU == 1 )
mov r4, lr /* r4 = LR/EXC_RETURN. */ tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
subs r1, r1, #16 /* r1 = r1 - 16. */ it eq
stm r1, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ vstmdbeq r1!, {s16-s31} /* Store the FPU registers which are not saved automatically. */
#else /* configENABLE_MPU */ #endif /* configENABLE_FPU */
subs r1, r1, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ #if ( configENABLE_MPU == 1 )
str r1, [r2] /* Save the new top of stack in TCB. */ subs r1, r1, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
adds r1, r1, #12 /* r1 = r1 + 12. */ str r1, [r2] /* Save the new top of stack in TCB. */
stm r1, {r4-r11} /* Store the registers that are not saved automatically. */ adds r1, r1, #16 /* r1 = r1 + 16. */
mrs r2, psplim /* r2 = PSPLIM. */ stm r1, {r4-r11} /* Store the registers that are not saved automatically. */
mov r3, lr /* r3 = LR/EXC_RETURN. */ mrs r2, psplim /* r2 = PSPLIM. */
subs r1, r1, #12 /* r1 = r1 - 12. */ mrs r3, control /* r3 = CONTROL. */
stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ mov r4, lr /* r4 = LR/EXC_RETURN. */
#endif /* configENABLE_MPU */ subs r1, r1, #16 /* r1 = r1 - 16. */
stm r1, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
select_next_task: #else /* configENABLE_MPU */
cpsid i subs r1, r1, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
bl vTaskSwitchContext str r1, [r2] /* Save the new top of stack in TCB. */
cpsie i adds r1, r1, #12 /* r1 = r1 + 12. */
stm r1, {r4-r11} /* Store the registers that are not saved automatically. */
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ mrs r2, psplim /* r2 = PSPLIM. */
ldr r3, [r2] /* Read pxCurrentTCB. */ mov r3, lr /* r3 = LR/EXC_RETURN. */
ldr r1, [r3] /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ subs r1, r1, #12 /* r1 = r1 - 12. */
stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
#if ( configENABLE_MPU == 1 ) #endif /* configENABLE_MPU */
dmb /* Complete outstanding transfers before disabling MPU. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ select_next_task:
ldr r4, [r2] /* Read the value of MPU_CTRL. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
str r4, [r2] /* Disable MPU. */ dsb
isb
adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ bl vTaskSwitchContext
ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ mov r0, #0 /* r0 = 0. */
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ msr basepri, r0 /* Enable interrupts. */
str r4, [r2] /* Program MAIR0. */
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
movs r4, #4 /* r4 = 4. */ ldr r3, [r2] /* Read pxCurrentTCB. */
str r4, [r2] /* Program RNR = 4. */ ldr r1, [r3] /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */
adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ #if ( configENABLE_MPU == 1 )
ldmia r3!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ dmb /* Complete outstanding transfers before disabling MPU. */
stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r4, [r2] /* Read the value of MPU_CTRL. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
ldr r4, [r2] /* Read the value of MPU_CTRL. */ str r4, [r2] /* Disable MPU. */
orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
str r4, [r2] /* Enable MPU. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
dsb /* Force memory writes before continuing. */ ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */
#endif /* configENABLE_MPU */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
str r4, [r2] /* Program MAIR0. */
#if ( configENABLE_MPU == 1 ) ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
ldmia r1!, {r0, r2-r4} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ movs r4, #4 /* r4 = 4. */
msr psplim, r2 /* Restore the PSPLIM register value for the task. */ str r4, [r2] /* Program RNR = 4. */
msr control, r3 /* Restore the CONTROL register value for the task. */ adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
mov lr, r4 /* LR = r4. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldmia r3!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
str r0, [r2] /* Restore the task's xSecureContext. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */
push {r1,r4} ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
bl SecureContext_LoadContext /* Restore the secure context. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */
pop {r1,r4} orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
mov lr, r4 /* LR = r4. */ str r4, [r2] /* Enable MPU. */
lsls r2, r4, #25 /* 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. */ dsb /* Force memory writes before continuing. */
bpl restore_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ #endif /* configENABLE_MPU */
msr psp, r1 /* Remember the new top of stack for the task. */
bx lr #if ( configENABLE_MPU == 1 )
#else /* configENABLE_MPU */ ldmia r1!, {r0, r2-r4} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */
ldmia r1!, {r0, r2-r3} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */
msr psplim, r2 /* Restore the PSPLIM register value for the task. */ msr control, r3 /* Restore the CONTROL register value for the task. */
mov lr, r3 /* LR = r3. */ mov lr, r4 /* LR = r4. */
ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
str r0, [r2] /* Restore the task's xSecureContext. */ str r0, [r2] /* Restore the task's xSecureContext. */
cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */
push {r1,r3} push {r1,r4}
bl SecureContext_LoadContext /* Restore the secure context. */ bl SecureContext_LoadContext /* Restore the secure context. */
pop {r1,r3} pop {r1,r4}
mov lr, r3 /* LR = r3. */ mov lr, r4 /* LR = r4. */
lsls r2, r3, #25 /* 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, r4, #25 /* 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 /* 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 /* 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 /* Remember the new top of stack for the task. */ msr psp, r1 /* Remember the new top of stack for the task. */
bx lr bx lr
#endif /* configENABLE_MPU */ #else /* configENABLE_MPU */
ldmia r1!, {r0, r2-r3} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */
restore_ns_context: msr psplim, r2 /* Restore the PSPLIM register value for the task. */
ldmia r1!, {r4-r11} /* Restore the registers that are not automatically restored. */ mov lr, r3 /* LR = r3. */
#if ( configENABLE_FPU == 1 ) ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ str r0, [r2] /* Restore the task's xSecureContext. */
it eq cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */
vldmiaeq r1!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */ push {r1,r3}
#endif /* configENABLE_FPU */ bl SecureContext_LoadContext /* Restore the secure context. */
msr psp, r1 /* Remember the new top of stack for the task. */ pop {r1,r3}
bx lr mov lr, r3 /* LR = r3. */
/*-----------------------------------------------------------*/ lsls r2, r3, #25 /* 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 /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
SVC_Handler: msr psp, r1 /* Remember the new top of stack for the task. */
tst lr, #4 bx lr
ite eq #endif /* configENABLE_MPU */
mrseq r0, msp
mrsne r0, psp restore_ns_context:
b vPortSVCHandler_C ldmia r1!, {r4-r11} /* Restore the registers that are not automatically restored. */
/*-----------------------------------------------------------*/ #if ( configENABLE_FPU == 1 )
tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
vPortFreeSecureContext: it eq
/* r0 = uint32_t *pulTCB. */ vldmiaeq r1!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */
ldr r1, [r0] /* The first item in the TCB is the top of the stack. */ #endif /* configENABLE_FPU */
ldr r0, [r1] /* The first item on the stack is the task's xSecureContext. */ msr psp, r1 /* Remember the new top of stack for the task. */
cmp r0, #0 /* Raise svc if task's xSecureContext is not NULL. */ bx lr
it ne /*-----------------------------------------------------------*/
svcne 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */
bx lr /* Return. */ SVC_Handler:
/*-----------------------------------------------------------*/ tst lr, #4
ite eq
END mrseq r0, msp
mrsne r0, psp
b vPortSVCHandler_C
/*-----------------------------------------------------------*/
vPortFreeSecureContext:
/* r0 = uint32_t *pulTCB. */
ldr r1, [r0] /* The first item in the TCB is the top of the stack. */
ldr r0, [r1] /* The first item on the stack is the task's xSecureContext. */
cmp r0, #0 /* Raise svc if task's xSecureContext is not NULL. */
it ne
svcne 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */
bx lr /* Return. */
/*-----------------------------------------------------------*/
END

View file

@ -1,299 +1,308 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#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.
* *
* The settings in this file configure FreeRTOS correctly for the given hardware * The settings in this file configure FreeRTOS correctly for the given hardware
* and compiler. * and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
*/ */
#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 void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #if( configENABLE_TRUSTZONE == 1 )
#endif /* configENABLE_TRUSTZONE */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_MPU == 1 ) #endif /* configENABLE_TRUSTZONE */
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #if( configENABLE_MPU == 1 )
#endif /* configENABLE_MPU */ extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
/*-----------------------------------------------------------*/ extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief MPU specific constants.
*/ /**
#if( configENABLE_MPU == 1 ) * @brief MPU specific constants.
#define portUSING_MPU_WRAPPERS 1 */
#define portPRIVILEGE_BIT ( 0x80000000UL ) #if( configENABLE_MPU == 1 )
#else #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#endif /* configENABLE_MPU */ #else
#define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */
/* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) /* MPU regions. */
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portSTACK_REGION ( 4UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portSTACK_REGION ( 4UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
/* Device memory attributes used in MPU_MAIR registers. #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
*
* 8-bit values encoded as follows: /* Device memory attributes used in MPU_MAIR registers.
* Bit[7:4] - 0000 - Device Memory *
* Bit[3:2] - 00 --> Device-nGnRnE * 8-bit values encoded as follows:
* 01 --> Device-nGnRE * Bit[7:4] - 0000 - Device Memory
* 10 --> Device-nGRE * Bit[3:2] - 00 --> Device-nGnRnE
* 11 --> Device-GRE * 01 --> Device-nGnRE
* Bit[1:0] - 00, Reserved. * 10 --> Device-nGRE
*/ * 11 --> Device-GRE
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ * Bit[1:0] - 00, Reserved.
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
/* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
#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. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
/* Attributes used in MPU_RBAR registers. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
/*-----------------------------------------------------------*/
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/** /*-----------------------------------------------------------*/
* @brief Settings to define an MPU region.
*/ /**
typedef struct MPURegionSettings * @brief Settings to define an MPU region.
{ */
uint32_t ulRBAR; /**< RBAR for the region. */ typedef struct MPURegionSettings
uint32_t ulRLAR; /**< RLAR for the region. */ {
} MPURegionSettings_t; uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */
/** } MPURegionSettings_t;
* @brief MPU settings as stored in the TCB.
*/ /**
typedef struct MPU_SETTINGS * @brief MPU settings as stored in the TCB.
{ */
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ typedef struct MPU_SETTINGS
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ {
} xMPU_SETTINGS; 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. */
} xMPU_SETTINGS;
/** /*-----------------------------------------------------------*/
* @brief SVC numbers.
*/ /**
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 * @brief SVC numbers.
#define portSVC_FREE_SECURE_CONTEXT 1 */
#define portSVC_START_SCHEDULER 2 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_FREE_SECURE_CONTEXT 1
/*-----------------------------------------------------------*/ #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3
/** /*-----------------------------------------------------------*/
* @brief Scheduler utilities.
*/ /**
#define portYIELD() vPortYield() * @brief Scheduler utilities.
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) */
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portYIELD() vPortYield()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
/*-----------------------------------------------------------*/ #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/** /*-----------------------------------------------------------*/
* @brief Critical section management.
*/ /**
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() * @brief Critical section management.
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) */
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portENTER_CRITICAL() vPortEnterCritical() #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portEXIT_CRITICAL() vPortExitCritical() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
/*-----------------------------------------------------------*/ #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/** /*-----------------------------------------------------------*/
* @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ /**
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) * @brief Task function macros as described on the FreeRTOS.org WEB site.
#define portTASK_FUNCTION( 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 )
#if( configENABLE_TRUSTZONE == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Allocate a secure context for the task. #if( configENABLE_TRUSTZONE == 1 )
* /**
* Tasks are not created with a secure context. Any task that is going to call * @brief Allocate a secure context for the task.
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a *
* secure context before it calls any secure function. * Tasks are not created with a secure context. Any task that is going to call
* * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * secure context before it calls any secure function.
*/ *
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/
/** #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
* @brief Called when a task is deleted to delete the task's secure context,
* if it has one. /**
* * @brief Called when a task is deleted to delete the task's secure context,
* @param[in] pxTCB The TCB of the task being deleted. * if it has one.
*/ *
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) * @param[in] pxTCB The TCB of the task being deleted.
#else */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#define portCLEAN_UP_TCB( pxTCB ) #else
#endif /* configENABLE_TRUSTZONE */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
/*-----------------------------------------------------------*/ #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */
#if( configENABLE_MPU == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Checks whether or not the processor is privileged. #if( configENABLE_MPU == 1 )
* /**
* @return 1 if the processor is already privileged, 0 otherwise. * @brief Checks whether or not the processor is privileged.
*/ *
#define portIS_PRIVILEGED() xIsPrivileged() * @return 1 if the processor is already privileged, 0 otherwise.
*/
/** #define portIS_PRIVILEGED() xIsPrivileged()
* @brief Raise an SVC request to raise privilege.
* /**
* The SVC handler checks that the SVC was raised from a system call and only * @brief Raise an SVC request to raise privilege.
* then it raises the privilege. If this is called from any other place, *
* the privilege is not raised. * 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,
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); * the privilege is not raised.
*/
/** #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
* register. /**
*/ * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
#define portRESET_PRIVILEGE() vResetPrivilege() * register.
#else */
#define portIS_PRIVILEGED() #define portRESET_PRIVILEGE() vResetPrivilege()
#define portRAISE_PRIVILEGE() #else
#define portRESET_PRIVILEGE() #define portIS_PRIVILEGED()
#endif /* configENABLE_MPU */ #define portRAISE_PRIVILEGE()
/*-----------------------------------------------------------*/ #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief Barriers.
*/ /**
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) * @brief Barriers.
/*-----------------------------------------------------------*/ */
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
#ifdef __cplusplus /*-----------------------------------------------------------*/
}
#endif /* 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
#endif /* PORTMACRO_H */ * warnings. */
#pragma diag_suppress=Be006
#pragma diag_suppress=Pa082
/*-----------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -1,242 +1,257 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Including FreeRTOSConfig.h here will cause build errors if the header file
EXTERN pxCurrentTCB contains code not understood by the assembler - for example the 'extern' keyword.
EXTERN vTaskSwitchContext To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
EXTERN vPortSVCHandler_C the code is included in C files but excluded by the preprocessor in assembly
files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
PUBLIC xIsPrivileged #include "FreeRTOSConfig.h"
PUBLIC vResetPrivilege
PUBLIC vRestoreContextOfFirstTask EXTERN pxCurrentTCB
PUBLIC vRaisePrivilege EXTERN vTaskSwitchContext
PUBLIC vStartFirstTask EXTERN vPortSVCHandler_C
PUBLIC ulSetInterruptMaskFromISR
PUBLIC vClearInterruptMaskFromISR PUBLIC xIsPrivileged
PUBLIC PendSV_Handler PUBLIC vResetPrivilege
PUBLIC SVC_Handler PUBLIC vRestoreContextOfFirstTask
/*-----------------------------------------------------------*/ PUBLIC vRaisePrivilege
PUBLIC vStartFirstTask
/*---------------- Unprivileged Functions -------------------*/ PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMask
/*-----------------------------------------------------------*/ PUBLIC PendSV_Handler
PUBLIC SVC_Handler
SECTION .text:CODE:NOROOT(2) /*-----------------------------------------------------------*/
THUMB
/*-----------------------------------------------------------*/ /*---------------- Unprivileged Functions -------------------*/
xIsPrivileged: /*-----------------------------------------------------------*/
mrs r0, control /* r0 = CONTROL. */
tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ SECTION .text:CODE:NOROOT(2)
ite ne THUMB
movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ /*-----------------------------------------------------------*/
moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */
bx lr /* Return. */ xIsPrivileged:
/*-----------------------------------------------------------*/ mrs r0, control /* r0 = CONTROL. */
tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
vResetPrivilege: ite ne
mrs r0, control /* r0 = CONTROL. */ movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
orr r0, r0, #1 /* r0 = r0 | 1. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */
msr control, r0 /* CONTROL = r0. */ bx lr /* Return. */
bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
vResetPrivilege:
/*----------------- Privileged Functions --------------------*/ mrs r0, control /* r0 = CONTROL. */
orr r0, r0, #1 /* r0 = r0 | 1. */
/*-----------------------------------------------------------*/ msr control, r0 /* CONTROL = r0. */
bx lr /* Return to the caller. */
SECTION privileged_functions:CODE:NOROOT(2) /*-----------------------------------------------------------*/
THUMB
/*-----------------------------------------------------------*/ /*----------------- Privileged Functions --------------------*/
vRestoreContextOfFirstTask: /*-----------------------------------------------------------*/
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r2] /* Read pxCurrentTCB. */ SECTION privileged_functions:CODE:NOROOT(2)
ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ THUMB
/*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 )
dmb /* Complete outstanding transfers before disabling MPU. */ vRestoreContextOfFirstTask:
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r4, [r2] /* Read the value of MPU_CTRL. */ ldr r1, [r2] /* Read pxCurrentTCB. */
bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
str r4, [r2] /* Disable MPU. */
#if ( configENABLE_MPU == 1 )
adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ dmb /* Complete outstanding transfers before disabling MPU. */
ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */
str r3, [r2] /* Program MAIR0. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ str r4, [r2] /* Disable MPU. */
movs r3, #4 /* r3 = 4. */
str r3, [r2] /* Program RNR = 4. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ str r3, [r2] /* Program MAIR0. */
stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
movs r3, #4 /* r3 = 4. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ str r3, [r2] /* Program RNR = 4. */
ldr r4, [r2] /* Read the value of MPU_CTRL. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
str r4, [r2] /* Enable MPU. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
dsb /* Force memory writes before continuing. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configENABLE_MPU */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
#if ( configENABLE_MPU == 1 ) ldr r4, [r2] /* Read the value of MPU_CTRL. */
ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
msr psplim, r1 /* Set this task's PSPLIM value. */ str r4, [r2] /* Enable MPU. */
msr control, r2 /* Set this task's CONTROL value. */ dsb /* Force memory writes before continuing. */
adds r0, #32 /* Discard everything up to r0. */ #endif /* configENABLE_MPU */
msr psp, r0 /* This is now the new top of stack to use in the task. */
isb #if ( configENABLE_MPU == 1 )
bx r3 /* Finally, branch to EXC_RETURN. */ ldm r0!, {r1-r3} /* Read from stack - r1 = PSPLIM, r2 = CONTROL and r3 = EXC_RETURN. */
#else /* configENABLE_MPU */ msr psplim, r1 /* Set this task's PSPLIM value. */
ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr control, r2 /* Set this task's CONTROL value. */
msr psplim, r1 /* Set this task's PSPLIM value. */ adds r0, #32 /* Discard everything up to r0. */
movs r1, #2 /* r1 = 2. */ msr psp, r0 /* This is now the new top of stack to use in the task. */
msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ isb
adds r0, #32 /* Discard everything up to r0. */ bx r3 /* Finally, branch to EXC_RETURN. */
msr psp, r0 /* This is now the new top of stack to use in the task. */ #else /* configENABLE_MPU */
isb ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
bx r2 /* Finally, branch to EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */
#endif /* configENABLE_MPU */ movs r1, #2 /* r1 = 2. */
/*-----------------------------------------------------------*/ msr CONTROL, r1 /* Switch to use PSP in the thread mode. */
adds r0, #32 /* Discard everything up to r0. */
vRaisePrivilege: msr psp, r0 /* This is now the new top of stack to use in the task. */
mrs r0, control /* Read the CONTROL register. */ isb
bic r0, r0, #1 /* Clear the bit 0. */ bx r2 /* Finally, branch to EXC_RETURN. */
msr control, r0 /* Write back the new CONTROL value. */ #endif /* configENABLE_MPU */
bx lr /* Return to the caller. */ /*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
vRaisePrivilege:
vStartFirstTask: mrs r0, control /* Read the CONTROL register. */
ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */ bic r0, r0, #1 /* Clear the bit 0. */
ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */ msr control, r0 /* Write back the new CONTROL value. */
ldr r0, [r0] /* The first entry in vector table is stack pointer. */ bx lr /* Return to the caller. */
msr msp, r0 /* Set the MSP back to the start of the stack. */ /*-----------------------------------------------------------*/
cpsie i /* Globally enable interrupts. */
cpsie f vStartFirstTask:
dsb ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */
isb ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */ ldr r0, [r0] /* The first entry in vector table is stack pointer. */
/*-----------------------------------------------------------*/ msr msp, r0 /* Set the MSP back to the start of the stack. */
cpsie i /* Globally enable interrupts. */
ulSetInterruptMaskFromISR: cpsie f
mrs r0, PRIMASK dsb
cpsid i isb
bx lr svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMaskFromISR: ulSetInterruptMask:
msr PRIMASK, r0 mrs r0, basepri /* r0 = basepri. Return original basepri value. */
bx lr mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
/*-----------------------------------------------------------*/ msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb
PendSV_Handler: isb
mrs r0, psp /* Read PSP in r0. */ bx lr /* Return. */
#if ( configENABLE_FPU == 1 ) /*-----------------------------------------------------------*/
tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
it eq vClearInterruptMask:
vstmdbeq r0!, {s16-s31} /* Store the FPU registers which are not saved automatically. */ msr basepri, r0 /* basepri = ulMask. */
#endif /* configENABLE_FPU */ dsb
#if ( configENABLE_MPU == 1 ) isb
mrs r1, psplim /* r1 = PSPLIM. */ bx lr /* Return. */
mrs r2, control /* r2 = CONTROL. */ /*-----------------------------------------------------------*/
mov r3, lr /* r3 = LR/EXC_RETURN. */
stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ PendSV_Handler:
#else /* configENABLE_MPU */ mrs r0, psp /* Read PSP in r0. */
mrs r2, psplim /* r2 = PSPLIM. */ #if ( configENABLE_FPU == 1 )
mov r3, lr /* r3 = LR/EXC_RETURN. */ tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ it eq
#endif /* configENABLE_MPU */ vstmdbeq r0!, {s16-s31} /* Store the FPU registers which are not saved automatically. */
#endif /* configENABLE_FPU */
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ #if ( configENABLE_MPU == 1 )
ldr r1, [r2] /* Read pxCurrentTCB. */ mrs r1, psplim /* r1 = PSPLIM. */
str r0, [r1] /* Save the new top of stack in TCB. */ mrs r2, control /* r2 = CONTROL. */
mov r3, lr /* r3 = LR/EXC_RETURN. */
cpsid i stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */
bl vTaskSwitchContext #else /* configENABLE_MPU */
cpsie i mrs r2, psplim /* r2 = PSPLIM. */
mov r3, lr /* r3 = LR/EXC_RETURN. */
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */
ldr r1, [r2] /* Read pxCurrentTCB. */ #endif /* configENABLE_MPU */
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
#if ( configENABLE_MPU == 1 ) ldr r1, [r2] /* Read pxCurrentTCB. */
dmb /* Complete outstanding transfers before disabling MPU. */ str r0, [r1] /* Save the new top of stack in TCB. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r4, [r2] /* Read the value of MPU_CTRL. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
str r4, [r2] /* Disable MPU. */ dsb
isb
adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ bl vTaskSwitchContext
ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ mov r0, #0 /* r0 = 0. */
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ msr basepri, r0 /* Enable interrupts. */
str r3, [r2] /* Program MAIR0. */
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
movs r3, #4 /* r3 = 4. */ ldr r1, [r2] /* Read pxCurrentTCB. */
str r3, [r2] /* Program RNR = 4. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ #if ( configENABLE_MPU == 1 )
ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ dmb /* Complete outstanding transfers before disabling MPU. */
stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
ldr r4, [r2] /* Read the value of MPU_CTRL. */
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
ldr r4, [r2] /* Read the value of MPU_CTRL. */ str r4, [r2] /* Disable MPU. */
orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
str r4, [r2] /* Enable MPU. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
dsb /* Force memory writes before continuing. */ ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */
#endif /* configENABLE_MPU */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
str r3, [r2] /* Program MAIR0. */
#if ( configENABLE_MPU == 1 ) ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ movs r3, #4 /* r3 = 4. */
#else /* configENABLE_MPU */ str r3, [r2] /* Program RNR = 4. */
ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
#endif /* configENABLE_MPU */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
#if ( configENABLE_FPU == 1 ) stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
it eq ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
vldmiaeq r0!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */
#endif /* configENABLE_FPU */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
str r4, [r2] /* Enable MPU. */
#if ( configENABLE_MPU == 1 ) dsb /* Force memory writes before continuing. */
msr psplim, r1 /* Restore the PSPLIM register value for the task. */ #endif /* configENABLE_MPU */
msr control, r2 /* Restore the CONTROL register value for the task. */
#else /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 )
msr psplim, r2 /* Restore the PSPLIM register value for the task. */ ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */
#endif /* configENABLE_MPU */ #else /* configENABLE_MPU */
msr psp, r0 /* Remember the new top of stack for the task. */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
bx r3 #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/
#if ( configENABLE_FPU == 1 )
SVC_Handler: tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
tst lr, #4 it eq
ite eq vldmiaeq r0!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */
mrseq r0, msp #endif /* configENABLE_FPU */
mrsne r0, psp
b vPortSVCHandler_C #if ( configENABLE_MPU == 1 )
/*-----------------------------------------------------------*/ msr psplim, r1 /* Restore the PSPLIM register value for the task. */
msr control, r2 /* Restore the CONTROL register value for the task. */
END #else /* configENABLE_MPU */
msr psplim, r2 /* Restore the PSPLIM register value for the task. */
#endif /* configENABLE_MPU */
msr psp, r0 /* Remember the new top of stack for the task. */
bx r3
/*-----------------------------------------------------------*/
SVC_Handler:
tst lr, #4
ite eq
mrseq r0, msp
mrsne r0, psp
b vPortSVCHandler_C
/*-----------------------------------------------------------*/
END

View file

@ -1,299 +1,308 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#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.
* *
* The settings in this file configure FreeRTOS correctly for the given hardware * The settings in this file configure FreeRTOS correctly for the given hardware
* and compiler. * and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
*/ */
#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 void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_TRUSTZONE == 1 ) extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; #if( configENABLE_TRUSTZONE == 1 )
#endif /* configENABLE_TRUSTZONE */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#if( configENABLE_MPU == 1 ) #endif /* configENABLE_TRUSTZONE */
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #if( configENABLE_MPU == 1 )
#endif /* configENABLE_MPU */ extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
/*-----------------------------------------------------------*/ extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief MPU specific constants.
*/ /**
#if( configENABLE_MPU == 1 ) * @brief MPU specific constants.
#define portUSING_MPU_WRAPPERS 1 */
#define portPRIVILEGE_BIT ( 0x80000000UL ) #if( configENABLE_MPU == 1 )
#else #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#endif /* configENABLE_MPU */ #else
#define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */
/* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) /* MPU regions. */
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portSTACK_REGION ( 4UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portSTACK_REGION ( 4UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
/* Device memory attributes used in MPU_MAIR registers. #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
*
* 8-bit values encoded as follows: /* Device memory attributes used in MPU_MAIR registers.
* Bit[7:4] - 0000 - Device Memory *
* Bit[3:2] - 00 --> Device-nGnRnE * 8-bit values encoded as follows:
* 01 --> Device-nGnRE * Bit[7:4] - 0000 - Device Memory
* 10 --> Device-nGRE * Bit[3:2] - 00 --> Device-nGnRnE
* 11 --> Device-GRE * 01 --> Device-nGnRE
* Bit[1:0] - 00, Reserved. * 10 --> Device-nGRE
*/ * 11 --> Device-GRE
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ * Bit[1:0] - 00, Reserved.
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
/* Normal memory attributes used in MPU_MAIR registers. */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
#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. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
/* Attributes used in MPU_RBAR registers. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
/*-----------------------------------------------------------*/
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/** /*-----------------------------------------------------------*/
* @brief Settings to define an MPU region.
*/ /**
typedef struct MPURegionSettings * @brief Settings to define an MPU region.
{ */
uint32_t ulRBAR; /**< RBAR for the region. */ typedef struct MPURegionSettings
uint32_t ulRLAR; /**< RLAR for the region. */ {
} MPURegionSettings_t; uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */
/** } MPURegionSettings_t;
* @brief MPU settings as stored in the TCB.
*/ /**
typedef struct MPU_SETTINGS * @brief MPU settings as stored in the TCB.
{ */
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ typedef struct MPU_SETTINGS
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ {
} xMPU_SETTINGS; 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. */
} xMPU_SETTINGS;
/** /*-----------------------------------------------------------*/
* @brief SVC numbers.
*/ /**
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 * @brief SVC numbers.
#define portSVC_FREE_SECURE_CONTEXT 1 */
#define portSVC_START_SCHEDULER 2 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_FREE_SECURE_CONTEXT 1
/*-----------------------------------------------------------*/ #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3
/** /*-----------------------------------------------------------*/
* @brief Scheduler utilities.
*/ /**
#define portYIELD() vPortYield() * @brief Scheduler utilities.
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) */
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portYIELD() vPortYield()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
/*-----------------------------------------------------------*/ #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/** /*-----------------------------------------------------------*/
* @brief Critical section management.
*/ /**
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() * @brief Critical section management.
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) */
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMask( x )
#define portENTER_CRITICAL() vPortEnterCritical() #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portEXIT_CRITICAL() vPortExitCritical() #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
/*-----------------------------------------------------------*/ #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/** /*-----------------------------------------------------------*/
* @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ /**
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) * @brief Task function macros as described on the FreeRTOS.org WEB site.
#define portTASK_FUNCTION( 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 )
#if( configENABLE_TRUSTZONE == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Allocate a secure context for the task. #if( configENABLE_TRUSTZONE == 1 )
* /**
* Tasks are not created with a secure context. Any task that is going to call * @brief Allocate a secure context for the task.
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a *
* secure context before it calls any secure function. * Tasks are not created with a secure context. Any task that is going to call
* * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * secure context before it calls any secure function.
*/ *
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/
/** #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
* @brief Called when a task is deleted to delete the task's secure context,
* if it has one. /**
* * @brief Called when a task is deleted to delete the task's secure context,
* @param[in] pxTCB The TCB of the task being deleted. * if it has one.
*/ *
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) * @param[in] pxTCB The TCB of the task being deleted.
#else */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#define portCLEAN_UP_TCB( pxTCB ) #else
#endif /* configENABLE_TRUSTZONE */ #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
/*-----------------------------------------------------------*/ #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */
#if( configENABLE_MPU == 1 ) /*-----------------------------------------------------------*/
/**
* @brief Checks whether or not the processor is privileged. #if( configENABLE_MPU == 1 )
* /**
* @return 1 if the processor is already privileged, 0 otherwise. * @brief Checks whether or not the processor is privileged.
*/ *
#define portIS_PRIVILEGED() xIsPrivileged() * @return 1 if the processor is already privileged, 0 otherwise.
*/
/** #define portIS_PRIVILEGED() xIsPrivileged()
* @brief Raise an SVC request to raise privilege.
* /**
* The SVC handler checks that the SVC was raised from a system call and only * @brief Raise an SVC request to raise privilege.
* then it raises the privilege. If this is called from any other place, *
* the privilege is not raised. * 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,
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); * the privilege is not raised.
*/
/** #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
* register. /**
*/ * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
#define portRESET_PRIVILEGE() vResetPrivilege() * register.
#else */
#define portIS_PRIVILEGED() #define portRESET_PRIVILEGE() vResetPrivilege()
#define portRAISE_PRIVILEGE() #else
#define portRESET_PRIVILEGE() #define portIS_PRIVILEGED()
#endif /* configENABLE_MPU */ #define portRAISE_PRIVILEGE()
/*-----------------------------------------------------------*/ #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */
/** /*-----------------------------------------------------------*/
* @brief Barriers.
*/ /**
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) * @brief Barriers.
/*-----------------------------------------------------------*/ */
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
#ifdef __cplusplus /*-----------------------------------------------------------*/
}
#endif /* 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
#endif /* PORTMACRO_H */ * warnings. */
#pragma diag_suppress=Be006
#pragma diag_suppress=Pa082
/*-----------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View file

@ -1,113 +1,113 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef __PORT_ASM_H__ #ifndef __PORT_ASM_H__
#define __PORT_ASM_H__ #define __PORT_ASM_H__
/* Scheduler includes. */ /* Scheduler includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
/* MPU wrappers includes. */ /* MPU wrappers includes. */
#include "mpu_wrappers.h" #include "mpu_wrappers.h"
/** /**
* @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
* register. * register.
* *
* @note This is a privileged function and should only be called from the kenrel * @note This is a privileged function and should only be called from the kenrel
* code. * code.
* *
* Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit 0 of the CONTROL register defines the privilege level of Thread Mode.
* 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
* register. * register.
* *
* Bit 0 of the CONTROL register defines the privilege level of Thread Mode. * Bit 0 of the CONTROL register defines the privilege level of Thread Mode.
* 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 ulSetInterruptMaskFromISR( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION; uint32_t ulSetInterruptMask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
/** /**
* @brief Enables interrupts. * @brief Enables interrupts.
*/ */
void vClearInterruptMaskFromISR( 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.
* *
* @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__ */

View file

@ -1,10 +1,10 @@
This directory tree contains the master copy of the FreeeRTOS Cortex-M33 port. This directory tree contains the master copy of the FreeeRTOS Cortex-M33 port.
Do not use the files located here! These file are copied into separate Do not use the files located here! These file are copied into separate
FreeRTOS/Source/portable/[compiler]/ARM_CM33_NNN directories prior to each FreeRTOS/Source/portable/[compiler]/ARM_CM33_NNN directories prior to each
FreeRTOS release. FreeRTOS release.
If your Cortex-M33 application uses TrustZone then use the files from the If your Cortex-M33 application uses TrustZone then use the files from the
FreeRTOS/Source/portable/[compiler]/ARM_CM33 directories. FreeRTOS/Source/portable/[compiler]/ARM_CM33 directories.
If your Cortex-M33 application does not use TrustZone then use the files from If your Cortex-M33 application does not use TrustZone then use the files from
the FreeRTOS/Source/portable/[compiler]/ARM_CM33_NTZ directories. the FreeRTOS/Source/portable/[compiler]/ARM_CM33_NTZ directories.

View file

@ -1,91 +1,91 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Secure context includes. */ /* Secure context includes. */
#include "secure_context.h" #include "secure_context.h"
/* 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
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ) secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
{ {
/* xSecureContextHandle value is in r0. */ /* xSecureContextHandle value is in r0. */
__asm volatile __asm volatile
( (
" .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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ) secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
{ {
/* xSecureContextHandle value is in r0. */ /* xSecureContextHandle value is in r0. */
__asm volatile __asm volatile
( (
" .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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,88 +1,88 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Secure context includes. */ /* Secure context includes. */
#include "secure_context.h" #include "secure_context.h"
/* Secure port macros. */ /* Secure port macros. */
#include "secure_port_macros.h" #include "secure_port_macros.h"
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ) secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
{ {
/* xSecureContextHandle value is in r0. */ /* xSecureContextHandle value is in r0. */
__asm volatile __asm volatile
( (
" .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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ) secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
{ {
/* xSecureContextHandle value is in r0. */ /* xSecureContextHandle value is in r0. */
__asm volatile __asm volatile
( (
" .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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,48 +1,48 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Secure context includes. */ /* Secure context includes. */
#include "secure_context.h" #include "secure_context.h"
/* Secure port macros. */ /* Secure port macros. */
#include "secure_port_macros.h" #include "secure_port_macros.h"
/* Functions implemented in assembler file. */ /* Functions implemented in assembler file. */
extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle ); extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle );
extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle ); extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle );
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ) secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
{ {
SecureContext_LoadContextAsm( xSecureContextHandle ); SecureContext_LoadContextAsm( xSecureContextHandle );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ) secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
{ {
SecureContext_SaveContextAsm( xSecureContextHandle ); SecureContext_SaveContextAsm( xSecureContextHandle );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,76 +1,76 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
SECTION .text:CODE:NOROOT(2) SECTION .text:CODE:NOROOT(2)
THUMB THUMB
PUBLIC SecureContext_LoadContextAsm PUBLIC SecureContext_LoadContextAsm
PUBLIC SecureContext_SaveContextAsm PUBLIC SecureContext_SaveContextAsm
#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
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
SecureContext_LoadContextAsm: SecureContext_LoadContextAsm:
/* xSecureContextHandle value is in r0. */ /* xSecureContextHandle value is in r0. */
mrs r1, ipsr /* r1 = IPSR. */ mrs r1, ipsr /* r1 = IPSR. */
cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
ldmia r0!, {r1, r2} /* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */ ldmia r0!, {r1, r2} /* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */ ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */
msr control, r3 /* CONTROL = r3. */ msr control, r3 /* CONTROL = r3. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
msr psplim, r2 /* PSPLIM = r2. */ msr psplim, r2 /* PSPLIM = r2. */
msr psp, r1 /* PSP = r1. */ msr psp, r1 /* PSP = r1. */
load_ctx_therad_mode: load_ctx_therad_mode:
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
SecureContext_SaveContextAsm: SecureContext_SaveContextAsm:
/* xSecureContextHandle value is in r0. */ /* xSecureContextHandle value is in r0. */
mrs r1, ipsr /* r1 = IPSR. */ mrs r1, ipsr /* r1 = IPSR. */
cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
mrs r1, psp /* r1 = PSP. */ mrs r1, psp /* r1 = PSP. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
mrs r2, control /* r2 = CONTROL. */ mrs r2, control /* r2 = CONTROL. */
subs r1, r1, #4 /* Make space for the CONTROL value on the stack. */ subs r1, r1, #4 /* Make space for the CONTROL value on the stack. */
str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */ str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
stmia r1!, {r2} /* Store CONTROL value on the stack. */ stmia r1!, {r2} /* Store CONTROL value on the stack. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */ str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
movs r1, #0 /* r1 = securecontextNO_STACK. */ movs r1, #0 /* r1 = securecontextNO_STACK. */
msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */ msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */
msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
save_ctx_therad_mode: save_ctx_therad_mode:
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
END END

View file

@ -1,48 +1,48 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Secure context includes. */ /* Secure context includes. */
#include "secure_context.h" #include "secure_context.h"
/* Secure port macros. */ /* Secure port macros. */
#include "secure_port_macros.h" #include "secure_port_macros.h"
/* Functions implemented in assembler file. */ /* Functions implemented in assembler file. */
extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle ); extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle );
extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle ); extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle );
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ) secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
{ {
SecureContext_LoadContextAsm( xSecureContextHandle ); SecureContext_LoadContextAsm( xSecureContextHandle );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ) secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
{ {
SecureContext_SaveContextAsm( xSecureContextHandle ); SecureContext_SaveContextAsm( xSecureContextHandle );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,73 +1,73 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
SECTION .text:CODE:NOROOT(2) SECTION .text:CODE:NOROOT(2)
THUMB THUMB
PUBLIC SecureContext_LoadContextAsm PUBLIC SecureContext_LoadContextAsm
PUBLIC SecureContext_SaveContextAsm PUBLIC SecureContext_SaveContextAsm
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
SecureContext_LoadContextAsm: SecureContext_LoadContextAsm:
/* xSecureContextHandle value is in r0. */ /* xSecureContextHandle value is in r0. */
mrs r1, ipsr /* r1 = IPSR. */ mrs r1, ipsr /* r1 = IPSR. */
cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
ldmia r0!, {r1, r2} /* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */ ldmia r0!, {r1, r2} /* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */ ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */
msr control, r3 /* CONTROL = r3. */ msr control, r3 /* CONTROL = r3. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
msr psplim, r2 /* PSPLIM = r2. */ msr psplim, r2 /* PSPLIM = r2. */
msr psp, r1 /* PSP = r1. */ msr psp, r1 /* PSP = r1. */
load_ctx_therad_mode: load_ctx_therad_mode:
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
SecureContext_SaveContextAsm: SecureContext_SaveContextAsm:
/* xSecureContextHandle value is in r0. */ /* xSecureContextHandle value is in r0. */
mrs r1, ipsr /* r1 = IPSR. */ mrs r1, ipsr /* r1 = IPSR. */
cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */ cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
mrs r1, psp /* r1 = PSP. */ mrs r1, psp /* r1 = PSP. */
#if ( configENABLE_FPU == 1 ) #if ( configENABLE_FPU == 1 )
vstmdb r1!, {s0} /* Trigger the defferred stacking of FPU registers. */ vstmdb r1!, {s0} /* Trigger the defferred stacking of FPU registers. */
vldmia r1!, {s0} /* Nullify the effect of the pervious statement. */ vldmia r1!, {s0} /* Nullify the effect of the pervious statement. */
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
mrs r2, control /* r2 = CONTROL. */ mrs r2, control /* r2 = CONTROL. */
stmdb r1!, {r2} /* Store CONTROL value on the stack. */ stmdb r1!, {r2} /* Store CONTROL value on the stack. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */ str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
movs r1, #0 /* r1 = securecontextNO_STACK. */ movs r1, #0 /* r1 = securecontextNO_STACK. */
msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */ msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */
msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */ msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
save_ctx_therad_mode: save_ctx_therad_mode:
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
END END

View file

@ -1,204 +1,204 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Secure context includes. */ /* Secure context includes. */
#include "secure_context.h" #include "secure_context.h"
/* Secure heap includes. */ /* Secure heap includes. */
#include "secure_heap.h" #include "secure_heap.h"
/* Secure port macros. */ /* Secure port macros. */
#include "secure_port_macros.h" #include "secure_port_macros.h"
/** /**
* @brief CONTROL value for privileged tasks. * @brief CONTROL value for privileged tasks.
* *
* Bit[0] - 0 --> Thread mode is privileged. * Bit[0] - 0 --> Thread mode is privileged.
* Bit[1] - 1 --> Thread mode uses PSP. * Bit[1] - 1 --> Thread mode uses PSP.
*/ */
#define securecontextCONTROL_VALUE_PRIVILEGED 0x02 #define securecontextCONTROL_VALUE_PRIVILEGED 0x02
/** /**
* @brief CONTROL value for un-privileged tasks. * @brief CONTROL value for un-privileged tasks.
* *
* Bit[0] - 1 --> Thread mode is un-privileged. * Bit[0] - 1 --> Thread mode is un-privileged.
* Bit[1] - 1 --> Thread mode uses PSP. * Bit[1] - 1 --> Thread mode uses PSP.
*/ */
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Structure to represent secure context. * @brief Structure to represent secure context.
* *
* @note Since stack grows down, pucStackStart is the highest address while * @note Since stack grows down, pucStackStart is the highest address while
* pucStackLimit is the first addess of the allocated memory. * pucStackLimit is the first addess of the allocated memory.
*/ */
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;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
{ {
uint32_t ulIPSR; uint32_t ulIPSR;
/* Read the Interrupt Program Status Register (IPSR) value. */ /* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR ); secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero /* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */ * when the processor is running in the Thread Mode. */
if( ulIPSR != 0 ) if( ulIPSR != 0 )
{ {
/* No stack for thread mode until a task's context is loaded. */ /* No stack for thread mode until a task's context is loaded. */
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 );
} }
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
{ {
/* Configure thread mode to use PSP and to be privileged.. */ /* Configure thread mode to use PSP and to be privileged.. */
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED ); secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
} }
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#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 ) #if( configENABLE_MPU == 1 )
uint32_t *pulCurrentStackPointer = NULL; 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. */
secureportREAD_IPSR( ulIPSR ); secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero /* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */ * when the processor is running in the Thread Mode. */
if( ulIPSR != 0 ) if( ulIPSR != 0 )
{ {
/* Allocate the context structure. */ /* Allocate the context structure. */
xSecureContextHandle = ( SecureContextHandle_t ) pvPortMalloc( sizeof( SecureContext_t ) ); xSecureContextHandle = ( SecureContextHandle_t ) pvPortMalloc( sizeof( SecureContext_t ) );
if( xSecureContextHandle != NULL ) if( xSecureContextHandle != NULL )
{ {
/* Allocate the stack space. */ /* Allocate the stack space. */
pucStackMemory = pvPortMalloc( ulSecureStackSize ); pucStackMemory = pvPortMalloc( ulSecureStackSize );
if( pucStackMemory != NULL ) if( pucStackMemory != NULL )
{ {
/* Since stack grows down, the starting point will be the last /* Since stack grows down, the starting point will be the last
* location. Note that this location is next to the last * location. Note that this location is next to the last
* allocated byte because the hardware decrements the stack * allocated byte because the hardware decrements the stack
* pointer before writing i.e. if stack pointer is 0x2, a push * pointer before writing i.e. if stack pointer is 0x2, a push
* operation will decrement the stack pointer to 0x1 and then * operation will decrement the stack pointer to 0x1 and then
* write at 0x1. */ * write at 0x1. */
xSecureContextHandle->pucStackStart = pucStackMemory + ulSecureStackSize; xSecureContextHandle->pucStackStart = pucStackMemory + ulSecureStackSize;
/* The stack cannot go beyond this location. This value is /* The stack cannot go beyond this location. This value is
* 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;
} }
else else
{ {
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED; *( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
} }
/* Store the current stack pointer. This value is programmed in /* Store the current stack pointer. This value is programmed in
* the PSP register on context switch. */ * the PSP register on context switch. */
xSecureContextHandle->pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer; xSecureContextHandle->pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
} }
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
{ {
/* 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 */
} }
else else
{ {
/* Free the context to avoid memory leak and make sure to return /* Free the context to avoid memory leak and make sure to return
* NULL to indicate failure. */ * NULL to indicate failure. */
vPortFree( xSecureContextHandle ); vPortFree( xSecureContextHandle );
xSecureContextHandle = NULL; xSecureContextHandle = NULL;
} }
} }
} }
return xSecureContextHandle; return xSecureContextHandle;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ) secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle )
{ {
uint32_t ulIPSR; uint32_t ulIPSR;
/* Read the Interrupt Program Status Register (IPSR) value. */ /* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR ); secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero /* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */ * when the processor is running in the Thread Mode. */
if( ulIPSR != 0 ) if( ulIPSR != 0 )
{ {
/* Ensure that valid parameters are passed. */ /* Ensure that valid parameters are passed. */
secureportASSERT( xSecureContextHandle != NULL ); secureportASSERT( xSecureContextHandle != NULL );
/* Free the stack space. */ /* Free the stack space. */
vPortFree( xSecureContextHandle->pucStackLimit ); vPortFree( xSecureContextHandle->pucStackLimit );
/* Free the context itself. */ /* Free the context itself. */
vPortFree( xSecureContextHandle ); vPortFree( xSecureContextHandle );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,111 +1,111 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef __SECURE_CONTEXT_H__ #ifndef __SECURE_CONTEXT_H__
#define __SECURE_CONTEXT_H__ #define __SECURE_CONTEXT_H__
/* Standard includes. */ /* Standard includes. */
#include <stdint.h> #include <stdint.h>
/* FreeRTOS includes. */ /* FreeRTOS includes. */
#include "FreeRTOSConfig.h" #include "FreeRTOSConfig.h"
/** /**
* @brief PSP value when no task's context is loaded. * @brief PSP value when no task's context is loaded.
*/ */
#define securecontextNO_STACK 0x0 #define securecontextNO_STACK 0x0
/** /**
* @brief Opaque handle. * @brief Opaque handle.
*/ */
struct SecureContext; struct SecureContext;
typedef struct SecureContext* SecureContextHandle_t; typedef struct SecureContext* SecureContextHandle_t;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Initializes the secure context management system. * @brief Initializes the secure context management system.
* *
* PSP is set to NULL and therefore a task must allocate and load a context * PSP is set to NULL and therefore a task must allocate and load a context
* before calling any secure side function in the thread mode. * before calling any secure side function in the thread mode.
* *
* @note This function must be called in the handler mode. It is no-op if called * @note This function must be called in the handler mode. It is no-op if called
* in the thread mode. * in the thread mode.
*/ */
void SecureContext_Init( void ); void SecureContext_Init( void );
/** /**
* @brief Allocates a context on the secure side. * @brief Allocates a context on the secure side.
* *
* @note This function must be called in the handler mode. It is no-op if called * @note This function must be called in the handler mode. It is no-op if called
* in the thread mode. * in the thread mode.
* *
* @param[in] ulSecureStackSize Size of the stack to allocate on secure side. * @param[in] ulSecureStackSize Size of the stack to allocate on secure side.
* @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise. * @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise.
* *
* @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 */
/** /**
* @brief Frees the given context. * @brief Frees the given context.
* *
* @note This function must be called in the handler mode. It is no-op if called * @note This function must be called in the handler mode. It is no-op if called
* in the thread mode. * in the thread mode.
* *
* @param[in] xSecureContextHandle Context handle corresponding to the * @param[in] xSecureContextHandle Context handle corresponding to the
* context to be freed. * context to be freed.
*/ */
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ); void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle );
/** /**
* @brief Loads the given context. * @brief Loads the given context.
* *
* @note This function must be called in the handler mode. It is no-op if called * @note This function must be called in the handler mode. It is no-op if called
* in the thread mode. * in the thread mode.
* *
* @param[in] xSecureContextHandle Context handle corresponding to the context * @param[in] xSecureContextHandle Context handle corresponding to the context
* to be loaded. * to be loaded.
*/ */
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ); void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle );
/** /**
* @brief Saves the given context. * @brief Saves the given context.
* *
* @note This function must be called in the handler mode. It is no-op if called * @note This function must be called in the handler mode. It is no-op if called
* in the thread mode. * in the thread mode.
* *
* @param[in] xSecureContextHandle Context handle corresponding to the context * @param[in] xSecureContextHandle Context handle corresponding to the context
* to be saved. * to be saved.
*/ */
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ); void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle );
#endif /* __SECURE_CONTEXT_H__ */ #endif /* __SECURE_CONTEXT_H__ */

View file

@ -1,450 +1,450 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Standard includes. */ /* Standard includes. */
#include <stdint.h> #include <stdint.h>
/* Secure context heap includes. */ /* Secure context heap includes. */
#include "secure_heap.h" #include "secure_heap.h"
/* Secure port macros. */ /* Secure port macros. */
#include "secure_port_macros.h" #include "secure_port_macros.h"
/** /**
* @brief Total heap size. * @brief Total heap size.
*/ */
#define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) ) #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
/* No test marker by default. */ /* No test marker by default. */
#ifndef mtCOVERAGE_TEST_MARKER #ifndef mtCOVERAGE_TEST_MARKER
#define mtCOVERAGE_TEST_MARKER() #define mtCOVERAGE_TEST_MARKER()
#endif #endif
/* No tracing by default. */ /* No tracing by default. */
#ifndef traceMALLOC #ifndef traceMALLOC
#define traceMALLOC( pvReturn, xWantedSize ) #define traceMALLOC( pvReturn, xWantedSize )
#endif #endif
/* No tracing by default. */ /* No tracing by default. */
#ifndef traceFREE #ifndef traceFREE
#define traceFREE( pv, xBlockSize ) #define traceFREE( pv, xBlockSize )
#endif #endif
/* Block sizes must not get too small. */ /* Block sizes must not get too small. */
#define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) #define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
/* Assumes 8bit bytes! */ /* Assumes 8bit bytes! */
#define secureheapBITS_PER_BYTE ( ( size_t ) 8 ) #define secureheapBITS_PER_BYTE ( ( size_t ) 8 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* 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 /* 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. */ * 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 ];
#endif /* configAPPLICATION_ALLOCATED_HEAP */ #endif /* configAPPLICATION_ALLOCATED_HEAP */
/** /**
* @brief The linked list structure. * @brief The linked list structure.
* *
* This is used to link free blocks in order of their memory address. * This is used to link free blocks in order of their memory address.
*/ */
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;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Called automatically to setup the required heap structures the first * @brief Called automatically to setup the required heap structures the first
* time pvPortMalloc() is called. * time pvPortMalloc() is called.
*/ */
static void prvHeapInit( void ); static void prvHeapInit( void );
/** /**
* @brief Inserts a block of memory that is being freed into the correct * @brief Inserts a block of memory that is being freed into the correct
* position in the list of free memory blocks. * position in the list of free memory blocks.
* *
* The block being freed will be merged with the block in front it and/or the * The block being freed will be merged with the block in front it and/or the
* block behind it if the memory blocks are adjacent to each other. * block behind it if the memory blocks are adjacent to each other.
* *
* @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 );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief The size of the structure placed at the beginning of each allocated * @brief The size of the structure placed at the beginning of each allocated
* memory block must by correctly byte aligned. * memory block must by correctly byte aligned.
*/ */
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
/** /**
* @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
* about fragmentation. * about fragmentation.
*/ */
static size_t xFreeBytesRemaining = 0U; static size_t xFreeBytesRemaining = 0U;
static size_t xMinimumEverFreeBytesRemaining = 0U; static size_t xMinimumEverFreeBytesRemaining = 0U;
/** /**
* @brief Gets set to the top bit of an size_t type. * @brief Gets set to the top bit of an size_t type.
* *
* When this bit in the xBlockSize member of an BlockLink_t structure is set * When this bit in the xBlockSize member of an BlockLink_t structure is set
* then the block belongs to the application. When the bit is free the block is * then the block belongs to the application. When the bit is free the block is
* still part of the free heap space. * still part of the free heap space.
*/ */
static size_t xBlockAllocatedBit = 0; 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;
if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 ) if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 )
{ {
uxAddress += ( secureportBYTE_ALIGNMENT - 1 ); uxAddress += ( secureportBYTE_ALIGNMENT - 1 );
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
} }
pucAlignedHeap = ( uint8_t * ) uxAddress; pucAlignedHeap = ( uint8_t * ) uxAddress;
/* xStart is used to hold a pointer to the first item in the list of free /* xStart is used to hold a pointer to the first item in the list of free
* blocks. The void cast is used to prevent compiler warnings. */ * blocks. The void cast is used to prevent compiler warnings. */
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
xStart.xBlockSize = ( size_t ) 0; xStart.xBlockSize = ( size_t ) 0;
/* pxEnd is used to mark the end of the list of free blocks and is inserted /* pxEnd is used to mark the end of the list of free blocks and is inserted
* at the end of the heap space. */ * at the end of the heap space. */
uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
uxAddress -= xHeapStructSize; uxAddress -= xHeapStructSize;
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK ); uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
pxEnd = ( void * ) uxAddress; pxEnd = ( void * ) uxAddress;
pxEnd->xBlockSize = 0; pxEnd->xBlockSize = 0;
pxEnd->pxNextFreeBlock = NULL; pxEnd->pxNextFreeBlock = NULL;
/* To start with there is a single free block that is sized to take up the /* To start with there is a single free block that is sized to take up the
* entire heap space, minus the space taken by pxEnd. */ * entire heap space, minus the space taken by pxEnd. */
pxFirstFreeBlock = ( void * ) pucAlignedHeap; pxFirstFreeBlock = ( void * ) pucAlignedHeap;
pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
pxFirstFreeBlock->pxNextFreeBlock = pxEnd; pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
/* Only one block exists - and it covers the entire usable heap space. */ /* Only one block exists - and it covers the entire usable heap space. */
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
/* Work out the position of the top bit in a size_t variable. */ /* Work out the position of the top bit in a size_t variable. */
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ); xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
{ {
/* Nothing to do here, just iterate to the right position. */ /* Nothing to do here, just iterate to the right position. */
} }
/* 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;
pxBlockToInsert = pxIterator; pxBlockToInsert = pxIterator;
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
/* 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 )
{ {
/* Form one big block from the two blocks. */ /* Form one big block from the two blocks. */
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
} }
else else
{ {
pxBlockToInsert->pxNextFreeBlock = pxEnd; pxBlockToInsert->pxNextFreeBlock = pxEnd;
} }
} }
else else
{ {
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
} }
/* If the block being inserted plugged a gab, so was merged with the block /* If the block being inserted plugged a gab, so was merged with the block
* before and the block after, then it's pxNextFreeBlock pointer will have * before and the block after, then it's pxNextFreeBlock pointer will have
* already been set, and should not be set here as that would make it point * already been set, and should not be set here as that would make it point
* to itself. */ * to itself. */
if( pxIterator != pxBlockToInsert ) if( pxIterator != pxBlockToInsert )
{ {
pxIterator->pxNextFreeBlock = pxBlockToInsert; pxIterator->pxNextFreeBlock = pxBlockToInsert;
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
if( pxEnd == NULL ) if( pxEnd == NULL )
{ {
prvHeapInit(); prvHeapInit();
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
/* Check the requested block size is not so large that the top bit is set. /* Check the requested block size is not so large that the top bit is set.
* The top bit of the block size member of the BlockLink_t structure is used * The top bit of the block size member of the BlockLink_t structure is used
* to determine who owns the block - the application or the kernel, so it * to determine who owns the block - the application or the kernel, so it
* must be free. */ * must be free. */
if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
{ {
/* The wanted size is increased so it can contain a BlockLink_t /* The wanted size is increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. */ * structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 ) if( xWantedSize > 0 )
{ {
xWantedSize += xHeapStructSize; xWantedSize += xHeapStructSize;
/* Ensure that blocks are always aligned to the required number of /* Ensure that blocks are always aligned to the required number of
* bytes. */ * bytes. */
if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 ) if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 )
{ {
/* Byte alignment required. */ /* Byte alignment required. */
xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) ); xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) );
secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 ); secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 );
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
{ {
/* Traverse the list from the start (lowest address) block until /* Traverse the list from the start (lowest address) block until
* 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;
pxBlock = pxBlock->pxNextFreeBlock; pxBlock = pxBlock->pxNextFreeBlock;
} }
/* If the end marker was reached then a block of adequate size was /* If the end marker was reached then a block of adequate size was
* not found. */ * not found. */
if( pxBlock != pxEnd ) if( pxBlock != pxEnd )
{ {
/* Return the memory space pointed to - jumping over the /* Return the memory space pointed to - jumping over the
* BlockLink_t structure at its start. */ * BlockLink_t structure at its start. */
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
/* This block is being returned for use so must be taken out /* This block is being returned for use so must be taken out
* of the list of free blocks. */ * of the list of free blocks. */
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
/* If the block is larger than required it can be split into /* If the block is larger than required it can be split into
* two. */ * two. */
if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE ) if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE )
{ {
/* This block is to be split into two. Create a new /* This block is to be split into two. Create a new
* block following the number of bytes requested. The void * block following the number of bytes requested. The void
* cast is used to prevent byte alignment warnings from the * cast is used to prevent byte alignment warnings from the
* compiler. */ * compiler. */
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 ); secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 );
/* Calculate the sizes of two blocks split from the single /* Calculate the sizes of two blocks split from the single
* block. */ * block. */
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
pxBlock->xBlockSize = xWantedSize; pxBlock->xBlockSize = xWantedSize;
/* Insert the new block into the list of free blocks. */ /* Insert the new block into the list of free blocks. */
prvInsertBlockIntoFreeList( pxNewBlockLink ); prvInsertBlockIntoFreeList( pxNewBlockLink );
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
xFreeBytesRemaining -= pxBlock->xBlockSize; xFreeBytesRemaining -= pxBlock->xBlockSize;
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
{ {
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
/* The block is being returned - it is allocated and owned by /* The block is being returned - it is allocated and owned by
* the application and has no "next" block. */ * the application and has no "next" block. */
pxBlock->xBlockSize |= xBlockAllocatedBit; pxBlock->xBlockSize |= xBlockAllocatedBit;
pxBlock->pxNextFreeBlock = NULL; pxBlock->pxNextFreeBlock = NULL;
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
traceMALLOC( pvReturn, xWantedSize ); traceMALLOC( pvReturn, xWantedSize );
#if( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) #if( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
{ {
if( pvReturn == NULL ) if( pvReturn == NULL )
{ {
extern void vApplicationMallocFailedHook( void ); extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook(); vApplicationMallocFailedHook();
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
#endif #endif
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 )
{ {
/* The memory being freed will have an BlockLink_t structure immediately /* The memory being freed will have an BlockLink_t structure immediately
* before it. */ * before it. */
puc -= xHeapStructSize; puc -= xHeapStructSize;
/* This casting is to keep the compiler from issuing warnings. */ /* This casting is to keep the compiler from issuing warnings. */
pxLink = ( void * ) puc; pxLink = ( void * ) puc;
/* Check the block is actually allocated. */ /* Check the block is actually allocated. */
secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
secureportASSERT( pxLink->pxNextFreeBlock == NULL ); secureportASSERT( pxLink->pxNextFreeBlock == NULL );
if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
{ {
if( pxLink->pxNextFreeBlock == NULL ) if( pxLink->pxNextFreeBlock == NULL )
{ {
/* The block is being returned to the heap - it is no longer /* The block is being returned to the heap - it is no longer
* allocated. */ * allocated. */
pxLink->xBlockSize &= ~xBlockAllocatedBit; pxLink->xBlockSize &= ~xBlockAllocatedBit;
secureportDISABLE_NON_SECURE_INTERRUPTS(); secureportDISABLE_NON_SECURE_INTERRUPTS();
{ {
/* Add this block to the list of free blocks. */ /* Add this block to the list of free blocks. */
xFreeBytesRemaining += pxLink->xBlockSize; xFreeBytesRemaining += pxLink->xBlockSize;
traceFREE( pv, pxLink->xBlockSize ); traceFREE( pv, pxLink->xBlockSize );
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
} }
secureportENABLE_NON_SECURE_INTERRUPTS(); secureportENABLE_NON_SECURE_INTERRUPTS();
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
size_t xPortGetFreeHeapSize( void ) size_t xPortGetFreeHeapSize( void )
{ {
return xFreeBytesRemaining; return xFreeBytesRemaining;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
size_t xPortGetMinimumEverFreeHeapSize( void ) size_t xPortGetMinimumEverFreeHeapSize( void )
{ {
return xMinimumEverFreeBytesRemaining; return xMinimumEverFreeBytesRemaining;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortInitialiseBlocks( void ) void vPortInitialiseBlocks( void )
{ {
/* This just exists to keep the linker quiet. */ /* This just exists to keep the linker quiet. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,51 +1,51 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef __SECURE_HEAP_H__ #ifndef __SECURE_HEAP_H__
#define __SECURE_HEAP_H__ #define __SECURE_HEAP_H__
/* Standard includes. */ /* Standard includes. */
#include <stdlib.h> #include <stdlib.h>
/** /**
* @brief Allocates memory from heap. * @brief Allocates memory from heap.
* *
* @param[in] xWantedSize The size of the memory to be allocated. * @param[in] xWantedSize The size of the memory to be allocated.
* *
* @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__ */

View file

@ -1,105 +1,105 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Standard includes. */ /* Standard includes. */
#include <stdint.h> #include <stdint.h>
/* Secure init includes. */ /* Secure init includes. */
#include "secure_init.h" #include "secure_init.h"
/* Secure port macros. */ /* Secure port macros. */
#include "secure_port_macros.h" #include "secure_port_macros.h"
/** /**
* @brief Constants required to manipulate the SCB. * @brief Constants required to manipulate the SCB.
*/ */
#define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */ #define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */
#define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL ) #define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL )
#define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS ) #define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS )
#define secureinitSCB_AIRCR_PRIS_POS ( 14UL ) #define secureinitSCB_AIRCR_PRIS_POS ( 14UL )
#define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS ) #define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS )
/** /**
* @brief Constants required to manipulate the FPU. * @brief Constants required to manipulate the FPU.
*/ */
#define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */
#define secureinitFPCCR_LSPENS_POS ( 29UL ) #define secureinitFPCCR_LSPENS_POS ( 29UL )
#define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS ) #define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS )
#define secureinitFPCCR_TS_POS ( 26UL ) #define secureinitFPCCR_TS_POS ( 26UL )
#define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS ) #define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS )
#define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */ #define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */
#define secureinitNSACR_CP10_POS ( 10UL ) #define secureinitNSACR_CP10_POS ( 10UL )
#define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS ) #define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS )
#define secureinitNSACR_CP11_POS ( 11UL ) #define secureinitNSACR_CP11_POS ( 11UL )
#define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS ) #define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void ) secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void )
{ {
uint32_t ulIPSR; uint32_t ulIPSR;
/* Read the Interrupt Program Status Register (IPSR) value. */ /* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR ); secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero /* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */ * when the processor is running in the Thread Mode. */
if( ulIPSR != 0 ) if( ulIPSR != 0 )
{ {
*( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) | *( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) |
( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) | ( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) |
( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK ); ( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void ) secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
{ {
uint32_t ulIPSR; uint32_t ulIPSR;
/* Read the Interrupt Program Status Register (IPSR) value. */ /* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR ); secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero /* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */ * when the processor is running in the Thread Mode. */
if( ulIPSR != 0 ) if( ulIPSR != 0 )
{ {
/* CP10 = 1 ==> Non-secure access to the Floating Point Unit is /* CP10 = 1 ==> Non-secure access to the Floating Point Unit is
* permitted. CP11 should be programmed to the same value as CP10. */ * permitted. CP11 should be programmed to the same value as CP10. */
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK ); *( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
/* 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
* restored on exception return. */ * restored on exception return. */
*( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK ); *( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,53 +1,53 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef __SECURE_INIT_H__ #ifndef __SECURE_INIT_H__
#define __SECURE_INIT_H__ #define __SECURE_INIT_H__
/** /**
* @brief De-prioritizes the non-secure exceptions. * @brief De-prioritizes the non-secure exceptions.
* *
* This is needed to ensure that the non-secure PendSV runs at the lowest * This is needed to ensure that the non-secure PendSV runs at the lowest
* priority. Context switch is done in the non-secure PendSV handler. * priority. Context switch is done in the non-secure PendSV handler.
* *
* @note This function must be called in the handler mode. It is no-op if called * @note This function must be called in the handler mode. It is no-op if called
* in the thread mode. * in the thread mode.
*/ */
void SecureInit_DePrioritizeNSExceptions( void ); void SecureInit_DePrioritizeNSExceptions( void );
/** /**
* @brief Sets up the Floating Point Unit (FPU) for Non-Secure access. * @brief Sets up the Floating Point Unit (FPU) for Non-Secure access.
* *
* Also sets FPCCR.TS=1 to ensure that the content of the Floating Point * Also sets FPCCR.TS=1 to ensure that the content of the Floating Point
* Registers are not leaked to the non-secure side. * Registers are not leaked to the non-secure side.
* *
* @note This function must be called in the handler mode. It is no-op if called * @note This function must be called in the handler mode. It is no-op if called
* in the thread mode. * in the thread mode.
*/ */
void SecureInit_EnableNSFPUAccess( void ); void SecureInit_EnableNSFPUAccess( void );
#endif /* __SECURE_INIT_H__ */ #endif /* __SECURE_INIT_H__ */

View file

@ -1,133 +1,133 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef __SECURE_PORT_MACROS_H__ #ifndef __SECURE_PORT_MACROS_H__
#define __SECURE_PORT_MACROS_H__ #define __SECURE_PORT_MACROS_H__
/** /**
* @brief Byte alignment requirements. * @brief Byte alignment requirements.
*/ */
#define secureportBYTE_ALIGNMENT 8 #define secureportBYTE_ALIGNMENT 8
#define secureportBYTE_ALIGNMENT_MASK ( 0x0007 ) #define secureportBYTE_ALIGNMENT_MASK ( 0x0007 )
/** /**
* @brief Macro to declare a function as non-secure callable. * @brief Macro to declare a function as non-secure callable.
*/ */
#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
/** /**
* @brief Set the secure PRIMASK value. * @brief Set the secure PRIMASK value.
*/ */
#define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \ #define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \
__asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" ) __asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" )
/** /**
* @brief Set the non-secure PRIMASK value. * @brief Set the non-secure PRIMASK value.
*/ */
#define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \ #define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \
__asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" ) __asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" )
/** /**
* @brief Read the PSP value in the given variable. * @brief Read the PSP value in the given variable.
*/ */
#define secureportREAD_PSP( pucOutCurrentStackPointer ) \ #define secureportREAD_PSP( pucOutCurrentStackPointer ) \
__asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) ) __asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) )
/** /**
* @brief Set the PSP to the given value. * @brief Set the PSP to the given value.
*/ */
#define secureportSET_PSP( pucCurrentStackPointer ) \ #define secureportSET_PSP( pucCurrentStackPointer ) \
__asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) )
/** /**
* @brief Set the PSPLIM to the given value. * @brief Set the PSPLIM to the given value.
*/ */
#define secureportSET_PSPLIM( pucStackLimit ) \ #define secureportSET_PSPLIM( pucStackLimit ) \
__asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) ) __asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) )
/** /**
* @brief Set the NonSecure MSP to the given value. * @brief Set the NonSecure MSP to the given value.
*/ */
#define secureportSET_MSP_NS( pucMainStackPointer ) \ #define secureportSET_MSP_NS( pucMainStackPointer ) \
__asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) ) __asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) )
/** /**
* @brief Set the CONTROL register to the given value. * @brief Set the CONTROL register to the given value.
*/ */
#define secureportSET_CONTROL( ulControl ) \ #define secureportSET_CONTROL( ulControl ) \
__asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" ) __asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" )
/** /**
* @brief Read the Interrupt Program Status Register (IPSR) value in the given * @brief Read the Interrupt Program Status Register (IPSR) value in the given
* variable. * variable.
*/ */
#define secureportREAD_IPSR( ulIPSR ) \ #define secureportREAD_IPSR( ulIPSR ) \
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) ) __asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) )
/** /**
* @brief PRIMASK value to enable interrupts. * @brief PRIMASK value to enable interrupts.
*/ */
#define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0 #define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0
/** /**
* @brief PRIMASK value to disable interrupts. * @brief PRIMASK value to disable interrupts.
*/ */
#define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1 #define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1
/** /**
* @brief Disable secure interrupts. * @brief Disable secure interrupts.
*/ */
#define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) #define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
/** /**
* @brief Disable non-secure interrupts. * @brief Disable non-secure interrupts.
* *
* This effectively disables context switches. * This effectively disables context switches.
*/ */
#define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL ) #define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
/** /**
* @brief Enable non-secure interrupts. * @brief Enable non-secure interrupts.
*/ */
#define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL ) #define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL )
/** /**
* @brief Assert definition. * @brief Assert definition.
*/ */
#define secureportASSERT( x ) \ #define secureportASSERT( x ) \
if( ( x ) == 0 ) \ if( ( x ) == 0 ) \
{ \ { \
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__ */

View file

@ -1,244 +1,244 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* /*
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>
#include <setjmp.h> #include <setjmp.h>
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
#include "portasm.h" #include "portasm.h"
/*lint -e950 Non ANSI reserved words okay in this file only. */ /*lint -e950 Non ANSI reserved words okay in this file only. */
#define portTIMER_EOI_TYPE ( 8 ) #define portTIMER_EOI_TYPE ( 8 )
#define portRESET_PIC() portOUTPUT_WORD( ( uint16_t ) 0xff22, portTIMER_EOI_TYPE ) #define portRESET_PIC() portOUTPUT_WORD( ( uint16_t ) 0xff22, portTIMER_EOI_TYPE )
#define portTIMER_INT_NUMBER 0x12 #define portTIMER_INT_NUMBER 0x12
#define portTIMER_1_CONTROL_REGISTER ( ( uint16_t ) 0xff5e ) #define portTIMER_1_CONTROL_REGISTER ( ( uint16_t ) 0xff5e )
#define portTIMER_0_CONTROL_REGISTER ( ( uint16_t ) 0xff56 ) #define portTIMER_0_CONTROL_REGISTER ( ( uint16_t ) 0xff56 )
#define portTIMER_INTERRUPT_ENABLE ( ( uint16_t ) 0x2000 ) #define portTIMER_INTERRUPT_ENABLE ( ( uint16_t ) 0x2000 )
/* Setup the hardware to generate the required tick frequency. */ /* Setup the hardware to generate the required tick frequency. */
static void prvSetTickFrequency( uint32_t ulTickRateHz ); static void prvSetTickFrequency( uint32_t ulTickRateHz );
/* Set the hardware back to the state as per before the scheduler started. */ /* Set the hardware back to the state as per before the scheduler started. */
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 /* Tick service routine used by the scheduler when preemptive scheduling is
being used. */ 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 /* Tick service routine used by the scheduler when cooperative scheduling is
being used. */ being used. */
static void __interrupt __far prvNonPreemptiveTick( void ); static void __interrupt __far prvNonPreemptiveTick( void );
#endif #endif
/* Trap routine used by taskYIELD() to manually cause a context switch. */ /* Trap routine used by taskYIELD() to manually cause a context switch. */
static void __interrupt __far prvYieldProcessor( void ); static void __interrupt __far prvYieldProcessor( void );
/*lint -e956 File scopes necessary here. */ /*lint -e956 File scopes necessary here. */
/* Set true when the vectors are set so the scheduler will service the tick. */ /* Set true when the vectors are set so the scheduler will service the tick. */
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;
/*lint +e956 */ /*lint +e956 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xPortStartScheduler( void ) 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 );
} }
#else #else
{ {
/* We want the timer interrupt to just increment the tick count. */ /* We want the timer interrupt to just increment the tick count. */
_dos_setvect( portTIMER_INT_NUMBER, prvNonPreemptiveTick ); _dos_setvect( portTIMER_INT_NUMBER, prvNonPreemptiveTick );
} }
#endif #endif
prvSetTickFrequency( configTICK_RATE_HZ ); prvSetTickFrequency( configTICK_RATE_HZ );
/* Clean up function if we want to return to DOS. */ /* Clean up function if we want to return to DOS. */
if( setjmp( xJumpBuf ) != 0 ) if( setjmp( xJumpBuf ) != 0 )
{ {
prvExitFunction(); prvExitFunction();
xSchedulerRunning = pdFALSE; xSchedulerRunning = pdFALSE;
} }
else else
{ {
xSchedulerRunning = pdTRUE; xSchedulerRunning = pdTRUE;
/* Kick off the scheduler by setting up the context of the first task. */ /* Kick off the scheduler by setting up the context of the first task. */
portFIRST_CONTEXT(); portFIRST_CONTEXT();
} }
return xSchedulerRunning; return xSchedulerRunning;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* 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. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
/* Switch in the context of the next task to be run. */ /* Switch in the context of the next task to be run. */
portSWITCH_CONTEXT(); portSWITCH_CONTEXT();
} }
/* Reset the PIC ready for the next time. */ /* Reset the PIC ready for the next time. */
portRESET_PIC(); portRESET_PIC();
} }
#else #else
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
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void __interrupt __far prvYieldProcessor( void ) static void __interrupt __far prvYieldProcessor( void )
{ {
/* Switch in the context of the next task to be run. */ /* Switch in the context of the next task to be run. */
portSWITCH_CONTEXT(); portSWITCH_CONTEXT();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
usTimer0Control = portINPUT_WORD( portTIMER_0_CONTROL_REGISTER ); usTimer0Control = portINPUT_WORD( portTIMER_0_CONTROL_REGISTER );
usTimer0Control |= portTIMER_INTERRUPT_ENABLE; usTimer0Control |= portTIMER_INTERRUPT_ENABLE;
portOUTPUT_WORD( portTIMER_0_CONTROL_REGISTER, usTimer0Control ); portOUTPUT_WORD( portTIMER_0_CONTROL_REGISTER, usTimer0Control );
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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 );
portOUTPUT_WORD( usTimerPriorityRegister, usTimerHighPriority ); portOUTPUT_WORD( usTimerPriorityRegister, usTimerHighPriority );
/* Stop the DOS tick - don't do this if you want to maintain a TOD clock. */ /* Stop the DOS tick - don't do this if you want to maintain a TOD clock. */
usTimer0Control = portINPUT_WORD( portTIMER_0_CONTROL_REGISTER ); usTimer0Control = portINPUT_WORD( portTIMER_0_CONTROL_REGISTER );
usTimer0Control &= ~portTIMER_INTERRUPT_ENABLE; usTimer0Control &= ~portTIMER_INTERRUPT_ENABLE;
portOUTPUT_WORD( portTIMER_0_CONTROL_REGISTER, usTimer0Control ); portOUTPUT_WORD( portTIMER_0_CONTROL_REGISTER, usTimer0Control );
} }
/*lint +e950 */ /*lint +e950 */

View file

@ -1,97 +1,97 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef PORTMACRO_H #ifndef PORTMACRO_H
#define PORTMACRO_H #define PORTMACRO_H
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Port specific definitions. * Port specific definitions.
* *
* The settings in this file configure FreeRTOS correctly for the * The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler. * given hardware and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*----------------------------------------------------------- *-----------------------------------------------------------
*/ */
/* Type definitions. */ /* Type definitions. */
#define portCHAR char #define portCHAR char
#define portFLOAT float #define portFLOAT float
#define portDOUBLE long #define portDOUBLE long
#define portLONG long #define portLONG long
#define portSHORT int #define portSHORT int
#define portSTACK_TYPE uint16_t #define portSTACK_TYPE uint16_t
#define portBASE_TYPE portSHORT #define portBASE_TYPE portSHORT
typedef portSTACK_TYPE StackType_t; 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
typedef uint32_t TickType_t; typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* 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 }
#define portDISABLE_INTERRUPTS() __asm{ cli } #define portDISABLE_INTERRUPTS() __asm{ cli }
#define portENABLE_INTERRUPTS() __asm{ sti } #define portENABLE_INTERRUPTS() __asm{ sti }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Hardware specifics. */ /* Hardware specifics. */
#define portNOP() __asm{ nop } #define portNOP() __asm{ nop }
#define portSTACK_GROWTH ( -1 ) #define portSTACK_GROWTH ( -1 )
#define portSWITCH_INT_NUMBER 0x80 #define portSWITCH_INT_NUMBER 0x80
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER } #define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 2 #define portBYTE_ALIGNMENT 2
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */ #define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Compiler specifics. */ /* Compiler specifics. */
#define portINPUT_BYTE( xAddr ) inp( xAddr ) #define portINPUT_BYTE( xAddr ) inp( xAddr )
#define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue ) #define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue )
#define portINPUT_WORD( xAddr ) inpw( xAddr ) #define portINPUT_WORD( xAddr ) inpw( xAddr )
#define portOUTPUT_WORD( xAddr, usValue ) outpw( xAddr, usValue ) #define portOUTPUT_WORD( xAddr, usValue ) outpw( xAddr, usValue )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* 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 */

View file

@ -1,288 +1,288 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* /*
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>
#include <setjmp.h> #include <setjmp.h>
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
#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. */
#define portTIMER_INT_NUMBER 0x08 #define portTIMER_INT_NUMBER 0x08
/* Setup hardware for required tick interrupt rate. */ /* Setup hardware for required tick interrupt rate. */
static void prvSetTickFrequency( uint32_t ulTickRateHz ); static void prvSetTickFrequency( uint32_t ulTickRateHz );
/* Restore hardware to as it was prior to starting the scheduler. */ /* Restore hardware to as it was prior to starting the scheduler. */
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 /* Tick service routine used by the scheduler when preemptive scheduling is
being used. */ 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 /* Tick service routine used by the scheduler when cooperative scheduling is
being used. */ being used. */
static void __interrupt __far prvNonPreemptiveTick( void ); static void __interrupt __far prvNonPreemptiveTick( void );
#endif #endif
/* Trap routine used by taskYIELD() to manually cause a context switch. */ /* Trap routine used by taskYIELD() to manually cause a context switch. */
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. */
/* Used to signal when to chain to the DOS tick, and when to just clear the PIC ourselves. */ /* Used to signal when to chain to the DOS tick, and when to just clear the PIC ourselves. */
static int16_t sDOSTickCounter; static int16_t sDOSTickCounter;
/* Set true when the vectors are set so the scheduler will service the tick. */ /* Set true when the vectors are set so the scheduler will service the tick. */
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;
/*lint +e956 */ /*lint +e956 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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 );
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 );
} }
#else #else
{ {
/* We want the timer interrupt to just increment the tick count. */ /* We want the timer interrupt to just increment the tick count. */
_dos_setvect( portTIMER_INT_NUMBER, prvNonPreemptiveTick ); _dos_setvect( portTIMER_INT_NUMBER, prvNonPreemptiveTick );
} }
#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. */
if( setjmp( xJumpBuf ) != 0 ) if( setjmp( xJumpBuf ) != 0 )
{ {
prvExitFunction(); prvExitFunction();
xSchedulerRunning = pdFALSE; xSchedulerRunning = pdFALSE;
} }
else else
{ {
xSchedulerRunning = pdTRUE; xSchedulerRunning = pdTRUE;
/* Kick off the scheduler by setting up the context of the first task. */ /* Kick off the scheduler by setting up the context of the first task. */
portFIRST_CONTEXT(); portFIRST_CONTEXT();
} }
return xSchedulerRunning; return xSchedulerRunning;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* 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. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
/* Switch in the context of the next task to be run. */ /* Switch in the context of the next task to be run. */
portSWITCH_CONTEXT(); portSWITCH_CONTEXT();
} }
/* Reset the PIC ready for the next time. */ /* Reset the PIC ready for the next time. */
prvPortResetPIC(); prvPortResetPIC();
} }
#else #else
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
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void __interrupt __far prvYieldProcessor( void ) static void __interrupt __far prvYieldProcessor( void )
{ {
/* Switch in the context of the next task to be run. */ /* Switch in the context of the next task to be run. */
portSWITCH_CONTEXT(); portSWITCH_CONTEXT();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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
out 20H, al out 20H, al
}; };
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
pxOriginalTickISR = _dos_getvect( portSWITCH_INT_NUMBER + 1 ); pxOriginalTickISR = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
_dos_setvect( portTIMER_INT_NUMBER, pxOriginalTickISR ); _dos_setvect( portTIMER_INT_NUMBER, 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 ) );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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 */

View file

@ -1,97 +1,97 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef PORTMACRO_H #ifndef PORTMACRO_H
#define PORTMACRO_H #define PORTMACRO_H
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Port specific definitions. * Port specific definitions.
* *
* The settings in this file configure FreeRTOS correctly for the * The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler. * given hardware and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*----------------------------------------------------------- *-----------------------------------------------------------
*/ */
/* Type definitions. */ /* Type definitions. */
#define portCHAR char #define portCHAR char
#define portFLOAT long #define portFLOAT long
#define portDOUBLE long #define portDOUBLE long
#define portLONG long #define portLONG long
#define portSHORT int #define portSHORT int
#define portSTACK_TYPE uint16_t #define portSTACK_TYPE uint16_t
#define portBASE_TYPE portSHORT #define portBASE_TYPE portSHORT
typedef portSTACK_TYPE StackType_t; 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
typedef uint32_t TickType_t; typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* 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 }
#define portDISABLE_INTERRUPTS() __asm{ cli } #define portDISABLE_INTERRUPTS() __asm{ cli }
#define portENABLE_INTERRUPTS() __asm{ sti } #define portENABLE_INTERRUPTS() __asm{ sti }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Hardware specifics. */ /* Hardware specifics. */
#define portNOP() __asm{ nop } #define portNOP() __asm{ nop }
#define portSTACK_GROWTH ( -1 ) #define portSTACK_GROWTH ( -1 )
#define portSWITCH_INT_NUMBER 0x80 #define portSWITCH_INT_NUMBER 0x80
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER } #define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
#define portDOS_TICK_RATE ( 18.20648 ) #define portDOS_TICK_RATE ( 18.20648 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portTICKS_PER_DOS_TICK ( ( uint16_t ) ( ( ( portDOUBLE ) configTICK_RATE_HZ / portDOS_TICK_RATE ) + 0.5 ) ) #define portTICKS_PER_DOS_TICK ( ( uint16_t ) ( ( ( portDOUBLE ) configTICK_RATE_HZ / portDOS_TICK_RATE ) + 0.5 ) )
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */ #define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
#define portBYTE_ALIGNMENT ( 2 ) #define portBYTE_ALIGNMENT ( 2 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Compiler specifics. */ /* Compiler specifics. */
#define portINPUT_BYTE( xAddr ) inp( xAddr ) #define portINPUT_BYTE( xAddr ) inp( xAddr )
#define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue ) #define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* 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 */

View file

@ -1,87 +1,87 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef PORT_ASM_H #ifndef PORT_ASM_H
#define PORT_ASM_H #define PORT_ASM_H
typedef void TCB_t; typedef void TCB_t;
extern volatile TCB_t * volatile pxCurrentTCB; extern volatile TCB_t * volatile pxCurrentTCB;
extern void vTaskSwitchContext( void ); extern void vTaskSwitchContext( void );
/* /*
* Saves the stack pointer for one task into its TCB, calls * Saves the stack pointer for one task into its TCB, calls
* vTaskSwitchContext() to update the TCB being used, then restores the stack * vTaskSwitchContext() to update the TCB being used, then restores the stack
* from the new TCB read to run the task. * from the new TCB read to run the task.
*/ */
void portSWITCH_CONTEXT( void ); void portSWITCH_CONTEXT( void );
/* /*
* Load the stack pointer from the TCB of the task which is going to be first * Load the stack pointer from the TCB of the task which is going to be first
* to execute. Then force an IRET so the registers and IP are popped off the * to execute. Then force an IRET so the registers and IP are popped off the
* stack. * stack.
*/ */
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. */ \
asm { mov ds, ax } \ asm { mov ds, ax } \
asm { les bx, dword ptr pxCurrentTCB } \ asm { les bx, dword ptr pxCurrentTCB } \
asm { mov ss, es:[ bx + 2 ] } \ asm { mov ss, es:[ bx + 2 ] } \
asm { mov sp, es:[ bx ] } asm { mov sp, es:[ bx ] }
#define portFIRST_CONTEXT() \ #define portFIRST_CONTEXT() \
__asm { mov ax, seg pxCurrentTCB } \ __asm { mov ax, seg pxCurrentTCB } \
__asm { mov ds, ax } \ __asm { mov ds, ax } \
__asm { les bx, dword ptr pxCurrentTCB } \ __asm { les bx, dword ptr pxCurrentTCB } \
__asm { mov ss, es:[ bx + 2 ] } \ __asm { mov ss, es:[ bx + 2 ] } \
__asm { mov sp, es:[ bx ] } \ __asm { mov sp, es:[ bx ] } \
__asm { pop bp } \ __asm { pop bp } \
__asm { pop di } \ __asm { pop di } \
__asm { pop si } \ __asm { pop si } \
__asm { pop ds } \ __asm { pop ds } \
__asm { pop es } \ __asm { pop es } \
__asm { pop dx } \ __asm { pop dx } \
__asm { pop cx } \ __asm { pop cx } \
__asm { pop bx } \ __asm { pop bx } \
__asm { pop ax } \ __asm { pop ax } \
__asm { iret } __asm { iret }
#endif #endif

View file

@ -1,120 +1,120 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* /*
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>
#include <stdlib.h> #include <stdlib.h>
#include "FreeRTOS.h" #include "FreeRTOS.h"
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* 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--;
*pxTopOfStack = 0x2222; *pxTopOfStack = 0x2222;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0x3333; *pxTopOfStack = 0x3333;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0x4444; *pxTopOfStack = 0x4444;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = 0x5555; *pxTopOfStack = 0x5555;
pxTopOfStack--; pxTopOfStack--;
/*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--;
*pxTopOfStack = FP_OFF( pvParameters ); *pxTopOfStack = FP_OFF( pvParameters );
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = FP_SEG( pxCode ); *pxTopOfStack = FP_SEG( pxCode );
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = FP_OFF( pxCode ); *pxTopOfStack = FP_OFF( pxCode );
pxTopOfStack--; pxTopOfStack--;
/* Next the status register and interrupt return address. */ /* Next the status register and interrupt return address. */
*pxTopOfStack = portINITIAL_SW; *pxTopOfStack = portINITIAL_SW;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = FP_SEG( pxCode ); *pxTopOfStack = FP_SEG( pxCode );
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = FP_OFF( pxCode ); *pxTopOfStack = FP_OFF( pxCode );
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 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0xCCCC; /* CX */ *pxTopOfStack = ( StackType_t ) 0xCCCC; /* CX */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0xDDDD; /* DX */ *pxTopOfStack = ( StackType_t ) 0xDDDD; /* DX */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0xEEEE; /* ES */ *pxTopOfStack = ( StackType_t ) 0xEEEE; /* ES */
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--;
*pxTopOfStack = ( StackType_t ) 0x0123; /* SI */ *pxTopOfStack = ( StackType_t ) 0x0123; /* SI */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0xDDDD; /* DI */ *pxTopOfStack = ( StackType_t ) 0xDDDD; /* DI */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BP */ *pxTopOfStack = ( StackType_t ) 0xBBBB; /* BP */
/*lint +e950 +e611 +e923 */ /*lint +e950 +e611 +e923 */
return pxTopOfStack; return pxTopOfStack;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

File diff suppressed because it is too large Load diff

View file

@ -1,144 +1,144 @@
;/* ;/*
; * FreeRTOS Kernel V10.2.1 ; * FreeRTOS Kernel V10.3.0
; * Copyright (C) 2019 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
; * ; *
; * 1 tab == 4 spaces! ; * 1 tab == 4 spaces!
; */ ; */
.thumb .thumb
.ref pxCurrentTCB .ref pxCurrentTCB
.ref vTaskSwitchContext .ref vTaskSwitchContext
.ref ulMaxSyscallInterruptPriority .ref ulMaxSyscallInterruptPriority
.def xPortPendSVHandler .def xPortPendSVHandler
.def ulPortGetIPSR .def ulPortGetIPSR
.def vPortSVCHandler .def vPortSVCHandler
.def vPortStartFirstTask .def vPortStartFirstTask
NVICOffsetConst: .word 0xE000ED08 NVICOffsetConst: .word 0xE000ED08
CPACRConst: .word 0xE000ED88 CPACRConst: .word 0xE000ED88
pxCurrentTCBConst: .word pxCurrentTCB pxCurrentTCBConst: .word pxCurrentTCB
ulMaxSyscallInterruptPriorityConst: .word ulMaxSyscallInterruptPriority ulMaxSyscallInterruptPriorityConst: .word ulMaxSyscallInterruptPriority
; ----------------------------------------------------------- ; -----------------------------------------------------------
.align 4 .align 4
ulPortGetIPSR: .asmfunc ulPortGetIPSR: .asmfunc
mrs r0, ipsr mrs r0, ipsr
bx r14 bx r14
.endasmfunc .endasmfunc
; ----------------------------------------------------------- ; -----------------------------------------------------------
.align 4 .align 4
vPortSetInterruptMask: .asmfunc vPortSetInterruptMask: .asmfunc
push {r0} push {r0}
ldr r0, ulMaxSyscallInterruptPriorityConst ldr r0, ulMaxSyscallInterruptPriorityConst
msr basepri, r0 msr basepri, r0
pop {r0} pop {r0}
bx r14 bx r14
.endasmfunc .endasmfunc
; ----------------------------------------------------------- ; -----------------------------------------------------------
.align 4 .align 4
xPortPendSVHandler: .asmfunc xPortPendSVHandler: .asmfunc
mrs r0, psp mrs r0, psp
isb isb
;/* Get the location of the current TCB. */ ;/* Get the location of the current TCB. */
ldr r3, pxCurrentTCBConst ldr r3, pxCurrentTCBConst
ldr r2, [r3] ldr r2, [r3]
;/* Save the core registers. */ ;/* Save the core registers. */
stmdb r0!, {r4-r11} stmdb r0!, {r4-r11}
;/* Save the new top of stack into the first member of the TCB. */ ;/* Save the new top of stack into the first member of the TCB. */
str r0, [r2] str r0, [r2]
stmdb sp!, {r3, r14} stmdb sp!, {r3, r14}
ldr r0, ulMaxSyscallInterruptPriorityConst ldr r0, ulMaxSyscallInterruptPriorityConst
ldr r1, [r0] ldr r1, [r0]
msr basepri, r1 msr basepri, r1
dsb dsb
isb isb
bl vTaskSwitchContext bl vTaskSwitchContext
mov r0, #0 mov r0, #0
msr basepri, r0 msr basepri, r0
ldmia sp!, {r3, r14} ldmia sp!, {r3, r14}
;/* The first item in pxCurrentTCB is the task top of stack. */ ;/* The first item in pxCurrentTCB is the task top of stack. */
ldr r1, [r3] ldr r1, [r3]
ldr r0, [r1] ldr r0, [r1]
;/* Pop the core registers. */ ;/* Pop the core registers. */
ldmia r0!, {r4-r11} ldmia r0!, {r4-r11}
msr psp, r0 msr psp, r0
isb isb
bx r14 bx r14
.endasmfunc .endasmfunc
; ----------------------------------------------------------- ; -----------------------------------------------------------
.align 4 .align 4
vPortSVCHandler: .asmfunc vPortSVCHandler: .asmfunc
;/* Get the location of the current TCB. */ ;/* Get the location of the current TCB. */
ldr r3, pxCurrentTCBConst ldr r3, pxCurrentTCBConst
ldr r1, [r3] ldr r1, [r3]
ldr r0, [r1] ldr r0, [r1]
;/* Pop the core registers. */ ;/* Pop the core registers. */
ldmia r0!, {r4-r11} ldmia r0!, {r4-r11}
msr psp, r0 msr psp, r0
isb isb
mov r0, #0 mov r0, #0
msr basepri, r0 msr basepri, r0
orr r14, #0xd orr r14, #0xd
bx r14 bx r14
.endasmfunc .endasmfunc
; ----------------------------------------------------------- ; -----------------------------------------------------------
.align 4 .align 4
vPortStartFirstTask: .asmfunc vPortStartFirstTask: .asmfunc
;/* Use the NVIC offset register to locate the stack. */ ;/* Use the NVIC offset register to locate the stack. */
ldr r0, NVICOffsetConst ldr r0, NVICOffsetConst
ldr r0, [r0] ldr r0, [r0]
ldr r0, [r0] ldr r0, [r0]
;/* Set the msp back to the start of the stack. */ ;/* Set the msp back to the start of the stack. */
msr msp, r0 msr msp, r0
;/* Clear the bit that indicates the FPU is in use in case the FPU was used ;/* Clear the bit that indicates the FPU is in use in case the FPU was used
;before the scheduler was started - which would otherwise result in the ;before the scheduler was started - which would otherwise result in the
;unnecessary leaving of space in the SVC stack for lazy saving of FPU ;unnecessary leaving of space in the SVC stack for lazy saving of FPU
;registers. */ ;registers. */
mov r0, #0 mov r0, #0
msr control, r0 msr control, r0
;/* Call SVC to start the first task. */ ;/* Call SVC to start the first task. */
cpsie i cpsie i
cpsie f cpsie f
dsb dsb
isb isb
svc #0 svc #0
.endasmfunc .endasmfunc
; ----------------------------------------------------------- ; -----------------------------------------------------------

View file

@ -1,171 +1,171 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#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.
* *
* The settings in this file configure FreeRTOS correctly for the * The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler. * given hardware and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*----------------------------------------------------------- *-----------------------------------------------------------
*/ */
/* 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 */

File diff suppressed because it is too large Load diff

View file

@ -1,171 +1,171 @@
;/* ;/*
; * FreeRTOS Kernel V10.2.1 ; * FreeRTOS Kernel V10.3.0
; * Copyright (C) 2019 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
; * ; *
; * 1 tab == 4 spaces! ; * 1 tab == 4 spaces!
; */ ; */
.thumb .thumb
.ref pxCurrentTCB .ref pxCurrentTCB
.ref vTaskSwitchContext .ref vTaskSwitchContext
.ref ulMaxSyscallInterruptPriority .ref ulMaxSyscallInterruptPriority
.def xPortPendSVHandler .def xPortPendSVHandler
.def ulPortGetIPSR .def ulPortGetIPSR
.def vPortSVCHandler .def vPortSVCHandler
.def vPortStartFirstTask .def vPortStartFirstTask
.def vPortEnableVFP .def vPortEnableVFP
NVICOffsetConst: .word 0xE000ED08 NVICOffsetConst: .word 0xE000ED08
CPACRConst: .word 0xE000ED88 CPACRConst: .word 0xE000ED88
pxCurrentTCBConst: .word pxCurrentTCB pxCurrentTCBConst: .word pxCurrentTCB
ulMaxSyscallInterruptPriorityConst: .word ulMaxSyscallInterruptPriority ulMaxSyscallInterruptPriorityConst: .word ulMaxSyscallInterruptPriority
; ----------------------------------------------------------- ; -----------------------------------------------------------
.align 4 .align 4
ulPortGetIPSR: .asmfunc ulPortGetIPSR: .asmfunc
mrs r0, ipsr mrs r0, ipsr
bx r14 bx r14
.endasmfunc .endasmfunc
; ----------------------------------------------------------- ; -----------------------------------------------------------
.align 4 .align 4
vPortSetInterruptMask: .asmfunc vPortSetInterruptMask: .asmfunc
push {r0} push {r0}
ldr r0, ulMaxSyscallInterruptPriorityConst ldr r0, ulMaxSyscallInterruptPriorityConst
msr basepri, r0 msr basepri, r0
pop {r0} pop {r0}
bx r14 bx r14
.endasmfunc .endasmfunc
; ----------------------------------------------------------- ; -----------------------------------------------------------
.align 4 .align 4
xPortPendSVHandler: .asmfunc xPortPendSVHandler: .asmfunc
mrs r0, psp mrs r0, psp
isb isb
;/* Get the location of the current TCB. */ ;/* Get the location of the current TCB. */
ldr r3, pxCurrentTCBConst ldr r3, pxCurrentTCBConst
ldr r2, [r3] ldr r2, [r3]
;/* Is the task using the FPU context? If so, push high vfp registers. */ ;/* Is the task using the FPU context? If so, push high vfp registers. */
tst r14, #0x10 tst r14, #0x10
it eq it eq
vstmdbeq r0!, {s16-s31} vstmdbeq r0!, {s16-s31}
;/* Save the core registers. */ ;/* Save the core registers. */
stmdb r0!, {r4-r11, r14} stmdb r0!, {r4-r11, r14}
;/* Save the new top of stack into the first member of the TCB. */ ;/* Save the new top of stack into the first member of the TCB. */
str r0, [r2] str r0, [r2]
stmdb sp!, {r0, r3} stmdb sp!, {r0, r3}
ldr r0, ulMaxSyscallInterruptPriorityConst ldr r0, ulMaxSyscallInterruptPriorityConst
ldr r1, [r0] ldr r1, [r0]
msr basepri, r1 msr basepri, r1
dsb dsb
isb isb
bl vTaskSwitchContext bl vTaskSwitchContext
mov r0, #0 mov r0, #0
msr basepri, r0 msr basepri, r0
ldmia sp!, {r0, r3} ldmia sp!, {r0, r3}
;/* The first item in pxCurrentTCB is the task top of stack. */ ;/* The first item in pxCurrentTCB is the task top of stack. */
ldr r1, [r3] ldr r1, [r3]
ldr r0, [r1] ldr r0, [r1]
;/* Pop the core registers. */ ;/* Pop the core registers. */
ldmia r0!, {r4-r11, r14} ldmia r0!, {r4-r11, r14}
;/* Is the task using the FPU context? If so, pop the high vfp registers ;/* Is the task using the FPU context? If so, pop the high vfp registers
;too. */ ;too. */
tst r14, #0x10 tst r14, #0x10
it eq it eq
vldmiaeq r0!, {s16-s31} vldmiaeq r0!, {s16-s31}
msr psp, r0 msr psp, r0
isb isb
bx r14 bx r14
.endasmfunc .endasmfunc
; ----------------------------------------------------------- ; -----------------------------------------------------------
.align 4 .align 4
vPortSVCHandler: .asmfunc vPortSVCHandler: .asmfunc
;/* Get the location of the current TCB. */ ;/* Get the location of the current TCB. */
ldr r3, pxCurrentTCBConst ldr r3, pxCurrentTCBConst
ldr r1, [r3] ldr r1, [r3]
ldr r0, [r1] ldr r0, [r1]
;/* Pop the core registers. */ ;/* Pop the core registers. */
ldmia r0!, {r4-r11, r14} ldmia r0!, {r4-r11, r14}
msr psp, r0 msr psp, r0
isb isb
mov r0, #0 mov r0, #0
msr basepri, r0 msr basepri, r0
bx r14 bx r14
.endasmfunc .endasmfunc
; ----------------------------------------------------------- ; -----------------------------------------------------------
.align 4 .align 4
vPortStartFirstTask: .asmfunc vPortStartFirstTask: .asmfunc
;/* Use the NVIC offset register to locate the stack. */ ;/* Use the NVIC offset register to locate the stack. */
ldr r0, NVICOffsetConst ldr r0, NVICOffsetConst
ldr r0, [r0] ldr r0, [r0]
ldr r0, [r0] ldr r0, [r0]
;/* Set the msp back to the start of the stack. */ ;/* Set the msp back to the start of the stack. */
msr msp, r0 msr msp, r0
;/* Clear the bit that indicates the FPU is in use in case the FPU was used ;/* Clear the bit that indicates the FPU is in use in case the FPU was used
;before the scheduler was started - which would otherwise result in the ;before the scheduler was started - which would otherwise result in the
;unnecessary leaving of space in the SVC stack for lazy saving of FPU ;unnecessary leaving of space in the SVC stack for lazy saving of FPU
;registers. */ ;registers. */
mov r0, #0 mov r0, #0
msr control, r0 msr control, r0
;/* Call SVC to start the first task. */ ;/* Call SVC to start the first task. */
cpsie i cpsie i
cpsie f cpsie f
dsb dsb
isb isb
svc #0 svc #0
.endasmfunc .endasmfunc
; ----------------------------------------------------------- ; -----------------------------------------------------------
.align 4 .align 4
vPortEnableVFP: .asmfunc vPortEnableVFP: .asmfunc
;/* The FPU enable bits are in the CPACR. */ ;/* The FPU enable bits are in the CPACR. */
ldr.w r0, CPACRConst ldr.w r0, CPACRConst
ldr r1, [r0] ldr r1, [r0]
;/* Enable CP10 and CP11 coprocessors, then save back. */ ;/* Enable CP10 and CP11 coprocessors, then save back. */
orr r1, r1, #( 0xf << 20 ) orr r1, r1, #( 0xf << 20 )
str r1, [r0] str r1, [r0]
bx r14 bx r14
.endasmfunc .endasmfunc
.end .end
; ----------------------------------------------------------- ; -----------------------------------------------------------

View file

@ -1,165 +1,165 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#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.
* *
* The settings in this file configure FreeRTOS correctly for the * The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler. * given hardware and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*----------------------------------------------------------- *-----------------------------------------------------------
*/ */
/* 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 */

View file

@ -1,312 +1,312 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* FreeRTOS includes. */ /* FreeRTOS includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Count of the critical section nesting depth. */ /* Count of the critical section nesting depth. */
uint32_t ulCriticalNesting = 9999; 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. */
#define portINITIAL_SPSR ( ( StackType_t ) 0x1F ) #define portINITIAL_SPSR ( ( StackType_t ) 0x1F )
#define portINITIAL_FPSCR ( ( StackType_t ) 0x00 ) #define portINITIAL_FPSCR ( ( StackType_t ) 0x00 )
#define portINSTRUCTION_SIZE ( ( StackType_t ) 0x04 ) #define portINSTRUCTION_SIZE ( ( StackType_t ) 0x04 )
#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 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* vPortStartFirstSTask() is defined in portASM.asm */ /* vPortStartFirstSTask() is defined in portASM.asm */
extern void vPortStartFirstTask( void ); 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;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* 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;
#if __TI_VFP_SUPPORT__ #if __TI_VFP_SUPPORT__
{ {
/* Ensure the stack is correctly aligned on exit. */ /* Ensure the stack is correctly aligned on exit. */
pxTopOfStack--; pxTopOfStack--;
} }
#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--;
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */ *pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */ *pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
pxTopOfStack--; pxTopOfStack--;
#ifdef portPRELOAD_TASK_REGISTERS #ifdef portPRELOAD_TASK_REGISTERS
{ {
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
pxTopOfStack--; pxTopOfStack--;
} }
#else #else
{ {
pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS; pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS;
} }
#endif #endif
/* Function parameters are passed in R0. */ /* Function parameters are passed in R0. */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
pxTopOfStack--; pxTopOfStack--;
/* Set the status register for system mode, with interrupts enabled. */ /* Set the status register for system mode, with interrupts enabled. */
*pxTopOfStack = ( StackType_t ) ( ( _get_CPSR() & ~0xFF ) | portINITIAL_SPSR ); *pxTopOfStack = ( StackType_t ) ( ( _get_CPSR() & ~0xFF ) | portINITIAL_SPSR );
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 ) if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
{ {
/* The task will start in thumb mode. */ /* The task will start in thumb mode. */
*pxTopOfStack |= portTHUMB_MODE_BIT; *pxTopOfStack |= portTHUMB_MODE_BIT;
} }
#ifdef __TI_VFP_SUPPORT__ #ifdef __TI_VFP_SUPPORT__
{ {
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
return pxTopOfStack; return pxTopOfStack;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt(void) static void prvSetupTimerInterrupt(void)
{ {
/* Disable timer 0. */ /* Disable timer 0. */
portRTI_GCTRL_REG &= 0xFFFFFFFEUL; portRTI_GCTRL_REG &= 0xFFFFFFFEUL;
/* Use the internal counter. */ /* Use the internal counter. */
portRTI_TBCTRL_REG = 0x00000000U; portRTI_TBCTRL_REG = 0x00000000U;
/* COMPSEL0 will use the RTIFRC0 counter. */ /* COMPSEL0 will use the RTIFRC0 counter. */
portRTI_COMPCTRL_REG = 0x00000000U; portRTI_COMPCTRL_REG = 0x00000000U;
/* Initialise the counter and the prescale counter registers. */ /* Initialise the counter and the prescale counter registers. */
portRTI_CNT0_UC0_REG = 0x00000000U; portRTI_CNT0_UC0_REG = 0x00000000U;
portRTI_CNT0_FRC0_REG = 0x00000000U; portRTI_CNT0_FRC0_REG = 0x00000000U;
/* Set Prescalar for RTI clock. */ /* Set Prescalar for RTI clock. */
portRTI_CNT0_CPUC0_REG = 0x00000001U; portRTI_CNT0_CPUC0_REG = 0x00000001U;
portRTI_CNT0_COMP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ; portRTI_CNT0_COMP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ;
portRTI_CNT0_UDCP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ; portRTI_CNT0_UDCP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ;
/* Clear interrupts. */ /* Clear interrupts. */
portRTI_INTFLAG_REG = 0x0007000FU; portRTI_INTFLAG_REG = 0x0007000FU;
portRTI_CLEARINTENA_REG = 0x00070F0FU; portRTI_CLEARINTENA_REG = 0x00070F0FU;
/* Enable the compare 0 interrupt. */ /* Enable the compare 0 interrupt. */
portRTI_SETINTENA_REG = 0x00000001U; portRTI_SETINTENA_REG = 0x00000001U;
portRTI_GCTRL_REG |= 0x00000001U; portRTI_GCTRL_REG |= 0x00000001U;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* 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();
/* Reset the critical section nesting count read to execute the first task. */ /* Reset the critical section nesting count read to execute the first task. */
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! */
return pdFAIL; return pdFAIL;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* 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 )
{ {
/* clear clock interrupt flag */ /* clear clock interrupt flag */
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
/* /*
************************************************************************** **************************************************************************
* 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
* is set to 1 in portmacro.h * is set to 1 in portmacro.h
************************************************************************** **************************************************************************
*/ */
void vPortPreemptiveTick( void ); void vPortPreemptiveTick( void );
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Disable interrupts, and keep a count of the nesting depth. * Disable interrupts, and keep a count of the nesting depth.
*/ */
void vPortEnterCritical( void ) void vPortEnterCritical( void )
{ {
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */ /* Disable interrupts as per portDISABLE_INTERRUPTS(); */
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++;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Decrement the critical nesting count, and if it has reached zero, re-enable * Decrement the critical nesting count, and if it has reached zero, re-enable
* interrupts. * interrupts.
*/ */
void vPortExitCritical( void ) void vPortExitCritical( void )
{ {
if( ulCriticalNesting > 0 ) if( ulCriticalNesting > 0 )
{ {
/* Decrement the nesting count as we are leaving a critical section. */ /* Decrement the nesting count as we are leaving a critical section. */
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(). */
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if __TI_VFP_SUPPORT__ #if __TI_VFP_SUPPORT__
void vPortTaskUsesFPU( void ) void vPortTaskUsesFPU( 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. */
vPortInitialiseFPSCR(); vPortInitialiseFPSCR();
} }
#endif /* __TI_VFP_SUPPORT__ */ #endif /* __TI_VFP_SUPPORT__ */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,229 +1,229 @@
;/* ;/*
; * FreeRTOS Kernel V10.2.1 ; * FreeRTOS Kernel V10.3.0
; * Copyright (C) 2019 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
; * ; *
; * 1 tab == 4 spaces! ; * 1 tab == 4 spaces!
; */ ; */
.text .text
.arm .arm
.ref vTaskSwitchContext .ref vTaskSwitchContext
.ref xTaskIncrementTick .ref xTaskIncrementTick
.ref ulTaskHasFPUContext .ref ulTaskHasFPUContext
.ref pxCurrentTCB .ref pxCurrentTCB
;/*-----------------------------------------------------------*/ ;/*-----------------------------------------------------------*/
; ;
; Save Task Context ; Save Task Context
; ;
portSAVE_CONTEXT .macro portSAVE_CONTEXT .macro
DSB DSB
; Push R0 as we are going to use it ; Push R0 as we are going to use it
STMDB SP!, {R0} STMDB SP!, {R0}
; Set R0 to point to the task stack pointer. ; Set R0 to point to the task stack pointer.
STMDB SP,{SP}^ STMDB SP,{SP}^
SUB SP, SP, #4 SUB SP, SP, #4
LDMIA SP!,{R0} LDMIA SP!,{R0}
; Push the return address onto the stack. ; Push the return address onto the stack.
STMDB R0!, {LR} STMDB R0!, {LR}
; Now LR has been saved, it can be used instead of R0. ; Now LR has been saved, it can be used instead of R0.
MOV LR, R0 MOV LR, R0
; Pop R0 so it can be saved onto the task stack. ; Pop R0 so it can be saved onto the task stack.
LDMIA SP!, {R0} LDMIA SP!, {R0}
; Push all the system mode registers onto the task stack. ; Push all the system mode registers onto the task stack.
STMDB LR,{R0-LR}^ STMDB LR,{R0-LR}^
SUB LR, LR, #60 SUB LR, LR, #60
; Push the SPSR onto the task stack. ; Push the SPSR onto the task stack.
MRS R0, SPSR MRS R0, SPSR
STMDB LR!, {R0} STMDB LR!, {R0}
.if (__TI_VFP_SUPPORT__) .if (__TI_VFP_SUPPORT__)
;Determine if the task maintains an FPU context. ;Determine if the task maintains an FPU context.
LDR R0, ulFPUContextConst LDR R0, ulFPUContextConst
LDR R0, [R0] LDR R0, [R0]
; Test the flag ; Test the flag
CMP R0, #0 CMP R0, #0
; If the task is not using a floating point context then skip the ; If the task is not using a floating point context then skip the
; saving of the FPU registers. ; saving of the FPU registers.
BEQ $+16 BEQ $+16
FSTMDBD LR!, {D0-D15} FSTMDBD LR!, {D0-D15}
FMRX R1, FPSCR FMRX R1, FPSCR
STMFD LR!, {R1} STMFD LR!, {R1}
; Save the flag ; Save the flag
STMDB LR!, {R0} STMDB LR!, {R0}
.endif .endif
; Store the new top of stack for the task. ; Store the new top of stack for the task.
LDR R0, pxCurrentTCBConst LDR R0, pxCurrentTCBConst
LDR R0, [R0] LDR R0, [R0]
STR LR, [R0] STR LR, [R0]
.endm .endm
;/*-----------------------------------------------------------*/ ;/*-----------------------------------------------------------*/
; ;
; Restore Task Context ; Restore Task Context
; ;
portRESTORE_CONTEXT .macro portRESTORE_CONTEXT .macro
LDR R0, pxCurrentTCBConst LDR R0, pxCurrentTCBConst
LDR R0, [R0] LDR R0, [R0]
LDR LR, [R0] LDR LR, [R0]
.if (__TI_VFP_SUPPORT__) .if (__TI_VFP_SUPPORT__)
; The floating point context flag is the first thing on the stack. ; The floating point context flag is the first thing on the stack.
LDR R0, ulFPUContextConst LDR R0, ulFPUContextConst
LDMFD LR!, {R1} LDMFD LR!, {R1}
STR R1, [R0] STR R1, [R0]
; Test the flag ; Test the flag
CMP R1, #0 CMP R1, #0
; If the task is not using a floating point context then skip the ; If the task is not using a floating point context then skip the
; VFP register loads. ; VFP register loads.
BEQ $+16 BEQ $+16
; Restore the floating point context. ; Restore the floating point context.
LDMFD LR!, {R0} LDMFD LR!, {R0}
FLDMIAD LR!, {D0-D15} FLDMIAD LR!, {D0-D15}
FMXR FPSCR, R0 FMXR FPSCR, R0
.endif .endif
; Get the SPSR from the stack. ; Get the SPSR from the stack.
LDMFD LR!, {R0} LDMFD LR!, {R0}
MSR SPSR_CSXF, R0 MSR SPSR_CSXF, R0
; Restore all system mode registers for the task. ; Restore all system mode registers for the task.
LDMFD LR, {R0-R14}^ LDMFD LR, {R0-R14}^
; Restore the return address. ; Restore the return address.
LDR LR, [LR, #+60] LDR LR, [LR, #+60]
; 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 SUBS PC, LR, #4
.endm .endm
;/*-----------------------------------------------------------*/ ;/*-----------------------------------------------------------*/
; Start the first task by restoring its context. ; Start the first task by restoring its context.
.def vPortStartFirstTask .def vPortStartFirstTask
vPortStartFirstTask: vPortStartFirstTask:
portRESTORE_CONTEXT portRESTORE_CONTEXT
;/*-----------------------------------------------------------*/ ;/*-----------------------------------------------------------*/
; Yield to another task. ; Yield to another task.
.def vPortYieldProcessor .def vPortYieldProcessor
vPortYieldProcessor: vPortYieldProcessor:
; 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. SWI doesn't do this. Add the offset manually so the ISR ; address. SWI doesn't do this. Add the offset manually so the ISR
; return code can be used. ; return code can be used.
ADD LR, LR, #4 ADD LR, LR, #4
; First save the context of the current task. ; First save the context of the current task.
portSAVE_CONTEXT portSAVE_CONTEXT
; Select the next task to execute. */ ; Select the next task to execute. */
BL vTaskSwitchContext BL vTaskSwitchContext
; Restore the context of the task selected to execute. ; Restore the context of the task selected to execute.
portRESTORE_CONTEXT portRESTORE_CONTEXT
;/*-----------------------------------------------------------*/ ;/*-----------------------------------------------------------*/
; Yield to another task from within the FreeRTOS API ; Yield to another task from within the FreeRTOS API
.def vPortYeildWithinAPI .def vPortYeildWithinAPI
vPortYeildWithinAPI: vPortYeildWithinAPI:
; Save the context of the current task. ; Save the context of the current task.
portSAVE_CONTEXT portSAVE_CONTEXT
; Clear SSI flag. ; Clear SSI flag.
MOVW R0, #0xFFF4 MOVW R0, #0xFFF4
MOVT R0, #0xFFFF MOVT R0, #0xFFFF
LDR R0, [R0] LDR R0, [R0]
; Select the next task to execute. */ ; Select the next task to execute. */
BL vTaskSwitchContext BL vTaskSwitchContext
; Restore the context of the task selected to execute. ; Restore the context of the task selected to execute.
portRESTORE_CONTEXT portRESTORE_CONTEXT
;/*-----------------------------------------------------------*/ ;/*-----------------------------------------------------------*/
; Preemptive Tick ; Preemptive Tick
.def vPortPreemptiveTick .def vPortPreemptiveTick
vPortPreemptiveTick: vPortPreemptiveTick:
; Save the context of the current task. ; Save the context of the current task.
portSAVE_CONTEXT portSAVE_CONTEXT
; Clear interrupt flag ; Clear interrupt flag
MOVW R0, #0xFC88 MOVW R0, #0xFC88
MOVT R0, #0xFFFF MOVT R0, #0xFFFF
MOV R1, #1 MOV R1, #1
STR R1, [R0] STR R1, [R0]
; Increment the tick count, making any adjustments to the blocked lists ; Increment the tick count, making any adjustments to the blocked lists
; that may be necessary. ; that may be necessary.
BL xTaskIncrementTick BL xTaskIncrementTick
; Select the next task to execute. ; Select the next task to execute.
CMP R0, #0 CMP R0, #0
BLNE vTaskSwitchContext BLNE vTaskSwitchContext
; Restore the context of the task selected to execute. ; Restore the context of the task selected to execute.
portRESTORE_CONTEXT portRESTORE_CONTEXT
;------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------
.if (__TI_VFP_SUPPORT__) .if (__TI_VFP_SUPPORT__)
.def vPortInitialiseFPSCR .def vPortInitialiseFPSCR
vPortInitialiseFPSCR: vPortInitialiseFPSCR:
MOV R0, #0 MOV R0, #0
FMXR FPSCR, R0 FMXR FPSCR, R0
BX LR BX LR
.endif ;__TI_VFP_SUPPORT__ .endif ;__TI_VFP_SUPPORT__
pxCurrentTCBConst .word pxCurrentTCB pxCurrentTCBConst .word pxCurrentTCB
ulFPUContextConst .word ulTaskHasFPUContext ulFPUContextConst .word ulTaskHasFPUContext
;------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------

View file

@ -1,117 +1,117 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef __PORTMACRO_H__ #ifndef __PORTMACRO_H__
#define __PORTMACRO_H__ #define __PORTMACRO_H__
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Port specific definitions. * Port specific definitions.
* *
* The settings in this file configure FreeRTOS correctly for the * The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler. * given hardware and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*----------------------------------------------------------- *-----------------------------------------------------------
*/ */
/* 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) 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
#endif #endif
/* 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 ) ) )
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
/* 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__ */

View file

@ -1,53 +1,53 @@
;/* ;/*
; * FreeRTOS Kernel V10.2.1 ; * FreeRTOS Kernel V10.3.0
; * Copyright (C) 2019 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
; * ; *
; * 1 tab == 4 spaces! ; * 1 tab == 4 spaces!
; */ ; */
.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
.define "pop.a", pop_x .define "pop.a", pop_x
.define "mov.a", mov_x .define "mov.a", mov_x
.else .else
.define "pushm.w", pushm_x .define "pushm.w", pushm_x
.define "popm.w", popm_x .define "popm.w", popm_x
.define "push.w", push_x .define "push.w", push_x
.define "pop.w", pop_x .define "pop.w", pop_x
.define "mov.w", mov_x .define "mov.w", mov_x
.endif .endif
.if $DEFINED( __LARGE_CODE_MODEL__ ) .if $DEFINED( __LARGE_CODE_MODEL__ )
.define "calla", call_x .define "calla", call_x
.define "reta", ret_x .define "reta", ret_x
.else .else
.define "call", call_x .define "call", call_x
.define "ret", ret_x .define "ret", ret_x
.endif .endif

View file

@ -1,187 +1,187 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Scheduler includes. */ /* Scheduler includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
#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;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Sets up the periodic ISR used for the RTOS tick. This uses timer 0, but * Sets up the periodic ISR used for the RTOS tick. This uses timer 0, but
* could have alternatively used the watchdog timer or timer 1. * could have alternatively used the watchdog timer or timer 1.
*/ */
void vPortSetupTimerInterrupt( void ); void vPortSetupTimerInterrupt( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Initialise the stack of a task to look exactly as if a call to * Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called. * portSAVE_CONTEXT had been called.
* *
* 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;
ulTemp = ( uint32_t ) pxCode; ulTemp = ( uint32_t ) pxCode;
*pusTopOfStack = ( uint16_t ) ulTemp; *pusTopOfStack = ( uint16_t ) ulTemp;
} }
else else
{ {
/* Make room for a 20 bit value stored as a 32 bit value. */ /* Make room for a 20 bit value stored as a 32 bit value. */
pusTopOfStack = ( uint16_t * ) pxTopOfStack; pusTopOfStack = ( uint16_t * ) pxTopOfStack;
pusTopOfStack--; pusTopOfStack--;
pulTopOfStack = ( uint32_t * ) pusTopOfStack; pulTopOfStack = ( uint32_t * ) pusTopOfStack;
*pulTopOfStack = ( uint32_t ) pxCode; *pulTopOfStack = ( uint32_t ) pxCode;
} }
pusTopOfStack--; pusTopOfStack--;
*pusTopOfStack = portFLAGS_INT_ENABLED; *pusTopOfStack = portFLAGS_INT_ENABLED;
pusTopOfStack -= ( sizeof( StackType_t ) / 2 ); pusTopOfStack -= ( sizeof( StackType_t ) / 2 );
/* From here on the size of stacked items depends on the memory model. */ /* From here on the size of stacked items depends on the memory model. */
pxTopOfStack = ( StackType_t * ) pusTopOfStack; pxTopOfStack = ( StackType_t * ) pusTopOfStack;
/* Next the general purpose registers. */ /* Next the general purpose registers. */
#ifdef PRELOAD_REGISTER_VALUES #ifdef PRELOAD_REGISTER_VALUES
*pxTopOfStack = ( StackType_t ) 0xffff; *pxTopOfStack = ( StackType_t ) 0xffff;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0xeeee; *pxTopOfStack = ( StackType_t ) 0xeeee;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0xdddd; *pxTopOfStack = ( StackType_t ) 0xdddd;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) pvParameters; *pxTopOfStack = ( StackType_t ) pvParameters;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0xbbbb; *pxTopOfStack = ( StackType_t ) 0xbbbb;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0xaaaa; *pxTopOfStack = ( StackType_t ) 0xaaaa;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x9999; *pxTopOfStack = ( StackType_t ) 0x9999;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x8888; *pxTopOfStack = ( StackType_t ) 0x8888;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x5555; *pxTopOfStack = ( StackType_t ) 0x5555;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x6666; *pxTopOfStack = ( StackType_t ) 0x6666;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x5555; *pxTopOfStack = ( StackType_t ) 0x5555;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x4444; *pxTopOfStack = ( StackType_t ) 0x4444;
pxTopOfStack--; pxTopOfStack--;
#else #else
pxTopOfStack -= 3; pxTopOfStack -= 3;
*pxTopOfStack = ( StackType_t ) pvParameters; *pxTopOfStack = ( StackType_t ) pvParameters;
pxTopOfStack -= 9; pxTopOfStack -= 9;
#endif #endif
/* 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;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Hardware initialisation to generate the RTOS tick. * Hardware initialisation to generate the RTOS tick.
*/ */
void vPortSetupTimerInterrupt( void ) void vPortSetupTimerInterrupt( void )
{ {
vApplicationSetupTimerInterrupt(); vApplicationSetupTimerInterrupt();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#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
extern void vPortPreemptiveTickISR( void ); extern void vPortPreemptiveTickISR( void );
vPortPreemptiveTickISR(); vPortPreemptiveTickISR();
#else #else
extern void vPortCooperativeTickISR( void ); extern void vPortCooperativeTickISR( void );
vPortCooperativeTickISR(); vPortCooperativeTickISR();
#endif #endif
} }

View file

@ -1,159 +1,159 @@
;/* ;/*
; * FreeRTOS Kernel V10.2.1 ; * FreeRTOS Kernel V10.3.0
; * Copyright (C) 2019 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
; * ; *
; * 1 tab == 4 spaces! ; * 1 tab == 4 spaces!
; */ ; */
; * The definition of the "register test" tasks, as described at the top of ; * The definition of the "register test" tasks, as described at the top of
; * main.c ; * main.c
.include data_model.h .include data_model.h
.global xTaskIncrementTick .global xTaskIncrementTick
.global vTaskSwitchContext .global vTaskSwitchContext
.global vPortSetupTimerInterrupt .global vPortSetupTimerInterrupt
.global pxCurrentTCB .global pxCurrentTCB
.global usCriticalNesting .global usCriticalNesting
.def vPortPreemptiveTickISR .def vPortPreemptiveTickISR
.def vPortCooperativeTickISR .def vPortCooperativeTickISR
.def vPortYield .def vPortYield
.def xPortStartScheduler .def xPortStartScheduler
;----------------------------------------------------------- ;-----------------------------------------------------------
portSAVE_CONTEXT .macro portSAVE_CONTEXT .macro
;Save the remaining registers. ;Save the remaining registers.
pushm_x #12, r15 pushm_x #12, r15
mov.w &usCriticalNesting, r14 mov.w &usCriticalNesting, r14
push_x r14 push_x r14
mov_x &pxCurrentTCB, r12 mov_x &pxCurrentTCB, r12
mov_x sp, 0( r12 ) mov_x sp, 0( r12 )
.endm .endm
;----------------------------------------------------------- ;-----------------------------------------------------------
portRESTORE_CONTEXT .macro portRESTORE_CONTEXT .macro
mov_x &pxCurrentTCB, r12 mov_x &pxCurrentTCB, r12
mov_x @r12, sp mov_x @r12, sp
pop_x r15 pop_x r15
mov.w r15, &usCriticalNesting mov.w r15, &usCriticalNesting
popm_x #12, r15 popm_x #12, r15
nop nop
pop.w sr pop.w sr
nop nop
ret_x ret_x
.endm .endm
;----------------------------------------------------------- ;-----------------------------------------------------------
;* ;*
;* The RTOS tick ISR. ;* The RTOS tick ISR.
;* ;*
;* If the cooperative scheduler is in use this simply increments the tick ;* If the cooperative scheduler is in use this simply increments the tick
;* count. ;* count.
;* ;*
;* If the preemptive scheduler is in use a context switch can also occur. ;* If the preemptive scheduler is in use a context switch can also occur.
;*/ ;*/
.text .text
.align 2 .align 2
vPortPreemptiveTickISR: .asmfunc vPortPreemptiveTickISR: .asmfunc
; The sr is not saved in portSAVE_CONTEXT() because vPortYield() needs ; The sr is not saved in portSAVE_CONTEXT() because vPortYield() needs
;to save it manually before it gets modified (interrupts get disabled). ;to save it manually before it gets modified (interrupts get disabled).
push.w sr push.w sr
portSAVE_CONTEXT portSAVE_CONTEXT
call_x #xTaskIncrementTick call_x #xTaskIncrementTick
call_x #vTaskSwitchContext call_x #vTaskSwitchContext
portRESTORE_CONTEXT portRESTORE_CONTEXT
.endasmfunc .endasmfunc
;----------------------------------------------------------- ;-----------------------------------------------------------
.align 2 .align 2
vPortCooperativeTickISR: .asmfunc vPortCooperativeTickISR: .asmfunc
; The sr is not saved in portSAVE_CONTEXT() because vPortYield() needs ; The sr is not saved in portSAVE_CONTEXT() because vPortYield() needs
;to save it manually before it gets modified (interrupts get disabled). ;to save it manually before it gets modified (interrupts get disabled).
push.w sr push.w sr
portSAVE_CONTEXT portSAVE_CONTEXT
call_x #xTaskIncrementTick call_x #xTaskIncrementTick
portRESTORE_CONTEXT portRESTORE_CONTEXT
.endasmfunc .endasmfunc
;----------------------------------------------------------- ;-----------------------------------------------------------
; ;
; Manual context switch called by the portYIELD() macro. ; Manual context switch called by the portYIELD() macro.
; ;
.align 2 .align 2
vPortYield: .asmfunc vPortYield: .asmfunc
; The sr needs saving before it is modified. ; The sr needs saving before it is modified.
push.w sr push.w sr
; Now the SR is stacked we can disable interrupts. ; Now the SR is stacked we can disable interrupts.
dint dint
nop nop
; Save the context of the current task. ; Save the context of the current task.
portSAVE_CONTEXT portSAVE_CONTEXT
; Select the next task to run. ; Select the next task to run.
call_x #vTaskSwitchContext call_x #vTaskSwitchContext
; Restore the context of the new task. ; Restore the context of the new task.
portRESTORE_CONTEXT portRESTORE_CONTEXT
.endasmfunc .endasmfunc
;----------------------------------------------------------- ;-----------------------------------------------------------
; ;
; Start off the scheduler by initialising the RTOS tick timer, then restoring ; Start off the scheduler by initialising the RTOS tick timer, then restoring
; the context of the first task. ; the context of the first task.
; ;
.align 2 .align 2
xPortStartScheduler: .asmfunc xPortStartScheduler: .asmfunc
; Setup the hardware to generate the tick. Interrupts are disabled ; Setup the hardware to generate the tick. Interrupts are disabled
; when this function is called. ; when this function is called.
call_x #vPortSetupTimerInterrupt call_x #vPortSetupTimerInterrupt
; Restore the context of the first task that is going to run. ; Restore the context of the first task that is going to run.
portRESTORE_CONTEXT portRESTORE_CONTEXT
.endasmfunc .endasmfunc
;----------------------------------------------------------- ;-----------------------------------------------------------
.end .end

View file

@ -1,143 +1,143 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef PORTMACRO_H #ifndef PORTMACRO_H
#define PORTMACRO_H #define PORTMACRO_H
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Port specific definitions. * Port specific definitions.
* *
* The settings in this file configure FreeRTOS correctly for the * The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler. * given hardware and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*----------------------------------------------------------- *-----------------------------------------------------------
*/ */
/* Hardware includes. */ /* Hardware includes. */
#include "msp430.h" #include "msp430.h"
/* 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 int #define portSHORT int
#define portBASE_TYPE portSHORT #define portBASE_TYPE portSHORT
/* The stack type changes depending on the data model. */ /* The stack type changes depending on the data model. */
#ifdef __LARGE_DATA_MODEL__ #ifdef __LARGE_DATA_MODEL__
#define portSTACK_TYPE uint32_t #define portSTACK_TYPE uint32_t
#else #else
#define portSTACK_TYPE uint16_t #define portSTACK_TYPE uint16_t
#define portPOINTER_SIZE_TYPE uint16_t #define portPOINTER_SIZE_TYPE uint16_t
#endif #endif
typedef portSTACK_TYPE StackType_t; 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
typedef uint32_t TickType_t; typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Interrupt control macros. */ /* Interrupt control macros. */
#define portDISABLE_INTERRUPTS() _disable_interrupt(); _nop() #define portDISABLE_INTERRUPTS() _disable_interrupt(); _nop()
#define portENABLE_INTERRUPTS() _enable_interrupt(); _nop() #define portENABLE_INTERRUPTS() _enable_interrupt(); _nop()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section control macros. */ /* Critical section control macros. */
#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(); \
\ \
/* Now interrupts are disabled usCriticalNesting can be accessed */ \ /* Now interrupts are disabled usCriticalNesting can be accessed */ \
/* 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 ) \
{ \ { \
/* Decrement the nesting count as we are leaving a critical section. */ \ /* Decrement the nesting count as we are leaving a critical section. */ \
usCriticalNesting--; \ usCriticalNesting--; \
\ \
/* 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( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \ if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \
{ \ { \
portENABLE_INTERRUPTS(); \ portENABLE_INTERRUPTS(); \
} \ } \
} \ } \
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task utilities. */ /* Task utilities. */
/* /*
* Manual context switch called by portYIELD or taskYIELD. * Manual context switch called by portYIELD or taskYIELD.
*/ */
extern void vPortYield( void ); extern void vPortYield( void );
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Hardware specifics. */ /* Hardware specifics. */
#define portBYTE_ALIGNMENT 2 #define portBYTE_ALIGNMENT 2
#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 portNOP() __no_operation() #define portNOP() __no_operation()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* 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()
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 */

View file

@ -1,183 +1,183 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Kernel includes. */ /* Kernel includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
#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 )
/* The clock frequency into the RTC. */ /* The clock frequency into the RTC. */
#define portRTC_CLOCK_HZ ( ( uint32_t ) 1000 ) #define portRTC_CLOCK_HZ ( ( uint32_t ) 1000 )
asm void interrupt VectorNumber_VL1swi vPortYieldISR( void ); 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. */
*pxTopOfStack = ( StackType_t ) pxCode; *pxTopOfStack = ( StackType_t ) pxCode;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( portINITIAL_FORMAT_VECTOR << 16UL ) | ( portINITIAL_STATUS_REGISTER ); *pxTopOfStack = ( portINITIAL_FORMAT_VECTOR << 16UL ) | ( portINITIAL_STATUS_REGISTER );
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x0; /*FP*/ *pxTopOfStack = ( StackType_t ) 0x0; /*FP*/
pxTopOfStack -= 14; /* A5 to D0. */ pxTopOfStack -= 14; /* A5 to D0. */
/* Parameter in A0. */ /* Parameter in A0. */
*( pxTopOfStack + 8 ) = ( StackType_t ) pvParameters; *( pxTopOfStack + 8 ) = ( StackType_t ) pvParameters;
/* A5 must be maintained as it is resurved by the compiler. */ /* A5 must be maintained as it is resurved by the compiler. */
*( pxTopOfStack + 13 ) = ulOriginalA5; *( pxTopOfStack + 13 ) = ulOriginalA5;
return pxTopOfStack; return pxTopOfStack;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
extern void vPortStartFirstTask( void ); extern void vPortStartFirstTask( void );
ulCriticalNesting = 0UL; ulCriticalNesting = 0UL;
/* Configure a timer to generate the tick interrupt. */ /* Configure a timer to generate the tick interrupt. */
prvSetupTimerInterrupt(); prvSetupTimerInterrupt();
/* Start the first task executing. */ /* Start the first task executing. */
vPortStartFirstTask(); vPortStartFirstTask();
return pdFALSE; return pdFALSE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void ) static void prvSetupTimerInterrupt( void )
{ {
/* Prescale by 1 - ie no prescale. */ /* Prescale by 1 - ie no prescale. */
RTCSC |= 8; RTCSC |= 8;
/* Compare match value. */ /* Compare match value. */
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;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented as there is nothing to return to. */ /* Not implemented as there is nothing to return to. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortEnterCritical( void ) 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++;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortExitCritical( void ) void vPortExitCritical( void )
{ {
ulCriticalNesting--; ulCriticalNesting--;
if( ulCriticalNesting == 0 ) if( ulCriticalNesting == 0 )
{ {
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
INTC_CFRC = 0x3E; INTC_CFRC = 0x3E;
vTaskSwitchContext(); vTaskSwitchContext();
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( 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;
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
{ {
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
taskYIELD(); taskYIELD();
} }
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
} }

View file

@ -1,130 +1,130 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* /*
* Purpose: Lowest level routines for all ColdFire processors. * Purpose: Lowest level routines for all ColdFire processors.
* *
* Notes: * Notes:
* *
* ulPortSetIPL() and mcf5xxx_wr_cacr() copied with permission from FreeScale * ulPortSetIPL() and mcf5xxx_wr_cacr() copied with permission from FreeScale
* supplied source files. * supplied source files.
*/ */
.global ulPortSetIPL .global ulPortSetIPL
.global _ulPortSetIPL .global _ulPortSetIPL
.global mcf5xxx_wr_cacrx .global mcf5xxx_wr_cacrx
.global _mcf5xxx_wr_cacrx .global _mcf5xxx_wr_cacrx
.global vPortYieldISR .global vPortYieldISR
.global _vPortYieldISR .global _vPortYieldISR
.global vPortStartFirstTask .global vPortStartFirstTask
.global _vPortStartFirstTask .global _vPortStartFirstTask
.extern _pxCurrentTCB .extern _pxCurrentTCB
.extern _vPortYieldHandler .extern _vPortYieldHandler
.text .text
.macro portSAVE_CONTEXT .macro portSAVE_CONTEXT
lea.l (-60, sp), sp lea.l (-60, sp), sp
movem.l d0-a6, (sp) movem.l d0-a6, (sp)
move.l _pxCurrentTCB, a0 move.l _pxCurrentTCB, a0
move.l sp, (a0) move.l sp, (a0)
.endm .endm
.macro portRESTORE_CONTEXT .macro portRESTORE_CONTEXT
move.l _pxCurrentTCB, a0 move.l _pxCurrentTCB, a0
move.l (a0), sp move.l (a0), sp
movem.l (sp), d0-a6 movem.l (sp), d0-a6
lea.l (60, sp), sp lea.l (60, sp), sp
rte rte
.endm .endm
/********************************************************************/ /********************************************************************/
/* /*
* This routines changes the IPL to the value passed into the routine. * This routines changes the IPL to the value passed into the routine.
* It also returns the old IPL value back. * It also returns the old IPL value back.
* Calling convention from C: * Calling convention from C:
* old_ipl = asm_set_ipl(new_ipl); * old_ipl = asm_set_ipl(new_ipl);
* For the Diab Data C compiler, it passes return value thru D0. * For the Diab Data C compiler, it passes return value thru D0.
* Note that only the least significant three bits of the passed * Note that only the least significant three bits of the passed
* value are used. * value are used.
*/ */
ulPortSetIPL: ulPortSetIPL:
_ulPortSetIPL: _ulPortSetIPL:
link A6,#-8 link A6,#-8
movem.l D6-D7,(SP) movem.l D6-D7,(SP)
move.w SR,D7 /* current sr */ move.w SR,D7 /* current sr */
move.l D7,D6 /* prepare return value */ move.l D7,D6 /* prepare return value */
andi.l #0x0700,D6 /* mask out IPL */ andi.l #0x0700,D6 /* mask out IPL */
lsr.l #8,D6 /* IPL */ lsr.l #8,D6 /* IPL */
andi.l #0x07,D0 /* least significant three bits */ andi.l #0x07,D0 /* least significant three bits */
lsl.l #8,D0 /* move over to make mask */ lsl.l #8,D0 /* move over to make mask */
andi.l #0x0000F8FF,D7 /* zero out current IPL */ andi.l #0x0000F8FF,D7 /* zero out current IPL */
or.l D0,D7 /* place new IPL in sr */ or.l D0,D7 /* place new IPL in sr */
move.w D7,SR move.w D7,SR
move.l D6, D0 /* Return value in D0. */ move.l D6, D0 /* Return value in D0. */
movem.l (SP),D6-D7 movem.l (SP),D6-D7
lea 8(SP),SP lea 8(SP),SP
unlk A6 unlk A6
rts rts
/********************************************************************/ /********************************************************************/
mcf5xxx_wr_cacrx: mcf5xxx_wr_cacrx:
_mcf5xxx_wr_cacrx: _mcf5xxx_wr_cacrx:
move.l 4(sp),d0 move.l 4(sp),d0
.long 0x4e7b0002 /* movec d0,cacr */ .long 0x4e7b0002 /* movec d0,cacr */
nop nop
rts rts
/********************************************************************/ /********************************************************************/
/* Yield interrupt. */ /* Yield interrupt. */
_vPortYieldISR: _vPortYieldISR:
vPortYieldISR: vPortYieldISR:
portSAVE_CONTEXT portSAVE_CONTEXT
jsr _vPortYieldHandler jsr _vPortYieldHandler
portRESTORE_CONTEXT portRESTORE_CONTEXT
/********************************************************************/ /********************************************************************/
vPortStartFirstTask: vPortStartFirstTask:
_vPortStartFirstTask: _vPortStartFirstTask:
portRESTORE_CONTEXT portRESTORE_CONTEXT
.end .end

View file

@ -1,115 +1,115 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#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.
* *
* The settings in this file configure FreeRTOS correctly for the * The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler. * given hardware and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*----------------------------------------------------------- *-----------------------------------------------------------
*/ */
/* 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 */

View file

@ -1,147 +1,147 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Kernel includes. */ /* Kernel includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
#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. */
*pxTopOfStack = ( StackType_t ) pxCode; *pxTopOfStack = ( StackType_t ) pxCode;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( portINITIAL_FORMAT_VECTOR << 16UL ) | ( portINITIAL_STATUS_REGISTER ); *pxTopOfStack = ( portINITIAL_FORMAT_VECTOR << 16UL ) | ( portINITIAL_STATUS_REGISTER );
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x0; /*FP*/ *pxTopOfStack = ( StackType_t ) 0x0; /*FP*/
pxTopOfStack -= 14; /* A5 to D0. */ pxTopOfStack -= 14; /* A5 to D0. */
return pxTopOfStack; return pxTopOfStack;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
extern void vPortStartFirstTask( void ); extern void vPortStartFirstTask( void );
ulCriticalNesting = 0UL; ulCriticalNesting = 0UL;
/* Configure the interrupts used by this port. */ /* Configure the interrupts used by this port. */
vApplicationSetupInterrupts(); vApplicationSetupInterrupts();
/* Start the first task executing. */ /* Start the first task executing. */
vPortStartFirstTask(); vPortStartFirstTask();
return pdFALSE; return pdFALSE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented as there is nothing to return to. */ /* Not implemented as there is nothing to return to. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortEnterCritical( void ) 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++;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortExitCritical( void ) void vPortExitCritical( void )
{ {
ulCriticalNesting--; ulCriticalNesting--;
if( ulCriticalNesting == 0 ) if( ulCriticalNesting == 0 )
{ {
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
MCF_INTC0_INTFRCL = 0; MCF_INTC0_INTFRCL = 0;
vTaskSwitchContext(); vTaskSwitchContext();
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,130 +1,130 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* /*
* Purpose: Lowest level routines for all ColdFire processors. * Purpose: Lowest level routines for all ColdFire processors.
* *
* Notes: * Notes:
* *
* ulPortSetIPL() and mcf5xxx_wr_cacr() copied with permission from FreeScale * ulPortSetIPL() and mcf5xxx_wr_cacr() copied with permission from FreeScale
* supplied source files. * supplied source files.
*/ */
.global ulPortSetIPL .global ulPortSetIPL
.global _ulPortSetIPL .global _ulPortSetIPL
.global mcf5xxx_wr_cacrx .global mcf5xxx_wr_cacrx
.global _mcf5xxx_wr_cacrx .global _mcf5xxx_wr_cacrx
.global vPortYieldISR .global vPortYieldISR
.global _vPortYieldISR .global _vPortYieldISR
.global vPortStartFirstTask .global vPortStartFirstTask
.global _vPortStartFirstTask .global _vPortStartFirstTask
.extern _pxCurrentTCB .extern _pxCurrentTCB
.extern _vPortYieldHandler .extern _vPortYieldHandler
.text .text
.macro portSAVE_CONTEXT .macro portSAVE_CONTEXT
lea.l (-60, sp), sp lea.l (-60, sp), sp
movem.l d0-a6, (sp) movem.l d0-a6, (sp)
move.l _pxCurrentTCB, a0 move.l _pxCurrentTCB, a0
move.l sp, (a0) move.l sp, (a0)
.endm .endm
.macro portRESTORE_CONTEXT .macro portRESTORE_CONTEXT
move.l _pxCurrentTCB, a0 move.l _pxCurrentTCB, a0
move.l (a0), sp move.l (a0), sp
movem.l (sp), d0-a6 movem.l (sp), d0-a6
lea.l (60, sp), sp lea.l (60, sp), sp
rte rte
.endm .endm
/********************************************************************/ /********************************************************************/
/* /*
* This routines changes the IPL to the value passed into the routine. * This routines changes the IPL to the value passed into the routine.
* It also returns the old IPL value back. * It also returns the old IPL value back.
* Calling convention from C: * Calling convention from C:
* old_ipl = asm_set_ipl(new_ipl); * old_ipl = asm_set_ipl(new_ipl);
* For the Diab Data C compiler, it passes return value thru D0. * For the Diab Data C compiler, it passes return value thru D0.
* Note that only the least significant three bits of the passed * Note that only the least significant three bits of the passed
* value are used. * value are used.
*/ */
ulPortSetIPL: ulPortSetIPL:
_ulPortSetIPL: _ulPortSetIPL:
link A6,#-8 link A6,#-8
movem.l D6-D7,(SP) movem.l D6-D7,(SP)
move.w SR,D7 /* current sr */ move.w SR,D7 /* current sr */
move.l D7,D0 /* prepare return value */ move.l D7,D0 /* prepare return value */
andi.l #0x0700,D0 /* mask out IPL */ andi.l #0x0700,D0 /* mask out IPL */
lsr.l #8,D0 /* IPL */ lsr.l #8,D0 /* IPL */
move.l 8(A6),D6 /* get argument */ move.l 8(A6),D6 /* get argument */
andi.l #0x07,D6 /* least significant three bits */ andi.l #0x07,D6 /* least significant three bits */
lsl.l #8,D6 /* move over to make mask */ lsl.l #8,D6 /* move over to make mask */
andi.l #0x0000F8FF,D7 /* zero out current IPL */ andi.l #0x0000F8FF,D7 /* zero out current IPL */
or.l D6,D7 /* place new IPL in sr */ or.l D6,D7 /* place new IPL in sr */
move.w D7,SR move.w D7,SR
movem.l (SP),D6-D7 movem.l (SP),D6-D7
lea 8(SP),SP lea 8(SP),SP
unlk A6 unlk A6
rts rts
/********************************************************************/ /********************************************************************/
mcf5xxx_wr_cacrx: mcf5xxx_wr_cacrx:
_mcf5xxx_wr_cacrx: _mcf5xxx_wr_cacrx:
move.l 4(sp),d0 move.l 4(sp),d0
.long 0x4e7b0002 /* movec d0,cacr */ .long 0x4e7b0002 /* movec d0,cacr */
nop nop
rts rts
/********************************************************************/ /********************************************************************/
/* Yield interrupt. */ /* Yield interrupt. */
_vPortYieldISR: _vPortYieldISR:
vPortYieldISR: vPortYieldISR:
portSAVE_CONTEXT portSAVE_CONTEXT
jsr _vPortYieldHandler jsr _vPortYieldHandler
portRESTORE_CONTEXT portRESTORE_CONTEXT
/********************************************************************/ /********************************************************************/
vPortStartFirstTask: vPortStartFirstTask:
_vPortStartFirstTask: _vPortStartFirstTask:
portRESTORE_CONTEXT portRESTORE_CONTEXT
.end .end

View file

@ -1,114 +1,114 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#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.
* *
* The settings in this file configure FreeRTOS correctly for the * The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler. * given hardware and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*----------------------------------------------------------- *-----------------------------------------------------------
*/ */
/* 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 */

View file

@ -1,237 +1,237 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Scheduler includes. */ /* Scheduler includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the HCS12 port. * Implementation of functions defined in portable.h for the HCS12 port.
*----------------------------------------------------------*/ *----------------------------------------------------------*/
/* /*
* Configure a timer to generate the RTOS tick at the frequency specified * Configure a timer to generate the RTOS tick at the frequency specified
* within FreeRTOSConfig.h. * within FreeRTOSConfig.h.
*/ */
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;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* 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. */
/* Y register */ /* Y register */
*pxTopOfStack = ( StackType_t ) 0xff; *pxTopOfStack = ( StackType_t ) 0xff;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0xee; *pxTopOfStack = ( StackType_t ) 0xee;
pxTopOfStack--; pxTopOfStack--;
/* X register */ /* X register */
*pxTopOfStack = ( StackType_t ) 0xdd; *pxTopOfStack = ( StackType_t ) 0xdd;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0xcc; *pxTopOfStack = ( StackType_t ) 0xcc;
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--;
#ifdef BANKED_MODEL #ifdef BANKED_MODEL
/* The page of the task. */ /* The page of the task. */
*pxTopOfStack = ( StackType_t ) ( ( int ) pxCode ); *pxTopOfStack = ( StackType_t ) ( ( int ) pxCode );
pxTopOfStack--; pxTopOfStack--;
#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;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* It is unlikely that the HCS12 port will get stopped. */ /* It is unlikely that the HCS12 port will get stopped. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupTimerInterrupt( void ) static void prvSetupTimerInterrupt( void )
{ {
TickTimer_SetFreqHz( configTICK_RATE_HZ ); TickTimer_SetFreqHz( configTICK_RATE_HZ );
TickTimer_Enable(); TickTimer_Enable();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#pragma CODE_SEG __NEAR_SEG NON_BANKED #pragma CODE_SEG __NEAR_SEG NON_BANKED
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. */
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
/* Simulate the end of an interrupt to start the scheduler off. */ /* Simulate the end of an interrupt to start the scheduler off. */
__asm( "rti" ); __asm( "rti" );
/* Should not get here! */ /* Should not get here! */
return pdFALSE; return pdFALSE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Context switch functions. These are both interrupt service routines. * Context switch functions. These are both interrupt service routines.
*/ */
/* /*
* Manual context switch forced by calling portYIELD(). This is the SWI * Manual context switch forced by calling portYIELD(). This is the SWI
* handler. * handler.
*/ */
void interrupt vPortYield( void ) void interrupt vPortYield( void )
{ {
portSAVE_CONTEXT(); portSAVE_CONTEXT();
vTaskSwitchContext(); vTaskSwitchContext();
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* RTOS tick interrupt service routine. If the cooperative scheduler is * RTOS tick interrupt service routine. If the cooperative scheduler is
* being used then this simply increments the tick count. If the * being used then this simply increments the tick count. If the
* preemptive scheduler is being used a context switch can occur. * preemptive scheduler is being used a context switch can occur.
*/ */
void interrupt vPortTickInterrupt( void ) void interrupt vPortTickInterrupt( void )
{ {
#if configUSE_PREEMPTION == 1 #if configUSE_PREEMPTION == 1
{ {
/* A context switch might happen so save the context. */ /* A context switch might happen so save the context. */
portSAVE_CONTEXT(); portSAVE_CONTEXT();
/* Increment the tick ... */ /* Increment the tick ... */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
vTaskSwitchContext(); vTaskSwitchContext();
} }
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
{ {
xTaskIncrementTick(); xTaskIncrementTick();
TFLG1 = 1; TFLG1 = 1;
} }
#endif #endif
} }
#pragma CODE_SEG DEFAULT #pragma CODE_SEG DEFAULT

View file

@ -1,202 +1,202 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef PORTMACRO_H #ifndef PORTMACRO_H
#define PORTMACRO_H #define PORTMACRO_H
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Port specific definitions. * Port specific definitions.
* *
* The settings in this file configure FreeRTOS correctly for the * The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler. * given hardware and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*----------------------------------------------------------- *-----------------------------------------------------------
*/ */
/* 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 uint8_t #define portSTACK_TYPE uint8_t
#define portBASE_TYPE char #define portBASE_TYPE char
typedef portSTACK_TYPE StackType_t; 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
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 1 #define portBYTE_ALIGNMENT 1
#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 portYIELD() __asm( "swi" ); #define portYIELD() __asm( "swi" );
#define portNOP() __asm( "nop" ); #define portNOP() __asm( "nop" );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section handling. */ /* Critical section handling. */
#define portENABLE_INTERRUPTS() __asm( "cli" ) #define portENABLE_INTERRUPTS() __asm( "cli" )
#define portDISABLE_INTERRUPTS() __asm( "sei" ) #define portDISABLE_INTERRUPTS() __asm( "sei" )
/* /*
* Disable interrupts before incrementing the count of critical section nesting. * Disable interrupts before incrementing the count of critical section nesting.
* The nesting count is maintained so we know when interrupts should be * The nesting count is maintained so we know when interrupts should be
* re-enabled. Once interrupts are disabled the nesting count can be accessed * re-enabled. Once interrupts are disabled the nesting count can be accessed
* 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
* nesting is found to be 0 (no nesting) then we are leaving the critical * nesting is found to be 0 (no nesting) then we are leaving the critical
* 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--; \
if( uxCriticalNesting == 0 ) \ if( uxCriticalNesting == 0 ) \
{ \ { \
portENABLE_INTERRUPTS(); \ portENABLE_INTERRUPTS(); \
} \ } \
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task utilities. */ /* Task utilities. */
/* /*
* These macros are very simple as the processor automatically saves and * These macros are very simple as the processor automatically saves and
* restores its registers as interrupts are entered and exited. In * restores its registers as interrupts are entered and exited. In
* addition to the (automatically stacked) registers we also stack the * addition to the (automatically stacked) registers we also stack the
* critical nesting count. Each task maintains its own critical nesting * critical nesting count. Each task maintains its own critical nesting
* count as it is legitimate for a task to yield from within a critical * count as it is legitimate for a task to yield from within a critical
* section. If the banked memory model is being used then the PPAGE * section. If the banked memory model is being used then the PPAGE
* register is also stored as part of the tasks context. * register is also stored as part of the tasks context.
*/ */
#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.
*/ */
#define portRESTORE_CONTEXT() \ #define portRESTORE_CONTEXT() \
{ \ { \
extern volatile void * pxCurrentTCB; \ extern volatile void * pxCurrentTCB; \
extern volatile UBaseType_t uxCriticalNesting; \ extern volatile UBaseType_t uxCriticalNesting; \
\ \
__asm( "ldx pxCurrentTCB" ); \ __asm( "ldx pxCurrentTCB" ); \
__asm( "lds 0, x" ); \ __asm( "lds 0, x" ); \
__asm( "pula" ); \ __asm( "pula" ); \
__asm( "staa uxCriticalNesting" ); \ __asm( "staa uxCriticalNesting" ); \
__asm( "pula" ); \ __asm( "pula" ); \
__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.
*/ */
#define portSAVE_CONTEXT() \ #define portSAVE_CONTEXT() \
{ \ { \
extern volatile void * pxCurrentTCB; \ extern volatile void * pxCurrentTCB; \
extern volatile UBaseType_t uxCriticalNesting; \ extern volatile UBaseType_t uxCriticalNesting; \
\ \
__asm( "ldaa 0x30" ); /* 0x30 = PPAGE */ \ __asm( "ldaa 0x30" ); /* 0x30 = PPAGE */ \
__asm( "psha" ); \ __asm( "psha" ); \
__asm( "ldaa uxCriticalNesting" ); \ __asm( "ldaa uxCriticalNesting" ); \
__asm( "psha" ); \ __asm( "psha" ); \
__asm( "ldx pxCurrentTCB" ); \ __asm( "ldx pxCurrentTCB" ); \
__asm( "sts 0, x" ); \ __asm( "sts 0, x" ); \
} }
#else #else
/* /*
* 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.
*/ */
#define portRESTORE_CONTEXT() \ #define portRESTORE_CONTEXT() \
{ \ { \
extern volatile void * pxCurrentTCB; \ extern volatile void * pxCurrentTCB; \
extern volatile UBaseType_t uxCriticalNesting; \ extern volatile UBaseType_t uxCriticalNesting; \
\ \
__asm( "ldx pxCurrentTCB" ); \ __asm( "ldx pxCurrentTCB" ); \
__asm( "lds 0, x" ); \ __asm( "lds 0, x" ); \
__asm( "pula" ); \ __asm( "pula" ); \
__asm( "staa uxCriticalNesting" ); \ __asm( "staa uxCriticalNesting" ); \
} }
#define portSAVE_CONTEXT() \ #define portSAVE_CONTEXT() \
{ \ { \
extern volatile void * pxCurrentTCB; \ extern volatile void * pxCurrentTCB; \
extern volatile UBaseType_t uxCriticalNesting; \ extern volatile UBaseType_t uxCriticalNesting; \
\ \
__asm( "ldaa uxCriticalNesting" ); \ __asm( "ldaa uxCriticalNesting" ); \
__asm( "psha" ); \ __asm( "psha" ); \
__asm( "ldx pxCurrentTCB" ); \ __asm( "ldx pxCurrentTCB" ); \
__asm( "sts 0, x" ); \ __asm( "sts 0, x" ); \
} }
#endif #endif
/* /*
* 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
* task switch from within a standard ISR. This macro can only be used if * task switch from within a standard ISR. This macro can only be used if
* the ISR does not use any local (stack) variables. If the ISR uses stack * the ISR does not use any local (stack) variables. If the ISR uses stack
* variables portYIELD() should be used in it's place. * variables portYIELD() should be used in it's place.
*/ */
#define portTASK_SWITCH_FROM_ISR() \ #define portTASK_SWITCH_FROM_ISR() \
portSAVE_CONTEXT(); \ portSAVE_CONTEXT(); \
vTaskSwitchContext(); \ vTaskSwitchContext(); \
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
/* 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

View file

@ -1,238 +1,238 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
* 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>
/* Scheduler includes. */ /* Scheduler includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
/* Hardware specific definitions. */ /* Hardware specific definitions. */
#include "AT91R40008.h" #include "AT91R40008.h"
#include "pio.h" #include "pio.h"
#include "aic.h" #include "aic.h"
#include "tc.h" #include "tc.h"
/* Constants required to setup the task context. */ /* Constants required to setup the task context. */
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */ #define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 ) #define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 ) #define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
#define portTICK_PRIORITY_6 ( 6 ) #define portTICK_PRIORITY_6 ( 6 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Setup the timer to generate the tick interrupts. */ /* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt( void ); static void prvSetupTimerInterrupt( void );
/* /*
* The scheduler can only be started from ARM mode, so * The scheduler can only be started from ARM mode, so
* vPortISRStartFirstSTask() is defined in portISR.c. * vPortISRStartFirstSTask() is defined in portISR.c.
*/ */
extern void vPortISRStartFirstTask( void ); extern void vPortISRStartFirstTask( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Initialise the stack of a task to look exactly as if a call to * Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called. * portSAVE_CONTEXT had been called.
* *
* 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--;
*pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */ *pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */ *pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
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
{ {
/* We want the task to start in thumb mode. */ /* We want the task to start in thumb mode. */
*pxTopOfStack |= portTHUMB_MODE_BIT; *pxTopOfStack |= portTHUMB_MODE_BIT;
} }
#endif #endif
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;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
vPortISRStartFirstTask(); vPortISRStartFirstTask();
/* Should not get here! */ /* Should not get here! */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Setup the tick timer to generate the tick interrupts at the required frequency. * Setup the tick timer to generate the tick interrupts at the required frequency.
*/ */
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;
/* Stop the tick timer... */ /* Stop the tick timer... */
portTIMER_REG_BASE_PTR->TC_CCR = TC_CLKDIS; portTIMER_REG_BASE_PTR->TC_CCR = TC_CLKDIS;
/* Start with tick timer interrupts disabled... */ /* Start with tick timer interrupts disabled... */
portTIMER_REG_BASE_PTR->TC_IDR = 0xFFFFFFFF; portTIMER_REG_BASE_PTR->TC_IDR = 0xFFFFFFFF;
/* Clear any pending tick timer interrupts... */ /* Clear any pending tick timer interrupts... */
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
/* Tick timer interrupt level-sensitive, priority 6... */ /* Tick timer interrupt level-sensitive, priority 6... */
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;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,233 +1,233 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
* 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"
#include "task.h" #include "task.h"
/* Constants required to handle interrupts. */ /* Constants required to handle interrupts. */
#define portCLEAR_AIC_INTERRUPT ( ( uint32_t ) 0 ) #define portCLEAR_AIC_INTERRUPT ( ( uint32_t ) 0 )
/* Constants required to handle critical sections. */ /* Constants required to handle critical sections. */
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
volatile uint32_t ulCriticalNesting = 9999UL; 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
* function here. * function here.
*/ */
void vPortISRStartFirstTask( void ); 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();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Called by portYIELD() or taskYIELD() to manually force a context switch. * Called by portYIELD() or taskYIELD() to manually force a context switch.
* *
* When a context switch is performed from the task level the saved task * When a context switch is performed from the task level the saved task
* context is made to look as if it occurred from within the tick ISR. This * context is made to look as if it occurred from within the tick ISR. This
* way the same restore context function can be used when restoring the context * way the same restore context function can be used when restoring the context
* saved from the ISR or that saved from a call to vPortYieldProcessor. * saved from the ISR or that saved from a call to vPortYieldProcessor.
*/ */
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. */
vTaskSwitchContext(); vTaskSwitchContext();
/* Restore the context of the new task. */ /* Restore the context of the new task. */
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* The ISR used for the scheduler tick depends on whether the cooperative or * The ISR used for the scheduler tick depends on whether the cooperative or
* the preemptive scheduler is being used. * the preemptive scheduler is being used.
*/ */
#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;
/* Clear tick timer interrupt indication. */ /* Clear tick timer interrupt indication. */
ulDummy = portTIMER_REG_BASE_PTR->TC_SR; ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
xTaskIncrementTick(); xTaskIncrementTick();
/* Acknowledge the interrupt at AIC level... */ /* Acknowledge the interrupt at AIC level... */
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT; AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
} }
#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();
} }
/* Acknowledge the interrupt at AIC level... */ /* Acknowledge the interrupt at AIC level... */
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT; AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
/* Restore the context of the new task. */ /* Restore the context of the new task. */
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* The interrupt management utilities can only be called from ARM mode. When * The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions here to * THUMB_INTERWORK is defined the utilities are defined as functions here to
* 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.
*/ */
#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++;
} }
void vPortExitCritical( void ) void vPortExitCritical( void )
{ {
if( ulCriticalNesting > portNO_CRITICAL_NESTING ) if( ulCriticalNesting > portNO_CRITICAL_NESTING )
{ {
/* Decrement the nesting count as we are leaving a critical section. */ /* Decrement the nesting count as we are leaving a critical section. */
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. */
} }
} }
} }

View file

@ -1,255 +1,255 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* /*
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.
* *
* The settings in this file configure FreeRTOS correctly for the * The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler. * given hardware and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*----------------------------------------------------------- *-----------------------------------------------------------
*/ */
/* 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. */
/* /*
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR * portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but * and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
* are included here for efficiency. An attempt to call one from * are included here for efficiency. An attempt to call one from
* 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. */
/* /*
* The interrupt management utilities can only be called from ARM mode. When * The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions in * THUMB_INTERWORK is defined the utilities are defined as functions in
* portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not * portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not
* 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

View file

@ -1,51 +1,51 @@
//* ---------------------------------------------------------------------------- //* ----------------------------------------------------------------------------
//* 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

View file

@ -1,213 +1,213 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
* 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>
/* Scheduler includes. */ /* Scheduler includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
/* Processor constants. */ /* Processor constants. */
#include "AT91SAM7X256.h" #include "AT91SAM7X256.h"
/* Constants required to setup the task context. */ /* Constants required to setup the task context. */
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */ #define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 ) #define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 ) #define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
/* Constants required to setup the tick ISR. */ /* Constants required to setup the tick ISR. */
#define portENABLE_TIMER ( ( uint8_t ) 0x01 ) #define portENABLE_TIMER ( ( uint8_t ) 0x01 )
#define portPRESCALE_VALUE 0x00 #define portPRESCALE_VALUE 0x00
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 ) #define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 ) #define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
/* Constants required to setup the PIT. */ /* Constants required to setup the PIT. */
#define portPIT_CLOCK_DIVISOR ( ( uint32_t ) 16 ) #define portPIT_CLOCK_DIVISOR ( ( uint32_t ) 16 )
#define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_PERIOD_MS ) #define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_PERIOD_MS )
#define portINT_LEVEL_SENSITIVE 0 #define portINT_LEVEL_SENSITIVE 0
#define portPIT_ENABLE ( ( uint16_t ) 0x1 << 24 ) #define portPIT_ENABLE ( ( uint16_t ) 0x1 << 24 )
#define portPIT_INT_ENABLE ( ( uint16_t ) 0x1 << 25 ) #define portPIT_INT_ENABLE ( ( uint16_t ) 0x1 << 25 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Setup the timer to generate the tick interrupts. */ /* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt( void ); static void prvSetupTimerInterrupt( void );
/* /*
* The scheduler can only be started from ARM mode, so * The scheduler can only be started from ARM mode, so
* vPortISRStartFirstSTask() is defined in portISR.c. * vPortISRStartFirstSTask() is defined in portISR.c.
*/ */
extern void vPortISRStartFirstTask( void ); extern void vPortISRStartFirstTask( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Initialise the stack of a task to look exactly as if a call to * Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called. * portSAVE_CONTEXT had been called.
* *
* 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--;
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */ *pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */ *pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
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
{ {
/* We want the task to start in thumb mode. */ /* We want the task to start in thumb mode. */
*pxTopOfStack |= portTHUMB_MODE_BIT; *pxTopOfStack |= portTHUMB_MODE_BIT;
} }
#endif #endif
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;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
vPortISRStartFirstTask(); vPortISRStartFirstTask();
/* Should not get here! */ /* Should not get here! */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Setup the timer 0 to generate the tick interrupts at the required frequency. * Setup the timer 0 to generate the tick interrupts at the required frequency.
*/ */
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;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,227 +1,227 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
* 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"
#include "task.h" #include "task.h"
#include "AT91SAM7X256.h" #include "AT91SAM7X256.h"
/* Constants required to handle interrupts. */ /* Constants required to handle interrupts. */
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 ) #define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 ) #define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
/* Constants required to handle critical sections. */ /* Constants required to handle critical sections. */
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
volatile uint32_t ulCriticalNesting = 9999UL; 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
* function here. * function here.
*/ */
void vPortISRStartFirstTask( void ); 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();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Called by portYIELD() or taskYIELD() to manually force a context switch. * Called by portYIELD() or taskYIELD() to manually force a context switch.
* *
* When a context switch is performed from the task level the saved task * When a context switch is performed from the task level the saved task
* context is made to look as if it occurred from within the tick ISR. This * context is made to look as if it occurred from within the tick ISR. This
* way the same restore context function can be used when restoring the context * way the same restore context function can be used when restoring the context
* saved from the ISR or that saved from a call to vPortYieldProcessor. * saved from the ISR or that saved from a call to vPortYieldProcessor.
*/ */
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. */
vTaskSwitchContext(); vTaskSwitchContext();
/* Restore the context of the new task. */ /* Restore the context of the new task. */
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* The ISR used for the scheduler tick depends on whether the cooperative or * The ISR used for the scheduler tick depends on whether the cooperative or
* the preemptive scheduler is being used. * the preemptive scheduler is being used.
*/ */
#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. */
ulDummy = AT91C_BASE_PITC->PITC_PIVR; ulDummy = AT91C_BASE_PITC->PITC_PIVR;
/* End the interrupt in the AIC. */ /* End the interrupt in the AIC. */
AT91C_BASE_AIC->AIC_EOICR = ulDummy; AT91C_BASE_AIC->AIC_EOICR = ulDummy;
} }
#else #else
/* 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. */
portSAVE_CONTEXT(); portSAVE_CONTEXT();
/* Increment the tick count - this may wake a task. */ /* Increment the tick count - this may wake a task. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
/* Find the highest priority task that is ready to run. */ /* Find the highest priority task that is ready to run. */
vTaskSwitchContext(); vTaskSwitchContext();
} }
/* End the interrupt in the AIC. */ /* End the interrupt in the AIC. */
AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR; AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR;
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* The interrupt management utilities can only be called from ARM mode. When * The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions here to * THUMB_INTERWORK is defined the utilities are defined as functions here to
* 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++;
} }
void vPortExitCritical( void ) void vPortExitCritical( void )
{ {
if( ulCriticalNesting > portNO_CRITICAL_NESTING ) if( ulCriticalNesting > portNO_CRITICAL_NESTING )
{ {
/* Decrement the nesting count as we are leaving a critical section. */ /* Decrement the nesting count as we are leaving a critical section. */
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. */
} }
} }
} }

View file

@ -1,249 +1,249 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* /*
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.
* *
* The settings in this file configure FreeRTOS correctly for the * The settings in this file configure FreeRTOS correctly for the
* given hardware and compiler. * given hardware and compiler.
* *
* These settings should not be altered. * These settings should not be altered.
*----------------------------------------------------------- *-----------------------------------------------------------
*/ */
/* 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" );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Scheduler utilities. */ /* Scheduler utilities. */
/* /*
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR * portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but * and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
* are included here for efficiency. An attempt to call one from * are included here for efficiency. An attempt to call one from
* 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" )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section management. */ /* Critical section management. */
/* /*
* The interrupt management utilities can only be called from ARM mode. When * The interrupt management utilities can only be called from ARM mode. When
* THUMB_INTERWORK is defined the utilities are defined as functions in * THUMB_INTERWORK is defined the utilities are defined as functions in
* portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not * portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not
* 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 */

View file

@ -1,221 +1,221 @@
/* /*
* FreeRTOS Kernel V10.2.1 * FreeRTOS Kernel V10.3.0
* Copyright (C) 2019 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
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
* 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>
/* Scheduler includes. */ /* Scheduler includes. */
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
/* Constants required to setup the task context. */ /* Constants required to setup the task context. */
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */ #define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 ) #define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 ) #define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
/* Constants required to setup the tick ISR. */ /* Constants required to setup the tick ISR. */
#define portENABLE_TIMER ( ( uint8_t ) 0x01 ) #define portENABLE_TIMER ( ( uint8_t ) 0x01 )
#define portPRESCALE_VALUE 0x00 #define portPRESCALE_VALUE 0x00
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 ) #define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 ) #define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
/* Constants required to setup the VIC for the tick ISR. */ /* Constants required to setup the VIC for the tick ISR. */
#define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 ) #define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 )
#define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 ) #define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 )
#define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 ) #define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Setup the timer to generate the tick interrupts. */ /* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt( void ); static void prvSetupTimerInterrupt( void );
/* /*
* The scheduler can only be started from ARM mode, so * The scheduler can only be started from ARM mode, so
* vPortISRStartFirstSTask() is defined in portISR.c. * vPortISRStartFirstSTask() is defined in portISR.c.
*/ */
extern void vPortISRStartFirstTask( void ); extern void vPortISRStartFirstTask( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Initialise the stack of a task to look exactly as if a call to * Initialise the stack of a task to look exactly as if a call to
* portSAVE_CONTEXT had been called. * portSAVE_CONTEXT had been called.
* *
* 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--;
*pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */ *pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */ *pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */ *pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */ *pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */ *pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */ *pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */ *pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */ *pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */ *pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */ *pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */ *pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */ *pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */ *pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
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 )
{ {
/* We want the task to start in thumb mode. */ /* We want the task to start in thumb mode. */
*pxTopOfStack |= portTHUMB_MODE_BIT; *pxTopOfStack |= portTHUMB_MODE_BIT;
} }
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;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
vPortISRStartFirstTask(); vPortISRStartFirstTask();
/* Should not get here! */ /* Should not get here! */
return 0; return 0;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* Setup the timer 0 to generate the tick interrupts at the required frequency. * Setup the timer 0 to generate the tick interrupts at the required frequency.
*/ */
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 );
} }
#endif #endif
T0_MR0 = ulCompareMatch; T0_MR0 = ulCompareMatch;
/* Generate tick with timer 0 compare match. */ /* Generate tick with timer 0 compare match. */
T0_MCR = portRESET_COUNT_ON_MATCH | portINTERRUPT_ON_MATCH; T0_MCR = portRESET_COUNT_ON_MATCH | portINTERRUPT_ON_MATCH;
/* Setup the VIC for the timer. */ /* Setup the VIC for the timer. */
VICIntSelect &= ~( portTIMER_VIC_CHANNEL_BIT ); VICIntSelect &= ~( portTIMER_VIC_CHANNEL_BIT );
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;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

Some files were not shown because too many files have changed in this diff Show more