Feature: SMP (#278)

* Add XMOS XCore ports

Some minor modifications are also made to the kernel to support the
XCore compiler's automatic stack size calculation.

* Update kernel to support SMP

The XMOS XCore ports are also updated to support SMP.

* Fix compiler warnings in xcore ports

The port set and clear interrupt mask from ISR macros were removed from
the ports so that the default macros found in FreeRTOS.h are used
instead. The default macros do not result in warnings when they are
used.

* Remove inline function from timers.h

Inline function converted to macro. This should now build when
optimizations are off and inlining is disabled.

* Fix compiler warnings in xcore ports and tasks.c

* fixed documentation for ulTaskNotifyTake() and ulTaskNotifyTakeIndexed()

* spelling fixes for tasks.c

Co-authored-by: Michael Bruno <mikeb@xmos.com>
This commit is contained in:
Joseph Julicher 2021-03-15 17:29:08 -07:00 committed by GitHub
parent cafae476e4
commit 989bc332b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
509 changed files with 176869 additions and 174380 deletions

View file

@ -1,70 +1,70 @@
# Contribution guidelines # Contribution guidelines
Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, code, or Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, code, or
documentation, we welcome our community to be involved in this project. documentation, we welcome our community to be involved in this project.
Please read through this document before submitting any issues or pull requests to ensure we are able to help you and all members of the community as effectively as possible. Please read through this document before submitting any issues or pull requests to ensure we are able to help you and all members of the community as effectively as possible.
## Code of conduct ## Code of conduct
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
opensource-codeofconduct@amazon.com with any additional questions or comments. opensource-codeofconduct@amazon.com with any additional questions or comments.
## Security issue notifications ## Security issue notifications
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](https://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](https://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
## Submitting a bugs/feature request ## Submitting a bugs/feature request
Have a bug to report or feature to request? Follow these steps: Have a bug to report or feature to request? Follow these steps:
1. Search on the [FreeRTOS Community Support Forums](https://forums.freertos.org/) and [GitHub issue tracker](https://github.com/FreeRTOS/FreeRTOS/issues?utf8=%E2%9C%93&q=is%3Aissue) to be sure this hasn't been already reported or discussed. 1. Search on the [FreeRTOS Community Support Forums](https://forums.freertos.org/) and [GitHub issue tracker](https://github.com/FreeRTOS/FreeRTOS/issues?utf8=%E2%9C%93&q=is%3Aissue) to be sure this hasn't been already reported or discussed.
2. If your search turns up empty, create a new topic in the [forums](https://forums.freertos.org/) and work with the community to help clarify issues or refine the idea. Include as many of the details listed below. 2. If your search turns up empty, create a new topic in the [forums](https://forums.freertos.org/) and work with the community to help clarify issues or refine the idea. Include as many of the details listed below.
3. Once the community has had time to discuss and digest, we welcome you to create an [issue](https://github.com/FreeRTOS/FreeRTOS/issues) to report bugs or suggest features. 3. Once the community has had time to discuss and digest, we welcome you to create an [issue](https://github.com/FreeRTOS/FreeRTOS/issues) to report bugs or suggest features.
When creating a new topic on the forums or filing an issue, please include as many relevant details as possible. Examples include: When creating a new topic on the forums or filing an issue, please include as many relevant details as possible. Examples include:
* A clear description of the situation — what you observe, what you expect, and your view on how the two differ. * A clear description of the situation — what you observe, what you expect, and your view on how the two differ.
* A reproducible test case or sequence of steps. * A reproducible test case or sequence of steps.
* The version of our code being used. * The version of our code being used.
* Any modifications you've made relevant to the bug. * Any modifications you've made relevant to the bug.
* Details of your environment or deployment. Highlight anything unusual. * Details of your environment or deployment. Highlight anything unusual.
## Contributing via pull request ## Contributing via pull request
Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
1. You are working against the latest source on the *master* branch. 1. You are working against the latest source on the *master* branch.
2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
To send us a pull request, please: To send us a pull request, please:
1. Fork the repository. 1. Fork the repository.
2. Modify the source; focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 2. Modify the source; focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
3. Follow the [coding style guide](https://www.FreeRTOS.org/FreeRTOS-Coding-Standard-and-Style-Guide.html). 3. Follow the [coding style guide](https://www.FreeRTOS.org/FreeRTOS-Coding-Standard-and-Style-Guide.html).
4. Commit to your fork using clear commit messages. 4. Commit to your fork using clear commit messages.
5. Send us a pull request, answering any default questions in the pull request interface. 5. Send us a pull request, answering any default questions in the pull request interface.
NOTE: Please make sure the default option (Allow edits from maintainers) is left checked. NOTE: Please make sure the default option (Allow edits from maintainers) is left checked.
6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). [creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
## Coding style ## Coding style
* Please ensure that your code complies to the [FreeRTOS coding style guidelines](https://www.FreeRTOS.org/FreeRTOS-Coding-Standard-and-Style-Guide.html). * Please ensure that your code complies to the [FreeRTOS coding style guidelines](https://www.FreeRTOS.org/FreeRTOS-Coding-Standard-and-Style-Guide.html).
## Getting your pull request merged ## Getting your pull request merged
All pull requests must be approved by our review team before it can be merged in. We appreciate your patience while pull requests are reviewed. The time it takes to review will depend on complexity and consideration of wider implications. All pull requests must be approved by our review team before it can be merged in. We appreciate your patience while pull requests are reviewed. The time it takes to review will depend on complexity and consideration of wider implications.
## Finding contributions to work on ## Finding contributions to work on
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), tackling open 'help wanted' issues is a great place to start. Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), tackling open 'help wanted' issues is a great place to start.
## Licensing ## Licensing
The FreeRTOS kernel is released under the MIT open source license, the text of which can be found [here](https://github.com/FreeRTOS/FreeRTOS/blob/master/FreeRTOS/License/license.txt) The FreeRTOS kernel is released under the MIT open source license, the text of which can be found [here](https://github.com/FreeRTOS/FreeRTOS/blob/master/FreeRTOS/License/license.txt)
Additional license files can be found in the folders containing any supplementary libraries licensed by their respective copyright owners where applicable. Additional license files can be found in the folders containing any supplementary libraries licensed by their respective copyright owners where applicable.
We may ask you to sign a [Contributor License Agreement (CLA)](https://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. We may ask you to sign a [Contributor License Agreement (CLA)](https://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes.

10
.github/SECURITY.md vendored
View file

@ -1,5 +1,5 @@
## Reporting a Vulnerability ## Reporting a Vulnerability
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security
via our [vulnerability reporting page](https://aws.amazon.com/security/vulnerability-reporting/) or directly via email to aws-security@amazon.com. via our [vulnerability reporting page](https://aws.amazon.com/security/vulnerability-reporting/) or directly via email to aws-security@amazon.com.
Please do **not** create a public github issue. Please do **not** create a public github issue.

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
[InternetShortcut] [InternetShortcut]
URL=https://www.FreeRTOS.org/FreeRTOS-quick-start-guide.html URL=https://www.FreeRTOS.org/FreeRTOS-quick-start-guide.html
IDList= IDList=
[{000214A0-0000-0000-C000-000000000046}] [{000214A0-0000-0000-C000-000000000046}]
Prop3=19,2 Prop3=19,2

View file

@ -1,361 +1,361 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
*/ */
#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 = NULL; /*< Points to the delayed co-routine list currently being used. */ static List_t * pxDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used. */
static List_t * pxOverflowDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ static List_t * pxOverflowDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
/* Other file private variables. --------------------------------*/ /* Other file private variables. --------------------------------*/
CRCB_t * pxCurrentCoRoutine = NULL; CRCB_t * pxCurrentCoRoutine = NULL;
static UBaseType_t uxTopCoRoutineReadyPriority = 0; static UBaseType_t uxTopCoRoutineReadyPriority = 0;
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
/* The initial state of the co-routine when it is created. */ /* The initial state of the co-routine when it is created. */
#define corINITIAL_STATE ( 0 ) #define corINITIAL_STATE ( 0 )
/* /*
* Place the co-routine represented by pxCRCB into the appropriate ready queue * Place the co-routine represented by pxCRCB into the appropriate ready queue
* 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, BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode,
UBaseType_t uxPriority, UBaseType_t uxPriority,
UBaseType_t uxIndex ) 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, void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
List_t * pxEventList ) 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 )
{ {
/* Only run a co-routine after prvInitialiseCoRoutineLists() has been /* Only run a co-routine after prvInitialiseCoRoutineLists() has been
* called. prvInitialiseCoRoutineLists() is called automatically when a * called. prvInitialiseCoRoutineLists() is called automatically when a
* co-routine is created. */ * co-routine is created. */
if( pxDelayedCoRoutineList != NULL ) if( pxDelayedCoRoutineList != NULL )
{ {
/* See if any co-routines readied by events need moving to the ready lists. */ /* See if any co-routines readied by events need moving to the ready lists. */
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 );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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,32 +1,32 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
*/ */
#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
#include "stack_macros.h" #include "stack_macros.h"

View file

@ -1,417 +1,417 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
*/ */
/** /**
* @file atomic.h * @file atomic.h
* @brief FreeRTOS atomic operation support. * @brief FreeRTOS atomic operation support.
* *
* This file implements atomic functions by disabling interrupts globally. * This file implements atomic functions by disabling interrupts globally.
* Implementations with architecture specific atomic instructions can be * Implementations with architecture specific atomic instructions can 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>
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* *INDENT-ON* */ /* *INDENT-ON* */
/* /*
* Port specific definitions -- entering/exiting critical section. * Port specific definitions -- entering/exiting critical section.
* Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h * Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h
* *
* Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with * Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with
* ATOMIC_ENTER_CRITICAL(). * ATOMIC_ENTER_CRITICAL().
* *
*/ */
#if defined( portSET_INTERRUPT_MASK_FROM_ISR ) #if defined( portSET_INTERRUPT_MASK_FROM_ISR )
/* Nested interrupt scheme is supported in this port. */ /* Nested interrupt scheme is supported in this port. */
#define ATOMIC_ENTER_CRITICAL() \ #define ATOMIC_ENTER_CRITICAL() \
UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR() UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()
#define ATOMIC_EXIT_CRITICAL() \ #define ATOMIC_EXIT_CRITICAL() \
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType ) portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
#else #else
/* Nested interrupt scheme is NOT supported in this port. */ /* Nested interrupt scheme is NOT supported in this port. */
#define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL() #define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
#define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL() #define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL()
#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */ #endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
/* /*
* Port specific definition -- "always inline". * Port specific definition -- "always inline".
* Inline is compiler specific, and may not always get inlined depending on your * Inline is compiler specific, and may not always get inlined depending on your
* optimization level. Also, inline is considered as performance optimization * optimization level. Also, inline is considered as performance optimization
* for atomic. Thus, if portFORCE_INLINE is not provided by portmacro.h, * for atomic. Thus, if portFORCE_INLINE is not provided by portmacro.h,
* instead of resulting error, simply define it away. * instead of resulting error, simply define it away.
*/ */
#ifndef portFORCE_INLINE #ifndef portFORCE_INLINE
#define portFORCE_INLINE #define portFORCE_INLINE
#endif #endif
#define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U /**< Compare and swap succeeded, swapped. */ #define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U /**< Compare and swap succeeded, swapped. */
#define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U /**< Compare and swap failed, did not swap. */ #define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U /**< Compare and swap failed, did not swap. */
/*----------------------------- Swap && CAS ------------------------------*/ /*----------------------------- Swap && CAS ------------------------------*/
/** /**
* Atomic compare-and-swap * Atomic compare-and-swap
* *
* @brief Performs an atomic compare-and-swap operation on the specified values. * @brief Performs an atomic compare-and-swap operation on the specified values.
* *
* @param[in, out] pulDestination Pointer to memory location from where value is * @param[in, out] pulDestination Pointer to memory location from where value is
* to be loaded and checked. * to be loaded and checked.
* @param[in] ulExchange If condition meets, write this value to memory. * @param[in] ulExchange If condition meets, write this value to memory.
* @param[in] ulComparand Swap condition. * @param[in] ulComparand Swap condition.
* *
* @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped. * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
* *
* @note This function only swaps *pulDestination with ulExchange, if previous * @note This function only swaps *pulDestination with ulExchange, if previous
* *pulDestination value equals ulComparand. * *pulDestination value equals ulComparand.
*/ */
static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination, static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination,
uint32_t ulExchange, uint32_t ulExchange,
uint32_t ulComparand ) uint32_t ulComparand )
{ {
uint32_t ulReturnValue; uint32_t ulReturnValue;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
if( *pulDestination == ulComparand ) if( *pulDestination == ulComparand )
{ {
*pulDestination = ulExchange; *pulDestination = ulExchange;
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
} }
else else
{ {
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE; ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
} }
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulReturnValue; return ulReturnValue;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* Atomic swap (pointers) * Atomic swap (pointers)
* *
* @brief Atomically sets the address pointed to by *ppvDestination to the value * @brief Atomically sets the address pointed to by *ppvDestination to the value
* of *pvExchange. * of *pvExchange.
* *
* @param[in, out] ppvDestination Pointer to memory location from where a pointer * @param[in, out] ppvDestination Pointer to memory location from where a pointer
* value is to be loaded and written back to. * value is to be loaded and written back to.
* @param[in] pvExchange Pointer value to be written to *ppvDestination. * @param[in] pvExchange Pointer value to be written to *ppvDestination.
* *
* @return The initial value of *ppvDestination. * @return The initial value of *ppvDestination.
*/ */
static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination, static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination,
void * pvExchange ) void * pvExchange )
{ {
void * pReturnValue; void * pReturnValue;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
pReturnValue = *ppvDestination; pReturnValue = *ppvDestination;
*ppvDestination = pvExchange; *ppvDestination = pvExchange;
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return pReturnValue; return pReturnValue;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* Atomic compare-and-swap (pointers) * Atomic compare-and-swap (pointers)
* *
* @brief Performs an atomic compare-and-swap operation on the specified pointer * @brief Performs an atomic compare-and-swap operation on the specified pointer
* values. * values.
* *
* @param[in, out] ppvDestination Pointer to memory location from where a pointer * @param[in, out] ppvDestination Pointer to memory location from where a pointer
* value is to be loaded and checked. * value is to be loaded and checked.
* @param[in] pvExchange If condition meets, write this value to memory. * @param[in] pvExchange If condition meets, write this value to memory.
* @param[in] pvComparand Swap condition. * @param[in] pvComparand Swap condition.
* *
* @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped. * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
* *
* @note This function only swaps *ppvDestination with pvExchange, if previous * @note This function only swaps *ppvDestination with pvExchange, if previous
* *ppvDestination value equals pvComparand. * *ppvDestination value equals pvComparand.
*/ */
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination, static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination,
void * pvExchange, void * pvExchange,
void * pvComparand ) void * pvComparand )
{ {
uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE; uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
if( *ppvDestination == pvComparand ) if( *ppvDestination == pvComparand )
{ {
*ppvDestination = pvExchange; *ppvDestination = pvExchange;
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
} }
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulReturnValue; return ulReturnValue;
} }
/*----------------------------- Arithmetic ------------------------------*/ /*----------------------------- Arithmetic ------------------------------*/
/** /**
* Atomic add * Atomic add
* *
* @brief Atomically adds count to the value of the specified pointer points to. * @brief Atomically adds count to the value of the specified pointer points to.
* *
* @param[in,out] pulAddend Pointer to memory location from where value is to be * @param[in,out] pulAddend Pointer to memory location from where value is to be
* loaded and written back to. * loaded and written back to.
* @param[in] ulCount Value to be added to *pulAddend. * @param[in] ulCount Value to be added to *pulAddend.
* *
* @return previous *pulAddend value. * @return previous *pulAddend value.
*/ */
static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend, static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend,
uint32_t ulCount ) uint32_t ulCount )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulAddend; ulCurrent = *pulAddend;
*pulAddend += ulCount; *pulAddend += ulCount;
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulCurrent; return ulCurrent;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* Atomic subtract * Atomic subtract
* *
* @brief Atomically subtracts count from the value of the specified pointer * @brief Atomically subtracts count from the value of the specified pointer
* pointers to. * pointers to.
* *
* @param[in,out] pulAddend Pointer to memory location from where value is to be * @param[in,out] pulAddend Pointer to memory location from where value is to be
* loaded and written back to. * loaded and written back to.
* @param[in] ulCount Value to be subtract from *pulAddend. * @param[in] ulCount Value to be subtract from *pulAddend.
* *
* @return previous *pulAddend value. * @return previous *pulAddend value.
*/ */
static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend, static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend,
uint32_t ulCount ) uint32_t ulCount )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulAddend; ulCurrent = *pulAddend;
*pulAddend -= ulCount; *pulAddend -= ulCount;
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulCurrent; return ulCurrent;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* Atomic increment * Atomic increment
* *
* @brief Atomically increments the value of the specified pointer points to. * @brief Atomically increments the value of the specified pointer points to.
* *
* @param[in,out] pulAddend Pointer to memory location from where value is to be * @param[in,out] pulAddend Pointer to memory location from where value is to be
* loaded and written back to. * loaded and written back to.
* *
* @return *pulAddend value before increment. * @return *pulAddend value before increment.
*/ */
static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend ) static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulAddend; ulCurrent = *pulAddend;
*pulAddend += 1; *pulAddend += 1;
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulCurrent; return ulCurrent;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* Atomic decrement * Atomic decrement
* *
* @brief Atomically decrements the value of the specified pointer points to * @brief Atomically decrements the value of the specified pointer points to
* *
* @param[in,out] pulAddend Pointer to memory location from where value is to be * @param[in,out] pulAddend Pointer to memory location from where value is to be
* loaded and written back to. * loaded and written back to.
* *
* @return *pulAddend value before decrement. * @return *pulAddend value before decrement.
*/ */
static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend ) static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulAddend; ulCurrent = *pulAddend;
*pulAddend -= 1; *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] pulDestination 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 ORed with *pulDestination. * @param [in] ulValue Value to be ORed with *pulDestination.
* *
* @return The original value of *pulDestination. * @return The original value of *pulDestination.
*/ */
static portFORCE_INLINE uint32_t Atomic_OR_u32( uint32_t volatile * pulDestination, static portFORCE_INLINE uint32_t Atomic_OR_u32( uint32_t volatile * pulDestination,
uint32_t ulValue ) uint32_t ulValue )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulDestination; ulCurrent = *pulDestination;
*pulDestination |= ulValue; *pulDestination |= 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] pulDestination 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 *pulDestination. * @param [in] ulValue Value to be ANDed with *pulDestination.
* *
* @return The original value of *pulDestination. * @return The original value of *pulDestination.
*/ */
static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination, static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination,
uint32_t ulValue ) uint32_t ulValue )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulDestination; ulCurrent = *pulDestination;
*pulDestination &= ulValue; *pulDestination &= 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] 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 NANDed with *pulDestination. * @param [in] ulValue Value to be NANDed with *pulDestination.
* *
* @return The original value of *pulDestination. * @return The original value of *pulDestination.
*/ */
static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination, static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination,
uint32_t ulValue ) uint32_t ulValue )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulDestination; ulCurrent = *pulDestination;
*pulDestination = ~( ulCurrent & ulValue ); *pulDestination = ~( ulCurrent & ulValue );
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulCurrent; 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 * @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 XORed with *pulDestination. * @param [in] ulValue Value to be XORed with *pulDestination.
* *
* @return The original value of *pulDestination. * @return The original value of *pulDestination.
*/ */
static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination, static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination,
uint32_t ulValue ) uint32_t ulValue )
{ {
uint32_t ulCurrent; uint32_t ulCurrent;
ATOMIC_ENTER_CRITICAL(); ATOMIC_ENTER_CRITICAL();
{ {
ulCurrent = *pulDestination; ulCurrent = *pulDestination;
*pulDestination ^= ulValue; *pulDestination ^= ulValue;
} }
ATOMIC_EXIT_CRITICAL(); ATOMIC_EXIT_CRITICAL();
return ulCurrent; return ulCurrent;
} }
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/* *INDENT-ON* */ /* *INDENT-ON* */
#endif /* ATOMIC_H */ #endif /* ATOMIC_H */

File diff suppressed because it is too large Load diff

View file

@ -1,279 +1,279 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
*/ */
#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 */

View file

@ -1,417 +1,417 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
*/ */
/* /*
* 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 LIST_H #ifndef LIST_H
#define LIST_H #define LIST_H
#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
/* /*
* 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 */
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* *INDENT-ON* */ /* *INDENT-ON* */
/* 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 /* if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) */ #else /* if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) */
/* Define macros that add new members into the list structures. */ /* Define macros that add new members into the list structures. */
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1; #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1;
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2; #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2;
/* Define macros that set the new structure members to known values. */ /* Define macros that set the new structure members to known values. */
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
/* Define macros that will assert if one of the structure members does not /* Define macros that will assert if one of the structure members does not
* contain its expected value. */ * contain its expected value. */
#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
#define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ #endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
/* /*
* Definition of the only type of object that a list can contain. * Definition of the only type of object that a list can contain.
*/ */
struct xLIST; struct xLIST;
struct xLIST_ITEM struct xLIST_ITEM
{ {
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */
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, void vListInsert( List_t * const pxList,
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; 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, void vListInsertEnd( List_t * const pxList,
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; 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;
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/* *INDENT-ON* */ /* *INDENT-ON* */
#endif /* ifndef LIST_H */ #endif /* ifndef LIST_H */

File diff suppressed because it is too large Load diff

View file

@ -1,257 +1,257 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
*/ */
/* /*
* 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, BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName, const char * const pcName,
const uint16_t usStackDepth, const uint16_t usStackDepth,
void * const pvParameters, void * const pvParameters,
UBaseType_t uxPriority, UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL; TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode,
const char * const pcName, const char * const pcName,
const uint32_t ulStackDepth, const uint32_t ulStackDepth,
void * const pvParameters, void * const pvParameters,
UBaseType_t uxPriority, UBaseType_t uxPriority,
StackType_t * const puxStackBuffer, StackType_t * const puxStackBuffer,
StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL; StaticTask_t * const pxTaskBuffer ) 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;
BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL; 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, void MPU_vTaskGetInfo( TaskHandle_t xTask,
TaskStatus_t * pxTaskStatus, TaskStatus_t * pxTaskStatus,
BaseType_t xGetFreeStackSpace, BaseType_t xGetFreeStackSpace,
eTaskState eState ) FREERTOS_SYSTEM_CALL; eTaskState eState ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskPrioritySet( TaskHandle_t xTask, void MPU_vTaskPrioritySet( TaskHandle_t xTask,
UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL; 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, void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask,
TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL; 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, void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
BaseType_t xIndex, BaseType_t xIndex,
void * pvValue ) FREERTOS_SYSTEM_CALL; void * pvValue ) FREERTOS_SYSTEM_CALL;
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
BaseType_t xIndex ) FREERTOS_SYSTEM_CALL; BaseType_t xIndex ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask,
void * pvParameter ) FREERTOS_SYSTEM_CALL; 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, UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
const UBaseType_t uxArraySize, const UBaseType_t uxArraySize,
uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL; 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, BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify,
UBaseType_t uxIndexToNotify, UBaseType_t uxIndexToNotify,
uint32_t ulValue, uint32_t ulValue,
eNotifyAction eAction, eNotifyAction eAction,
uint32_t * pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL; uint32_t * pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn,
uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnEntry,
uint32_t ulBitsToClearOnExit, uint32_t ulBitsToClearOnExit,
uint32_t * pulNotificationValue, uint32_t * pulNotificationValue,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn,
BaseType_t xClearCountOnExit, BaseType_t xClearCountOnExit,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask,
UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL; UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL;
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask,
UBaseType_t uxIndexToClear, UBaseType_t uxIndexToClear,
uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL; uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL; void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL;
/* MPU versions of queue.h API functions. */ /* MPU versions of queue.h API functions. */
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue,
const void * const pvItemToQueue, const void * const pvItemToQueue,
TickType_t xTicksToWait, TickType_t xTicksToWait,
const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL; const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue,
void * const pvBuffer, void * const pvBuffer,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue,
void * const pvBuffer, void * const pvBuffer,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType,
StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL; StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount,
const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL; const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount,
const UBaseType_t uxInitialCount, const UBaseType_t uxInitialCount,
StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL; StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, void MPU_vQueueAddToRegistry( QueueHandle_t xQueue,
const char * pcName ) FREERTOS_SYSTEM_CALL; const char * pcName ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength,
const UBaseType_t uxItemSize, const UBaseType_t uxItemSize,
const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength,
const UBaseType_t uxItemSize, const UBaseType_t uxItemSize,
uint8_t * pucQueueStorage, uint8_t * pucQueueStorage,
StaticQueue_t * pxStaticQueue, StaticQueue_t * pxStaticQueue,
const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL; QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,
BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL; BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue,
UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL; UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
/* MPU versions of timers.h API functions. */ /* MPU versions of timers.h API functions. */
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks, const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL; TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL;
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks, const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, const UBaseType_t uxAutoReload,
void * const pvTimerID, void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction, TimerCallbackFunction_t pxCallbackFunction,
StaticTimer_t * pxTimerBuffer ) FREERTOS_SYSTEM_CALL; StaticTimer_t * pxTimerBuffer ) FREERTOS_SYSTEM_CALL;
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void MPU_vTimerSetTimerID( TimerHandle_t xTimer,
void * pvNewID ) FREERTOS_SYSTEM_CALL; void * pvNewID ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
void * pvParameter1, void * pvParameter1,
uint32_t ulParameter2, uint32_t ulParameter2,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, void MPU_vTimerSetReloadMode( TimerHandle_t xTimer,
const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer,
const BaseType_t xCommandID, const BaseType_t xCommandID,
const TickType_t xOptionalValue, const TickType_t xOptionalValue,
BaseType_t * const pxHigherPriorityTaskWoken, BaseType_t * const pxHigherPriorityTaskWoken,
const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
/* MPU versions of event_group.h API functions. */ /* MPU versions of event_group.h API functions. */
EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL; EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL;
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor, const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit, const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits, const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL; const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet, const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor, const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL;
/* MPU versions of message/stream_buffer.h API functions. */ /* MPU versions of message/stream_buffer.h API functions. */
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
const void * pvTxData, const void * pvTxData,
size_t xDataLengthBytes, size_t xDataLengthBytes,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
void * pvRxData, void * pvRxData,
size_t xBufferLengthBytes, size_t xBufferLengthBytes,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL;
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes, size_t xTriggerLevelBytes,
BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL;
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes, size_t xTriggerLevelBytes,
BaseType_t xIsMessageBuffer, BaseType_t xIsMessageBuffer,
uint8_t * const pucStreamBufferStorageArea, uint8_t * const pucStreamBufferStorageArea,
StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL; StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL;
#endif /* MPU_PROTOTYPES_H */ #endif /* MPU_PROTOTYPES_H */

View file

@ -1,185 +1,185 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
*/ */
#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 vTaskDelete MPU_vTaskDelete #define vTaskDelete MPU_vTaskDelete
#define vTaskDelay MPU_vTaskDelay #define vTaskDelay MPU_vTaskDelay
#define xTaskDelayUntil MPU_xTaskDelayUntil #define xTaskDelayUntil MPU_xTaskDelayUntil
#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 xTaskGenericNotifyWait MPU_xTaskGenericNotifyWait #define xTaskGenericNotifyWait MPU_xTaskGenericNotifyWait
#define ulTaskGenericNotifyTake MPU_ulTaskGenericNotifyTake #define ulTaskGenericNotifyTake MPU_ulTaskGenericNotifyTake
#define xTaskGenericNotifyStateClear MPU_xTaskGenericNotifyStateClear #define xTaskGenericNotifyStateClear MPU_xTaskGenericNotifyStateClear
#define ulTaskGenericNotifyValueClear MPU_ulTaskGenericNotifyValueClear #define ulTaskGenericNotifyValueClear MPU_ulTaskGenericNotifyValueClear
#define xTaskCatchUpTicks MPU_xTaskCatchUpTicks #define xTaskCatchUpTicks MPU_xTaskCatchUpTicks
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
#define vTaskSetTimeOutState MPU_vTaskSetTimeOutState #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState
#define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
/* Map standard queue.h API functions to the MPU equivalents. */ /* Map standard queue.h API functions to the MPU equivalents. */
#define xQueueGenericSend MPU_xQueueGenericSend #define xQueueGenericSend MPU_xQueueGenericSend
#define xQueueReceive MPU_xQueueReceive #define xQueueReceive MPU_xQueueReceive
#define xQueuePeek MPU_xQueuePeek #define xQueuePeek MPU_xQueuePeek
#define xQueueSemaphoreTake MPU_xQueueSemaphoreTake #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
#define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable
#define vQueueDelete MPU_vQueueDelete #define vQueueDelete MPU_vQueueDelete
#define xQueueCreateMutex MPU_xQueueCreateMutex #define xQueueCreateMutex MPU_xQueueCreateMutex
#define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
#define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic
#define xQueueGetMutexHolder MPU_xQueueGetMutexHolder #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
#define xQueueGenericCreate MPU_xQueueGenericCreate #define xQueueGenericCreate MPU_xQueueGenericCreate
#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic
#define xQueueCreateSet MPU_xQueueCreateSet #define xQueueCreateSet MPU_xQueueCreateSet
#define xQueueAddToSet MPU_xQueueAddToSet #define xQueueAddToSet MPU_xQueueAddToSet
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
#define xQueueSelectFromSet MPU_xQueueSelectFromSet #define xQueueSelectFromSet MPU_xQueueSelectFromSet
#define xQueueGenericReset MPU_xQueueGenericReset #define xQueueGenericReset MPU_xQueueGenericReset
#if ( configQUEUE_REGISTRY_SIZE > 0 ) #if ( configQUEUE_REGISTRY_SIZE > 0 )
#define vQueueAddToRegistry MPU_vQueueAddToRegistry #define vQueueAddToRegistry MPU_vQueueAddToRegistry
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
#define pcQueueGetName MPU_pcQueueGetName #define pcQueueGetName MPU_pcQueueGetName
#endif #endif
/* Map standard timer.h API functions to the MPU equivalents. */ /* Map standard timer.h API functions to the MPU equivalents. */
#define xTimerCreate MPU_xTimerCreate #define xTimerCreate MPU_xTimerCreate
#define xTimerCreateStatic MPU_xTimerCreateStatic #define xTimerCreateStatic MPU_xTimerCreateStatic
#define pvTimerGetTimerID MPU_pvTimerGetTimerID #define pvTimerGetTimerID MPU_pvTimerGetTimerID
#define vTimerSetTimerID MPU_vTimerSetTimerID #define vTimerSetTimerID MPU_vTimerSetTimerID
#define xTimerIsTimerActive MPU_xTimerIsTimerActive #define xTimerIsTimerActive MPU_xTimerIsTimerActive
#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle
#define xTimerPendFunctionCall MPU_xTimerPendFunctionCall #define xTimerPendFunctionCall MPU_xTimerPendFunctionCall
#define pcTimerGetName MPU_pcTimerGetName #define pcTimerGetName MPU_pcTimerGetName
#define vTimerSetReloadMode MPU_vTimerSetReloadMode #define vTimerSetReloadMode MPU_vTimerSetReloadMode
#define uxTimerGetReloadMode MPU_uxTimerGetReloadMode #define uxTimerGetReloadMode MPU_uxTimerGetReloadMode
#define xTimerGetPeriod MPU_xTimerGetPeriod #define xTimerGetPeriod MPU_xTimerGetPeriod
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
#define xTimerGenericCommand MPU_xTimerGenericCommand #define xTimerGenericCommand MPU_xTimerGenericCommand
/* Map standard event_group.h API functions to the MPU equivalents. */ /* Map standard event_group.h API functions to the MPU equivalents. */
#define xEventGroupCreate MPU_xEventGroupCreate #define xEventGroupCreate MPU_xEventGroupCreate
#define xEventGroupCreateStatic MPU_xEventGroupCreateStatic #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic
#define xEventGroupWaitBits MPU_xEventGroupWaitBits #define xEventGroupWaitBits MPU_xEventGroupWaitBits
#define xEventGroupClearBits MPU_xEventGroupClearBits #define xEventGroupClearBits MPU_xEventGroupClearBits
#define xEventGroupSetBits MPU_xEventGroupSetBits #define xEventGroupSetBits MPU_xEventGroupSetBits
#define xEventGroupSync MPU_xEventGroupSync #define xEventGroupSync MPU_xEventGroupSync
#define vEventGroupDelete MPU_vEventGroupDelete #define vEventGroupDelete MPU_vEventGroupDelete
/* Map standard message/stream_buffer.h API functions to the MPU /* Map standard message/stream_buffer.h API functions to the MPU
* equivalents. */ * equivalents. */
#define xStreamBufferSend MPU_xStreamBufferSend #define xStreamBufferSend MPU_xStreamBufferSend
#define xStreamBufferReceive MPU_xStreamBufferReceive #define xStreamBufferReceive MPU_xStreamBufferReceive
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes #define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
#define vStreamBufferDelete MPU_vStreamBufferDelete #define vStreamBufferDelete MPU_vStreamBufferDelete
#define xStreamBufferIsFull MPU_xStreamBufferIsFull #define xStreamBufferIsFull MPU_xStreamBufferIsFull
#define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty #define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty
#define xStreamBufferReset MPU_xStreamBufferReset #define xStreamBufferReset MPU_xStreamBufferReset
#define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable #define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable
#define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable #define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable
#define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel #define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel
#define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate #define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate
#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic #define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic
/* Remove the privileged function macro, but keep the PRIVILEGED_DATA /* Remove the privileged function macro, but keep the PRIVILEGED_DATA
* macro so applications can place data in privileged access sections * macro so applications can place data in privileged access sections
* (useful when using statically allocated objects). */ * (useful when using statically allocated objects). */
#define PRIVILEGED_FUNCTION #define PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) ) #define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
#define FREERTOS_SYSTEM_CALL #define FREERTOS_SYSTEM_CALL
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
/* Ensure API functions go in the privileged execution section. */ /* Ensure API functions go in the privileged execution section. */
#define PRIVILEGED_FUNCTION __attribute__( ( section( "privileged_functions" ) ) ) #define PRIVILEGED_FUNCTION __attribute__( ( section( "privileged_functions" ) ) )
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) ) #define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
#define FREERTOS_SYSTEM_CALL __attribute__( ( section( "freertos_system_calls" ) ) ) #define FREERTOS_SYSTEM_CALL __attribute__( ( section( "freertos_system_calls" ) ) )
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
#else /* portUSING_MPU_WRAPPERS */ #else /* portUSING_MPU_WRAPPERS */
#define PRIVILEGED_FUNCTION #define PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA #define PRIVILEGED_DATA
#define FREERTOS_SYSTEM_CALL #define FREERTOS_SYSTEM_CALL
#define portUSING_MPU_WRAPPERS 0 #define portUSING_MPU_WRAPPERS 0
#endif /* portUSING_MPU_WRAPPERS */ #endif /* portUSING_MPU_WRAPPERS */
#endif /* MPU_WRAPPERS_H */ #endif /* MPU_WRAPPERS_H */

View file

@ -1,224 +1,224 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
* 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
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* *INDENT-ON* */ /* *INDENT-ON* */
#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 * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack, StackType_t * pxEndOfStack,
TaskFunction_t pxCode, TaskFunction_t pxCode,
void * pvParameters, void * pvParameters,
BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
#else #else
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode, TaskFunction_t pxCode,
void * pvParameters, void * pvParameters,
BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
#endif #endif
#else /* if ( portUSING_MPU_WRAPPERS == 1 ) */ #else /* if ( portUSING_MPU_WRAPPERS == 1 ) */
#if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack, StackType_t * pxEndOfStack,
TaskFunction_t pxCode, TaskFunction_t pxCode,
void * pvParameters ) PRIVILEGED_FUNCTION; void * pvParameters ) PRIVILEGED_FUNCTION;
#else #else
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode, TaskFunction_t pxCode,
void * pvParameters ) PRIVILEGED_FUNCTION; void * pvParameters ) PRIVILEGED_FUNCTION;
#endif #endif
#endif /* if ( portUSING_MPU_WRAPPERS == 1 ) */ #endif /* if ( portUSING_MPU_WRAPPERS == 1 ) */
/* Used by heap_5.c to define the start address and size of each memory region /* Used by heap_5.c to define the start address and size of each memory region
* that together comprise the total FreeRTOS heap space. */ * that together comprise the total FreeRTOS heap space. */
typedef struct HeapRegion typedef struct HeapRegion
{ {
uint8_t * pucStartAddress; uint8_t * pucStartAddress;
size_t xSizeInBytes; size_t xSizeInBytes;
} HeapRegion_t; } HeapRegion_t;
/* Used to pass information about the heap out of vPortGetHeapStats(). */ /* Used to pass information about the heap out of vPortGetHeapStats(). */
typedef struct xHeapStats typedef struct xHeapStats
{ {
size_t xAvailableHeapSpaceInBytes; /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */ size_t xAvailableHeapSpaceInBytes; /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */
size_t xSizeOfLargestFreeBlockInBytes; /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */ size_t xSizeOfLargestFreeBlockInBytes; /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */ size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
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;
#if( configSTACK_ALLOCATION_FROM_SEPARATE_HEAP == 1 ) #if( configSTACK_ALLOCATION_FROM_SEPARATE_HEAP == 1 )
void *pvPortMallocStack( size_t xSize ) PRIVILEGED_FUNCTION; void *pvPortMallocStack( size_t xSize ) PRIVILEGED_FUNCTION;
void vPortFreeStack( void *pv ) PRIVILEGED_FUNCTION; void vPortFreeStack( void *pv ) PRIVILEGED_FUNCTION;
#else #else
#define pvPortMallocStack pvPortMalloc #define pvPortMallocStack pvPortMalloc
#define vPortFreeStack vPortFree #define vPortFreeStack vPortFree
#endif #endif
/* /*
* 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, void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
const struct xMEMORY_REGION * const xRegions, const struct xMEMORY_REGION * const xRegions,
StackType_t * pxBottomOfStack, StackType_t * pxBottomOfStack,
uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; uint32_t ulStackDepth ) PRIVILEGED_FUNCTION;
#endif #endif
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/* *INDENT-ON* */ /* *INDENT-ON* */
#endif /* PORTABLE_H */ #endif /* PORTABLE_H */

View file

@ -1,120 +1,120 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
*/ */
#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 ) 1000U ) ) #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000U ) )
#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

View file

@ -1,127 +1,127 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
*/ */
#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,52 +1,52 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
*/ */
#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 compiler's include * header file, as that directory will already be in the compiler's 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

View file

@ -214,6 +214,9 @@ typedef enum
* task. h * task. h
* *
* Macro to disable all maskable interrupts. * Macro to disable all maskable interrupts.
* This also returns what the interrupt state was
* upon being called. This state may subsequently
* be passed to taskRESTORE_INTERRUPTS().
* *
* \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS
* \ingroup SchedulerControl * \ingroup SchedulerControl
@ -230,6 +233,28 @@ typedef enum
*/ */
#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() #define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS()
/**
* task. h
*
* Macro to restore microcontroller interrupts to
* a previous state.
*
* \defgroup taskRESTORE_INTERRUPTS taskRESTORE_INTERRUPTS
* \ingroup SchedulerControl
*/
#define taskRESTORE_INTERRUPTS(ulState) portRESTORE_INTERRUPTS(ulState)
/**
* task. h
*
* Macro that determines if it is being called from within an ISR
* or a task. Returns non-zero if it is in an ISR.
*
* \defgroup taskCHECK_IF_IN_ISR taskCHECK_IF_IN_ISR
* \ingroup SchedulerControl
*/
#define taskCHECK_IF_IN_ISR() portCHECK_IF_IN_ISR()
/* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is /* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is
* 0 to generate more optimal code when configASSERT() is defined as the constant * 0 to generate more optimal code when configASSERT() is defined as the constant
* is used in assert() statements. */ * is used in assert() statements. */
@ -237,6 +262,8 @@ typedef enum
#define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 ) #define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 )
#define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 ) #define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 )
/* Check if core value is valid */
#define taskVALID_CORE_ID( xCoreID ) ( ( BaseType_t ) ( ( 0 <= xCoreID ) && ( xCoreID < configNUM_CORES ) ) )
/*----------------------------------------------------------- /*-----------------------------------------------------------
* TASK CREATION API * TASK CREATION API
@ -1208,6 +1235,12 @@ void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;
*/ */
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;
void vTaskCoreExclusionSet( const TaskHandle_t xTask, UBaseType_t uxCoreExclude );
UBaseType_t vTaskCoreExclusionGet( const TaskHandle_t xTask );
void vTaskPreemptionDisable( const TaskHandle_t xTask );
void vTaskPreemptionEnable( const TaskHandle_t xTask );
/*----------------------------------------------------------- /*-----------------------------------------------------------
* SCHEDULER CONTROL * SCHEDULER CONTROL
*----------------------------------------------------------*/ *----------------------------------------------------------*/
@ -1666,10 +1699,10 @@ BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask,
* xTaskGetIdleTaskHandle() is only available if * xTaskGetIdleTaskHandle() is only available if
* INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h.
* *
* Simply returns the handle of the idle task. It is not valid to call * Simply returns a pointer to the array of idle task handles.
* xTaskGetIdleTaskHandle() before the scheduler has been started. * It is not valid to call xTaskGetIdleTaskHandle() before the scheduler has been started.
*/ */
TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION; TaskHandle_t *xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION;
/** /**
* configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for
@ -2947,7 +2980,7 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem,
* Sets the pointer to the current TCB to the TCB of the highest priority task * Sets the pointer to the current TCB to the TCB of the highest priority task
* that is ready to run. * that is ready to run.
*/ */
portDONT_DISCARD void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; portDONT_DISCARD void vTaskSwitchContext( BaseType_t xCoreID ) PRIVILEGED_FUNCTION;
/* /*
* THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY * THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY
@ -2960,6 +2993,11 @@ TickType_t uxTaskResetEventItemValue( void ) PRIVILEGED_FUNCTION;
*/ */
TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION;
/*
* Return the handle of the task running on specified core.
*/
TaskHandle_t xTaskGetCurrentTaskHandleCPU( UBaseType_t xCoreID ) PRIVILEGED_FUNCTION;
/* /*
* Shortcut used by the queue implementation to prevent unnecessary call to * Shortcut used by the queue implementation to prevent unnecessary call to
* taskYIELD(); * taskYIELD();
@ -3045,6 +3083,11 @@ TaskHandle_t pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION;
*/ */
void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION;
/*
* For internal use only. Same as portYIELD_WITHIN_API() in single core FreeRTOS.
* For SMP this is not defined by the port.
*/
void vTaskYieldWithinAPI( void );
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -1312,11 +1312,29 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* for use by the kernel only. * for use by the kernel only.
*/ */
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer,
const BaseType_t xCommandID, /*
const TickType_t xOptionalValue, * Splitting the xTimerGenericCommand into two sub functions and making it a macro
BaseType_t * const pxHigherPriorityTaskWoken, * removes a recursion path when called from ISRs. This is primarily for the XCore
const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; * XCC port which detects the recursion path and throws an error during compilation
* when this is not split.
*/
BaseType_t xTimerGenericCommandFromTask( TimerHandle_t xTimer,
const BaseType_t xCommandID,
const TickType_t xOptionalValue,
BaseType_t * const pxHigherPriorityTaskWoken,
const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
BaseType_t xTimerGenericCommandFromISR( TimerHandle_t xTimer,
const BaseType_t xCommandID,
const TickType_t xOptionalValue,
BaseType_t * const pxHigherPriorityTaskWoken,
const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
#define xTimerGenericCommand( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ) \
( ( xCommandID ) < tmrFIRST_FROM_ISR_COMMAND ? \
xTimerGenericCommandFromTask( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ) : \
xTimerGenericCommandFromISR( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ) )
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
void vTimerSetTimerNumber( TimerHandle_t xTimer, void vTimerSetTimerNumber( TimerHandle_t xTimer,

426
list.c
View file

@ -1,213 +1,213 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
*/ */
#include <stdlib.h> #include <stdlib.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
* all the API functions to use the MPU wrappers. That should only be done when * all the API functions to use the MPU wrappers. That should only be done when
* task.h is included from an application file. */ * task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "list.h" #include "list.h"
/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified /* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified
* because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be
* defined for the header files above, but not in this file, in order to * defined for the header files above, but not in this file, in order to
* generate the correct privileged Vs unprivileged linkage and placement. */ * generate the correct privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */
/*----------------------------------------------------------- /*-----------------------------------------------------------
* 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, void vListInsertEnd( List_t * const pxList,
ListItem_t * const pxNewListItem ) 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, void vListInsert( List_t * const pxList,
ListItem_t * const pxNewListItem ) 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?).
* 5) If the FreeRTOS port supports interrupt nesting then ensure that * 5) If the FreeRTOS port supports interrupt nesting then ensure that
* the priority of the tick interrupt is at or below * the priority of the tick interrupt is at or below
* configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
**********************************************************************/ **********************************************************************/
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

@ -1,2 +1,2 @@
The FreeRTOS GCC port layer also builds and works with the ARMClang compiler. 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. 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.4.3 # * FreeRTOS Kernel V10.4.3
# * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. # * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# * # *
# * Permission is hereby granted, free of charge, to any person obtaining a copy of # * Permission is hereby granted, free of charge, to any person obtaining a copy of
# * this software and associated documentation files (the "Software"), to deal in # * this software and associated documentation files (the "Software"), to deal in
# * the Software without restriction, including without limitation the rights to # * the Software without restriction, including without limitation the rights to
# * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of # * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# * the Software, and to permit persons to whom the Software is furnished to do so, # * the Software, and to permit persons to whom the Software is furnished to do so,
# * subject to the following conditions: # * subject to the following conditions:
# * # *
# * The above copyright notice and this permission notice shall be included in all # * The above copyright notice and this permission notice shall be included in all
# * copies or substantial portions of the Software. # * copies or substantial portions of the Software.
# * # *
# * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS # * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR # * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER # * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# * # *
# * https://www.FreeRTOS.org # * https://www.FreeRTOS.org
# * https://github.com/FreeRTOS # * https://github.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.

View file

@ -1,453 +1,453 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 ulSetInterruptMask( 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" msr PRIMASK, r0 \n" " msr PRIMASK, r0 \n"
" bx lr \n" " bx lr \n"
::: "memory" ::: "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" .syntax unified \n" " .syntax unified \n"
" .extern SecureContext_SaveContext \n" " .extern SecureContext_SaveContext \n"
" .extern SecureContext_LoadContext \n" " .extern SecureContext_LoadContext \n"
" \n" " \n"
" mrs r1, psp \n"/* Read PSP in r1. */ " mrs r1, psp \n"/* Read PSP in r1. */
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
" ldr r0, [r2] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ " ldr r0, [r2] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
" \n" " \n"
" cbz r0, save_ns_context \n"/* No secure context to save. */ " cbz r0, save_ns_context \n"/* No secure context to save. */
" push {r0-r2, r14} \n" " push {r0-r2, r14} \n"
" bl SecureContext_SaveContext \n" " bl SecureContext_SaveContext \n"
" pop {r0-r3} \n"/* LR is now in r3. */ " pop {r0-r3} \n"/* LR is now in r3. */
" mov lr, r3 \n"/* LR = r3. */ " mov lr, r3 \n"/* LR = r3. */
" lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ " lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
" bpl save_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " bpl save_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r2, [r3] \n"/* Read pxCurrentTCB. */ " ldr r2, [r3] \n"/* Read pxCurrentTCB. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" subs r1, r1, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " subs r1, r1, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
" str r1, [r2] \n"/* Save the new top of stack in TCB. */ " str r1, [r2] \n"/* Save the new top of stack in TCB. */
" mrs r2, psplim \n"/* r2 = PSPLIM. */ " mrs r2, psplim \n"/* r2 = PSPLIM. */
" mrs r3, control \n"/* r3 = CONTROL. */ " mrs r3, control \n"/* r3 = CONTROL. */
" mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */
" stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
" subs r1, r1, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ " subs r1, r1, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */
" str r1, [r2] \n"/* Save the new top of stack in TCB. */ " str r1, [r2] \n"/* Save the new top of stack in TCB. */
" mrs r2, psplim \n"/* r2 = PSPLIM. */ " mrs r2, psplim \n"/* r2 = PSPLIM. */
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
" stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" b select_next_task \n" " b select_next_task \n"
" \n" " \n"
" save_ns_context: \n" " save_ns_context: \n"
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r2, [r3] \n"/* Read pxCurrentTCB. */ " ldr r2, [r3] \n"/* Read pxCurrentTCB. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" subs r1, r1, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ " subs r1, r1, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
" str r1, [r2] \n"/* Save the new top of stack in TCB. */ " str r1, [r2] \n"/* Save the new top of stack in TCB. */
" adds r1, r1, #16 \n"/* r1 = r1 + 16. */ " adds r1, r1, #16 \n"/* r1 = r1 + 16. */
" stmia r1!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */ " stmia r1!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */
" mov r4, r8 \n"/* r4 = r8. */ " mov r4, r8 \n"/* r4 = r8. */
" mov r5, r9 \n"/* r5 = r9. */ " mov r5, r9 \n"/* r5 = r9. */
" mov r6, r10 \n"/* r6 = r10. */ " mov r6, r10 \n"/* r6 = r10. */
" mov r7, r11 \n"/* r7 = r11. */ " mov r7, r11 \n"/* r7 = r11. */
" stmia r1!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ " stmia r1!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
" mrs r2, psplim \n"/* r2 = PSPLIM. */ " mrs r2, psplim \n"/* r2 = PSPLIM. */
" mrs r3, control \n"/* r3 = CONTROL. */ " mrs r3, control \n"/* r3 = CONTROL. */
" mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */
" subs r1, r1, #48 \n"/* r1 = r1 - 48. */ " subs r1, r1, #48 \n"/* r1 = r1 - 48. */
" stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
" subs r1, r1, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ " subs r1, r1, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
" str r1, [r2] \n"/* Save the new top of stack in TCB. */ " str r1, [r2] \n"/* Save the new top of stack in TCB. */
" mrs r2, psplim \n"/* r2 = PSPLIM. */ " mrs r2, psplim \n"/* r2 = PSPLIM. */
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
" stmia r1!, {r0, r2-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ " stmia r1!, {r0, r2-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */
" mov r4, r8 \n"/* r4 = r8. */ " mov r4, r8 \n"/* r4 = r8. */
" mov r5, r9 \n"/* r5 = r9. */ " mov r5, r9 \n"/* r5 = r9. */
" mov r6, r10 \n"/* r6 = r10. */ " mov r6, r10 \n"/* r6 = r10. */
" mov r7, r11 \n"/* r7 = r11. */ " mov r7, r11 \n"/* r7 = r11. */
" stmia r1!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ " stmia r1!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
" select_next_task: \n" " select_next_task: \n"
" cpsid i \n" " cpsid i \n"
" bl vTaskSwitchContext \n" " bl vTaskSwitchContext \n"
" cpsie i \n" " cpsie i \n"
" \n" " \n"
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r3, [r2] \n"/* Read pxCurrentTCB. */ " ldr r3, [r2] \n"/* Read pxCurrentTCB. */
" ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ " ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */
" \n" " \n"
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" dmb \n"/* Complete outstanding transfers before disabling MPU. */ " dmb \n"/* Complete outstanding transfers before disabling MPU. */
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
" movs r5, #1 \n"/* r5 = 1. */ " movs r5, #1 \n"/* r5 = 1. */
" bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
" str r4, [r2] \n"/* Disable MPU. */ " str r4, [r2] \n"/* Disable MPU. */
" \n" " \n"
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
" ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */
" ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
" str r4, [r2] \n"/* Program MAIR0. */ " str r4, [r2] \n"/* Program MAIR0. */
" ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
" movs r5, #4 \n"/* r5 = 4. */ " movs r5, #4 \n"/* r5 = 4. */
" str r5, [r2] \n"/* Program RNR = 4. */ " str r5, [r2] \n"/* Program RNR = 4. */
" ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ " ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */
" ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ " ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
" stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ " stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */
" movs r5, #5 \n"/* r5 = 5. */ " movs r5, #5 \n"/* r5 = 5. */
" str r5, [r2] \n"/* Program RNR = 5. */ " str r5, [r2] \n"/* Program RNR = 5. */
" ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ " ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */
" ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ " ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
" stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ " stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */
" movs r5, #6 \n"/* r5 = 6. */ " movs r5, #6 \n"/* r5 = 6. */
" str r5, [r2] \n"/* Program RNR = 6. */ " str r5, [r2] \n"/* Program RNR = 6. */
" ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ " ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */
" ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ " ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
" stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ " stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */
" movs r5, #7 \n"/* r5 = 7. */ " movs r5, #7 \n"/* r5 = 7. */
" str r5, [r2] \n"/* Program RNR = 7. */ " str r5, [r2] \n"/* Program RNR = 7. */
" ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ " ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */
" ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ " ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */
" stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ " stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */
" \n" " \n"
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
" movs r5, #1 \n"/* r5 = 1. */ " movs r5, #1 \n"/* r5 = 1. */
" orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
" str r4, [r2] \n"/* Enable MPU. */ " str r4, [r2] \n"/* Enable MPU. */
" dsb \n"/* Force memory writes before continuing. */ " dsb \n"/* Force memory writes before continuing. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" ldmia r1!, {r0, r2-r4} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ " ldmia r1!, {r0, r2-r4} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
" msr control, r3 \n"/* Restore the CONTROL register value for the task. */ " msr control, r3 \n"/* Restore the CONTROL register value for the task. */
" mov lr, r4 \n"/* LR = r4. */ " mov lr, r4 \n"/* LR = r4. */
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
" str r0, [r2] \n"/* Restore the task's xSecureContext. */ " str r0, [r2] \n"/* Restore the task's xSecureContext. */
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
" push {r1,r4} \n" " push {r1,r4} \n"
" bl SecureContext_LoadContext \n"/* Restore the secure context. */ " bl SecureContext_LoadContext \n"/* Restore the secure context. */
" pop {r1,r4} \n" " pop {r1,r4} \n"
" mov lr, r4 \n"/* LR = r4. */ " mov lr, r4 \n"/* LR = r4. */
" lsls r2, r4, #25 \n"/* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ " lsls r2, r4, #25 \n"/* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
" msr psp, r1 \n"/* Remember the new top of stack for the task. */ " msr psp, r1 \n"/* Remember the new top of stack for the task. */
" bx lr \n" " bx lr \n"
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
" ldmia r1!, {r0, r2-r3} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ " ldmia r1!, {r0, r2-r3} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
" mov lr, r3 \n"/* LR = r3. */ " mov lr, r3 \n"/* LR = r3. */
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
" str r0, [r2] \n"/* Restore the task's xSecureContext. */ " str r0, [r2] \n"/* Restore the task's xSecureContext. */
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
" push {r1,r3} \n" " push {r1,r3} \n"
" bl SecureContext_LoadContext \n"/* Restore the secure context. */ " bl SecureContext_LoadContext \n"/* Restore the secure context. */
" pop {r1,r3} \n" " pop {r1,r3} \n"
" mov lr, r3 \n"/* LR = r3. */ " mov lr, r3 \n"/* LR = r3. */
" lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ " lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
" msr psp, r1 \n"/* Remember the new top of stack for the task. */ " msr psp, r1 \n"/* Remember the new top of stack for the task. */
" bx lr \n" " bx lr \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
" restore_ns_context: \n" " restore_ns_context: \n"
" adds r1, r1, #16 \n"/* Move to the high registers. */ " adds r1, r1, #16 \n"/* Move to the high registers. */
" ldmia r1!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ " ldmia r1!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */
" mov r8, r4 \n"/* r8 = r4. */ " mov r8, r4 \n"/* r8 = r4. */
" mov r9, r5 \n"/* r9 = r5. */ " mov r9, r5 \n"/* r9 = r5. */
" mov r10, r6 \n"/* r10 = r6. */ " mov r10, r6 \n"/* r10 = r6. */
" mov r11, r7 \n"/* r11 = r7. */ " mov r11, r7 \n"/* r11 = r7. */
" msr psp, r1 \n"/* Remember the new top of stack for the task. */ " msr psp, r1 \n"/* Remember the new top of stack for the task. */
" subs r1, r1, #32 \n"/* Go back to the low registers. */ " subs r1, r1, #32 \n"/* Go back to the low registers. */
" ldmia r1!, {r4-r7} \n"/* Restore the low registers that are not automatically restored. */ " ldmia r1!, {r4-r7} \n"/* Restore the low registers that are not automatically restored. */
" bx lr \n" " bx lr \n"
" \n" " \n"
" .align 4 \n" " .align 4 \n"
"pxCurrentTCBConst: .word pxCurrentTCB \n" "pxCurrentTCBConst: .word pxCurrentTCB \n"
"xSecureContextConst: .word xSecureContext \n" "xSecureContextConst: .word xSecureContext \n"
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
"xMPUCTRLConst: .word 0xe000ed94 \n" "xMPUCTRLConst: .word 0xe000ed94 \n"
"xMAIR0Const: .word 0xe000edc0 \n" "xMAIR0Const: .word 0xe000edc0 \n"
"xRNRConst: .word 0xe000ed98 \n" "xRNRConst: .word 0xe000ed98 \n"
"xRBARConst: .word 0xe000ed9c \n" "xRBARConst: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" movs r0, #4 \n" " movs r0, #4 \n"
" mov r1, lr \n" " mov r1, lr \n"
" tst r0, r1 \n" " tst r0, r1 \n"
" beq stacking_used_msp \n" " beq stacking_used_msp \n"
" mrs r0, psp \n" " mrs r0, psp \n"
" ldr r2, svchandler_address_const \n" " ldr r2, svchandler_address_const \n"
" bx r2 \n" " bx r2 \n"
" stacking_used_msp: \n" " stacking_used_msp: \n"
" mrs r0, msp \n" " mrs r0, msp \n"
" ldr r2, svchandler_address_const \n" " ldr r2, svchandler_address_const \n"
" bx r2 \n" " bx r2 \n"
" \n" " \n"
" .align 4 \n" " .align 4 \n"
"svchandler_address_const: .word vPortSVCHandler_C \n" "svchandler_address_const: .word vPortSVCHandler_C \n"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */
{ {
__asm volatile __asm volatile
( (
" svc %0 \n"/* Secure context is allocated in the supervisor call. */ " svc %0 \n"/* Secure context is allocated in the supervisor call. */
" bx lr \n"/* Return. */ " bx lr \n"/* Return. */
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory" ::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" ldr r1, [r0] \n"/* The first item in the TCB is the top of the stack. */ " ldr r1, [r0] \n"/* The first item in the TCB is the top of the stack. */
" ldr r0, [r1] \n"/* The first item on the stack is the task's xSecureContext. */ " ldr r0, [r1] \n"/* The first item on the stack is the task's xSecureContext. */
" cmp r0, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ " cmp r0, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */
" beq free_secure_context \n" " beq free_secure_context \n"
" bx lr \n"/* There is no secure context (xSecureContext is NULL). */ " bx lr \n"/* There is no secure context (xSecureContext is NULL). */
" free_secure_context: \n" " free_secure_context: \n"
" svc %0 \n"/* Secure context is freed in the supervisor call. */ " svc %0 \n"/* Secure context is freed in the supervisor call. */
" bx lr \n"/* Return. */ " bx lr \n"/* Return. */
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,312 +1,312 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 BaseType_t xPortIsInsideInterrupt( void ); extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief MPU specific constants. * @brief MPU specific constants.
*/ */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
#define portUSING_MPU_WRAPPERS 1 #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x80000000UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#else #else
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/* MPU regions. */ /* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portSTACK_REGION ( 4UL ) #define portSTACK_REGION ( 4UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
/* Device memory attributes used in MPU_MAIR registers. /* Device memory attributes used in MPU_MAIR registers.
* *
* 8-bit values encoded as follows: * 8-bit values encoded as follows:
* Bit[7:4] - 0000 - Device Memory * Bit[7:4] - 0000 - Device Memory
* Bit[3:2] - 00 --> Device-nGnRnE * Bit[3:2] - 00 --> Device-nGnRnE
* 01 --> Device-nGnRE * 01 --> Device-nGnRE
* 10 --> Device-nGRE * 10 --> Device-nGRE
* 11 --> Device-GRE * 11 --> Device-GRE
* Bit[1:0] - 00, Reserved. * Bit[1:0] - 00, Reserved.
*/ */
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
/* Normal memory attributes used in MPU_MAIR registers. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
/* Attributes used in MPU_RBAR registers. */ /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */
} MPURegionSettings_t; } MPURegionSettings_t;
/** /**
* @brief MPU settings as stored in the TCB. * @brief MPU settings as stored in the TCB.
*/ */
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
} xMPU_SETTINGS; } xMPU_SETTINGS;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief SVC numbers. * @brief SVC numbers.
*/ */
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_FREE_SECURE_CONTEXT 1
#define portSVC_START_SCHEDULER 2 #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_RAISE_PRIVILEGE 3
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Scheduler utilities. * @brief Scheduler utilities.
*/ */
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Tickless idle/low power functionality. * @brief Tickless idle/low power functionality.
*/ */
#ifndef portSUPPRESS_TICKS_AND_SLEEP #ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Task function macros as described on the FreeRTOS.org WEB site. * @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
* Tasks are not created with a secure context. Any task that is going to call * Tasks are not created with a secure context. Any task that is going to call
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* secure context before it calls any secure function. * secure context before it calls any secure function.
* *
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/ */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
/** /**
* @brief Called when a task is deleted to delete the task's secure context, * @brief Called when a task is deleted to delete the task's secure context,
* if it has one. * if it has one.
* *
* @param[in] pxTCB The TCB of the task being deleted. * @param[in] pxTCB The TCB of the task being deleted.
*/ */
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#else #else
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
#define portCLEAN_UP_TCB( pxTCB ) #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *
* @return 1 if the processor is already privileged, 0 otherwise. * @return 1 if the processor is already privileged, 0 otherwise.
*/ */
#define portIS_PRIVILEGED() xIsPrivileged() #define portIS_PRIVILEGED() xIsPrivileged()
/** /**
* @brief Raise an SVC request to raise privilege. * @brief Raise an SVC request to raise privilege.
* *
* The SVC handler checks that the SVC was raised from a system call and only * The SVC handler checks that the SVC was raised from a system call and only
* then it raises the privilege. If this is called from any other place, * then it raises the privilege. If this is called from any other place,
* the privilege is not raised. * the privilege is not raised.
*/ */
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
/** /**
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
* register. * register.
*/ */
#define portRESET_PRIVILEGE() vResetPrivilege() #define portRESET_PRIVILEGE() vResetPrivilege()
#else #else
#define portIS_PRIVILEGED() #define portIS_PRIVILEGED()
#define portRAISE_PRIVILEGE() #define portRAISE_PRIVILEGE()
#define portRESET_PRIVILEGE() #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Barriers. * @brief Barriers.
*/ */
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -1,366 +1,366 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 ulSetInterruptMask( 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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" msr PRIMASK, r0 \n" " msr PRIMASK, r0 \n"
" bx lr \n" " bx lr \n"
::: "memory" ::: "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" .syntax unified \n" " .syntax unified \n"
" \n" " \n"
" mrs r0, psp \n"/* Read PSP in r0. */ " mrs r0, psp \n"/* Read PSP in r0. */
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" subs r0, r0, #44 \n"/* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */ " subs r0, r0, #44 \n"/* Make space for PSPLIM, CONTROL, LR and the remaining registers on the stack. */
" str r0, [r1] \n"/* Save the new top of stack in TCB. */ " str r0, [r1] \n"/* Save the new top of stack in TCB. */
" mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */
" mrs r2, control \n"/* r2 = CONTROL. */ " mrs r2, control \n"/* r2 = CONTROL. */
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
" stmia r0!, {r1-r7} \n"/* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */ " stmia r0!, {r1-r7} \n"/* Store on the stack - PSPLIM, CONTROL, LR and low registers that are not automatically saved. */
" mov r4, r8 \n"/* r4 = r8. */ " mov r4, r8 \n"/* r4 = r8. */
" mov r5, r9 \n"/* r5 = r9. */ " mov r5, r9 \n"/* r5 = r9. */
" mov r6, r10 \n"/* r6 = r10. */ " mov r6, r10 \n"/* r6 = r10. */
" mov r7, r11 \n"/* r7 = r11. */ " mov r7, r11 \n"/* r7 = r11. */
" stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ " stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
" subs r0, r0, #40 \n"/* Make space for PSPLIM, LR and the remaining registers on the stack. */ " subs r0, r0, #40 \n"/* Make space for PSPLIM, LR and the remaining registers on the stack. */
" str r0, [r1] \n"/* Save the new top of stack in TCB. */ " str r0, [r1] \n"/* Save the new top of stack in TCB. */
" mrs r2, psplim \n"/* r2 = PSPLIM. */ " mrs r2, psplim \n"/* r2 = PSPLIM. */
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
" stmia r0!, {r2-r7} \n"/* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */ " stmia r0!, {r2-r7} \n"/* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
" mov r4, r8 \n"/* r4 = r8. */ " mov r4, r8 \n"/* r4 = r8. */
" mov r5, r9 \n"/* r5 = r9. */ " mov r5, r9 \n"/* r5 = r9. */
" mov r6, r10 \n"/* r6 = r10. */ " mov r6, r10 \n"/* r6 = r10. */
" mov r7, r11 \n"/* r7 = r11. */ " mov r7, r11 \n"/* r7 = r11. */
" stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ " stmia r0!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
" cpsid i \n" " cpsid i \n"
" bl vTaskSwitchContext \n" " bl vTaskSwitchContext \n"
" cpsie i \n" " cpsie i \n"
" \n" " \n"
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
" \n" " \n"
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" dmb \n"/* Complete outstanding transfers before disabling MPU. */ " dmb \n"/* Complete outstanding transfers before disabling MPU. */
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */
" movs r4, #1 \n"/* r4 = 1. */ " movs r4, #1 \n"/* r4 = 1. */
" bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */ " bics r3, r4 \n"/* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
" str r3, [r2] \n"/* Disable MPU. */ " str r3, [r2] \n"/* Disable MPU. */
" \n" " \n"
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
" ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */
" ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
" str r4, [r2] \n"/* Program MAIR0. */ " str r4, [r2] \n"/* Program MAIR0. */
" ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
" movs r4, #4 \n"/* r4 = 4. */ " movs r4, #4 \n"/* r4 = 4. */
" str r4, [r2] \n"/* Program RNR = 4. */ " str r4, [r2] \n"/* Program RNR = 4. */
" ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */ " ldmia r1!, {r5,r6} \n"/* Read first set of RBAR/RLAR from TCB. */
" ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
" stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */ " stmia r3!, {r5,r6} \n"/* Write first set of RBAR/RLAR registers. */
" movs r4, #5 \n"/* r4 = 5. */ " movs r4, #5 \n"/* r4 = 5. */
" str r4, [r2] \n"/* Program RNR = 5. */ " str r4, [r2] \n"/* Program RNR = 5. */
" ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */ " ldmia r1!, {r5,r6} \n"/* Read second set of RBAR/RLAR from TCB. */
" ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
" stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */ " stmia r3!, {r5,r6} \n"/* Write second set of RBAR/RLAR registers. */
" movs r4, #6 \n"/* r4 = 6. */ " movs r4, #6 \n"/* r4 = 6. */
" str r4, [r2] \n"/* Program RNR = 6. */ " str r4, [r2] \n"/* Program RNR = 6. */
" ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */ " ldmia r1!, {r5,r6} \n"/* Read third set of RBAR/RLAR from TCB. */
" ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
" stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */ " stmia r3!, {r5,r6} \n"/* Write third set of RBAR/RLAR registers. */
" movs r4, #7 \n"/* r4 = 7. */ " movs r4, #7 \n"/* r4 = 7. */
" str r4, [r2] \n"/* Program RNR = 7. */ " str r4, [r2] \n"/* Program RNR = 7. */
" ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */ " ldmia r1!, {r5,r6} \n"/* Read fourth set of RBAR/RLAR from TCB. */
" ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */
" stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */ " stmia r3!, {r5,r6} \n"/* Write fourth set of RBAR/RLAR registers. */
" \n" " \n"
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */ " ldr r3, [r2] \n"/* Read the value of MPU_CTRL. */
" movs r4, #1 \n"/* r4 = 1. */ " movs r4, #1 \n"/* r4 = 1. */
" orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */ " orrs r3, r4 \n"/* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
" str r3, [r2] \n"/* Enable MPU. */ " str r3, [r2] \n"/* Enable MPU. */
" dsb \n"/* Force memory writes before continuing. */ " dsb \n"/* Force memory writes before continuing. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" adds r0, r0, #28 \n"/* Move to the high registers. */ " adds r0, r0, #28 \n"/* Move to the high registers. */
" ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ " ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */
" mov r8, r4 \n"/* r8 = r4. */ " mov r8, r4 \n"/* r8 = r4. */
" mov r9, r5 \n"/* r9 = r5. */ " mov r9, r5 \n"/* r9 = r5. */
" mov r10, r6 \n"/* r10 = r6. */ " mov r10, r6 \n"/* r10 = r6. */
" mov r11, r7 \n"/* r11 = r7. */ " mov r11, r7 \n"/* r11 = r7. */
" msr psp, r0 \n"/* Remember the new top of stack for the task. */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */
" subs r0, r0, #44 \n"/* Move to the starting of the saved context. */ " subs r0, r0, #44 \n"/* Move to the starting of the saved context. */
" ldmia r0!, {r1-r7} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */ " ldmia r0!, {r1-r7} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r7 restored. */
" msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */
" msr control, r2 \n"/* Restore the CONTROL register value for the task. */ " msr control, r2 \n"/* Restore the CONTROL register value for the task. */
" bx r3 \n" " bx r3 \n"
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
" adds r0, r0, #24 \n"/* Move to the high registers. */ " adds r0, r0, #24 \n"/* Move to the high registers. */
" ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ " ldmia r0!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */
" mov r8, r4 \n"/* r8 = r4. */ " mov r8, r4 \n"/* r8 = r4. */
" mov r9, r5 \n"/* r9 = r5. */ " mov r9, r5 \n"/* r9 = r5. */
" mov r10, r6 \n"/* r10 = r6. */ " mov r10, r6 \n"/* r10 = r6. */
" mov r11, r7 \n"/* r11 = r7. */ " mov r11, r7 \n"/* r11 = r7. */
" msr psp, r0 \n"/* Remember the new top of stack for the task. */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */
" subs r0, r0, #40 \n"/* Move to the starting of the saved context. */ " subs r0, r0, #40 \n"/* Move to the starting of the saved context. */
" ldmia r0!, {r2-r7} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */ " ldmia r0!, {r2-r7} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
" bx r3 \n" " bx r3 \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
" .align 4 \n" " .align 4 \n"
"pxCurrentTCBConst: .word pxCurrentTCB \n" "pxCurrentTCBConst: .word pxCurrentTCB \n"
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
"xMPUCTRLConst: .word 0xe000ed94 \n" "xMPUCTRLConst: .word 0xe000ed94 \n"
"xMAIR0Const: .word 0xe000edc0 \n" "xMAIR0Const: .word 0xe000edc0 \n"
"xRNRConst: .word 0xe000ed98 \n" "xRNRConst: .word 0xe000ed98 \n"
"xRBARConst: .word 0xe000ed9c \n" "xRBARConst: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" movs r0, #4 \n" " movs r0, #4 \n"
" mov r1, lr \n" " mov r1, lr \n"
" tst r0, r1 \n" " tst r0, r1 \n"
" beq stacking_used_msp \n" " beq stacking_used_msp \n"
" mrs r0, psp \n" " mrs r0, psp \n"
" ldr r2, svchandler_address_const \n" " ldr r2, svchandler_address_const \n"
" bx r2 \n" " bx r2 \n"
" stacking_used_msp: \n" " stacking_used_msp: \n"
" mrs r0, msp \n" " mrs r0, msp \n"
" ldr r2, svchandler_address_const \n" " ldr r2, svchandler_address_const \n"
" bx r2 \n" " bx r2 \n"
" \n" " \n"
" .align 4 \n" " .align 4 \n"
"svchandler_address_const: .word vPortSVCHandler_C \n" "svchandler_address_const: .word vPortSVCHandler_C \n"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,312 +1,312 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 BaseType_t xPortIsInsideInterrupt( void ); extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief MPU specific constants. * @brief MPU specific constants.
*/ */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
#define portUSING_MPU_WRAPPERS 1 #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x80000000UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#else #else
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/* MPU regions. */ /* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portSTACK_REGION ( 4UL ) #define portSTACK_REGION ( 4UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
/* Device memory attributes used in MPU_MAIR registers. /* Device memory attributes used in MPU_MAIR registers.
* *
* 8-bit values encoded as follows: * 8-bit values encoded as follows:
* Bit[7:4] - 0000 - Device Memory * Bit[7:4] - 0000 - Device Memory
* Bit[3:2] - 00 --> Device-nGnRnE * Bit[3:2] - 00 --> Device-nGnRnE
* 01 --> Device-nGnRE * 01 --> Device-nGnRE
* 10 --> Device-nGRE * 10 --> Device-nGRE
* 11 --> Device-GRE * 11 --> Device-GRE
* Bit[1:0] - 00, Reserved. * Bit[1:0] - 00, Reserved.
*/ */
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
/* Normal memory attributes used in MPU_MAIR registers. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
/* Attributes used in MPU_RBAR registers. */ /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */
} MPURegionSettings_t; } MPURegionSettings_t;
/** /**
* @brief MPU settings as stored in the TCB. * @brief MPU settings as stored in the TCB.
*/ */
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
} xMPU_SETTINGS; } xMPU_SETTINGS;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief SVC numbers. * @brief SVC numbers.
*/ */
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_FREE_SECURE_CONTEXT 1
#define portSVC_START_SCHEDULER 2 #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_RAISE_PRIVILEGE 3
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Scheduler utilities. * @brief Scheduler utilities.
*/ */
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Tickless idle/low power functionality. * @brief Tickless idle/low power functionality.
*/ */
#ifndef portSUPPRESS_TICKS_AND_SLEEP #ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Task function macros as described on the FreeRTOS.org WEB site. * @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
* Tasks are not created with a secure context. Any task that is going to call * Tasks are not created with a secure context. Any task that is going to call
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* secure context before it calls any secure function. * secure context before it calls any secure function.
* *
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/ */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
/** /**
* @brief Called when a task is deleted to delete the task's secure context, * @brief Called when a task is deleted to delete the task's secure context,
* if it has one. * if it has one.
* *
* @param[in] pxTCB The TCB of the task being deleted. * @param[in] pxTCB The TCB of the task being deleted.
*/ */
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#else #else
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
#define portCLEAN_UP_TCB( pxTCB ) #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *
* @return 1 if the processor is already privileged, 0 otherwise. * @return 1 if the processor is already privileged, 0 otherwise.
*/ */
#define portIS_PRIVILEGED() xIsPrivileged() #define portIS_PRIVILEGED() xIsPrivileged()
/** /**
* @brief Raise an SVC request to raise privilege. * @brief Raise an SVC request to raise privilege.
* *
* The SVC handler checks that the SVC was raised from a system call and only * The SVC handler checks that the SVC was raised from a system call and only
* then it raises the privilege. If this is called from any other place, * then it raises the privilege. If this is called from any other place,
* the privilege is not raised. * the privilege is not raised.
*/ */
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
/** /**
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
* register. * register.
*/ */
#define portRESET_PRIVILEGE() vResetPrivilege() #define portRESET_PRIVILEGE() vResetPrivilege()
#else #else
#define portIS_PRIVILEGED() #define portIS_PRIVILEGED()
#define portRAISE_PRIVILEGE() #define portRAISE_PRIVILEGE()
#define portRESET_PRIVILEGE() #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Barriers. * @brief Barriers.
*/ */
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -1,414 +1,414 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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"
" mov r0, #0 \n" " mov r0, #0 \n"
" msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */
" 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"
" mov r0, #0 \n" " mov r0, #0 \n"
" msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */
" 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 ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */ " mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */
" mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" dsb \n" " dsb \n"
" isb \n" " isb \n"
" bx lr \n"/* Return. */ " bx lr \n"/* Return. */
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" msr basepri, r0 \n"/* basepri = ulMask. */ " msr basepri, r0 \n"/* basepri = ulMask. */
" dsb \n" " dsb \n"
" isb \n" " isb \n"
" bx lr \n"/* Return. */ " bx lr \n"/* Return. */
::: "memory" ::: "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" .syntax unified \n" " .syntax unified \n"
" .extern SecureContext_SaveContext \n" " .extern SecureContext_SaveContext \n"
" .extern SecureContext_LoadContext \n" " .extern SecureContext_LoadContext \n"
" \n" " \n"
" mrs r1, psp \n"/* Read PSP in r1. */ " mrs r1, psp \n"/* Read PSP in r1. */
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
" ldr r0, [r2] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ " ldr r0, [r2] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
" \n" " \n"
" cbz r0, save_ns_context \n"/* No secure context to save. */ " cbz r0, save_ns_context \n"/* No secure context to save. */
" push {r0-r2, r14} \n" " push {r0-r2, r14} \n"
" bl SecureContext_SaveContext \n" " bl SecureContext_SaveContext \n"
" pop {r0-r3} \n"/* LR is now in r3. */ " pop {r0-r3} \n"/* LR is now in r3. */
" mov lr, r3 \n"/* LR = r3. */ " mov lr, r3 \n"/* LR = r3. */
" lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ " lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
" bpl save_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " bpl save_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r2, [r3] \n"/* Read pxCurrentTCB. */ " ldr r2, [r3] \n"/* Read pxCurrentTCB. */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" subs r1, r1, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " subs r1, r1, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */
" str r1, [r2] \n"/* Save the new top of stack in TCB. */ " str r1, [r2] \n"/* Save the new top of stack in TCB. */
" mrs r2, psplim \n"/* r2 = PSPLIM. */ " mrs r2, psplim \n"/* r2 = PSPLIM. */
" mrs r3, control \n"/* r3 = CONTROL. */ " mrs r3, control \n"/* r3 = CONTROL. */
" mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */
" stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
" subs r1, r1, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ " subs r1, r1, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */
" str r1, [r2] \n"/* Save the new top of stack in TCB. */ " str r1, [r2] \n"/* Save the new top of stack in TCB. */
" mrs r2, psplim \n"/* r2 = PSPLIM. */ " mrs r2, psplim \n"/* r2 = PSPLIM. */
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
" stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" b select_next_task \n" " b select_next_task \n"
" \n" " \n"
" save_ns_context: \n" " save_ns_context: \n"
" ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r2, [r3] \n"/* Read pxCurrentTCB. */ " ldr r2, [r3] \n"/* Read pxCurrentTCB. */
#if ( configENABLE_FPU == 1 ) #if ( configENABLE_FPU == 1 )
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
" it eq \n" " it eq \n"
" vstmdbeq r1!, {s16-s31} \n"/* Store the FPU registers which are not saved automatically. */ " vstmdbeq r1!, {s16-s31} \n"/* Store the FPU registers which are not saved automatically. */
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" subs r1, r1, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ " subs r1, r1, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */
" str r1, [r2] \n"/* Save the new top of stack in TCB. */ " str r1, [r2] \n"/* Save the new top of stack in TCB. */
" adds r1, r1, #16 \n"/* r1 = r1 + 16. */ " adds r1, r1, #16 \n"/* r1 = r1 + 16. */
" stm r1, {r4-r11} \n"/* Store the registers that are not saved automatically. */ " stm r1, {r4-r11} \n"/* Store the registers that are not saved automatically. */
" mrs r2, psplim \n"/* r2 = PSPLIM. */ " mrs r2, psplim \n"/* r2 = PSPLIM. */
" mrs r3, control \n"/* r3 = CONTROL. */ " mrs r3, control \n"/* r3 = CONTROL. */
" mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */
" subs r1, r1, #16 \n"/* r1 = r1 - 16. */ " subs r1, r1, #16 \n"/* r1 = r1 - 16. */
" stm r1, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ " stm r1, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
" subs r1, r1, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ " subs r1, r1, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
" str r1, [r2] \n"/* Save the new top of stack in TCB. */ " str r1, [r2] \n"/* Save the new top of stack in TCB. */
" adds r1, r1, #12 \n"/* r1 = r1 + 12. */ " adds r1, r1, #12 \n"/* r1 = r1 + 12. */
" stm r1, {r4-r11} \n"/* Store the registers that are not saved automatically. */ " stm r1, {r4-r11} \n"/* Store the registers that are not saved automatically. */
" mrs r2, psplim \n"/* r2 = PSPLIM. */ " mrs r2, psplim \n"/* r2 = PSPLIM. */
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
" subs r1, r1, #12 \n"/* r1 = r1 - 12. */ " subs r1, r1, #12 \n"/* r1 = r1 - 12. */
" stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ " stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
" select_next_task: \n" " select_next_task: \n"
" mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
" msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" dsb \n" " dsb \n"
" isb \n" " isb \n"
" bl vTaskSwitchContext \n" " bl vTaskSwitchContext \n"
" mov r0, #0 \n"/* r0 = 0. */ " mov r0, #0 \n"/* r0 = 0. */
" msr basepri, r0 \n"/* Enable interrupts. */ " msr basepri, r0 \n"/* Enable interrupts. */
" \n" " \n"
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r3, [r2] \n"/* Read pxCurrentTCB. */ " ldr r3, [r2] \n"/* Read pxCurrentTCB. */
" ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ " ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */
" \n" " \n"
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" dmb \n"/* Complete outstanding transfers before disabling MPU. */ " dmb \n"/* Complete outstanding transfers before disabling MPU. */
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
" bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
" str r4, [r2] \n"/* Disable MPU. */ " str r4, [r2] \n"/* Disable MPU. */
" \n" " \n"
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
" ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */
" ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
" str r4, [r2] \n"/* Program MAIR0. */ " str r4, [r2] \n"/* Program MAIR0. */
" ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */
" movs r4, #4 \n"/* r4 = 4. */ " movs r4, #4 \n"/* r4 = 4. */
" str r4, [r2] \n"/* Program RNR = 4. */ " str r4, [r2] \n"/* Program RNR = 4. */
" adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
" ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */
" ldmia r3!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " ldmia r3!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */
" stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
" orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
" str r4, [r2] \n"/* Enable MPU. */ " str r4, [r2] \n"/* Enable MPU. */
" dsb \n"/* Force memory writes before continuing. */ " dsb \n"/* Force memory writes before continuing. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" ldmia r1!, {r0, r2-r4} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ " ldmia r1!, {r0, r2-r4} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
" msr control, r3 \n"/* Restore the CONTROL register value for the task. */ " msr control, r3 \n"/* Restore the CONTROL register value for the task. */
" mov lr, r4 \n"/* LR = r4. */ " mov lr, r4 \n"/* LR = r4. */
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
" str r0, [r2] \n"/* Restore the task's xSecureContext. */ " str r0, [r2] \n"/* Restore the task's xSecureContext. */
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
" push {r1,r4} \n" " push {r1,r4} \n"
" bl SecureContext_LoadContext \n"/* Restore the secure context. */ " bl SecureContext_LoadContext \n"/* Restore the secure context. */
" pop {r1,r4} \n" " pop {r1,r4} \n"
" mov lr, r4 \n"/* LR = r4. */ " mov lr, r4 \n"/* LR = r4. */
" lsls r2, r4, #25 \n"/* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ " lsls r2, r4, #25 \n"/* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
" msr psp, r1 \n"/* Remember the new top of stack for the task. */ " msr psp, r1 \n"/* Remember the new top of stack for the task. */
" bx lr \n" " bx lr \n"
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
" ldmia r1!, {r0, r2-r3} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ " ldmia r1!, {r0, r2-r3} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
" mov lr, r3 \n"/* LR = r3. */ " mov lr, r3 \n"/* LR = r3. */
" ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */
" str r0, [r2] \n"/* Restore the task's xSecureContext. */ " str r0, [r2] \n"/* Restore the task's xSecureContext. */
" cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */
" push {r1,r3} \n" " push {r1,r3} \n"
" bl SecureContext_LoadContext \n"/* Restore the secure context. */ " bl SecureContext_LoadContext \n"/* Restore the secure context. */
" pop {r1,r3} \n" " pop {r1,r3} \n"
" mov lr, r3 \n"/* LR = r3. */ " mov lr, r3 \n"/* LR = r3. */
" lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ " lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
" bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */
" msr psp, r1 \n"/* Remember the new top of stack for the task. */ " msr psp, r1 \n"/* Remember the new top of stack for the task. */
" bx lr \n" " bx lr \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
" restore_ns_context: \n" " restore_ns_context: \n"
" ldmia r1!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ " ldmia r1!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */
#if ( configENABLE_FPU == 1 ) #if ( configENABLE_FPU == 1 )
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
" it eq \n" " it eq \n"
" vldmiaeq r1!, {s16-s31} \n"/* Restore the FPU registers which are not restored automatically. */ " vldmiaeq r1!, {s16-s31} \n"/* Restore the FPU registers which are not restored automatically. */
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
" msr psp, r1 \n"/* Remember the new top of stack for the task. */ " msr psp, r1 \n"/* Remember the new top of stack for the task. */
" bx lr \n" " bx lr \n"
" \n" " \n"
" .align 4 \n" " .align 4 \n"
"pxCurrentTCBConst: .word pxCurrentTCB \n" "pxCurrentTCBConst: .word pxCurrentTCB \n"
"xSecureContextConst: .word xSecureContext \n" "xSecureContextConst: .word xSecureContext \n"
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
"xMPUCTRLConst: .word 0xe000ed94 \n" "xMPUCTRLConst: .word 0xe000ed94 \n"
"xMAIR0Const: .word 0xe000edc0 \n" "xMAIR0Const: .word 0xe000edc0 \n"
"xRNRConst: .word 0xe000ed98 \n" "xRNRConst: .word 0xe000ed98 \n"
"xRBARConst: .word 0xe000ed9c \n" "xRBARConst: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" tst lr, #4 \n" " tst lr, #4 \n"
" ite eq \n" " ite eq \n"
" mrseq r0, msp \n" " mrseq r0, msp \n"
" mrsne r0, psp \n" " mrsne r0, psp \n"
" ldr r1, svchandler_address_const \n" " ldr r1, svchandler_address_const \n"
" bx r1 \n" " bx r1 \n"
" \n" " \n"
" .align 4 \n" " .align 4 \n"
"svchandler_address_const: .word vPortSVCHandler_C \n" "svchandler_address_const: .word vPortSVCHandler_C \n"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */ void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */
{ {
__asm volatile __asm volatile
( (
" svc %0 \n"/* Secure context is allocated in the supervisor call. */ " svc %0 \n"/* Secure context is allocated in the supervisor call. */
" bx lr \n"/* Return. */ " bx lr \n"/* Return. */
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory" ::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" ldr r1, [r0] \n"/* The first item in the TCB is the top of the stack. */ " ldr r1, [r0] \n"/* The first item in the TCB is the top of the stack. */
" ldr r0, [r1] \n"/* The first item on the stack is the task's xSecureContext. */ " ldr r0, [r1] \n"/* The first item on the stack is the task's xSecureContext. */
" cmp r0, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ " cmp r0, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */
" it ne \n" " it ne \n"
" svcne %0 \n"/* Secure context is freed in the supervisor call. */ " svcne %0 \n"/* Secure context is freed in the supervisor call. */
" bx lr \n"/* Return. */ " bx lr \n"/* Return. */
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,312 +1,312 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 BaseType_t xPortIsInsideInterrupt( void ); extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief MPU specific constants. * @brief MPU specific constants.
*/ */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
#define portUSING_MPU_WRAPPERS 1 #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x80000000UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#else #else
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/* MPU regions. */ /* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portSTACK_REGION ( 4UL ) #define portSTACK_REGION ( 4UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
/* Device memory attributes used in MPU_MAIR registers. /* Device memory attributes used in MPU_MAIR registers.
* *
* 8-bit values encoded as follows: * 8-bit values encoded as follows:
* Bit[7:4] - 0000 - Device Memory * Bit[7:4] - 0000 - Device Memory
* Bit[3:2] - 00 --> Device-nGnRnE * Bit[3:2] - 00 --> Device-nGnRnE
* 01 --> Device-nGnRE * 01 --> Device-nGnRE
* 10 --> Device-nGRE * 10 --> Device-nGRE
* 11 --> Device-GRE * 11 --> Device-GRE
* Bit[1:0] - 00, Reserved. * Bit[1:0] - 00, Reserved.
*/ */
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
/* Normal memory attributes used in MPU_MAIR registers. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
/* Attributes used in MPU_RBAR registers. */ /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */
} MPURegionSettings_t; } MPURegionSettings_t;
/** /**
* @brief MPU settings as stored in the TCB. * @brief MPU settings as stored in the TCB.
*/ */
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
} xMPU_SETTINGS; } xMPU_SETTINGS;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief SVC numbers. * @brief SVC numbers.
*/ */
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_FREE_SECURE_CONTEXT 1
#define portSVC_START_SCHEDULER 2 #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_RAISE_PRIVILEGE 3
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Scheduler utilities. * @brief Scheduler utilities.
*/ */
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Tickless idle/low power functionality. * @brief Tickless idle/low power functionality.
*/ */
#ifndef portSUPPRESS_TICKS_AND_SLEEP #ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Task function macros as described on the FreeRTOS.org WEB site. * @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
* Tasks are not created with a secure context. Any task that is going to call * Tasks are not created with a secure context. Any task that is going to call
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* secure context before it calls any secure function. * secure context before it calls any secure function.
* *
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/ */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
/** /**
* @brief Called when a task is deleted to delete the task's secure context, * @brief Called when a task is deleted to delete the task's secure context,
* if it has one. * if it has one.
* *
* @param[in] pxTCB The TCB of the task being deleted. * @param[in] pxTCB The TCB of the task being deleted.
*/ */
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#else #else
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
#define portCLEAN_UP_TCB( pxTCB ) #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *
* @return 1 if the processor is already privileged, 0 otherwise. * @return 1 if the processor is already privileged, 0 otherwise.
*/ */
#define portIS_PRIVILEGED() xIsPrivileged() #define portIS_PRIVILEGED() xIsPrivileged()
/** /**
* @brief Raise an SVC request to raise privilege. * @brief Raise an SVC request to raise privilege.
* *
* The SVC handler checks that the SVC was raised from a system call and only * The SVC handler checks that the SVC was raised from a system call and only
* then it raises the privilege. If this is called from any other place, * then it raises the privilege. If this is called from any other place,
* the privilege is not raised. * the privilege is not raised.
*/ */
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
/** /**
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
* register. * register.
*/ */
#define portRESET_PRIVILEGE() vResetPrivilege() #define portRESET_PRIVILEGE() vResetPrivilege()
#else #else
#define portIS_PRIVILEGED() #define portIS_PRIVILEGED()
#define portRAISE_PRIVILEGE() #define portRAISE_PRIVILEGE()
#define portRESET_PRIVILEGE() #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Barriers. * @brief Barriers.
*/ */
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -1,320 +1,320 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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"
" mov r0, #0 \n" " mov r0, #0 \n"
" msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */
" 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"
" mov r0, #0 \n" " mov r0, #0 \n"
" msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */
" 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 ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */ " mrs r0, basepri \n"/* r0 = basepri. Return original basepri value. */
" mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " mov r1, %0 \n"/* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " msr basepri, r1 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" dsb \n" " dsb \n"
" isb \n" " isb \n"
" bx lr \n"/* Return. */ " bx lr \n"/* Return. */
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" msr basepri, r0 \n"/* basepri = ulMask. */ " msr basepri, r0 \n"/* basepri = ulMask. */
" dsb \n" " dsb \n"
" isb \n" " isb \n"
" bx lr \n"/* Return. */ " bx lr \n"/* Return. */
::: "memory" ::: "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" .syntax unified \n" " .syntax unified \n"
" \n" " \n"
" mrs r0, psp \n"/* Read PSP in r0. */ " mrs r0, psp \n"/* Read PSP in r0. */
#if ( configENABLE_FPU == 1 ) #if ( configENABLE_FPU == 1 )
" tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
" it eq \n" " it eq \n"
" vstmdbeq r0!, {s16-s31} \n"/* Store the FPU registers which are not saved automatically. */ " vstmdbeq r0!, {s16-s31} \n"/* Store the FPU registers which are not saved automatically. */
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" mrs r1, psplim \n"/* r1 = PSPLIM. */ " mrs r1, psplim \n"/* r1 = PSPLIM. */
" mrs r2, control \n"/* r2 = CONTROL. */ " mrs r2, control \n"/* r2 = CONTROL. */
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
" stmdb r0!, {r1-r11} \n"/* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ " stmdb r0!, {r1-r11} \n"/* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
" mrs r2, psplim \n"/* r2 = PSPLIM. */ " mrs r2, psplim \n"/* r2 = PSPLIM. */
" mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */
" stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " stmdb r0!, {r2-r11} \n"/* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */
" str r0, [r1] \n"/* Save the new top of stack in TCB. */ " str r0, [r1] \n"/* Save the new top of stack in TCB. */
" \n" " \n"
" mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " mov r0, %0 \n"/* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
" msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " msr basepri, r0 \n"/* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" dsb \n" " dsb \n"
" isb \n" " isb \n"
" bl vTaskSwitchContext \n" " bl vTaskSwitchContext \n"
" mov r0, #0 \n"/* r0 = 0. */ " mov r0, #0 \n"/* r0 = 0. */
" msr basepri, r0 \n"/* Enable interrupts. */ " msr basepri, r0 \n"/* Enable interrupts. */
" \n" " \n"
" ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r2] \n"/* Read pxCurrentTCB. */ " ldr r1, [r2] \n"/* Read pxCurrentTCB. */
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
" \n" " \n"
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" dmb \n"/* Complete outstanding transfers before disabling MPU. */ " dmb \n"/* Complete outstanding transfers before disabling MPU. */
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
" bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
" str r4, [r2] \n"/* Disable MPU. */ " str r4, [r2] \n"/* Disable MPU. */
" \n" " \n"
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
" ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */ " ldr r3, [r1] \n"/* r3 = *r1 i.e. r3 = MAIR0. */
" ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */
" str r3, [r2] \n"/* Program MAIR0. */ " str r3, [r2] \n"/* Program MAIR0. */
" ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */
" movs r3, #4 \n"/* r3 = 4. */ " movs r3, #4 \n"/* r3 = 4. */
" str r3, [r2] \n"/* Program RNR = 4. */ " str r3, [r2] \n"/* Program RNR = 4. */
" adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
" ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */
" ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */
" stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
" ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */
" orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */
" str r4, [r2] \n"/* Enable MPU. */ " str r4, [r2] \n"/* Enable MPU. */
" dsb \n"/* Force memory writes before continuing. */ " dsb \n"/* Force memory writes before continuing. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" ldmia r0!, {r1-r11} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ " ldmia r0!, {r1-r11} \n"/* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
" ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " ldmia r0!, {r2-r11} \n"/* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" \n" " \n"
#if ( configENABLE_FPU == 1 ) #if ( configENABLE_FPU == 1 )
" tst r3, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ " tst r3, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
" it eq \n" " it eq \n"
" vldmiaeq r0!, {s16-s31} \n"/* Restore the FPU registers which are not restored automatically. */ " vldmiaeq r0!, {s16-s31} \n"/* Restore the FPU registers which are not restored automatically. */
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
" \n" " \n"
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
" msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */
" msr control, r2 \n"/* Restore the CONTROL register value for the task. */ " msr control, r2 \n"/* Restore the CONTROL register value for the task. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
" msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
" msr psp, r0 \n"/* Remember the new top of stack for the task. */ " msr psp, r0 \n"/* Remember the new top of stack for the task. */
" bx r3 \n" " bx r3 \n"
" \n" " \n"
" .align 4 \n" " .align 4 \n"
"pxCurrentTCBConst: .word pxCurrentTCB \n" "pxCurrentTCBConst: .word pxCurrentTCB \n"
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
"xMPUCTRLConst: .word 0xe000ed94 \n" "xMPUCTRLConst: .word 0xe000ed94 \n"
"xMAIR0Const: .word 0xe000edc0 \n" "xMAIR0Const: .word 0xe000edc0 \n"
"xRNRConst: .word 0xe000ed98 \n" "xRNRConst: .word 0xe000ed98 \n"
"xRBARConst: .word 0xe000ed9c \n" "xRBARConst: .word 0xe000ed9c \n"
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{ {
__asm volatile __asm volatile
( (
" tst lr, #4 \n" " tst lr, #4 \n"
" ite eq \n" " ite eq \n"
" mrseq r0, msp \n" " mrseq r0, msp \n"
" mrsne r0, psp \n" " mrsne r0, psp \n"
" ldr r1, svchandler_address_const \n" " ldr r1, svchandler_address_const \n"
" bx r1 \n" " bx r1 \n"
" \n" " \n"
" .align 4 \n" " .align 4 \n"
"svchandler_address_const: .word vPortSVCHandler_C \n" "svchandler_address_const: .word vPortSVCHandler_C \n"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,312 +1,312 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 BaseType_t xPortIsInsideInterrupt( void ); extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief MPU specific constants. * @brief MPU specific constants.
*/ */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
#define portUSING_MPU_WRAPPERS 1 #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x80000000UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#else #else
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/* MPU regions. */ /* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portSTACK_REGION ( 4UL ) #define portSTACK_REGION ( 4UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
/* Device memory attributes used in MPU_MAIR registers. /* Device memory attributes used in MPU_MAIR registers.
* *
* 8-bit values encoded as follows: * 8-bit values encoded as follows:
* Bit[7:4] - 0000 - Device Memory * Bit[7:4] - 0000 - Device Memory
* Bit[3:2] - 00 --> Device-nGnRnE * Bit[3:2] - 00 --> Device-nGnRnE
* 01 --> Device-nGnRE * 01 --> Device-nGnRE
* 10 --> Device-nGRE * 10 --> Device-nGRE
* 11 --> Device-GRE * 11 --> Device-GRE
* Bit[1:0] - 00, Reserved. * Bit[1:0] - 00, Reserved.
*/ */
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
/* Normal memory attributes used in MPU_MAIR registers. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
/* Attributes used in MPU_RBAR registers. */ /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */
} MPURegionSettings_t; } MPURegionSettings_t;
/** /**
* @brief MPU settings as stored in the TCB. * @brief MPU settings as stored in the TCB.
*/ */
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
} xMPU_SETTINGS; } xMPU_SETTINGS;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief SVC numbers. * @brief SVC numbers.
*/ */
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_FREE_SECURE_CONTEXT 1
#define portSVC_START_SCHEDULER 2 #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_RAISE_PRIVILEGE 3
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Scheduler utilities. * @brief Scheduler utilities.
*/ */
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Tickless idle/low power functionality. * @brief Tickless idle/low power functionality.
*/ */
#ifndef portSUPPRESS_TICKS_AND_SLEEP #ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Task function macros as described on the FreeRTOS.org WEB site. * @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
* Tasks are not created with a secure context. Any task that is going to call * Tasks are not created with a secure context. Any task that is going to call
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* secure context before it calls any secure function. * secure context before it calls any secure function.
* *
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/ */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
/** /**
* @brief Called when a task is deleted to delete the task's secure context, * @brief Called when a task is deleted to delete the task's secure context,
* if it has one. * if it has one.
* *
* @param[in] pxTCB The TCB of the task being deleted. * @param[in] pxTCB The TCB of the task being deleted.
*/ */
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#else #else
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
#define portCLEAN_UP_TCB( pxTCB ) #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *
* @return 1 if the processor is already privileged, 0 otherwise. * @return 1 if the processor is already privileged, 0 otherwise.
*/ */
#define portIS_PRIVILEGED() xIsPrivileged() #define portIS_PRIVILEGED() xIsPrivileged()
/** /**
* @brief Raise an SVC request to raise privilege. * @brief Raise an SVC request to raise privilege.
* *
* The SVC handler checks that the SVC was raised from a system call and only * The SVC handler checks that the SVC was raised from a system call and only
* then it raises the privilege. If this is called from any other place, * then it raises the privilege. If this is called from any other place,
* the privilege is not raised. * the privilege is not raised.
*/ */
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
/** /**
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
* register. * register.
*/ */
#define portRESET_PRIVILEGE() vResetPrivilege() #define portRESET_PRIVILEGE() vResetPrivilege()
#else #else
#define portIS_PRIVILEGED() #define portIS_PRIVILEGED()
#define portRAISE_PRIVILEGE() #define portRAISE_PRIVILEGE()
#define portRESET_PRIVILEGE() #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Barriers. * @brief Barriers.
*/ */
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -1,377 +1,377 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 ulSetInterruptMask PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMask 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. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMask: ulSetInterruptMask:
mrs r0, PRIMASK mrs r0, PRIMASK
cpsid i cpsid i
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMask: 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,319 +1,319 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 BaseType_t xPortIsInsideInterrupt( void ); extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief MPU specific constants. * @brief MPU specific constants.
*/ */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
#define portUSING_MPU_WRAPPERS 1 #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x80000000UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#else #else
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/* MPU regions. */ /* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portSTACK_REGION ( 4UL ) #define portSTACK_REGION ( 4UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
/* Device memory attributes used in MPU_MAIR registers. /* Device memory attributes used in MPU_MAIR registers.
* *
* 8-bit values encoded as follows: * 8-bit values encoded as follows:
* Bit[7:4] - 0000 - Device Memory * Bit[7:4] - 0000 - Device Memory
* Bit[3:2] - 00 --> Device-nGnRnE * Bit[3:2] - 00 --> Device-nGnRnE
* 01 --> Device-nGnRE * 01 --> Device-nGnRE
* 10 --> Device-nGRE * 10 --> Device-nGRE
* 11 --> Device-GRE * 11 --> Device-GRE
* Bit[1:0] - 00, Reserved. * Bit[1:0] - 00, Reserved.
*/ */
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
/* Normal memory attributes used in MPU_MAIR registers. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
/* Attributes used in MPU_RBAR registers. */ /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */
} MPURegionSettings_t; } MPURegionSettings_t;
/** /**
* @brief MPU settings as stored in the TCB. * @brief MPU settings as stored in the TCB.
*/ */
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
} xMPU_SETTINGS; } xMPU_SETTINGS;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief SVC numbers. * @brief SVC numbers.
*/ */
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_FREE_SECURE_CONTEXT 1
#define portSVC_START_SCHEDULER 2 #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_RAISE_PRIVILEGE 3
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Scheduler utilities. * @brief Scheduler utilities.
*/ */
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Tickless idle/low power functionality. * @brief Tickless idle/low power functionality.
*/ */
#ifndef portSUPPRESS_TICKS_AND_SLEEP #ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Task function macros as described on the FreeRTOS.org WEB site. * @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
* Tasks are not created with a secure context. Any task that is going to call * Tasks are not created with a secure context. Any task that is going to call
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* secure context before it calls any secure function. * secure context before it calls any secure function.
* *
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/ */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
/** /**
* @brief Called when a task is deleted to delete the task's secure context, * @brief Called when a task is deleted to delete the task's secure context,
* if it has one. * if it has one.
* *
* @param[in] pxTCB The TCB of the task being deleted. * @param[in] pxTCB The TCB of the task being deleted.
*/ */
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#else #else
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
#define portCLEAN_UP_TCB( pxTCB ) #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *
* @return 1 if the processor is already privileged, 0 otherwise. * @return 1 if the processor is already privileged, 0 otherwise.
*/ */
#define portIS_PRIVILEGED() xIsPrivileged() #define portIS_PRIVILEGED() xIsPrivileged()
/** /**
* @brief Raise an SVC request to raise privilege. * @brief Raise an SVC request to raise privilege.
* *
* The SVC handler checks that the SVC was raised from a system call and only * The SVC handler checks that the SVC was raised from a system call and only
* then it raises the privilege. If this is called from any other place, * then it raises the privilege. If this is called from any other place,
* the privilege is not raised. * the privilege is not raised.
*/ */
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
/** /**
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
* register. * register.
*/ */
#define portRESET_PRIVILEGE() vResetPrivilege() #define portRESET_PRIVILEGE() vResetPrivilege()
#else #else
#define portIS_PRIVILEGED() #define portIS_PRIVILEGED()
#define portRAISE_PRIVILEGE() #define portRAISE_PRIVILEGE()
#define portRESET_PRIVILEGE() #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Barriers. * @brief Barriers.
*/ */
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
* the source code because to do so would cause other compilers to generate * the source code because to do so would cause other compilers to generate
* warnings. */ * warnings. */
#pragma diag_suppress=Be006 #pragma diag_suppress=Be006
#pragma diag_suppress=Pa082 #pragma diag_suppress=Pa082
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -1,303 +1,303 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 ulSetInterruptMask PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMask 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
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMask: ulSetInterruptMask:
mrs r0, PRIMASK mrs r0, PRIMASK
cpsid i cpsid i
bx lr bx lr
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMask: 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,319 +1,319 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 BaseType_t xPortIsInsideInterrupt( void ); extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief MPU specific constants. * @brief MPU specific constants.
*/ */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
#define portUSING_MPU_WRAPPERS 1 #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x80000000UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#else #else
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/* MPU regions. */ /* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portSTACK_REGION ( 4UL ) #define portSTACK_REGION ( 4UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
/* Device memory attributes used in MPU_MAIR registers. /* Device memory attributes used in MPU_MAIR registers.
* *
* 8-bit values encoded as follows: * 8-bit values encoded as follows:
* Bit[7:4] - 0000 - Device Memory * Bit[7:4] - 0000 - Device Memory
* Bit[3:2] - 00 --> Device-nGnRnE * Bit[3:2] - 00 --> Device-nGnRnE
* 01 --> Device-nGnRE * 01 --> Device-nGnRE
* 10 --> Device-nGRE * 10 --> Device-nGRE
* 11 --> Device-GRE * 11 --> Device-GRE
* Bit[1:0] - 00, Reserved. * Bit[1:0] - 00, Reserved.
*/ */
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
/* Normal memory attributes used in MPU_MAIR registers. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
/* Attributes used in MPU_RBAR registers. */ /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */
} MPURegionSettings_t; } MPURegionSettings_t;
/** /**
* @brief MPU settings as stored in the TCB. * @brief MPU settings as stored in the TCB.
*/ */
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
} xMPU_SETTINGS; } xMPU_SETTINGS;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief SVC numbers. * @brief SVC numbers.
*/ */
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_FREE_SECURE_CONTEXT 1
#define portSVC_START_SCHEDULER 2 #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_RAISE_PRIVILEGE 3
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Scheduler utilities. * @brief Scheduler utilities.
*/ */
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Tickless idle/low power functionality. * @brief Tickless idle/low power functionality.
*/ */
#ifndef portSUPPRESS_TICKS_AND_SLEEP #ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Task function macros as described on the FreeRTOS.org WEB site. * @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
* Tasks are not created with a secure context. Any task that is going to call * Tasks are not created with a secure context. Any task that is going to call
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* secure context before it calls any secure function. * secure context before it calls any secure function.
* *
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/ */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
/** /**
* @brief Called when a task is deleted to delete the task's secure context, * @brief Called when a task is deleted to delete the task's secure context,
* if it has one. * if it has one.
* *
* @param[in] pxTCB The TCB of the task being deleted. * @param[in] pxTCB The TCB of the task being deleted.
*/ */
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#else #else
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
#define portCLEAN_UP_TCB( pxTCB ) #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *
* @return 1 if the processor is already privileged, 0 otherwise. * @return 1 if the processor is already privileged, 0 otherwise.
*/ */
#define portIS_PRIVILEGED() xIsPrivileged() #define portIS_PRIVILEGED() xIsPrivileged()
/** /**
* @brief Raise an SVC request to raise privilege. * @brief Raise an SVC request to raise privilege.
* *
* The SVC handler checks that the SVC was raised from a system call and only * The SVC handler checks that the SVC was raised from a system call and only
* then it raises the privilege. If this is called from any other place, * then it raises the privilege. If this is called from any other place,
* the privilege is not raised. * the privilege is not raised.
*/ */
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
/** /**
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
* register. * register.
*/ */
#define portRESET_PRIVILEGE() vResetPrivilege() #define portRESET_PRIVILEGE() vResetPrivilege()
#else #else
#define portIS_PRIVILEGED() #define portIS_PRIVILEGED()
#define portRAISE_PRIVILEGE() #define portRAISE_PRIVILEGE()
#define portRESET_PRIVILEGE() #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Barriers. * @brief Barriers.
*/ */
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
* the source code because to do so would cause other compilers to generate * the source code because to do so would cause other compilers to generate
* warnings. */ * warnings. */
#pragma diag_suppress=Be006 #pragma diag_suppress=Be006
#pragma diag_suppress=Pa082 #pragma diag_suppress=Pa082
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -1,345 +1,345 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Including FreeRTOSConfig.h here will cause build errors if the header file /* Including FreeRTOSConfig.h here will cause build errors if the header file
contains code not understood by the assembler - for example the 'extern' keyword. contains code not understood by the assembler - for example the 'extern' keyword.
To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
the code is included in C files but excluded by the preprocessor in assembly 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. */ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
#include "FreeRTOSConfig.h" #include "FreeRTOSConfig.h"
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 ulSetInterruptMask PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMask PUBLIC vClearInterruptMask
PUBLIC PendSV_Handler PUBLIC PendSV_Handler
PUBLIC SVC_Handler PUBLIC SVC_Handler
PUBLIC vPortFreeSecureContext PUBLIC vPortFreeSecureContext
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*---------------- 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. */
tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
ite ne ite ne
movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ 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. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */
bx lr /* Return. */ bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vResetPrivilege: vResetPrivilege:
mrs r0, control /* r0 = CONTROL. */ mrs r0, control /* r0 = CONTROL. */
orr r0, r0, #1 /* r0 = r0 | 1. */ orr r0, r0, #1 /* r0 = r0 | 1. */
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. */
bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ bic r4, r4, #1 /* r4 = r4 & ~1 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]. */
movs r4, #4 /* r4 = 4. */ movs r4, #4 /* r4 = 4. */
str r4, [r2] /* Program RNR = 4. */ str r4, [r2] /* Program RNR = 4. */
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. */
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */ ldmia r3!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */
stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias 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. */
orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ orr r4, r4, #1 /* r4 = r4 | 1 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
mov r0, #0 mov r0, #0
msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */
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
mov r0, #0 mov r0, #0
msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */
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. */
bic r0, r0, #1 /* Clear the bit 0. */ bic r0, r0, #1 /* 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. */
cpsie f cpsie f
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. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMask: ulSetInterruptMask:
mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mrs r0, basepri /* r0 = basepri. Return original basepri value. */
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb dsb
isb isb
bx lr /* Return. */ bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMask: vClearInterruptMask:
msr basepri, r0 /* basepri = ulMask. */ msr basepri, r0 /* basepri = ulMask. */
dsb dsb
isb isb
bx lr /* Return. */ bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
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_FPU == 1 ) #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. */ tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
it eq it eq
vstmdbeq r1!, {s16-s31} /* Store the FPU registers which are not saved automatically. */ vstmdbeq r1!, {s16-s31} /* Store the FPU registers which are not saved automatically. */
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
subs r1, r1, #48 /* 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. */
stm r1, {r4-r11} /* Store the registers that are not saved automatically. */ stm r1, {r4-r11} /* Store the 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, #16 /* r1 = r1 - 16. */ subs r1, r1, #16 /* r1 = r1 - 16. */
stm r1, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ stm 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. */
adds r1, r1, #12 /* r1 = r1 + 12. */ adds r1, r1, #12 /* r1 = r1 + 12. */
stm r1, {r4-r11} /* Store the registers that are not saved automatically. */ stm r1, {r4-r11} /* Store the registers that are not saved automatically. */
mrs r2, psplim /* r2 = PSPLIM. */ mrs r2, psplim /* r2 = PSPLIM. */
mov r3, lr /* r3 = LR/EXC_RETURN. */ mov r3, lr /* r3 = LR/EXC_RETURN. */
subs r1, r1, #12 /* r1 = r1 - 12. */ subs r1, r1, #12 /* r1 = r1 - 12. */
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 */
select_next_task: select_next_task:
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb dsb
isb isb
bl vTaskSwitchContext bl vTaskSwitchContext
mov r0, #0 /* r0 = 0. */ mov r0, #0 /* r0 = 0. */
msr basepri, r0 /* Enable interrupts. */ msr basepri, r0 /* Enable interrupts. */
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. */
bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ bic r4, r4, #1 /* r4 = r4 & ~1 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]. */
movs r4, #4 /* r4 = 4. */ movs r4, #4 /* r4 = 4. */
str r4, [r2] /* Program RNR = 4. */ str r4, [r2] /* Program RNR = 4. */
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. */
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
ldmia r3!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ ldmia r3!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias 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. */
orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ orr r4, r4, #1 /* r4 = r4 | 1 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:
ldmia r1!, {r4-r11} /* Restore the registers that are not automatically restored. */ ldmia r1!, {r4-r11} /* Restore the registers that are not automatically restored. */
#if ( configENABLE_FPU == 1 ) #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. */ tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
it eq it eq
vldmiaeq r1!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */ vldmiaeq r1!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
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
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
SVC_Handler: SVC_Handler:
tst lr, #4 tst lr, #4
ite eq ite eq
mrseq r0, msp mrseq r0, msp
mrsne r0, psp mrsne r0, psp
b vPortSVCHandler_C b vPortSVCHandler_C
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vPortFreeSecureContext: vPortFreeSecureContext:
/* r0 = uint32_t *pulTCB. */ /* r0 = uint32_t *pulTCB. */
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. */
it ne it ne
svcne 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */ svcne 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,319 +1,319 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 BaseType_t xPortIsInsideInterrupt( void ); extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief MPU specific constants. * @brief MPU specific constants.
*/ */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
#define portUSING_MPU_WRAPPERS 1 #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x80000000UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#else #else
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/* MPU regions. */ /* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portSTACK_REGION ( 4UL ) #define portSTACK_REGION ( 4UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
/* Device memory attributes used in MPU_MAIR registers. /* Device memory attributes used in MPU_MAIR registers.
* *
* 8-bit values encoded as follows: * 8-bit values encoded as follows:
* Bit[7:4] - 0000 - Device Memory * Bit[7:4] - 0000 - Device Memory
* Bit[3:2] - 00 --> Device-nGnRnE * Bit[3:2] - 00 --> Device-nGnRnE
* 01 --> Device-nGnRE * 01 --> Device-nGnRE
* 10 --> Device-nGRE * 10 --> Device-nGRE
* 11 --> Device-GRE * 11 --> Device-GRE
* Bit[1:0] - 00, Reserved. * Bit[1:0] - 00, Reserved.
*/ */
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
/* Normal memory attributes used in MPU_MAIR registers. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
/* Attributes used in MPU_RBAR registers. */ /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */
} MPURegionSettings_t; } MPURegionSettings_t;
/** /**
* @brief MPU settings as stored in the TCB. * @brief MPU settings as stored in the TCB.
*/ */
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
} xMPU_SETTINGS; } xMPU_SETTINGS;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief SVC numbers. * @brief SVC numbers.
*/ */
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_FREE_SECURE_CONTEXT 1
#define portSVC_START_SCHEDULER 2 #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_RAISE_PRIVILEGE 3
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Scheduler utilities. * @brief Scheduler utilities.
*/ */
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Tickless idle/low power functionality. * @brief Tickless idle/low power functionality.
*/ */
#ifndef portSUPPRESS_TICKS_AND_SLEEP #ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Task function macros as described on the FreeRTOS.org WEB site. * @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
* Tasks are not created with a secure context. Any task that is going to call * Tasks are not created with a secure context. Any task that is going to call
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* secure context before it calls any secure function. * secure context before it calls any secure function.
* *
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/ */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
/** /**
* @brief Called when a task is deleted to delete the task's secure context, * @brief Called when a task is deleted to delete the task's secure context,
* if it has one. * if it has one.
* *
* @param[in] pxTCB The TCB of the task being deleted. * @param[in] pxTCB The TCB of the task being deleted.
*/ */
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#else #else
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
#define portCLEAN_UP_TCB( pxTCB ) #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *
* @return 1 if the processor is already privileged, 0 otherwise. * @return 1 if the processor is already privileged, 0 otherwise.
*/ */
#define portIS_PRIVILEGED() xIsPrivileged() #define portIS_PRIVILEGED() xIsPrivileged()
/** /**
* @brief Raise an SVC request to raise privilege. * @brief Raise an SVC request to raise privilege.
* *
* The SVC handler checks that the SVC was raised from a system call and only * The SVC handler checks that the SVC was raised from a system call and only
* then it raises the privilege. If this is called from any other place, * then it raises the privilege. If this is called from any other place,
* the privilege is not raised. * the privilege is not raised.
*/ */
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
/** /**
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
* register. * register.
*/ */
#define portRESET_PRIVILEGE() vResetPrivilege() #define portRESET_PRIVILEGE() vResetPrivilege()
#else #else
#define portIS_PRIVILEGED() #define portIS_PRIVILEGED()
#define portRAISE_PRIVILEGE() #define portRAISE_PRIVILEGE()
#define portRESET_PRIVILEGE() #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Barriers. * @brief Barriers.
*/ */
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
* the source code because to do so would cause other compilers to generate * the source code because to do so would cause other compilers to generate
* warnings. */ * warnings. */
#pragma diag_suppress=Be006 #pragma diag_suppress=Be006
#pragma diag_suppress=Pa082 #pragma diag_suppress=Pa082
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -1,261 +1,261 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.com/FreeRTOS
* *
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
/* Including FreeRTOSConfig.h here will cause build errors if the header file /* Including FreeRTOSConfig.h here will cause build errors if the header file
contains code not understood by the assembler - for example the 'extern' keyword. contains code not understood by the assembler - for example the 'extern' keyword.
To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
the code is included in C files but excluded by the preprocessor in assembly 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. */ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
#include "FreeRTOSConfig.h" #include "FreeRTOSConfig.h"
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 ulSetInterruptMask PUBLIC ulSetInterruptMask
PUBLIC vClearInterruptMask PUBLIC vClearInterruptMask
PUBLIC PendSV_Handler PUBLIC PendSV_Handler
PUBLIC SVC_Handler PUBLIC SVC_Handler
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*---------------- 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. */
tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */ tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
ite ne ite ne
movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */ 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. */ moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */
bx lr /* Return. */ bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vResetPrivilege: vResetPrivilege:
mrs r0, control /* r0 = CONTROL. */ mrs r0, control /* r0 = CONTROL. */
orr r0, r0, #1 /* r0 = r0 | 1. */ orr r0, r0, #1 /* r0 = r0 | 1. */
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 r4, [r2] /* Read the value of MPU_CTRL. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */
bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
str r4, [r2] /* Disable MPU. */ str r4, [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 r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
str r3, [r2] /* Program MAIR0. */ str r3, [r2] /* Program MAIR0. */
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
movs r3, #4 /* r3 = 4. */ movs r3, #4 /* r3 = 4. */
str r3, [r2] /* Program RNR = 4. */ str r3, [r2] /* Program RNR = 4. */
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. */
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias 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. */
orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ orr r4, r4, #1 /* r4 = r4 | 1 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-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
mov r0, #0 mov r0, #0
msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */
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
mov r0, #0 mov r0, #0
msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */ msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */
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. */
bic r0, r0, #1 /* Clear the bit 0. */ bic r0, r0, #1 /* 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. */
cpsie f cpsie f
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. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
ulSetInterruptMask: ulSetInterruptMask:
mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mrs r0, basepri /* r0 = basepri. Return original basepri value. */
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb dsb
isb isb
bx lr /* Return. */ bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
vClearInterruptMask: vClearInterruptMask:
msr basepri, r0 /* basepri = ulMask. */ msr basepri, r0 /* basepri = ulMask. */
dsb dsb
isb isb
bx lr /* Return. */ bx lr /* Return. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
PendSV_Handler: PendSV_Handler:
mrs r0, psp /* Read PSP in r0. */ mrs r0, psp /* Read PSP in r0. */
#if ( configENABLE_FPU == 1 ) #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. */ tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
it eq it eq
vstmdbeq r0!, {s16-s31} /* Store the FPU registers which are not saved automatically. */ vstmdbeq r0!, {s16-s31} /* Store the FPU registers which are not saved automatically. */
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
mrs r1, psplim /* 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. */
stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */ stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
mrs r2, psplim /* r2 = PSPLIM. */ mrs r2, psplim /* r2 = PSPLIM. */
mov r3, lr /* r3 = LR/EXC_RETURN. */ mov r3, lr /* r3 = LR/EXC_RETURN. */
stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
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. */
str r0, [r1] /* Save the new top of stack in TCB. */ str r0, [r1] /* Save the new top of stack in TCB. */
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */
dsb dsb
isb isb
bl vTaskSwitchContext bl vTaskSwitchContext
mov r0, #0 /* r0 = 0. */ mov r0, #0 /* r0 = 0. */
msr basepri, r0 /* Enable interrupts. */ msr basepri, r0 /* Enable interrupts. */
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 r4, [r2] /* Read the value of MPU_CTRL. */ ldr r4, [r2] /* Read the value of MPU_CTRL. */
bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */
str r4, [r2] /* Disable MPU. */ str r4, [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 r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */ ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
str r3, [r2] /* Program MAIR0. */ str r3, [r2] /* Program MAIR0. */
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
movs r3, #4 /* r3 = 4. */ movs r3, #4 /* r3 = 4. */
str r3, [r2] /* Program RNR = 4. */ str r3, [r2] /* Program RNR = 4. */
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. */
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias 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. */
orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ orr r4, r4, #1 /* r4 = r4 | 1 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 r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */ ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
#if ( configENABLE_FPU == 1 ) #if ( configENABLE_FPU == 1 )
tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
it eq it eq
vldmiaeq r0!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */ vldmiaeq r0!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
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. */
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
msr psplim, r2 /* Restore the PSPLIM register value for the task. */ msr psplim, r2 /* Restore the PSPLIM register value for the task. */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
msr psp, r0 /* Remember the new top of stack for the task. */ msr psp, r0 /* Remember the new top of stack for the task. */
bx r3 bx r3
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
SVC_Handler: SVC_Handler:
tst lr, #4 tst lr, #4
ite eq ite eq
mrseq r0, msp mrseq r0, msp
mrsne r0, psp mrsne r0, psp
b vPortSVCHandler_C b vPortSVCHandler_C
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
END END

View file

@ -1,319 +1,319 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 BaseType_t xPortIsInsideInterrupt( void ); extern BaseType_t xPortIsInsideInterrupt( void );
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */; extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */; extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */; extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */ extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */; extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief MPU specific constants. * @brief MPU specific constants.
*/ */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
#define portUSING_MPU_WRAPPERS 1 #define portUSING_MPU_WRAPPERS 1
#define portPRIVILEGE_BIT ( 0x80000000UL ) #define portPRIVILEGE_BIT ( 0x80000000UL )
#else #else
#define portPRIVILEGE_BIT ( 0x0UL ) #define portPRIVILEGE_BIT ( 0x0UL )
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/* MPU regions. */ /* MPU regions. */
#define portPRIVILEGED_FLASH_REGION ( 0UL ) #define portPRIVILEGED_FLASH_REGION ( 0UL )
#define portUNPRIVILEGED_FLASH_REGION ( 1UL ) #define portUNPRIVILEGED_FLASH_REGION ( 1UL )
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL ) #define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
#define portPRIVILEGED_RAM_REGION ( 3UL ) #define portPRIVILEGED_RAM_REGION ( 3UL )
#define portSTACK_REGION ( 4UL ) #define portSTACK_REGION ( 4UL )
#define portFIRST_CONFIGURABLE_REGION ( 5UL ) #define portFIRST_CONFIGURABLE_REGION ( 5UL )
#define portLAST_CONFIGURABLE_REGION ( 7UL ) #define portLAST_CONFIGURABLE_REGION ( 7UL )
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
/* Device memory attributes used in MPU_MAIR registers. /* Device memory attributes used in MPU_MAIR registers.
* *
* 8-bit values encoded as follows: * 8-bit values encoded as follows:
* Bit[7:4] - 0000 - Device Memory * Bit[7:4] - 0000 - Device Memory
* Bit[3:2] - 00 --> Device-nGnRnE * Bit[3:2] - 00 --> Device-nGnRnE
* 01 --> Device-nGnRE * 01 --> Device-nGnRE
* 10 --> Device-nGRE * 10 --> Device-nGRE
* 11 --> Device-GRE * 11 --> Device-GRE
* Bit[1:0] - 00, Reserved. * Bit[1:0] - 00, Reserved.
*/ */
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ #define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ #define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ #define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ #define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
/* Normal memory attributes used in MPU_MAIR registers. */ /* Normal memory attributes used in MPU_MAIR registers. */
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ #define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ #define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
/* Attributes used in MPU_RBAR registers. */ /* Attributes used in MPU_RBAR registers. */
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) #define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) #define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) #define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) #define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) #define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) #define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) #define portMPU_REGION_EXECUTE_NEVER ( 1UL )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ uint32_t ulRBAR; /**< RBAR for the region. */
uint32_t ulRLAR; /**< RLAR for the region. */ uint32_t ulRLAR; /**< RLAR for the region. */
} MPURegionSettings_t; } MPURegionSettings_t;
/** /**
* @brief MPU settings as stored in the TCB. * @brief MPU settings as stored in the TCB.
*/ */
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
} xMPU_SETTINGS; } xMPU_SETTINGS;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief SVC numbers. * @brief SVC numbers.
*/ */
#define portSVC_ALLOCATE_SECURE_CONTEXT 0 #define portSVC_ALLOCATE_SECURE_CONTEXT 0
#define portSVC_FREE_SECURE_CONTEXT 1 #define portSVC_FREE_SECURE_CONTEXT 1
#define portSVC_START_SCHEDULER 2 #define portSVC_START_SCHEDULER 2
#define portSVC_RAISE_PRIVILEGE 3 #define portSVC_RAISE_PRIVILEGE 3
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Scheduler utilities. * @brief Scheduler utilities.
*/ */
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Critical section management. * @brief Critical section management.
*/ */
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
#define portDISABLE_INTERRUPTS() ulSetInterruptMask() #define portDISABLE_INTERRUPTS() ulSetInterruptMask()
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 ) #define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Tickless idle/low power functionality. * @brief Tickless idle/low power functionality.
*/ */
#ifndef portSUPPRESS_TICKS_AND_SLEEP #ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Task function macros as described on the FreeRTOS.org WEB site. * @brief Task function macros as described on the FreeRTOS.org WEB site.
*/ */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
* Tasks are not created with a secure context. Any task that is going to call * Tasks are not created with a secure context. Any task that is going to call
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
* secure context before it calls any secure function. * secure context before it calls any secure function.
* *
* @param[in] ulSecureStackSize The size of the secure stack to be allocated. * @param[in] ulSecureStackSize The size of the secure stack to be allocated.
*/ */
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
/** /**
* @brief Called when a task is deleted to delete the task's secure context, * @brief Called when a task is deleted to delete the task's secure context,
* if it has one. * if it has one.
* *
* @param[in] pxTCB The TCB of the task being deleted. * @param[in] pxTCB The TCB of the task being deleted.
*/ */
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
#else #else
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
#define portCLEAN_UP_TCB( pxTCB ) #define portCLEAN_UP_TCB( pxTCB )
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *
* @return 1 if the processor is already privileged, 0 otherwise. * @return 1 if the processor is already privileged, 0 otherwise.
*/ */
#define portIS_PRIVILEGED() xIsPrivileged() #define portIS_PRIVILEGED() xIsPrivileged()
/** /**
* @brief Raise an SVC request to raise privilege. * @brief Raise an SVC request to raise privilege.
* *
* The SVC handler checks that the SVC was raised from a system call and only * The SVC handler checks that the SVC was raised from a system call and only
* then it raises the privilege. If this is called from any other place, * then it raises the privilege. If this is called from any other place,
* the privilege is not raised. * the privilege is not raised.
*/ */
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
/** /**
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
* register. * register.
*/ */
#define portRESET_PRIVILEGE() vResetPrivilege() #define portRESET_PRIVILEGE() vResetPrivilege()
#else #else
#define portIS_PRIVILEGED() #define portIS_PRIVILEGED()
#define portRAISE_PRIVILEGE() #define portRAISE_PRIVILEGE()
#define portRESET_PRIVILEGE() #define portRESET_PRIVILEGE()
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/** /**
* @brief Barriers. * @brief Barriers.
*/ */
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in /* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
* the source code because to do so would cause other compilers to generate * the source code because to do so would cause other compilers to generate
* warnings. */ * warnings. */
#pragma diag_suppress=Be006 #pragma diag_suppress=Be006
#pragma diag_suppress=Pa082 #pragma diag_suppress=Pa082
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -1,113 +1,113 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
/** /**
* @brief Enables interrupts. * @brief Enables interrupts.
*/ */
void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
/** /**
* @brief PendSV Exception handler. * @brief PendSV Exception handler.
*/ */
void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
/** /**
* @brief SVC Handler. * @brief SVC Handler.
*/ */
void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
/** /**
* @brief Allocate a Secure context for the calling task. * @brief Allocate a Secure context for the calling task.
* *
* @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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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,206 +1,206 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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, secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
uint32_t ulIsTaskPrivileged ) 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,112 +1,112 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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, SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
uint32_t ulIsTaskPrivileged ); 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,454 +1,454 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */ #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
return pvReturn; return pvReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortFree( void * pv ) void vPortFree( void * pv )
{ {
uint8_t * puc = ( uint8_t * ) pv; uint8_t * puc = ( uint8_t * ) pv;
BlockLink_t * pxLink; BlockLink_t * pxLink;
if( pv != NULL ) if( pv != NULL )
{ {
/* 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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 ; * FreeRTOS Kernel V10.4.3
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
; * ; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in ; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to ; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so, ; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions: ; * subject to the following conditions:
; * ; *
; * The above copyright notice and this permission notice shall be included in all ; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software. ; * copies or substantial portions of the Software.
; * ; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; * ; *
; * https://www.FreeRTOS.org ; * https://www.FreeRTOS.org
; * https://github.com/FreeRTOS ; * https://github.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,170 +1,170 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 ; * FreeRTOS Kernel V10.4.3
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
; * ; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in ; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to ; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so, ; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions: ; * subject to the following conditions:
; * ; *
; * The above copyright notice and this permission notice shall be included in all ; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software. ; * copies or substantial portions of the Software.
; * ; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; * ; *
; * https://www.FreeRTOS.org ; * https://www.FreeRTOS.org
; * https://github.com/FreeRTOS ; * https://github.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,164 +1,164 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 ; * FreeRTOS Kernel V10.4.3
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
; * ; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in ; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to ; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so, ; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions: ; * subject to the following conditions:
; * ; *
; * The above copyright notice and this permission notice shall be included in all ; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software. ; * copies or substantial portions of the Software.
; * ; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; * ; *
; * https://www.FreeRTOS.org ; * https://www.FreeRTOS.org
; * https://github.com/FreeRTOS ; * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 ; * FreeRTOS Kernel V10.4.3
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
; * ; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in ; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to ; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so, ; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions: ; * subject to the following conditions:
; * ; *
; * The above copyright notice and this permission notice shall be included in all ; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software. ; * copies or substantial portions of the Software.
; * ; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; * ; *
; * https://www.FreeRTOS.org ; * https://www.FreeRTOS.org
; * https://github.com/FreeRTOS ; * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 ; * FreeRTOS Kernel V10.4.3
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
; * ; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in ; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to ; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so, ; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions: ; * subject to the following conditions:
; * ; *
; * The above copyright notice and this permission notice shall be included in all ; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software. ; * copies or substantial portions of the Software.
; * ; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; * ; *
; * https://www.FreeRTOS.org ; * https://www.FreeRTOS.org
; * https://github.com/FreeRTOS ; * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,215 +1,215 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 V2.5.2 Changes from V2.5.2
+ The critical section management functions have been changed. These no + The critical section management functions have been changed. These no
longer modify the stack and are safe to use at all optimisation levels. longer modify the stack and are safe to use at all optimisation levels.
The functions are now also the same for both ARM and THUMB modes. The functions are now also the same for both ARM and THUMB modes.
Changes from V2.6.0 Changes from V2.6.0
+ Removed the 'static' from the definition of vNonPreemptiveTick() to + Removed the 'static' from the definition of vNonPreemptiveTick() to
allow the demo to link when using the cooperative scheduler. allow the demo to link when using the cooperative scheduler.
Changes from V3.2.4 Changes from V3.2.4
+ The assembler statements are now included in a single asm block rather + The assembler statements are now included in a single asm block rather
than each line having its own asm block. than each line having its own asm block.
*/ */
/* Scheduler includes. */ /* Scheduler includes. */
#include "FreeRTOS.h" #include "FreeRTOS.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. */
__asm volatile ( "bl vTaskSwitchContext" ); __asm volatile ( "bl vTaskSwitchContext" );
/* Restore the context of the new task. */ /* Restore the context of the new task. */
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* The ISR used for the scheduler tick. * The ISR used for the scheduler tick.
*/ */
void vTickISR( void ) __attribute__((naked)); void vTickISR( void ) __attribute__((naked));
void vTickISR( void ) void vTickISR( void )
{ {
/* Save the context of the interrupted task. */ /* Save the context of the interrupted task. */
portSAVE_CONTEXT(); portSAVE_CONTEXT();
/* Increment the RTOS tick count, then look for the highest priority /* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */ task that is ready to run. */
__asm volatile __asm volatile
( (
" bl xTaskIncrementTick \t\n" \ " bl xTaskIncrementTick \t\n" \
" cmp r0, #0 \t\n" \ " cmp r0, #0 \t\n" \
" beq SkipContextSwitch \t\n" \ " beq SkipContextSwitch \t\n" \
" bl vTaskSwitchContext \t\n" \ " bl vTaskSwitchContext \t\n" \
"SkipContextSwitch: \t\n" "SkipContextSwitch: \t\n"
); );
/* Ready for the next interrupt. */ /* Ready for the next interrupt. */
T0_IR = portTIMER_MATCH_ISR_BIT; T0_IR = portTIMER_MATCH_ISR_BIT;
VICVectAddr = portCLEAR_VIC_INTERRUPT; VICVectAddr = portCLEAR_VIC_INTERRUPT;
/* Restore the context of the new task. */ /* Restore the context of the new task. */
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
* 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,226 +1,226 @@
/* /*
* FreeRTOS Kernel V10.4.3 * FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to * the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, * the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: * subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
* https://www.FreeRTOS.org * https://www.FreeRTOS.org
* https://github.com/FreeRTOS * https://github.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 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; \
} }
extern void vTaskSwitchContext( void ); extern void vTaskSwitchContext( void );
#define portYIELD_FROM_ISR() vTaskSwitchContext() #define portYIELD_FROM_ISR() vTaskSwitchContext()
#define portYIELD() __asm volatile ( "SWI 0" ) #define portYIELD() __asm volatile ( "SWI 0" )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* 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 */

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