Deleting kernel source derectory.
This commit is contained in:
parent
4983d44023
commit
56edcc6fdd
@ -1,753 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||
all the API functions to use the MPU wrappers. That should only be done when
|
||||
task.h is included from an application file. */
|
||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "timers.h"
|
||||
#include "event_groups.h"
|
||||
|
||||
/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified
|
||||
because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
|
||||
for the header files above, but not in this file, in order to generate the
|
||||
correct privileged Vs unprivileged linkage and placement. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */
|
||||
|
||||
/* The following bit fields convey control information in a task's event list
|
||||
item value. It is important they don't clash with the
|
||||
taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
|
||||
#if configUSE_16_BIT_TICKS == 1
|
||||
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
|
||||
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
|
||||
#define eventWAIT_FOR_ALL_BITS 0x0400U
|
||||
#define eventEVENT_BITS_CONTROL_BYTES 0xff00U
|
||||
#else
|
||||
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL
|
||||
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL
|
||||
#define eventWAIT_FOR_ALL_BITS 0x04000000UL
|
||||
#define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
|
||||
#endif
|
||||
|
||||
typedef struct EventGroupDef_t
|
||||
{
|
||||
EventBits_t uxEventBits;
|
||||
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
|
||||
|
||||
#if( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxEventGroupNumber;
|
||||
#endif
|
||||
|
||||
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
|
||||
#endif
|
||||
} EventGroup_t;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Test the bits set in uxCurrentEventBits to see if the wait condition is met.
|
||||
* The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is
|
||||
* pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor
|
||||
* are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the
|
||||
* wait condition is met if any of the bits set in uxBitsToWait for are also set
|
||||
* in uxCurrentEventBits.
|
||||
*/
|
||||
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer )
|
||||
{
|
||||
EventGroup_t *pxEventBits;
|
||||
|
||||
/* A StaticEventGroup_t object must be provided. */
|
||||
configASSERT( pxEventGroupBuffer );
|
||||
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
/* Sanity check that the size of the structure used to declare a
|
||||
variable of type StaticEventGroup_t equals the size of the real
|
||||
event group structure. */
|
||||
volatile size_t xSize = sizeof( StaticEventGroup_t );
|
||||
configASSERT( xSize == sizeof( EventGroup_t ) );
|
||||
} /*lint !e529 xSize is referenced if configASSERT() is defined. */
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* The user has provided a statically allocated event group - use it. */
|
||||
pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 !e9087 EventGroup_t and StaticEventGroup_t are deliberately aliased for data hiding purposes and guaranteed to have the same size and alignment requirement - checked by configASSERT(). */
|
||||
|
||||
if( pxEventBits != NULL )
|
||||
{
|
||||
pxEventBits->uxEventBits = 0;
|
||||
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
{
|
||||
/* Both static and dynamic allocation can be used, so note that
|
||||
this event group was created statically in case the event group
|
||||
is later deleted. */
|
||||
pxEventBits->ucStaticallyAllocated = pdTRUE;
|
||||
}
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
|
||||
traceEVENT_GROUP_CREATE( pxEventBits );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* xEventGroupCreateStatic should only ever be called with
|
||||
pxEventGroupBuffer pointing to a pre-allocated (compile time
|
||||
allocated) StaticEventGroup_t variable. */
|
||||
traceEVENT_GROUP_CREATE_FAILED();
|
||||
}
|
||||
|
||||
return pxEventBits;
|
||||
}
|
||||
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
|
||||
EventGroupHandle_t xEventGroupCreate( void )
|
||||
{
|
||||
EventGroup_t *pxEventBits;
|
||||
|
||||
/* Allocate the event group. Justification for MISRA deviation as
|
||||
follows: pvPortMalloc() always ensures returned memory blocks are
|
||||
aligned per the requirements of the MCU stack. In this case
|
||||
pvPortMalloc() must return a pointer that is guaranteed to meet the
|
||||
alignment requirements of the EventGroup_t structure - which (if you
|
||||
follow it through) is the alignment requirements of the TickType_t type
|
||||
(EventBits_t being of TickType_t itself). Therefore, whenever the
|
||||
stack alignment requirements are greater than or equal to the
|
||||
TickType_t alignment requirements the cast is safe. In other cases,
|
||||
where the natural word size of the architecture is less than
|
||||
sizeof( TickType_t ), the TickType_t variables will be accessed in two
|
||||
or more reads operations, and the alignment requirements is only that
|
||||
of each individual read. */
|
||||
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */
|
||||
|
||||
if( pxEventBits != NULL )
|
||||
{
|
||||
pxEventBits->uxEventBits = 0;
|
||||
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
{
|
||||
/* Both static and dynamic allocation can be used, so note this
|
||||
event group was allocated statically in case the event group is
|
||||
later deleted. */
|
||||
pxEventBits->ucStaticallyAllocated = pdFALSE;
|
||||
}
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
traceEVENT_GROUP_CREATE( pxEventBits );
|
||||
}
|
||||
else
|
||||
{
|
||||
traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */
|
||||
}
|
||||
|
||||
return pxEventBits;
|
||||
}
|
||||
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
|
||||
{
|
||||
EventBits_t uxOriginalBitValue, uxReturn;
|
||||
EventGroup_t *pxEventBits = xEventGroup;
|
||||
BaseType_t xAlreadyYielded;
|
||||
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
|
||||
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
configASSERT( uxBitsToWaitFor != 0 );
|
||||
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||
{
|
||||
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
uxOriginalBitValue = pxEventBits->uxEventBits;
|
||||
|
||||
( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet );
|
||||
|
||||
if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||
{
|
||||
/* All the rendezvous bits are now set - no need to block. */
|
||||
uxReturn = ( uxOriginalBitValue | uxBitsToSet );
|
||||
|
||||
/* Rendezvous always clear the bits. They will have been cleared
|
||||
already unless this is the only task in the rendezvous. */
|
||||
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||
|
||||
xTicksToWait = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( xTicksToWait != ( TickType_t ) 0 )
|
||||
{
|
||||
traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
|
||||
|
||||
/* Store the bits that the calling task is waiting for in the
|
||||
task's event list item so the kernel knows when a match is
|
||||
found. Then enter the blocked state. */
|
||||
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
|
||||
|
||||
/* This assignment is obsolete as uxReturn will get set after
|
||||
the task unblocks, but some compilers mistakenly generate a
|
||||
warning about uxReturn being returned without being set if the
|
||||
assignment is omitted. */
|
||||
uxReturn = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The rendezvous bits were not set, but no block time was
|
||||
specified - just return the current event bit value. */
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
xTimeoutOccurred = pdTRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
xAlreadyYielded = xTaskResumeAll();
|
||||
|
||||
if( xTicksToWait != ( TickType_t ) 0 )
|
||||
{
|
||||
if( xAlreadyYielded == pdFALSE )
|
||||
{
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* The task blocked to wait for its required bits to be set - at this
|
||||
point either the required bits were set or the block time expired. If
|
||||
the required bits were set they will have been stored in the task's
|
||||
event list item, and they should now be retrieved then cleared. */
|
||||
uxReturn = uxTaskResetEventItemValue();
|
||||
|
||||
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||
{
|
||||
/* The task timed out, just return the current event bit value. */
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
|
||||
/* Although the task got here because it timed out before the
|
||||
bits it was waiting for were set, it is possible that since it
|
||||
unblocked another task has set the bits. If this is the case
|
||||
then it needs to clear the bits before exiting. */
|
||||
if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||
{
|
||||
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
xTimeoutOccurred = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The task unblocked because the bits were set. */
|
||||
}
|
||||
|
||||
/* Control bits might be set as the task had blocked should not be
|
||||
returned. */
|
||||
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||
}
|
||||
|
||||
traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
|
||||
|
||||
/* Prevent compiler warnings when trace macros are not used. */
|
||||
( void ) xTimeoutOccurred;
|
||||
|
||||
return uxReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
|
||||
{
|
||||
EventGroup_t *pxEventBits = xEventGroup;
|
||||
EventBits_t uxReturn, uxControlBits = 0;
|
||||
BaseType_t xWaitConditionMet, xAlreadyYielded;
|
||||
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
|
||||
/* Check the user is not attempting to wait on the bits used by the kernel
|
||||
itself, and that at least one bit is being requested. */
|
||||
configASSERT( xEventGroup );
|
||||
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
configASSERT( uxBitsToWaitFor != 0 );
|
||||
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||
{
|
||||
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
|
||||
|
||||
/* Check to see if the wait condition is already met or not. */
|
||||
xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );
|
||||
|
||||
if( xWaitConditionMet != pdFALSE )
|
||||
{
|
||||
/* The wait condition has already been met so there is no need to
|
||||
block. */
|
||||
uxReturn = uxCurrentEventBits;
|
||||
xTicksToWait = ( TickType_t ) 0;
|
||||
|
||||
/* Clear the wait bits if requested to do so. */
|
||||
if( xClearOnExit != pdFALSE )
|
||||
{
|
||||
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else if( xTicksToWait == ( TickType_t ) 0 )
|
||||
{
|
||||
/* The wait condition has not been met, but no block time was
|
||||
specified, so just return the current value. */
|
||||
uxReturn = uxCurrentEventBits;
|
||||
xTimeoutOccurred = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The task is going to block to wait for its required bits to be
|
||||
set. uxControlBits are used to remember the specified behaviour of
|
||||
this call to xEventGroupWaitBits() - for use when the event bits
|
||||
unblock the task. */
|
||||
if( xClearOnExit != pdFALSE )
|
||||
{
|
||||
uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
if( xWaitForAllBits != pdFALSE )
|
||||
{
|
||||
uxControlBits |= eventWAIT_FOR_ALL_BITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* Store the bits that the calling task is waiting for in the
|
||||
task's event list item so the kernel knows when a match is
|
||||
found. Then enter the blocked state. */
|
||||
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
|
||||
|
||||
/* This is obsolete as it will get set after the task unblocks, but
|
||||
some compilers mistakenly generate a warning about the variable
|
||||
being returned without being set if it is not done. */
|
||||
uxReturn = 0;
|
||||
|
||||
traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
|
||||
}
|
||||
}
|
||||
xAlreadyYielded = xTaskResumeAll();
|
||||
|
||||
if( xTicksToWait != ( TickType_t ) 0 )
|
||||
{
|
||||
if( xAlreadyYielded == pdFALSE )
|
||||
{
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* The task blocked to wait for its required bits to be set - at this
|
||||
point either the required bits were set or the block time expired. If
|
||||
the required bits were set they will have been stored in the task's
|
||||
event list item, and they should now be retrieved then cleared. */
|
||||
uxReturn = uxTaskResetEventItemValue();
|
||||
|
||||
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* The task timed out, just return the current event bit value. */
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
|
||||
/* It is possible that the event bits were updated between this
|
||||
task leaving the Blocked state and running again. */
|
||||
if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
|
||||
{
|
||||
if( xClearOnExit != pdFALSE )
|
||||
{
|
||||
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
xTimeoutOccurred = pdTRUE;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The task unblocked because the bits were set. */
|
||||
}
|
||||
|
||||
/* The task blocked so control bits may have been set. */
|
||||
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||
}
|
||||
traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
|
||||
|
||||
/* Prevent compiler warnings when trace macros are not used. */
|
||||
( void ) xTimeoutOccurred;
|
||||
|
||||
return uxReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
||||
{
|
||||
EventGroup_t *pxEventBits = xEventGroup;
|
||||
EventBits_t uxReturn;
|
||||
|
||||
/* Check the user is not attempting to clear the bits used by the kernel
|
||||
itself. */
|
||||
configASSERT( xEventGroup );
|
||||
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
|
||||
|
||||
/* The value returned is the event group value prior to the bits being
|
||||
cleared. */
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
|
||||
/* Clear the bits. */
|
||||
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
return uxReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||
|
||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
|
||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
|
||||
{
|
||||
UBaseType_t uxSavedInterruptStatus;
|
||||
EventGroup_t const * const pxEventBits = xEventGroup;
|
||||
EventBits_t uxReturn;
|
||||
|
||||
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
|
||||
|
||||
return uxReturn;
|
||||
} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
|
||||
{
|
||||
ListItem_t *pxListItem, *pxNext;
|
||||
ListItem_t const *pxListEnd;
|
||||
List_t const * pxList;
|
||||
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
|
||||
EventGroup_t *pxEventBits = xEventGroup;
|
||||
BaseType_t xMatchFound = pdFALSE;
|
||||
|
||||
/* Check the user is not attempting to set the bits used by the kernel
|
||||
itself. */
|
||||
configASSERT( xEventGroup );
|
||||
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
|
||||
pxList = &( pxEventBits->xTasksWaitingForBits );
|
||||
pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
|
||||
|
||||
pxListItem = listGET_HEAD_ENTRY( pxList );
|
||||
|
||||
/* Set the bits. */
|
||||
pxEventBits->uxEventBits |= uxBitsToSet;
|
||||
|
||||
/* See if the new bit value should unblock any tasks. */
|
||||
while( pxListItem != pxListEnd )
|
||||
{
|
||||
pxNext = listGET_NEXT( pxListItem );
|
||||
uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );
|
||||
xMatchFound = pdFALSE;
|
||||
|
||||
/* Split the bits waited for from the control bits. */
|
||||
uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES;
|
||||
uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||
|
||||
if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
|
||||
{
|
||||
/* Just looking for single bit being set. */
|
||||
if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
|
||||
{
|
||||
xMatchFound = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
|
||||
{
|
||||
/* All bits are set. */
|
||||
xMatchFound = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Need all bits to be set, but not all the bits were set. */
|
||||
}
|
||||
|
||||
if( xMatchFound != pdFALSE )
|
||||
{
|
||||
/* The bits match. Should the bits be cleared on exit? */
|
||||
if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 )
|
||||
{
|
||||
uxBitsToClear |= uxBitsWaitedFor;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* Store the actual event flag value in the task's event list
|
||||
item before removing the task from the event list. The
|
||||
eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
|
||||
that is was unblocked due to its required bits matching, rather
|
||||
than because it timed out. */
|
||||
vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||
}
|
||||
|
||||
/* Move onto the next list item. Note pxListItem->pxNext is not
|
||||
used here as the list item may have been removed from the event list
|
||||
and inserted into the ready/pending reading list. */
|
||||
pxListItem = pxNext;
|
||||
}
|
||||
|
||||
/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
|
||||
bit was set in the control word. */
|
||||
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||
}
|
||||
( void ) xTaskResumeAll();
|
||||
|
||||
return pxEventBits->uxEventBits;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
||||
{
|
||||
EventGroup_t *pxEventBits = xEventGroup;
|
||||
const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
traceEVENT_GROUP_DELETE( xEventGroup );
|
||||
|
||||
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* Unblock the task, returning 0 as the event list is being deleted
|
||||
and cannot therefore have any bits set. */
|
||||
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
||||
vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||
}
|
||||
|
||||
#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
|
||||
{
|
||||
/* The event group can only have been allocated dynamically - free
|
||||
it again. */
|
||||
vPortFree( pxEventBits );
|
||||
}
|
||||
#elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
{
|
||||
/* The event group could have been allocated statically or
|
||||
dynamically, so check before attempting to free the memory. */
|
||||
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
|
||||
{
|
||||
vPortFree( pxEventBits );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
}
|
||||
( void ) xTaskResumeAll();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* For internal use only - execute a 'set bits' command that was pended from
|
||||
an interrupt. */
|
||||
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
|
||||
{
|
||||
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* For internal use only - execute a 'clear bits' command that was pended from
|
||||
an interrupt. */
|
||||
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )
|
||||
{
|
||||
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits )
|
||||
{
|
||||
BaseType_t xWaitConditionMet = pdFALSE;
|
||||
|
||||
if( xWaitForAllBits == pdFALSE )
|
||||
{
|
||||
/* Task only has to wait for one bit within uxBitsToWaitFor to be
|
||||
set. Is one already set? */
|
||||
if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
|
||||
{
|
||||
xWaitConditionMet = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Task has to wait for all the bits in uxBitsToWaitFor to be set.
|
||||
Are they set already? */
|
||||
if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||
{
|
||||
xWaitConditionMet = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
|
||||
return xWaitConditionMet;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||
|
||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
|
||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if (configUSE_TRACE_FACILITY == 1)
|
||||
|
||||
UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
|
||||
{
|
||||
UBaseType_t xReturn;
|
||||
EventGroup_t const *pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
|
||||
|
||||
if( xEventGroup == NULL )
|
||||
{
|
||||
xReturn = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pxEventBits->uxEventGroupNumber;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber )
|
||||
{
|
||||
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
|
||||
}
|
||||
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,547 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file atomic.h
|
||||
* @brief FreeRTOS atomic operation support.
|
||||
*
|
||||
* Two implementations of atomic are given in this header file:
|
||||
* 1. Disabling interrupt globally.
|
||||
* 2. ISA native atomic support.
|
||||
* The former is available to all ports (compiler-architecture combination),
|
||||
* while the latter is only available to ports compiling with GCC (version at
|
||||
* least 4.7.0), which also have ISA atomic support.
|
||||
*
|
||||
* User can select which implementation to use by:
|
||||
* setting/clearing configUSE_ATOMIC_INSTRUCTION in FreeRTOSConfig.h.
|
||||
* Define AND set configUSE_ATOMIC_INSTRUCTION to 1 for ISA native atomic support.
|
||||
* Undefine OR clear configUSE_ATOMIC_INSTRUCTION for disabling global interrupt
|
||||
* implementation.
|
||||
*
|
||||
* @see GCC Built-in Functions for Memory Model Aware Atomic Operations
|
||||
* https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
|
||||
*/
|
||||
|
||||
#ifndef ATOMIC_H
|
||||
#define ATOMIC_H
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#error "include FreeRTOS.h must appear in source files before include atomic.h"
|
||||
#endif
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
|
||||
|
||||
/* Needed for __atomic_compare_exchange() weak=false. */
|
||||
#include <stdbool.h>
|
||||
|
||||
/* This branch is for GCC compiler and GCC compiler only. */
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/* Port specific definitions -- entering/exiting critical section.
|
||||
* Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h
|
||||
*
|
||||
* Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with
|
||||
* ATOMIC_ENTER_CRITICAL().
|
||||
*/
|
||||
#if defined( portSET_INTERRUPT_MASK_FROM_ISR )
|
||||
|
||||
/* Nested interrupt scheme is supported in this port. */
|
||||
#define ATOMIC_ENTER_CRITICAL() \
|
||||
UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()
|
||||
|
||||
#define ATOMIC_EXIT_CRITICAL() \
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
|
||||
|
||||
#else
|
||||
|
||||
/* Nested interrupt scheme is NOT supported in this port. */
|
||||
#define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
|
||||
#define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL()
|
||||
|
||||
#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
|
||||
|
||||
/* Port specific definition -- "always inline".
|
||||
* Inline is compiler specific, and may not always get inlined depending on your optimization level.
|
||||
* Also, inline is considerred as performance optimization for atomic.
|
||||
* Thus, if portFORCE_INLINE is not provided by portmacro.h, instead of resulting error,
|
||||
* simply define it.
|
||||
*/
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* configUSE_GCC_BUILTIN_ATOMICS */
|
||||
|
||||
#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. */
|
||||
|
||||
/*----------------------------- Swap && CAS ------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic compare-and-swap
|
||||
*
|
||||
* @brief Performs an atomic compare-and-swap operation on the specified values.
|
||||
*
|
||||
* @param[in, out] pDestination Pointer to memory location from where value is
|
||||
* to be loaded and checked.
|
||||
* @param[in] ulExchange If condition meets, write this value to memory.
|
||||
* @param[in] ulComparand Swap condition.
|
||||
*
|
||||
* @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
|
||||
*
|
||||
* @note This function only swaps *pDestination with ulExchange, if previous
|
||||
* *pDestination value equals ulComparand.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32(
|
||||
uint32_t volatile * pDestination,
|
||||
uint32_t ulExchange,
|
||||
uint32_t ulComparand )
|
||||
{
|
||||
|
||||
uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
|
||||
|
||||
#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
|
||||
|
||||
if ( __atomic_compare_exchange( pDestination,
|
||||
&ulComparand,
|
||||
&ulExchange,
|
||||
false,
|
||||
__ATOMIC_SEQ_CST,
|
||||
__ATOMIC_SEQ_CST ) )
|
||||
{
|
||||
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
|
||||
if ( *pDestination == ulComparand )
|
||||
{
|
||||
*pDestination = ulExchange;
|
||||
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
|
||||
}
|
||||
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
#endif
|
||||
|
||||
return ulReturnValue;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomic swap (pointers)
|
||||
*
|
||||
* @brief Atomically sets the address pointed to by *ppDestination to the value
|
||||
* of *pExchange.
|
||||
*
|
||||
* @param[in, out] ppDestination Pointer to memory location from where a pointer
|
||||
* value is to be loaded and written back to.
|
||||
* @param[in] pExchange Pointer value to be written to *ppDestination.
|
||||
*
|
||||
* @return The initial value of *ppDestination.
|
||||
*/
|
||||
static portFORCE_INLINE void * Atomic_SwapPointers_p32(
|
||||
void * volatile * ppDestination,
|
||||
void * pExchange )
|
||||
{
|
||||
void * pReturnValue;
|
||||
|
||||
#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
|
||||
|
||||
__atomic_exchange( ppDestination, &pExchange, &pReturnValue, __ATOMIC_SEQ_CST );
|
||||
|
||||
#else
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
|
||||
pReturnValue = *ppDestination;
|
||||
|
||||
*ppDestination = pExchange;
|
||||
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
#endif
|
||||
|
||||
return pReturnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomic compare-and-swap (pointers)
|
||||
*
|
||||
* @brief Performs an atomic compare-and-swap operation on the specified pointer
|
||||
* values.
|
||||
*
|
||||
* @param[in, out] ppDestination Pointer to memory location from where a pointer
|
||||
* value is to be loaded and checked.
|
||||
* @param[in] pExchange If condition meets, write this value to memory.
|
||||
* @param[in] pComparand Swap condition.
|
||||
*
|
||||
* @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
|
||||
*
|
||||
* @note This function only swaps *ppDestination with pExchange, if previous
|
||||
* *ppDestination value equals pComparand.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32(
|
||||
void * volatile * ppDestination,
|
||||
void * pExchange, void * pComparand )
|
||||
{
|
||||
uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
|
||||
|
||||
#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
|
||||
if ( __atomic_compare_exchange( ppDestination,
|
||||
&pComparand,
|
||||
&pExchange,
|
||||
false,
|
||||
__ATOMIC_SEQ_CST,
|
||||
__ATOMIC_SEQ_CST ) )
|
||||
{
|
||||
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
|
||||
if ( *ppDestination == pComparand )
|
||||
{
|
||||
*ppDestination = pExchange;
|
||||
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
|
||||
}
|
||||
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
#endif
|
||||
|
||||
return ulReturnValue;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------- Arithmetic ------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic add
|
||||
*
|
||||
* @brief Atomically adds count to the value of the specified pointer points to.
|
||||
*
|
||||
* @param[in,out] pAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
* @param[in] ulCount Value to be added to *pAddend.
|
||||
*
|
||||
* @return previous *pAddend value.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_Add_u32(
|
||||
uint32_t volatile * pAddend,
|
||||
uint32_t ulCount )
|
||||
{
|
||||
#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
|
||||
|
||||
return __atomic_fetch_add(pAddend, ulCount, __ATOMIC_SEQ_CST);
|
||||
|
||||
#else
|
||||
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
|
||||
ulCurrent = *pAddend;
|
||||
|
||||
*pAddend += ulCount;
|
||||
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomic subtract
|
||||
*
|
||||
* @brief Atomically subtracts count from the value of the specified pointer
|
||||
* pointers to.
|
||||
*
|
||||
* @param[in,out] pAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
* @param[in] ulCount Value to be subtract from *pAddend.
|
||||
*
|
||||
* @return previous *pAddend value.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_Subtract_u32(
|
||||
uint32_t volatile * pAddend,
|
||||
uint32_t ulCount )
|
||||
{
|
||||
#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
|
||||
|
||||
return __atomic_fetch_sub(pAddend, ulCount, __ATOMIC_SEQ_CST);
|
||||
|
||||
#else
|
||||
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
|
||||
ulCurrent = *pAddend;
|
||||
|
||||
*pAddend -= ulCount;
|
||||
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomic increment
|
||||
*
|
||||
* @brief Atomically increments the value of the specified pointer points to.
|
||||
*
|
||||
* @param[in,out] pAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
*
|
||||
* @return *pAddend value before increment.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pAddend )
|
||||
{
|
||||
#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
|
||||
|
||||
return __atomic_fetch_add(pAddend, 1, __ATOMIC_SEQ_CST);
|
||||
|
||||
#else
|
||||
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
|
||||
ulCurrent = *pAddend;
|
||||
|
||||
*pAddend += 1;
|
||||
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomic decrement
|
||||
*
|
||||
* @brief Atomically decrements the value of the specified pointer points to
|
||||
*
|
||||
* @param[in,out] pAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
*
|
||||
* @return *pAddend value before decrement.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pAddend )
|
||||
{
|
||||
#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
|
||||
|
||||
return __atomic_fetch_sub(pAddend, 1, __ATOMIC_SEQ_CST);
|
||||
|
||||
#else
|
||||
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
|
||||
ulCurrent = *pAddend;
|
||||
|
||||
*pAddend -= 1;
|
||||
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*----------------------------- Bitwise Logical ------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic OR
|
||||
*
|
||||
* @brief Performs an atomic OR operation on the specified values.
|
||||
*
|
||||
* @param [in, out] pDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be ORed with *pDestination.
|
||||
*
|
||||
* @return The original value of *pDestination.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_OR_u32(
|
||||
uint32_t volatile * pDestination,
|
||||
uint32_t ulValue )
|
||||
{
|
||||
#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
|
||||
|
||||
return __atomic_fetch_or(pDestination, ulValue, __ATOMIC_SEQ_CST);
|
||||
|
||||
#else
|
||||
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
|
||||
ulCurrent = *pDestination;
|
||||
|
||||
*pDestination |= ulValue;
|
||||
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomic AND
|
||||
*
|
||||
* @brief Performs an atomic AND operation on the specified values.
|
||||
*
|
||||
* @param [in, out] pDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be ANDed with *pDestination.
|
||||
*
|
||||
* @return The original value of *pDestination.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_AND_u32(
|
||||
uint32_t volatile * pDestination,
|
||||
uint32_t ulValue )
|
||||
{
|
||||
#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
|
||||
|
||||
return __atomic_fetch_and(pDestination, ulValue, __ATOMIC_SEQ_CST);
|
||||
|
||||
#else
|
||||
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
|
||||
ulCurrent = *pDestination;
|
||||
|
||||
*pDestination &= ulValue;
|
||||
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomic NAND
|
||||
*
|
||||
* @brief Performs an atomic NAND operation on the specified values.
|
||||
*
|
||||
* @param [in, out] pDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be NANDed with *pDestination.
|
||||
*
|
||||
* @return The original value of *pDestination.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_NAND_u32(
|
||||
uint32_t volatile * pDestination,
|
||||
uint32_t ulValue )
|
||||
{
|
||||
#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
|
||||
|
||||
return __atomic_fetch_nand(pDestination, ulValue, __ATOMIC_SEQ_CST);
|
||||
|
||||
#else
|
||||
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
|
||||
ulCurrent = *pDestination;
|
||||
|
||||
*pDestination = ~(ulCurrent & ulValue);
|
||||
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomic XOR
|
||||
*
|
||||
* @brief Performs an atomic XOR operation on the specified values.
|
||||
*
|
||||
* @param [in, out] pDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be XORed with *pDestination.
|
||||
*
|
||||
* @return The original value of *pDestination.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_XOR_u32(
|
||||
uint32_t volatile * pDestination,
|
||||
uint32_t ulValue )
|
||||
{
|
||||
#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
|
||||
|
||||
return __atomic_fetch_xor(pDestination, ulValue, __ATOMIC_SEQ_CST);
|
||||
|
||||
#else
|
||||
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
|
||||
ulCurrent = *pDestination;
|
||||
|
||||
*pDestination ^= ulValue;
|
||||
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ATOMIC_H */
|
@ -1,279 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef DEPRECATED_DEFINITIONS_H
|
||||
#define DEPRECATED_DEFINITIONS_H
|
||||
|
||||
|
||||
/* 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
|
||||
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
|
||||
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
|
||||
definitions below remain in the code for backward compatibility only. New
|
||||
projects should not use them. */
|
||||
|
||||
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
||||
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
||||
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MEGA_AVR
|
||||
#include "../portable/GCC/ATMega323/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_MEGA_AVR
|
||||
#include "../portable/IAR/ATMega323/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC24_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_DSPIC_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC18F_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC18F/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC32MX_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef _FEDPICC
|
||||
#include "libFreeRTOS/Include/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SDCC_CYGNAL
|
||||
#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARM7
|
||||
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARM7_ECLIPSE
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ROWLEY_LPC23xx
|
||||
#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_MSP430
|
||||
#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MSP430
|
||||
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ROWLEY_MSP430
|
||||
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ARM7_LPC21xx_KEIL_RVDS
|
||||
#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM7_GCC
|
||||
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM7_IAR
|
||||
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM9XE_IAR
|
||||
#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef LPC2000_IAR
|
||||
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR71X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR75X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR75X_GCC
|
||||
#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR91X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_H8S
|
||||
#include "../../Source/portable/GCC/H8S2329/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_AT91FR40008
|
||||
#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef RVDS_ARMCM3_LM3S102
|
||||
#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARMCM3_LM3S102
|
||||
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARMCM3
|
||||
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_ARM_CM3
|
||||
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_ARMCM3_LM
|
||||
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef HCS12_CODE_WARRIOR
|
||||
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MICROBLAZE_GCC
|
||||
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef TERN_EE
|
||||
#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_HCS12
|
||||
#include "../../Source/portable/GCC/HCS12/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MCF5235
|
||||
#include "../../Source/portable/GCC/MCF5235/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef COLDFIRE_V2_GCC
|
||||
#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef COLDFIRE_V2_CODEWARRIOR
|
||||
#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_PPC405
|
||||
#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_PPC440
|
||||
#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef _16FX_SOFTUNE
|
||||
#include "..\..\Source\portable\Softune\MB96340\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef BCC_INDUSTRIAL_PC_PORT
|
||||
/* A short file name has to be used in place of the normal
|
||||
FreeRTOSConfig.h when using the Borland compiler. */
|
||||
#include "frconfig.h"
|
||||
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef BCC_FLASH_LITE_186_PORT
|
||||
/* A short file name has to be used in place of the normal
|
||||
FreeRTOSConfig.h when using the Borland compiler. */
|
||||
#include "frconfig.h"
|
||||
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifdef __AVR32_AVR32A__
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __ICCAVR32__
|
||||
#ifdef __CORE__
|
||||
#if __CORE__ == __AVR32A__
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __91467D
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __96340
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __IAR_V850ES_Fx3__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx3__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx3_L__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx2__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Hx2__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_78K0R_Kx3__
|
||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_78K0R_Kx3L__
|
||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||
#endif
|
||||
|
||||
#endif /* DEPRECATED_DEFINITIONS_H */
|
||||
|
@ -1,757 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef EVENT_GROUPS_H
|
||||
#define EVENT_GROUPS_H
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
|
||||
#endif
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "timers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* An event group is a collection of bits to which an application can assign a
|
||||
* meaning. For example, an application may create an event group to convey
|
||||
* the status of various CAN bus related events in which bit 0 might mean "A CAN
|
||||
* message has been received and is ready for processing", bit 1 might mean "The
|
||||
* application has queued a message that is ready for sending onto the CAN
|
||||
* network", and bit 2 might mean "It is time to send a SYNC message onto the
|
||||
* CAN network" etc. A task can then test the bit values to see which events
|
||||
* are active, and optionally enter the Blocked state to wait for a specified
|
||||
* bit or a group of specified bits to be active. To continue the CAN bus
|
||||
* example, a CAN controlling task can enter the Blocked state (and therefore
|
||||
* not consume any processing time) until either bit 0, bit 1 or bit 2 are
|
||||
* active, at which time the bit that was actually active would inform the task
|
||||
* which action it had to take (process a received message, send a message, or
|
||||
* send a SYNC).
|
||||
*
|
||||
* The event groups implementation contains intelligence to avoid race
|
||||
* conditions that would otherwise occur were an application to use a simple
|
||||
* variable for the same purpose. This is particularly important with respect
|
||||
* to when a bit within an event group is to be cleared, and when bits have to
|
||||
* be set and then tested atomically - as is the case where event groups are
|
||||
* used to create a synchronisation point between multiple tasks (a
|
||||
* 'rendezvous').
|
||||
*
|
||||
* \defgroup EventGroup
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*
|
||||
* Type by which event groups are referenced. For example, a call to
|
||||
* xEventGroupCreate() returns an EventGroupHandle_t variable that can then
|
||||
* be used as a parameter to other event group functions.
|
||||
*
|
||||
* \defgroup EventGroupHandle_t EventGroupHandle_t
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
struct EventGroupDef_t;
|
||||
typedef struct EventGroupDef_t * EventGroupHandle_t;
|
||||
|
||||
/*
|
||||
* The type that holds event bits always matches TickType_t - therefore the
|
||||
* number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1,
|
||||
* 32 bits if set to 0.
|
||||
*
|
||||
* \defgroup EventBits_t EventBits_t
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
typedef TickType_t EventBits_t;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventGroupHandle_t xEventGroupCreate( void );
|
||||
</pre>
|
||||
*
|
||||
* Create a new event group.
|
||||
*
|
||||
* Internally, within the FreeRTOS implementation, event groups use a [small]
|
||||
* block of memory, in which the event group's structure is stored. If an event
|
||||
* groups is created using xEventGropuCreate() then the required memory is
|
||||
* automatically dynamically allocated inside the xEventGroupCreate() function.
|
||||
* (see http://www.freertos.org/a00111.html). If an event group is created
|
||||
* using xEventGropuCreateStatic() then the application writer must instead
|
||||
* provide the memory that will get used by the event group.
|
||||
* xEventGroupCreateStatic() therefore allows an event group to be created
|
||||
* without using any dynamic memory allocation.
|
||||
*
|
||||
* Although event groups are not related to ticks, for internal implementation
|
||||
* reasons the number of bits available for use in an event group is dependent
|
||||
* on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If
|
||||
* configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
|
||||
* 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has
|
||||
* 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store
|
||||
* event bits within an event group.
|
||||
*
|
||||
* @return If the event group was created then a handle to the event group is
|
||||
* returned. If there was insufficient FreeRTOS heap available to create the
|
||||
* event group then NULL is returned. See http://www.freertos.org/a00111.html
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Declare a variable to hold the created event group.
|
||||
EventGroupHandle_t xCreatedEventGroup;
|
||||
|
||||
// Attempt to create the event group.
|
||||
xCreatedEventGroup = xEventGroupCreate();
|
||||
|
||||
// Was the event group created successfully?
|
||||
if( xCreatedEventGroup == NULL )
|
||||
{
|
||||
// The event group was not created because there was insufficient
|
||||
// FreeRTOS heap available.
|
||||
}
|
||||
else
|
||||
{
|
||||
// The event group was created.
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xEventGroupCreate xEventGroupCreate
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Create a new event group.
|
||||
*
|
||||
* Internally, within the FreeRTOS implementation, event groups use a [small]
|
||||
* block of memory, in which the event group's structure is stored. If an event
|
||||
* groups is created using xEventGropuCreate() then the required memory is
|
||||
* automatically dynamically allocated inside the xEventGroupCreate() function.
|
||||
* (see http://www.freertos.org/a00111.html). If an event group is created
|
||||
* using xEventGropuCreateStatic() then the application writer must instead
|
||||
* provide the memory that will get used by the event group.
|
||||
* xEventGroupCreateStatic() therefore allows an event group to be created
|
||||
* without using any dynamic memory allocation.
|
||||
*
|
||||
* Although event groups are not related to ticks, for internal implementation
|
||||
* reasons the number of bits available for use in an event group is dependent
|
||||
* on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If
|
||||
* configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
|
||||
* 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has
|
||||
* 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store
|
||||
* event bits within an event group.
|
||||
*
|
||||
* @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type
|
||||
* StaticEventGroup_t, which will be then be used to hold the event group's data
|
||||
* structures, removing the need for the memory to be allocated dynamically.
|
||||
*
|
||||
* @return If the event group was created then a handle to the event group is
|
||||
* returned. If pxEventGroupBuffer was NULL then NULL is returned.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// StaticEventGroup_t is a publicly accessible structure that has the same
|
||||
// size and alignment requirements as the real event group structure. It is
|
||||
// provided as a mechanism for applications to know the size of the event
|
||||
// group (which is dependent on the architecture and configuration file
|
||||
// settings) without breaking the strict data hiding policy by exposing the
|
||||
// real event group internals. This StaticEventGroup_t variable is passed
|
||||
// into the xSemaphoreCreateEventGroupStatic() function and is used to store
|
||||
// the event group's data structures
|
||||
StaticEventGroup_t xEventGroupBuffer;
|
||||
|
||||
// Create the event group without dynamically allocating any memory.
|
||||
xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
|
||||
</pre>
|
||||
*/
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xClearOnExit,
|
||||
const BaseType_t xWaitForAllBits,
|
||||
const TickType_t xTicksToWait );
|
||||
</pre>
|
||||
*
|
||||
* [Potentially] block to wait for one or more bits to be set within a
|
||||
* previously created event group.
|
||||
*
|
||||
* This function cannot be called from an interrupt.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are being tested. The
|
||||
* event group must have previously been created using a call to
|
||||
* xEventGroupCreate().
|
||||
*
|
||||
* @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||
* inside the event group. For example, to wait for bit 0 and/or bit 2 set
|
||||
* uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set
|
||||
* uxBitsToWaitFor to 0x07. Etc.
|
||||
*
|
||||
* @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within
|
||||
* uxBitsToWaitFor that are set within the event group will be cleared before
|
||||
* xEventGroupWaitBits() returns if the wait condition was met (if the function
|
||||
* returns for a reason other than a timeout). If xClearOnExit is set to
|
||||
* pdFALSE then the bits set in the event group are not altered when the call to
|
||||
* xEventGroupWaitBits() returns.
|
||||
*
|
||||
* @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then
|
||||
* xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor
|
||||
* are set or the specified block time expires. If xWaitForAllBits is set to
|
||||
* pdFALSE then xEventGroupWaitBits() will return when any one of the bits set
|
||||
* in uxBitsToWaitFor is set or the specified block time expires. The block
|
||||
* time is specified by the xTicksToWait parameter.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
|
||||
* for one/all (depending on the xWaitForAllBits value) of the bits specified by
|
||||
* uxBitsToWaitFor to become set.
|
||||
*
|
||||
* @return The value of the event group at the time either the bits being waited
|
||||
* for became set, or the block time expired. Test the return value to know
|
||||
* which bits were set. If xEventGroupWaitBits() returned because its timeout
|
||||
* expired then not all the bits being waited for will be set. If
|
||||
* xEventGroupWaitBits() returned because the bits it was waiting for were set
|
||||
* then the returned value is the event group value before any bits were
|
||||
* automatically cleared in the case that xClearOnExit parameter was set to
|
||||
* pdTRUE.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
#define BIT_0 ( 1 << 0 )
|
||||
#define BIT_4 ( 1 << 4 )
|
||||
|
||||
void aFunction( EventGroupHandle_t xEventGroup )
|
||||
{
|
||||
EventBits_t uxBits;
|
||||
const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
||||
|
||||
// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
|
||||
// the event group. Clear the bits before exiting.
|
||||
uxBits = xEventGroupWaitBits(
|
||||
xEventGroup, // The event group being tested.
|
||||
BIT_0 | BIT_4, // The bits within the event group to wait for.
|
||||
pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
|
||||
pdFALSE, // Don't wait for both bits, either bit will do.
|
||||
xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
|
||||
|
||||
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||
{
|
||||
// xEventGroupWaitBits() returned because both bits were set.
|
||||
}
|
||||
else if( ( uxBits & BIT_0 ) != 0 )
|
||||
{
|
||||
// xEventGroupWaitBits() returned because just BIT_0 was set.
|
||||
}
|
||||
else if( ( uxBits & BIT_4 ) != 0 )
|
||||
{
|
||||
// xEventGroupWaitBits() returned because just BIT_4 was set.
|
||||
}
|
||||
else
|
||||
{
|
||||
// xEventGroupWaitBits() returned because xTicksToWait ticks passed
|
||||
// without either BIT_0 or BIT_4 becoming set.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xEventGroupWaitBits xEventGroupWaitBits
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
|
||||
</pre>
|
||||
*
|
||||
* Clear bits within an event group. This function cannot be called from an
|
||||
* interrupt.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are to be cleared.
|
||||
*
|
||||
* @param uxBitsToClear A bitwise value that indicates the bit or bits to clear
|
||||
* in the event group. For example, to clear bit 3 only, set uxBitsToClear to
|
||||
* 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09.
|
||||
*
|
||||
* @return The value of the event group before the specified bits were cleared.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
#define BIT_0 ( 1 << 0 )
|
||||
#define BIT_4 ( 1 << 4 )
|
||||
|
||||
void aFunction( EventGroupHandle_t xEventGroup )
|
||||
{
|
||||
EventBits_t uxBits;
|
||||
|
||||
// Clear bit 0 and bit 4 in xEventGroup.
|
||||
uxBits = xEventGroupClearBits(
|
||||
xEventGroup, // The event group being updated.
|
||||
BIT_0 | BIT_4 );// The bits being cleared.
|
||||
|
||||
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||
{
|
||||
// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
|
||||
// called. Both will now be clear (not set).
|
||||
}
|
||||
else if( ( uxBits & BIT_0 ) != 0 )
|
||||
{
|
||||
// Bit 0 was set before xEventGroupClearBits() was called. It will
|
||||
// now be clear.
|
||||
}
|
||||
else if( ( uxBits & BIT_4 ) != 0 )
|
||||
{
|
||||
// Bit 4 was set before xEventGroupClearBits() was called. It will
|
||||
// now be clear.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Neither bit 0 nor bit 4 were set in the first place.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xEventGroupClearBits xEventGroupClearBits
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||
</pre>
|
||||
*
|
||||
* A version of xEventGroupClearBits() that can be called from an interrupt.
|
||||
*
|
||||
* Setting bits in an event group is not a deterministic operation because there
|
||||
* are an unknown number of tasks that may be waiting for the bit or bits being
|
||||
* set. FreeRTOS does not allow nondeterministic operations to be performed
|
||||
* while interrupts are disabled, so protects event groups that are accessed
|
||||
* from tasks by suspending the scheduler rather than disabling interrupts. As
|
||||
* a result event groups cannot be accessed directly from an interrupt service
|
||||
* routine. Therefore xEventGroupClearBitsFromISR() sends a message to the
|
||||
* timer task to have the clear operation performed in the context of the timer
|
||||
* task.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are to be cleared.
|
||||
*
|
||||
* @param uxBitsToClear A bitwise value that indicates the bit or bits to clear.
|
||||
* For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3
|
||||
* and bit 0 set uxBitsToClear to 0x09.
|
||||
*
|
||||
* @return If the request to execute the function was posted successfully then
|
||||
* pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned
|
||||
* if the timer service queue was full.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
#define BIT_0 ( 1 << 0 )
|
||||
#define BIT_4 ( 1 << 4 )
|
||||
|
||||
// An event group which it is assumed has already been created by a call to
|
||||
// xEventGroupCreate().
|
||||
EventGroupHandle_t xEventGroup;
|
||||
|
||||
void anInterruptHandler( void )
|
||||
{
|
||||
// Clear bit 0 and bit 4 in xEventGroup.
|
||||
xResult = xEventGroupClearBitsFromISR(
|
||||
xEventGroup, // The event group being updated.
|
||||
BIT_0 | BIT_4 ); // The bits being set.
|
||||
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
// The message was posted successfully.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
#if( configUSE_TRACE_FACILITY == 1 )
|
||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||
</pre>
|
||||
*
|
||||
* Set bits within an event group.
|
||||
* This function cannot be called from an interrupt. xEventGroupSetBitsFromISR()
|
||||
* is a version that can be called from an interrupt.
|
||||
*
|
||||
* Setting bits in an event group will automatically unblock tasks that are
|
||||
* blocked waiting for the bits.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are to be set.
|
||||
*
|
||||
* @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
|
||||
* For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
|
||||
* and bit 0 set uxBitsToSet to 0x09.
|
||||
*
|
||||
* @return The value of the event group at the time the call to
|
||||
* xEventGroupSetBits() returns. There are two reasons why the returned value
|
||||
* might have the bits specified by the uxBitsToSet parameter cleared. First,
|
||||
* if setting a bit results in a task that was waiting for the bit leaving the
|
||||
* blocked state then it is possible the bit will be cleared automatically
|
||||
* (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any
|
||||
* unblocked (or otherwise Ready state) task that has a priority above that of
|
||||
* the task that called xEventGroupSetBits() will execute and may change the
|
||||
* event group value before the call to xEventGroupSetBits() returns.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
#define BIT_0 ( 1 << 0 )
|
||||
#define BIT_4 ( 1 << 4 )
|
||||
|
||||
void aFunction( EventGroupHandle_t xEventGroup )
|
||||
{
|
||||
EventBits_t uxBits;
|
||||
|
||||
// Set bit 0 and bit 4 in xEventGroup.
|
||||
uxBits = xEventGroupSetBits(
|
||||
xEventGroup, // The event group being updated.
|
||||
BIT_0 | BIT_4 );// The bits being set.
|
||||
|
||||
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||
{
|
||||
// Both bit 0 and bit 4 remained set when the function returned.
|
||||
}
|
||||
else if( ( uxBits & BIT_0 ) != 0 )
|
||||
{
|
||||
// Bit 0 remained set when the function returned, but bit 4 was
|
||||
// cleared. It might be that bit 4 was cleared automatically as a
|
||||
// task that was waiting for bit 4 was removed from the Blocked
|
||||
// state.
|
||||
}
|
||||
else if( ( uxBits & BIT_4 ) != 0 )
|
||||
{
|
||||
// Bit 4 remained set when the function returned, but bit 0 was
|
||||
// cleared. It might be that bit 0 was cleared automatically as a
|
||||
// task that was waiting for bit 0 was removed from the Blocked
|
||||
// state.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Neither bit 0 nor bit 4 remained set. It might be that a task
|
||||
// was waiting for both of the bits to be set, and the bits were
|
||||
// cleared as the task left the Blocked state.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xEventGroupSetBits xEventGroupSetBits
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* A version of xEventGroupSetBits() that can be called from an interrupt.
|
||||
*
|
||||
* Setting bits in an event group is not a deterministic operation because there
|
||||
* are an unknown number of tasks that may be waiting for the bit or bits being
|
||||
* set. FreeRTOS does not allow nondeterministic operations to be performed in
|
||||
* interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR()
|
||||
* sends a message to the timer task to have the set operation performed in the
|
||||
* context of the timer task - where a scheduler lock is used in place of a
|
||||
* critical section.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are to be set.
|
||||
*
|
||||
* @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
|
||||
* For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
|
||||
* and bit 0 set uxBitsToSet to 0x09.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken As mentioned above, calling this function
|
||||
* will result in a message being sent to the timer daemon task. If the
|
||||
* priority of the timer daemon task is higher than the priority of the
|
||||
* currently running task (the task the interrupt interrupted) then
|
||||
* *pxHigherPriorityTaskWoken will be set to pdTRUE by
|
||||
* xEventGroupSetBitsFromISR(), indicating that a context switch should be
|
||||
* requested before the interrupt exits. For that reason
|
||||
* *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the
|
||||
* example code below.
|
||||
*
|
||||
* @return If the request to execute the function was posted successfully then
|
||||
* pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned
|
||||
* if the timer service queue was full.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
#define BIT_0 ( 1 << 0 )
|
||||
#define BIT_4 ( 1 << 4 )
|
||||
|
||||
// An event group which it is assumed has already been created by a call to
|
||||
// xEventGroupCreate().
|
||||
EventGroupHandle_t xEventGroup;
|
||||
|
||||
void anInterruptHandler( void )
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken, xResult;
|
||||
|
||||
// xHigherPriorityTaskWoken must be initialised to pdFALSE.
|
||||
xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
// Set bit 0 and bit 4 in xEventGroup.
|
||||
xResult = xEventGroupSetBitsFromISR(
|
||||
xEventGroup, // The event group being updated.
|
||||
BIT_0 | BIT_4 // The bits being set.
|
||||
&xHigherPriorityTaskWoken );
|
||||
|
||||
// Was the message posted successfully?
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
|
||||
// switch should be requested. The macro used is port specific and
|
||||
// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
|
||||
// refer to the documentation page for the port being used.
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
#if( configUSE_TRACE_FACILITY == 1 )
|
||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
TickType_t xTicksToWait );
|
||||
</pre>
|
||||
*
|
||||
* Atomically set bits within an event group, then wait for a combination of
|
||||
* bits to be set within the same event group. This functionality is typically
|
||||
* used to synchronise multiple tasks, where each task has to wait for the other
|
||||
* tasks to reach a synchronisation point before proceeding.
|
||||
*
|
||||
* This function cannot be used from an interrupt.
|
||||
*
|
||||
* The function will return before its block time expires if the bits specified
|
||||
* by the uxBitsToWait parameter are set, or become set within that time. In
|
||||
* this case all the bits specified by uxBitsToWait will be automatically
|
||||
* cleared before the function returns.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are being tested. The
|
||||
* event group must have previously been created using a call to
|
||||
* xEventGroupCreate().
|
||||
*
|
||||
* @param uxBitsToSet The bits to set in the event group before determining
|
||||
* if, and possibly waiting for, all the bits specified by the uxBitsToWait
|
||||
* parameter are set.
|
||||
*
|
||||
* @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||
* inside the event group. For example, to wait for bit 0 and bit 2 set
|
||||
* uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set
|
||||
* uxBitsToWaitFor to 0x07. Etc.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
|
||||
* for all of the bits specified by uxBitsToWaitFor to become set.
|
||||
*
|
||||
* @return The value of the event group at the time either the bits being waited
|
||||
* for became set, or the block time expired. Test the return value to know
|
||||
* which bits were set. If xEventGroupSync() returned because its timeout
|
||||
* expired then not all the bits being waited for will be set. If
|
||||
* xEventGroupSync() returned because all the bits it was waiting for were
|
||||
* set then the returned value is the event group value before any bits were
|
||||
* automatically cleared.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Bits used by the three tasks.
|
||||
#define TASK_0_BIT ( 1 << 0 )
|
||||
#define TASK_1_BIT ( 1 << 1 )
|
||||
#define TASK_2_BIT ( 1 << 2 )
|
||||
|
||||
#define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
|
||||
|
||||
// Use an event group to synchronise three tasks. It is assumed this event
|
||||
// group has already been created elsewhere.
|
||||
EventGroupHandle_t xEventBits;
|
||||
|
||||
void vTask0( void *pvParameters )
|
||||
{
|
||||
EventBits_t uxReturn;
|
||||
TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Perform task functionality here.
|
||||
|
||||
// Set bit 0 in the event flag to note this task has reached the
|
||||
// sync point. The other two tasks will set the other two bits defined
|
||||
// by ALL_SYNC_BITS. All three tasks have reached the synchronisation
|
||||
// point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms
|
||||
// for this to happen.
|
||||
uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
|
||||
|
||||
if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
|
||||
{
|
||||
// All three tasks reached the synchronisation point before the call
|
||||
// to xEventGroupSync() timed out.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vTask1( void *pvParameters )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
// Perform task functionality here.
|
||||
|
||||
// Set bit 1 in the event flag to note this task has reached the
|
||||
// synchronisation point. The other two tasks will set the other two
|
||||
// bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
||||
// synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
||||
// indefinitely for this to happen.
|
||||
xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
||||
|
||||
// xEventGroupSync() was called with an indefinite block time, so
|
||||
// this task will only reach here if the syncrhonisation was made by all
|
||||
// three tasks, so there is no need to test the return value.
|
||||
}
|
||||
}
|
||||
|
||||
void vTask2( void *pvParameters )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
// Perform task functionality here.
|
||||
|
||||
// Set bit 2 in the event flag to note this task has reached the
|
||||
// synchronisation point. The other two tasks will set the other two
|
||||
// bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
||||
// synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
||||
// indefinitely for this to happen.
|
||||
xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
||||
|
||||
// xEventGroupSync() was called with an indefinite block time, so
|
||||
// this task will only reach here if the syncrhonisation was made by all
|
||||
// three tasks, so there is no need to test the return value.
|
||||
}
|
||||
}
|
||||
|
||||
</pre>
|
||||
* \defgroup xEventGroupSync xEventGroupSync
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
|
||||
</pre>
|
||||
*
|
||||
* Returns the current value of the bits in an event group. This function
|
||||
* cannot be used from an interrupt.
|
||||
*
|
||||
* @param xEventGroup The event group being queried.
|
||||
*
|
||||
* @return The event group bits at the time xEventGroupGetBits() was called.
|
||||
*
|
||||
* \defgroup xEventGroupGetBits xEventGroupGetBits
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
|
||||
</pre>
|
||||
*
|
||||
* A version of xEventGroupGetBits() that can be called from an ISR.
|
||||
*
|
||||
* @param xEventGroup The event group being queried.
|
||||
*
|
||||
* @return The event group bits at the time xEventGroupGetBitsFromISR() was called.
|
||||
*
|
||||
* \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
void xEventGroupDelete( EventGroupHandle_t xEventGroup );
|
||||
</pre>
|
||||
*
|
||||
* Delete an event group that was previously created by a call to
|
||||
* xEventGroupCreate(). Tasks that are blocked on the event group will be
|
||||
* unblocked and obtain 0 as the event group's value.
|
||||
*
|
||||
* @param xEventGroup The event group being deleted.
|
||||
*/
|
||||
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/* For internal use only. */
|
||||
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
|
||||
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
#if (configUSE_TRACE_FACILITY == 1)
|
||||
UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION;
|
||||
void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EVENT_GROUPS_H */
|
||||
|
||||
|
@ -1,412 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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
|
||||
* application code.
|
||||
*
|
||||
* 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
|
||||
* descending item value order.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* is because the tail contains a wrap back pointer to the true head of
|
||||
* the list.
|
||||
*
|
||||
* 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)
|
||||
* and a pointer to back to the object that contains it. These later two
|
||||
* pointers are included for efficiency of list manipulation. There is
|
||||
* effectively a two way link between the object containing the list item and
|
||||
* the list item itself.
|
||||
*
|
||||
*
|
||||
* \page ListIntroduction List Implementation
|
||||
* \ingroup FreeRTOSIntro
|
||||
*/
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#error FreeRTOS.h must be included before list.h
|
||||
#endif
|
||||
|
||||
#ifndef LIST_H
|
||||
#define LIST_H
|
||||
|
||||
/*
|
||||
* The list structure members are modified from within interrupts, and therefore
|
||||
* by rights should be declared volatile. However, they are only modified in a
|
||||
* functionally atomic way (within critical sections of with the scheduler
|
||||
* 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
|
||||
* qualifier can be omitted in order to provide a moderate performance
|
||||
* improvement without adversely affecting functional behaviour. The assembly
|
||||
* instructions generated by the IAR, ARM and GCC compilers when the respective
|
||||
* compiler's options were set for maximum optimisation has been inspected 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
|
||||
* 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
|
||||
* that a compiler removing essential code because, without the volatile
|
||||
* qualifier on the list structure members and with aggressive cross module
|
||||
* optimisation, the compiler deemed the code unnecessary will result in
|
||||
* 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
|
||||
* list structures by simply defining configLIST_VOLATILE to volatile in
|
||||
* FreeRTOSConfig.h (as per the example at the bottom of this comment block).
|
||||
* If configLIST_VOLATILE is not defined then the preprocessor directives below
|
||||
* will simply #define configLIST_VOLATILE away completely.
|
||||
*
|
||||
* To use volatile list structure members then add the following line to
|
||||
* FreeRTOSConfig.h (without the quotes):
|
||||
* "#define configLIST_VOLATILE volatile"
|
||||
*/
|
||||
#ifndef configLIST_VOLATILE
|
||||
#define configLIST_VOLATILE
|
||||
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
the application. These may catch the list data structures being overwritten in
|
||||
memory. They will not catch data errors caused by incorrect configuration or
|
||||
use of FreeRTOS.*/
|
||||
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
|
||||
/* Define the macros to do nothing. */
|
||||
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
||||
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
||||
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE
|
||||
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE
|
||||
#define listSET_FIRST_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_2_VALUE( pxList )
|
||||
#define listTEST_LIST_ITEM_INTEGRITY( pxItem )
|
||||
#define listTEST_LIST_INTEGRITY( pxList )
|
||||
#else
|
||||
/* Define macros that add new members into the list structures. */
|
||||
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
|
||||
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
|
||||
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1;
|
||||
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2;
|
||||
|
||||
/* 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_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_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
||||
|
||||
/* Define macros that will assert if one of the structure members does not
|
||||
contain its expected 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 ) )
|
||||
#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
|
||||
|
||||
|
||||
/*
|
||||
* Definition of the only type of object that a list can contain.
|
||||
*/
|
||||
struct xLIST;
|
||||
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. */
|
||||
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 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. */
|
||||
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. */
|
||||
};
|
||||
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
|
||||
|
||||
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. */
|
||||
configLIST_VOLATILE TickType_t xItemValue;
|
||||
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
|
||||
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
|
||||
};
|
||||
typedef struct xMINI_LIST_ITEM MiniListItem_t;
|
||||
|
||||
/*
|
||||
* Definition of the type of queue used by the scheduler.
|
||||
*/
|
||||
typedef struct xLIST
|
||||
{
|
||||
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;
|
||||
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. */
|
||||
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
} List_t;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#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
|
||||
* is the object (usually a TCB) that contains the list item.
|
||||
*
|
||||
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner )
|
||||
|
||||
/*
|
||||
* Access macro to set the value of the list item. In most cases the value is
|
||||
* used to sort the list in descending order.
|
||||
*
|
||||
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) )
|
||||
|
||||
/*
|
||||
* 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
|
||||
* which a task should be unblocked.
|
||||
*
|
||||
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
|
||||
|
||||
/*
|
||||
* Access macro to retrieve the value of the list item at the head of a given
|
||||
* list.
|
||||
*
|
||||
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue )
|
||||
|
||||
/*
|
||||
* Return the list item at the head of the list.
|
||||
*
|
||||
* \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext )
|
||||
|
||||
/*
|
||||
* Return the list item at the head of the list.
|
||||
*
|
||||
* \page listGET_NEXT listGET_NEXT
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext )
|
||||
|
||||
/*
|
||||
* Return the list item that marks the end of the list
|
||||
*
|
||||
* \page listGET_END_MARKER listGET_END_MARKER
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
|
||||
|
||||
/*
|
||||
* Access macro to determine if a list contains any items. The macro will
|
||||
* only have the value true if the list is empty.
|
||||
*
|
||||
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
|
||||
|
||||
/*
|
||||
* Access macro to return the number of items in the list.
|
||||
*/
|
||||
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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
|
||||
* function it is therefore possible to move through every item contained in
|
||||
* a list.
|
||||
*
|
||||
* 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 pxOwner parameter effectively creates a two way link between the list
|
||||
* item and its owner.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
||||
{ \
|
||||
List_t * const pxConstList = ( pxList ); \
|
||||
/* 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. */ \
|
||||
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||
if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
|
||||
{ \
|
||||
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||
} \
|
||||
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Access function to obtain the owner of the first entry in a list. Lists
|
||||
* are normally sorted in ascending item value order.
|
||||
*
|
||||
* 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 list item. In the scheduler this is normally a task control block.
|
||||
* The pxOwner parameter effectively creates a two way link between the list
|
||||
* item and its owner.
|
||||
*
|
||||
* @param pxList The list from which the owner of the head item is to be
|
||||
* returned.
|
||||
*
|
||||
* \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#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
|
||||
* "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.
|
||||
*
|
||||
* @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.
|
||||
* @return pdTRUE if the list item is in the list, otherwise pdFALSE.
|
||||
*/
|
||||
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) )
|
||||
|
||||
/*
|
||||
* Return the list a list item is contained within (referenced from).
|
||||
*
|
||||
* @param pxListItem The list item being queried.
|
||||
* @return A pointer to the List_t object that references the pxListItem
|
||||
*/
|
||||
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer )
|
||||
|
||||
/*
|
||||
* 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()
|
||||
* function.
|
||||
*/
|
||||
#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )
|
||||
|
||||
/*
|
||||
* 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
|
||||
* marker to the back of the list.
|
||||
*
|
||||
* @param pxList Pointer to the list being initialised.
|
||||
*
|
||||
* \page vListInitialise vListInitialise
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* @param pxItem Pointer to the list item being initialised.
|
||||
*
|
||||
* \page vListInitialiseItem vListInitialiseItem
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* 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).
|
||||
*
|
||||
* @param pxList The list into which the item is to be inserted.
|
||||
*
|
||||
* @param pxNewListItem The item that is to be placed in the list.
|
||||
*
|
||||
* \page vListInsert vListInsert
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Insert a list item into a list. The item will be inserted in a position
|
||||
* such that it will be the last item within the list returned by multiple
|
||||
* calls to listGET_OWNER_OF_NEXT_ENTRY.
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
|
||||
* the pxIndex parameter again points to the item being inserted.
|
||||
*
|
||||
* @param pxList The list into which the item is to be inserted.
|
||||
*
|
||||
* @param pxNewListItem The list item to be inserted into the list.
|
||||
*
|
||||
* \page vListInsertEnd vListInsertEnd
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Remove an item from a list. The list item has a pointer to the list that
|
||||
* 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
|
||||
* the list pointed to by it's pxContainer parameter.
|
||||
*
|
||||
* @return The number of items that remain in the list after the list item has
|
||||
* been removed.
|
||||
*
|
||||
* \page uxListRemove uxListRemove
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,799 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Message buffers build functionality on top of FreeRTOS stream buffers.
|
||||
* Whereas stream buffers are used to send a continuous stream of data from one
|
||||
* task or interrupt to another, message buffers are used to send variable
|
||||
* length discrete messages from one task or interrupt to another. Their
|
||||
* implementation is light weight, making them particularly suited for interrupt
|
||||
* to task and core to core communication scenarios.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* timeout to 0.
|
||||
*
|
||||
* Message buffers hold variable length messages. To enable that, when a
|
||||
* message is written to the message buffer an additional sizeof( size_t ) bytes
|
||||
* are also written to store the message's length (that happens internally, with
|
||||
* the API function). sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||
* architecture, so writing a 10 byte message to a message buffer on a 32-bit
|
||||
* architecture will actually reduce the available space in the message buffer
|
||||
* by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length
|
||||
* of the message).
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_MESSAGE_BUFFER_H
|
||||
#define FREERTOS_MESSAGE_BUFFER_H
|
||||
|
||||
/* Message buffers are built onto of stream buffers. */
|
||||
#include "stream_buffer.h"
|
||||
|
||||
#if defined( __cplusplus )
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Type by which message buffers are referenced. For example, a call to
|
||||
* xMessageBufferCreate() returns an MessageBufferHandle_t variable that can
|
||||
* then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(),
|
||||
* etc.
|
||||
*/
|
||||
typedef void * MessageBufferHandle_t;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
|
||||
</pre>
|
||||
*
|
||||
* Creates a new message buffer using dynamically allocated memory. See
|
||||
* xMessageBufferCreateStatic() for a version that uses statically allocated
|
||||
* memory (memory that is allocated at compile time).
|
||||
*
|
||||
* configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in
|
||||
* FreeRTOSConfig.h for xMessageBufferCreate() to be available.
|
||||
*
|
||||
* @param xBufferSizeBytes The total number of bytes (not messages) the message
|
||||
* buffer will be able to hold at any one time. When a message is written to
|
||||
* the message buffer an additional sizeof( size_t ) bytes are also written to
|
||||
* store the message's length. sizeof( size_t ) is typically 4 bytes on a
|
||||
* 32-bit architecture, so on most 32-bit architectures a 10 byte message will
|
||||
* take up 14 bytes of message buffer space.
|
||||
*
|
||||
* @return If NULL is returned, then the message buffer cannot be created
|
||||
* because there is insufficient heap memory available for FreeRTOS to allocate
|
||||
* the message buffer data structures and storage area. A non-NULL value being
|
||||
* returned indicates that the message buffer has been created successfully -
|
||||
* the returned value should be stored as the handle to the created message
|
||||
* buffer.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
|
||||
void vAFunction( void )
|
||||
{
|
||||
MessageBufferHandle_t xMessageBuffer;
|
||||
const size_t xMessageBufferSizeBytes = 100;
|
||||
|
||||
// Create a message buffer that can hold 100 bytes. The memory used to hold
|
||||
// both the message buffer structure and the messages themselves is allocated
|
||||
// dynamically. Each message added to the buffer consumes an additional 4
|
||||
// bytes which are used to hold the lengh of the message.
|
||||
xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
|
||||
|
||||
if( xMessageBuffer == NULL )
|
||||
{
|
||||
// There was not enough heap memory space available to create the
|
||||
// message buffer.
|
||||
}
|
||||
else
|
||||
{
|
||||
// The message buffer was created successfully and can now be used.
|
||||
}
|
||||
|
||||
</pre>
|
||||
* \defgroup xMessageBufferCreate xMessageBufferCreate
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferCreate( xBufferSizeBytes ) ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
|
||||
uint8_t *pucMessageBufferStorageArea,
|
||||
StaticMessageBuffer_t *pxStaticMessageBuffer );
|
||||
</pre>
|
||||
* Creates a new message buffer using statically allocated memory. See
|
||||
* xMessageBufferCreate() for a version that uses dynamically allocated memory.
|
||||
*
|
||||
* @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the
|
||||
* pucMessageBufferStorageArea parameter. When a message is written to the
|
||||
* message buffer an additional sizeof( size_t ) bytes are also written to store
|
||||
* the message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||
* architecture, so on most 32-bit architecture a 10 byte message will take up
|
||||
* 14 bytes of message buffer space. The maximum number of bytes that can be
|
||||
* stored in the message buffer is actually (xBufferSizeBytes - 1).
|
||||
*
|
||||
* @param pucMessageBufferStorageArea Must point to a uint8_t array that is at
|
||||
* least xBufferSizeBytes + 1 big. This is the array to which messages are
|
||||
* copied when they are written to the message buffer.
|
||||
*
|
||||
* @param pxStaticMessageBuffer Must point to a variable of type
|
||||
* StaticMessageBuffer_t, which will be used to hold the message buffer's data
|
||||
* structure.
|
||||
*
|
||||
* @return If the message buffer is created successfully then a handle to the
|
||||
* created message buffer is returned. If either pucMessageBufferStorageArea or
|
||||
* pxStaticmessageBuffer are NULL then NULL is returned.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
|
||||
// Used to dimension the array used to hold the messages. The available space
|
||||
// will actually be one less than this, so 999.
|
||||
#define STORAGE_SIZE_BYTES 1000
|
||||
|
||||
// Defines the memory that will actually hold the messages within the message
|
||||
// buffer.
|
||||
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
|
||||
|
||||
// The variable used to hold the message buffer structure.
|
||||
StaticMessageBuffer_t xMessageBufferStruct;
|
||||
|
||||
void MyFunction( void )
|
||||
{
|
||||
MessageBufferHandle_t xMessageBuffer;
|
||||
|
||||
xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ),
|
||||
ucBufferStorage,
|
||||
&xMessageBufferStruct );
|
||||
|
||||
// As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
|
||||
// parameters were NULL, xMessageBuffer will not be NULL, and can be used to
|
||||
// reference the created message buffer in other message buffer API calls.
|
||||
|
||||
// Other code that uses the message buffer can go here.
|
||||
}
|
||||
|
||||
</pre>
|
||||
* \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
TickType_t xTicksToWait );
|
||||
<pre>
|
||||
*
|
||||
* Sends a discrete message to the message buffer. The message can be any
|
||||
* length that fits within the buffer's free space, and is copied into the
|
||||
* buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xMessageBufferSend() to write to a message buffer from a task. Use
|
||||
* xMessageBufferSendFromISR() to write to a message buffer from an interrupt
|
||||
* service routine (ISR).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer to which a message is
|
||||
* being sent.
|
||||
*
|
||||
* @param pvTxData A pointer to the message that is to be copied into the
|
||||
* message buffer.
|
||||
*
|
||||
* @param xDataLengthBytes The length of the message. That is, the number of
|
||||
* bytes to copy from pvTxData into the message buffer. When a message is
|
||||
* written to the message buffer an additional sizeof( size_t ) bytes are also
|
||||
* written to store the message's length. sizeof( size_t ) is typically 4 bytes
|
||||
* on a 32-bit architecture, so on most 32-bit architecture setting
|
||||
* xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
|
||||
* bytes (20 bytes of message data and 4 bytes to hold the message length).
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the calling task should remain
|
||||
* in the Blocked state to wait for enough space to become available in the
|
||||
* message buffer, should the message buffer have insufficient space when
|
||||
* xMessageBufferSend() is called. The calling task will never block if
|
||||
* xTicksToWait is zero. The block time is specified in tick periods, so the
|
||||
* absolute time it represents is dependent on the tick frequency. The macro
|
||||
* pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into
|
||||
* a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will cause
|
||||
* the task to wait indefinitely (without timing out), provided
|
||||
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||
* CPU time when they are in the Blocked state.
|
||||
*
|
||||
* @return The number of bytes written to the message buffer. If the call to
|
||||
* xMessageBufferSend() times out before there was enough space to write the
|
||||
* message into the message buffer then zero is returned. If the call did not
|
||||
* time out then xDataLengthBytes is returned.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
void vAFunction( MessageBufferHandle_t xMessageBuffer )
|
||||
{
|
||||
size_t xBytesSent;
|
||||
uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
|
||||
char *pcStringToSend = "String to send";
|
||||
const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
||||
|
||||
// Send an array to the message buffer, blocking for a maximum of 100ms to
|
||||
// wait for enough space to be available in the message buffer.
|
||||
xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
|
||||
|
||||
if( xBytesSent != sizeof( ucArrayToSend ) )
|
||||
{
|
||||
// The call to xMessageBufferSend() times out before there was enough
|
||||
// space in the buffer for the data to be written.
|
||||
}
|
||||
|
||||
// Send the string to the message buffer. Return immediately if there is
|
||||
// not enough space in the buffer.
|
||||
xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
|
||||
|
||||
if( xBytesSent != strlen( pcStringToSend ) )
|
||||
{
|
||||
// The string could not be added to the message buffer because there was
|
||||
// not enough free space in the buffer.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xMessageBufferSend xMessageBufferSend
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
BaseType_t *pxHigherPriorityTaskWoken );
|
||||
<pre>
|
||||
*
|
||||
* Interrupt safe version of the API function that sends a discrete message to
|
||||
* the message buffer. The message can be any length that fits within the
|
||||
* buffer's free space, and is copied into the buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xMessageBufferSend() to write to a message buffer from a task. Use
|
||||
* xMessageBufferSendFromISR() to write to a message buffer from an interrupt
|
||||
* service routine (ISR).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer to which a message is
|
||||
* being sent.
|
||||
*
|
||||
* @param pvTxData A pointer to the message that is to be copied into the
|
||||
* message buffer.
|
||||
*
|
||||
* @param xDataLengthBytes The length of the message. That is, the number of
|
||||
* bytes to copy from pvTxData into the message buffer. When a message is
|
||||
* written to the message buffer an additional sizeof( size_t ) bytes are also
|
||||
* written to store the message's length. sizeof( size_t ) is typically 4 bytes
|
||||
* on a 32-bit architecture, so on most 32-bit architecture setting
|
||||
* xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
|
||||
* bytes (20 bytes of message data and 4 bytes to hold the message length).
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken It is possible that a message buffer will
|
||||
* have a task blocked on it waiting for data. Calling
|
||||
* xMessageBufferSendFromISR() can make data available, and so cause a task that
|
||||
* was waiting for data to leave the Blocked state. If calling
|
||||
* xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the
|
||||
* unblocked task has a priority higher than the currently executing task (the
|
||||
* task that was interrupted), then, internally, xMessageBufferSendFromISR()
|
||||
* will set *pxHigherPriorityTaskWoken to pdTRUE. If
|
||||
* xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a
|
||||
* context switch should be performed before the interrupt is exited. This will
|
||||
* ensure that the interrupt returns directly to the highest priority Ready
|
||||
* state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it
|
||||
* is passed into the function. See the code example below for an example.
|
||||
*
|
||||
* @return The number of bytes actually written to the message buffer. If the
|
||||
* message buffer didn't have enough free space for the message to be stored
|
||||
* then 0 is returned, otherwise xDataLengthBytes is returned.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
// A message buffer that has already been created.
|
||||
MessageBufferHandle_t xMessageBuffer;
|
||||
|
||||
void vAnInterruptServiceRoutine( void )
|
||||
{
|
||||
size_t xBytesSent;
|
||||
char *pcStringToSend = "String to send";
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
|
||||
// Attempt to send the string to the message buffer.
|
||||
xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
|
||||
( void * ) pcStringToSend,
|
||||
strlen( pcStringToSend ),
|
||||
&xHigherPriorityTaskWoken );
|
||||
|
||||
if( xBytesSent != strlen( pcStringToSend ) )
|
||||
{
|
||||
// The string could not be added to the message buffer because there was
|
||||
// not enough free space in the buffer.
|
||||
}
|
||||
|
||||
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||
// xMessageBufferSendFromISR() then a task that has a priority above the
|
||||
// priority of the currently executing task was unblocked and a context
|
||||
// switch should be performed to ensure the ISR returns to the unblocked
|
||||
// task. In most FreeRTOS ports this is done by simply passing
|
||||
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||
// variables value, and perform the context switch if necessary. Check the
|
||||
// documentation for the port in use for port specific instructions.
|
||||
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
TickType_t xTicksToWait );
|
||||
</pre>
|
||||
*
|
||||
* Receives a discrete message from a message buffer. Messages can be of
|
||||
* variable length and are copied out of the buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xMessageBufferReceive() to read from a message buffer from a task. Use
|
||||
* xMessageBufferReceiveFromISR() to read from a message buffer from an
|
||||
* interrupt service routine (ISR).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer from which a message
|
||||
* is being received.
|
||||
*
|
||||
* @param pvRxData A pointer to the buffer into which the received message is
|
||||
* to be copied.
|
||||
*
|
||||
* @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
|
||||
* parameter. This sets the maximum length of the message that can be received.
|
||||
* If xBufferLengthBytes is too small to hold the next message then the message
|
||||
* will be left in the message buffer and 0 will be returned.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the task should remain in the
|
||||
* Blocked state to wait for a message, should the message buffer be empty.
|
||||
* xMessageBufferReceive() will return immediately if xTicksToWait is zero and
|
||||
* the message buffer is empty. The block time is specified in tick periods, so
|
||||
* the absolute time it represents is dependent on the tick frequency. The
|
||||
* macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
|
||||
* into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will
|
||||
* cause the task to wait indefinitely (without timing out), provided
|
||||
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||
* CPU time when they are in the Blocked state.
|
||||
*
|
||||
* @return The length, in bytes, of the message read from the message buffer, if
|
||||
* any. If xMessageBufferReceive() times out before a message became available
|
||||
* then zero is returned. If the length of the message is greater than
|
||||
* xBufferLengthBytes then the message will be left in the message buffer and
|
||||
* zero is returned.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
void vAFunction( MessageBuffer_t xMessageBuffer )
|
||||
{
|
||||
uint8_t ucRxData[ 20 ];
|
||||
size_t xReceivedBytes;
|
||||
const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
||||
|
||||
// Receive the next message from the message buffer. Wait in the Blocked
|
||||
// state (so not using any CPU processing time) for a maximum of 100ms for
|
||||
// a message to become available.
|
||||
xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
|
||||
( void * ) ucRxData,
|
||||
sizeof( ucRxData ),
|
||||
xBlockTime );
|
||||
|
||||
if( xReceivedBytes > 0 )
|
||||
{
|
||||
// A ucRxData contains a message that is xReceivedBytes long. Process
|
||||
// the message here....
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xMessageBufferReceive xMessageBufferReceive
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) xStreamBufferReceive( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait )
|
||||
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* An interrupt safe version of the API function that receives a discrete
|
||||
* message from a message buffer. Messages can be of variable length and are
|
||||
* copied out of the buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xMessageBufferReceive() to read from a message buffer from a task. Use
|
||||
* xMessageBufferReceiveFromISR() to read from a message buffer from an
|
||||
* interrupt service routine (ISR).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer from which a message
|
||||
* is being received.
|
||||
*
|
||||
* @param pvRxData A pointer to the buffer into which the received message is
|
||||
* to be copied.
|
||||
*
|
||||
* @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
|
||||
* parameter. This sets the maximum length of the message that can be received.
|
||||
* If xBufferLengthBytes is too small to hold the next message then the message
|
||||
* will be left in the message buffer and 0 will be returned.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken It is possible that a message buffer will
|
||||
* have a task blocked on it waiting for space to become available. Calling
|
||||
* xMessageBufferReceiveFromISR() can make space available, and so cause a task
|
||||
* that is waiting for space to leave the Blocked state. If calling
|
||||
* xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and
|
||||
* the unblocked task has a priority higher than the currently executing task
|
||||
* (the task that was interrupted), then, internally,
|
||||
* xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE.
|
||||
* If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a
|
||||
* context switch should be performed before the interrupt is exited. That will
|
||||
* ensure the interrupt returns directly to the highest priority Ready state
|
||||
* task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is
|
||||
* passed into the function. See the code example below for an example.
|
||||
*
|
||||
* @return The length, in bytes, of the message read from the message buffer, if
|
||||
* any.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
// A message buffer that has already been created.
|
||||
MessageBuffer_t xMessageBuffer;
|
||||
|
||||
void vAnInterruptServiceRoutine( void )
|
||||
{
|
||||
uint8_t ucRxData[ 20 ];
|
||||
size_t xReceivedBytes;
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
|
||||
// Receive the next message from the message buffer.
|
||||
xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
|
||||
( void * ) ucRxData,
|
||||
sizeof( ucRxData ),
|
||||
&xHigherPriorityTaskWoken );
|
||||
|
||||
if( xReceivedBytes > 0 )
|
||||
{
|
||||
// A ucRxData contains a message that is xReceivedBytes long. Process
|
||||
// the message here....
|
||||
}
|
||||
|
||||
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||
// xMessageBufferReceiveFromISR() then a task that has a priority above the
|
||||
// priority of the currently executing task was unblocked and a context
|
||||
// switch should be performed to ensure the ISR returns to the unblocked
|
||||
// task. In most FreeRTOS ports this is done by simply passing
|
||||
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||
// variables value, and perform the context switch if necessary. Check the
|
||||
// documentation for the port in use for port specific instructions.
|
||||
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Deletes a message buffer that was previously created using a call to
|
||||
* xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message
|
||||
* buffer was created using dynamic memory (that is, by xMessageBufferCreate()),
|
||||
* then the allocated memory is freed.
|
||||
*
|
||||
* A message buffer handle must not be used after the message buffer has been
|
||||
* deleted.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer to be deleted.
|
||||
*
|
||||
*/
|
||||
#define vMessageBufferDelete( xMessageBuffer ) vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
|
||||
</pre>
|
||||
*
|
||||
* Tests to see if a message buffer is full. A message buffer is full if it
|
||||
* cannot accept any more messages, of any size, until space is made available
|
||||
* by a message being removed from the message buffer.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||
*
|
||||
* @return If the message buffer referenced by xMessageBuffer is full then
|
||||
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
||||
*/
|
||||
#define xMessageBufferIsFull( xMessageBuffer ) xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
|
||||
</pre>
|
||||
*
|
||||
* Tests to see if a message buffer is empty (does not contain any messages).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||
*
|
||||
* @return If the message buffer referenced by xMessageBuffer is empty then
|
||||
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
||||
*
|
||||
*/
|
||||
#define xMessageBufferIsEmpty( xMessageBuffer ) xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Resets a message buffer to its initial empty state, discarding any message it
|
||||
* contained.
|
||||
*
|
||||
* A message buffer can only be reset if there are no tasks blocked on it.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being reset.
|
||||
*
|
||||
* @return If the message buffer was reset then pdPASS is returned. If the
|
||||
* message buffer could not be reset because either there was a task blocked on
|
||||
* the message queue to wait for space to become available, or to wait for a
|
||||
* a message to be available, then pdFAIL is returned.
|
||||
*
|
||||
* \defgroup xMessageBufferReset xMessageBufferReset
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferReset( xMessageBuffer ) xStreamBufferReset( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
|
||||
</pre>
|
||||
* Returns the number of bytes of free space in the message buffer.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||
*
|
||||
* @return The number of bytes that can be written to the message buffer before
|
||||
* the message buffer would be full. When a message is written to the message
|
||||
* buffer an additional sizeof( size_t ) bytes are also written to store the
|
||||
* message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||
* architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size
|
||||
* of the largest message that can be written to the message buffer is 6 bytes.
|
||||
*
|
||||
* \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||
#define xMessageBufferSpacesAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) /* Corrects typo in original macro name. */
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) );
|
||||
</pre>
|
||||
* Returns the length (in bytes) of the next message in a message buffer.
|
||||
* Useful if xMessageBufferReceive() returned 0 because the size of the buffer
|
||||
* passed into xMessageBufferReceive() was too small to hold the next message.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||
*
|
||||
* @return The length (in bytes) of the next message in the message buffer, or 0
|
||||
* if the message buffer is empty.
|
||||
*
|
||||
* \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
* The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||
* data is sent to a message buffer or stream buffer. If there was a task that
|
||||
* was blocked on the message or stream buffer waiting for data to arrive then
|
||||
* the sbSEND_COMPLETED() macro sends a notification to the task to remove it
|
||||
* from the Blocked state. xMessageBufferSendCompletedFromISR() does the same
|
||||
* thing. It is provided to enable application writers to implement their own
|
||||
* version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME.
|
||||
*
|
||||
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||
* additional information.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to which data was
|
||||
* written.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||
* initialised to pdFALSE before it is passed into
|
||||
* xMessageBufferSendCompletedFromISR(). If calling
|
||||
* xMessageBufferSendCompletedFromISR() removes a task from the Blocked state,
|
||||
* and the task has a priority above the priority of the currently running task,
|
||||
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||
* context switch should be performed before exiting the ISR.
|
||||
*
|
||||
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||
* Otherwise pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
* The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||
* data is read out of a message buffer or stream buffer. If there was a task
|
||||
* that was blocked on the message or stream buffer waiting for data to arrive
|
||||
* then the sbRECEIVE_COMPLETED() macro sends a notification to the task to
|
||||
* remove it from the Blocked state. xMessageBufferReceiveCompletedFromISR()
|
||||
* does the same thing. It is provided to enable application writers to
|
||||
* implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT
|
||||
* ANY OTHER TIME.
|
||||
*
|
||||
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||
* additional information.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer from which data was
|
||||
* read.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||
* initialised to pdFALSE before it is passed into
|
||||
* xMessageBufferReceiveCompletedFromISR(). If calling
|
||||
* xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state,
|
||||
* and the task has a priority above the priority of the currently running task,
|
||||
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||
* context switch should be performed before exiting the ISR.
|
||||
*
|
||||
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||
* Otherwise pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferReceiveCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken )
|
||||
|
||||
#if defined( __cplusplus )
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */
|
@ -1,157 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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,
|
||||
* so the kernel code always runs will full privileges.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MPU_PROTOTYPES_H
|
||||
#define MPU_PROTOTYPES_H
|
||||
|
||||
/* MPU versions of tasks.h API functions. */
|
||||
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL;
|
||||
TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL;
|
||||
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) FREERTOS_SYSTEM_CALL;
|
||||
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL;
|
||||
TickType_t MPU_xTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of queue.h API functions. */
|
||||
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxQueueSpacesAvailable( const 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_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
||||
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
|
||||
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of timers.h API functions. */
|
||||
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL;
|
||||
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL;
|
||||
TickType_t MPU_xTimerGetPeriod( 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_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of event_group.h API functions. */
|
||||
EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL;
|
||||
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL;
|
||||
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL;
|
||||
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of message/stream_buffer.h API functions. */
|
||||
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vStreamBufferDelete( 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_xStreamBufferReset( 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;
|
||||
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL;
|
||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
|
||||
|
||||
#endif /* MPU_PROTOTYPES_H */
|
||||
|
@ -1,186 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef MPU_WRAPPERS_H
|
||||
#define MPU_WRAPPERS_H
|
||||
|
||||
/* This file redefines API functions to be called through a wrapper macro, but
|
||||
only for ports that are using the MPU. */
|
||||
#ifdef portUSING_MPU_WRAPPERS
|
||||
|
||||
/* 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
|
||||
those files. */
|
||||
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/*
|
||||
* Map standard (non MPU) API functions to equivalents that start
|
||||
* "MPU_". This will cause the application code to call the MPU_
|
||||
* version, which wraps the non-MPU version with privilege promoting
|
||||
* then demoting code, so the kernel code always runs will full
|
||||
* privileges.
|
||||
*/
|
||||
|
||||
/* Map standard tasks.h API functions to the MPU equivalents. */
|
||||
#define xTaskCreate MPU_xTaskCreate
|
||||
#define xTaskCreateStatic MPU_xTaskCreateStatic
|
||||
#define xTaskCreateRestricted MPU_xTaskCreateRestricted
|
||||
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
|
||||
#define vTaskDelete MPU_vTaskDelete
|
||||
#define vTaskDelay MPU_vTaskDelay
|
||||
#define vTaskDelayUntil MPU_vTaskDelayUntil
|
||||
#define xTaskAbortDelay MPU_xTaskAbortDelay
|
||||
#define uxTaskPriorityGet MPU_uxTaskPriorityGet
|
||||
#define eTaskGetState MPU_eTaskGetState
|
||||
#define vTaskGetInfo MPU_vTaskGetInfo
|
||||
#define vTaskPrioritySet MPU_vTaskPrioritySet
|
||||
#define vTaskSuspend MPU_vTaskSuspend
|
||||
#define vTaskResume MPU_vTaskResume
|
||||
#define vTaskSuspendAll MPU_vTaskSuspendAll
|
||||
#define xTaskResumeAll MPU_xTaskResumeAll
|
||||
#define xTaskGetTickCount MPU_xTaskGetTickCount
|
||||
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
|
||||
#define pcTaskGetName MPU_pcTaskGetName
|
||||
#define xTaskGetHandle MPU_xTaskGetHandle
|
||||
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
|
||||
#define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2
|
||||
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
|
||||
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
|
||||
#define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer
|
||||
#define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer
|
||||
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
|
||||
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
|
||||
#define uxTaskGetSystemState MPU_uxTaskGetSystemState
|
||||
#define vTaskList MPU_vTaskList
|
||||
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
|
||||
#define xTaskGetIdleRunTimeCounter MPU_xTaskGetIdleRunTimeCounter
|
||||
#define xTaskGenericNotify MPU_xTaskGenericNotify
|
||||
#define xTaskNotifyWait MPU_xTaskNotifyWait
|
||||
#define ulTaskNotifyTake MPU_ulTaskNotifyTake
|
||||
#define xTaskNotifyStateClear MPU_xTaskNotifyStateClear
|
||||
|
||||
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
|
||||
#define vTaskSetTimeOutState MPU_vTaskSetTimeOutState
|
||||
#define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut
|
||||
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
||||
|
||||
/* Map standard queue.h API functions to the MPU equivalents. */
|
||||
#define xQueueGenericSend MPU_xQueueGenericSend
|
||||
#define xQueueReceive MPU_xQueueReceive
|
||||
#define xQueuePeek MPU_xQueuePeek
|
||||
#define xQueueSemaphoreTake MPU_xQueueSemaphoreTake
|
||||
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
||||
#define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable
|
||||
#define vQueueDelete MPU_vQueueDelete
|
||||
#define xQueueCreateMutex MPU_xQueueCreateMutex
|
||||
#define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic
|
||||
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
|
||||
#define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic
|
||||
#define xQueueGetMutexHolder MPU_xQueueGetMutexHolder
|
||||
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
|
||||
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
|
||||
#define xQueueGenericCreate MPU_xQueueGenericCreate
|
||||
#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic
|
||||
#define xQueueCreateSet MPU_xQueueCreateSet
|
||||
#define xQueueAddToSet MPU_xQueueAddToSet
|
||||
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
|
||||
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
|
||||
#define xQueueGenericReset MPU_xQueueGenericReset
|
||||
|
||||
#if( configQUEUE_REGISTRY_SIZE > 0 )
|
||||
#define vQueueAddToRegistry MPU_vQueueAddToRegistry
|
||||
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
|
||||
#define pcQueueGetName MPU_pcQueueGetName
|
||||
#endif
|
||||
|
||||
/* Map standard timer.h API functions to the MPU equivalents. */
|
||||
#define xTimerCreate MPU_xTimerCreate
|
||||
#define xTimerCreateStatic MPU_xTimerCreateStatic
|
||||
#define pvTimerGetTimerID MPU_pvTimerGetTimerID
|
||||
#define vTimerSetTimerID MPU_vTimerSetTimerID
|
||||
#define xTimerIsTimerActive MPU_xTimerIsTimerActive
|
||||
#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle
|
||||
#define xTimerPendFunctionCall MPU_xTimerPendFunctionCall
|
||||
#define pcTimerGetName MPU_pcTimerGetName
|
||||
#define vTimerSetReloadMode MPU_vTimerSetReloadMode
|
||||
#define xTimerGetPeriod MPU_xTimerGetPeriod
|
||||
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
|
||||
#define xTimerGenericCommand MPU_xTimerGenericCommand
|
||||
|
||||
/* Map standard event_group.h API functions to the MPU equivalents. */
|
||||
#define xEventGroupCreate MPU_xEventGroupCreate
|
||||
#define xEventGroupCreateStatic MPU_xEventGroupCreateStatic
|
||||
#define xEventGroupWaitBits MPU_xEventGroupWaitBits
|
||||
#define xEventGroupClearBits MPU_xEventGroupClearBits
|
||||
#define xEventGroupSetBits MPU_xEventGroupSetBits
|
||||
#define xEventGroupSync MPU_xEventGroupSync
|
||||
#define vEventGroupDelete MPU_vEventGroupDelete
|
||||
|
||||
/* Map standard message/stream_buffer.h API functions to the MPU
|
||||
equivalents. */
|
||||
#define xStreamBufferSend MPU_xStreamBufferSend
|
||||
#define xStreamBufferReceive MPU_xStreamBufferReceive
|
||||
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
|
||||
#define vStreamBufferDelete MPU_vStreamBufferDelete
|
||||
#define xStreamBufferIsFull MPU_xStreamBufferIsFull
|
||||
#define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty
|
||||
#define xStreamBufferReset MPU_xStreamBufferReset
|
||||
#define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable
|
||||
#define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable
|
||||
#define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel
|
||||
#define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate
|
||||
#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic
|
||||
|
||||
|
||||
/* Remove the privileged function macro, but keep the PRIVILEGED_DATA
|
||||
macro so applications can place data in privileged access sections
|
||||
(useful when using statically allocated objects). */
|
||||
#define PRIVILEGED_FUNCTION
|
||||
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
|
||||
#define FREERTOS_SYSTEM_CALL
|
||||
|
||||
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||
|
||||
/* Ensure API functions go in the privileged execution section. */
|
||||
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
|
||||
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
|
||||
#define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls")))
|
||||
|
||||
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||
|
||||
#else /* portUSING_MPU_WRAPPERS */
|
||||
|
||||
#define PRIVILEGED_FUNCTION
|
||||
#define PRIVILEGED_DATA
|
||||
#define FREERTOS_SYSTEM_CALL
|
||||
#define portUSING_MPU_WRAPPERS 0
|
||||
|
||||
#endif /* portUSING_MPU_WRAPPERS */
|
||||
|
||||
|
||||
#endif /* MPU_WRAPPERS_H */
|
||||
|
@ -1,181 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Portable layer API. Each function must be defined for each port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#ifndef PORTABLE_H
|
||||
#define PORTABLE_H
|
||||
|
||||
/* 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
|
||||
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
|
||||
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.
|
||||
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
|
||||
specific constants has been moved into the deprecated_definitions.h header
|
||||
file. */
|
||||
#include "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
|
||||
included here. In this case the path to the correct portmacro.h header file
|
||||
must be set in the compiler's include path. */
|
||||
#ifndef portENTER_CRITICAL
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
#if portBYTE_ALIGNMENT == 32
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x001f )
|
||||
#endif
|
||||
|
||||
#if portBYTE_ALIGNMENT == 16
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x000f )
|
||||
#endif
|
||||
|
||||
#if portBYTE_ALIGNMENT == 8
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||
#endif
|
||||
|
||||
#if portBYTE_ALIGNMENT == 4
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
|
||||
#endif
|
||||
|
||||
#if portBYTE_ALIGNMENT == 2
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
|
||||
#endif
|
||||
|
||||
#if portBYTE_ALIGNMENT == 1
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
|
||||
#endif
|
||||
|
||||
#ifndef portBYTE_ALIGNMENT_MASK
|
||||
#error "Invalid portBYTE_ALIGNMENT definition"
|
||||
#endif
|
||||
|
||||
#ifndef portNUM_CONFIGURABLE_REGIONS
|
||||
#define portNUM_CONFIGURABLE_REGIONS 1
|
||||
#endif
|
||||
|
||||
#ifndef portHAS_STACK_OVERFLOW_CHECKING
|
||||
#define portHAS_STACK_OVERFLOW_CHECKING 0
|
||||
#endif
|
||||
|
||||
#ifndef portARCH_NAME
|
||||
#define portARCH_NAME NULL
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mpu_wrappers.h"
|
||||
|
||||
/*
|
||||
* 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
|
||||
* the order that the port expects to find them.
|
||||
*
|
||||
*/
|
||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||
#if( portHAS_STACK_OVERFLOW_CHECKING == 1 )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
#else
|
||||
#if( portHAS_STACK_OVERFLOW_CHECKING == 1 )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Used by heap_5.c. */
|
||||
typedef struct HeapRegion
|
||||
{
|
||||
uint8_t *pucStartAddress;
|
||||
size_t xSizeInBytes;
|
||||
} HeapRegion_t;
|
||||
|
||||
/*
|
||||
* 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,
|
||||
* queue, semaphore, mutex, software timer, event group, etc. will result in
|
||||
* pvPortMalloc being called.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
/*
|
||||
* Map to the memory management routines required for the port.
|
||||
*/
|
||||
void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
|
||||
void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
|
||||
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
|
||||
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
|
||||
* the hardware is left in its original condition after the scheduler stops
|
||||
* executing.
|
||||
*/
|
||||
void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* The structures and methods of manipulating the MPU are contained within the
|
||||
* port layer.
|
||||
*
|
||||
* Fills the xMPUSettings structure with the memory region information
|
||||
* contained in xRegions.
|
||||
*/
|
||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||
struct xMEMORY_REGION;
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTABLE_H */
|
||||
|
@ -1,124 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PROJDEFS_H
|
||||
#define PROJDEFS_H
|
||||
|
||||
/*
|
||||
* Defines the prototype to which task functions must conform. Defined in this
|
||||
* file to ensure the type is known before portable.h is included.
|
||||
*/
|
||||
typedef void (*TaskFunction_t)( void * );
|
||||
|
||||
/* 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
|
||||
definition here is not suitable for your application. */
|
||||
#ifndef pdMS_TO_TICKS
|
||||
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )
|
||||
#endif
|
||||
|
||||
#define pdFALSE ( ( BaseType_t ) 0 )
|
||||
#define pdTRUE ( ( BaseType_t ) 1 )
|
||||
|
||||
#define pdPASS ( pdTRUE )
|
||||
#define pdFAIL ( pdFALSE )
|
||||
#define errQUEUE_EMPTY ( ( BaseType_t ) 0 )
|
||||
#define errQUEUE_FULL ( ( BaseType_t ) 0 )
|
||||
|
||||
/* FreeRTOS error definitions. */
|
||||
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
|
||||
#define errQUEUE_BLOCKED ( -4 )
|
||||
#define errQUEUE_YIELD ( -5 )
|
||||
|
||||
/* Macros used for basic data corruption checks. */
|
||||
#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES
|
||||
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0
|
||||
#endif
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
#define pdINTEGRITY_CHECK_VALUE 0x5a5a
|
||||
#else
|
||||
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL
|
||||
#endif
|
||||
|
||||
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
|
||||
itself. */
|
||||
#define pdFREERTOS_ERRNO_NONE 0 /* No errors */
|
||||
#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
|
||||
#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */
|
||||
#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */
|
||||
#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */
|
||||
#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */
|
||||
#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */
|
||||
#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */
|
||||
#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */
|
||||
#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */
|
||||
#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */
|
||||
#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */
|
||||
#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */
|
||||
#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */
|
||||
#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */
|
||||
#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */
|
||||
#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */
|
||||
#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */
|
||||
#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */
|
||||
#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */
|
||||
#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */
|
||||
#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */
|
||||
#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */
|
||||
#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */
|
||||
#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */
|
||||
#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */
|
||||
#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_ENOBUFS 105 /* No buffer space available */
|
||||
#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */
|
||||
#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */
|
||||
#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */
|
||||
#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */
|
||||
#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */
|
||||
#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */
|
||||
#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */
|
||||
#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */
|
||||
#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */
|
||||
#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */
|
||||
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
|
||||
|
||||
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS
|
||||
itself. */
|
||||
#define pdFREERTOS_LITTLE_ENDIAN 0
|
||||
#define pdFREERTOS_BIG_ENDIAN 1
|
||||
|
||||
/* Re-defining endian values for generic naming. */
|
||||
#define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN
|
||||
#define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN
|
||||
|
||||
|
||||
#endif /* PROJDEFS_H */
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,129 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef STACK_MACROS_H
|
||||
#define STACK_MACROS_H
|
||||
|
||||
/*
|
||||
* 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
|
||||
* past.
|
||||
*
|
||||
* 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 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
|
||||
* 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
|
||||
* stack will always be recognised.
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||
|
||||
/* Only the current stack state is to be checked. */
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||
|
||||
/* Only the current stack state is to be checked. */
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
\
|
||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
|
||||
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \
|
||||
\
|
||||
if( ( pulStack[ 0 ] != ulCheckValue ) || \
|
||||
( pulStack[ 1 ] != ulCheckValue ) || \
|
||||
( pulStack[ 2 ] != ulCheckValue ) || \
|
||||
( pulStack[ 3 ] != ulCheckValue ) ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
|
||||
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 }; \
|
||||
\
|
||||
\
|
||||
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
|
||||
\
|
||||
/* Has the extremity of the task stack ever been written over? */ \
|
||||
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Remove stack overflow macro if not being used. */
|
||||
#ifndef taskCHECK_FOR_STACK_OVERFLOW
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW()
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* STACK_MACROS_H */
|
||||
|
@ -1,855 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
* Stream buffers are used to send a continuous stream of data from one task or
|
||||
* interrupt to another. Their implementation is light weight, making them
|
||||
* particularly suited for interrupt to task and core to core communication
|
||||
* scenarios.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xStreamBufferRead()) inside a critical section section and set the
|
||||
* receive block time to 0.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STREAM_BUFFER_H
|
||||
#define STREAM_BUFFER_H
|
||||
|
||||
#if defined( __cplusplus )
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Type by which stream buffers are referenced. For example, a call to
|
||||
* xStreamBufferCreate() returns an StreamBufferHandle_t variable that can
|
||||
* then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(),
|
||||
* etc.
|
||||
*/
|
||||
struct StreamBufferDef_t;
|
||||
typedef struct StreamBufferDef_t * StreamBufferHandle_t;
|
||||
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
|
||||
</pre>
|
||||
*
|
||||
* Creates a new stream buffer using dynamically allocated memory. See
|
||||
* xStreamBufferCreateStatic() for a version that uses statically allocated
|
||||
* memory (memory that is allocated at compile time).
|
||||
*
|
||||
* configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in
|
||||
* FreeRTOSConfig.h for xStreamBufferCreate() to be available.
|
||||
*
|
||||
* @param xBufferSizeBytes The total number of bytes the stream buffer will be
|
||||
* able to hold at any one time.
|
||||
*
|
||||
* @param xTriggerLevelBytes The number of bytes that must be in the stream
|
||||
* buffer before a task that is blocked on the stream buffer to wait for data is
|
||||
* moved out of the blocked state. For example, if a task is blocked on a read
|
||||
* of an empty stream buffer that has a trigger level of 1 then the task will be
|
||||
* unblocked when a single byte is written to the buffer or the task's block
|
||||
* time expires. As another example, if a task is blocked on a read of an empty
|
||||
* stream buffer that has a trigger level of 10 then the task will not be
|
||||
* unblocked until the stream buffer contains at least 10 bytes or the task's
|
||||
* block time expires. If a reading task's block time expires before the
|
||||
* trigger level is reached then the task will still receive however many bytes
|
||||
* are actually available. Setting a trigger level of 0 will result in a
|
||||
* trigger level of 1 being used. It is not valid to specify a trigger level
|
||||
* that is greater than the buffer size.
|
||||
*
|
||||
* @return If NULL is returned, then the stream buffer cannot be created
|
||||
* because there is insufficient heap memory available for FreeRTOS to allocate
|
||||
* the stream buffer data structures and storage area. A non-NULL value being
|
||||
* returned indicates that the stream buffer has been created successfully -
|
||||
* the returned value should be stored as the handle to the created stream
|
||||
* buffer.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
|
||||
void vAFunction( void )
|
||||
{
|
||||
StreamBufferHandle_t xStreamBuffer;
|
||||
const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
|
||||
|
||||
// Create a stream buffer that can hold 100 bytes. The memory used to hold
|
||||
// both the stream buffer structure and the data in the stream buffer is
|
||||
// allocated dynamically.
|
||||
xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
|
||||
|
||||
if( xStreamBuffer == NULL )
|
||||
{
|
||||
// There was not enough heap memory space available to create the
|
||||
// stream buffer.
|
||||
}
|
||||
else
|
||||
{
|
||||
// The stream buffer was created successfully and can now be used.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xStreamBufferCreate xStreamBufferCreate
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE )
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
uint8_t *pucStreamBufferStorageArea,
|
||||
StaticStreamBuffer_t *pxStaticStreamBuffer );
|
||||
</pre>
|
||||
* Creates a new stream buffer using statically allocated memory. See
|
||||
* xStreamBufferCreate() for a version that uses dynamically allocated memory.
|
||||
*
|
||||
* configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for
|
||||
* xStreamBufferCreateStatic() to be available.
|
||||
*
|
||||
* @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the
|
||||
* pucStreamBufferStorageArea parameter.
|
||||
*
|
||||
* @param xTriggerLevelBytes The number of bytes that must be in the stream
|
||||
* buffer before a task that is blocked on the stream buffer to wait for data is
|
||||
* moved out of the blocked state. For example, if a task is blocked on a read
|
||||
* of an empty stream buffer that has a trigger level of 1 then the task will be
|
||||
* unblocked when a single byte is written to the buffer or the task's block
|
||||
* time expires. As another example, if a task is blocked on a read of an empty
|
||||
* stream buffer that has a trigger level of 10 then the task will not be
|
||||
* unblocked until the stream buffer contains at least 10 bytes or the task's
|
||||
* block time expires. If a reading task's block time expires before the
|
||||
* trigger level is reached then the task will still receive however many bytes
|
||||
* are actually available. Setting a trigger level of 0 will result in a
|
||||
* trigger level of 1 being used. It is not valid to specify a trigger level
|
||||
* that is greater than the buffer size.
|
||||
*
|
||||
* @param pucStreamBufferStorageArea Must point to a uint8_t array that is at
|
||||
* least xBufferSizeBytes + 1 big. This is the array to which streams are
|
||||
* copied when they are written to the stream buffer.
|
||||
*
|
||||
* @param pxStaticStreamBuffer Must point to a variable of type
|
||||
* StaticStreamBuffer_t, which will be used to hold the stream buffer's data
|
||||
* structure.
|
||||
*
|
||||
* @return If the stream buffer is created successfully then a handle to the
|
||||
* created stream buffer is returned. If either pucStreamBufferStorageArea or
|
||||
* pxStaticstreamBuffer are NULL then NULL is returned.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
|
||||
// Used to dimension the array used to hold the streams. The available space
|
||||
// will actually be one less than this, so 999.
|
||||
#define STORAGE_SIZE_BYTES 1000
|
||||
|
||||
// Defines the memory that will actually hold the streams within the stream
|
||||
// buffer.
|
||||
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
|
||||
|
||||
// The variable used to hold the stream buffer structure.
|
||||
StaticStreamBuffer_t xStreamBufferStruct;
|
||||
|
||||
void MyFunction( void )
|
||||
{
|
||||
StreamBufferHandle_t xStreamBuffer;
|
||||
const size_t xTriggerLevel = 1;
|
||||
|
||||
xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ),
|
||||
xTriggerLevel,
|
||||
ucBufferStorage,
|
||||
&xStreamBufferStruct );
|
||||
|
||||
// As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
|
||||
// parameters were NULL, xStreamBuffer will not be NULL, and can be used to
|
||||
// reference the created stream buffer in other stream buffer API calls.
|
||||
|
||||
// Other code that uses the stream buffer can go here.
|
||||
}
|
||||
|
||||
</pre>
|
||||
* \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer )
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
TickType_t xTicksToWait );
|
||||
</pre>
|
||||
*
|
||||
* Sends bytes to a stream buffer. The bytes are copied into the stream buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xStreamBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xStreamBufferSend() to write to a stream buffer from a task. Use
|
||||
* xStreamBufferSendFromISR() to write to a stream buffer from an interrupt
|
||||
* service routine (ISR).
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to which a stream is
|
||||
* being sent.
|
||||
*
|
||||
* @param pvTxData A pointer to the buffer that holds the bytes to be copied
|
||||
* into the stream buffer.
|
||||
*
|
||||
* @param xDataLengthBytes The maximum number of bytes to copy from pvTxData
|
||||
* into the stream buffer.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the task should remain in the
|
||||
* Blocked state to wait for enough space to become available in the stream
|
||||
* buffer, should the stream buffer contain too little space to hold the
|
||||
* another xDataLengthBytes bytes. The block time is specified in tick periods,
|
||||
* so the absolute time it represents is dependent on the tick frequency. The
|
||||
* macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
|
||||
* into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will
|
||||
* cause the task to wait indefinitely (without timing out), provided
|
||||
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out
|
||||
* before it can write all xDataLengthBytes into the buffer it will still write
|
||||
* as many bytes as possible. A task does not use any CPU time when it is in
|
||||
* the blocked state.
|
||||
*
|
||||
* @return The number of bytes written to the stream buffer. If a task times
|
||||
* out before it can write all xDataLengthBytes into the buffer it will still
|
||||
* write as many bytes as possible.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
void vAFunction( StreamBufferHandle_t xStreamBuffer )
|
||||
{
|
||||
size_t xBytesSent;
|
||||
uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
|
||||
char *pcStringToSend = "String to send";
|
||||
const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
||||
|
||||
// Send an array to the stream buffer, blocking for a maximum of 100ms to
|
||||
// wait for enough space to be available in the stream buffer.
|
||||
xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
|
||||
|
||||
if( xBytesSent != sizeof( ucArrayToSend ) )
|
||||
{
|
||||
// The call to xStreamBufferSend() times out before there was enough
|
||||
// space in the buffer for the data to be written, but it did
|
||||
// successfully write xBytesSent bytes.
|
||||
}
|
||||
|
||||
// Send the string to the stream buffer. Return immediately if there is not
|
||||
// enough space in the buffer.
|
||||
xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
|
||||
|
||||
if( xBytesSent != strlen( pcStringToSend ) )
|
||||
{
|
||||
// The entire string could not be added to the stream buffer because
|
||||
// there was not enough free space in the buffer, but xBytesSent bytes
|
||||
// were sent. Could try again to send the remaining bytes.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xStreamBufferSend xStreamBufferSend
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* Interrupt safe version of the API function that sends a stream of bytes to
|
||||
* the stream buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xStreamBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xStreamBufferSend() to write to a stream buffer from a task. Use
|
||||
* xStreamBufferSendFromISR() to write to a stream buffer from an interrupt
|
||||
* service routine (ISR).
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to which a stream is
|
||||
* being sent.
|
||||
*
|
||||
* @param pvTxData A pointer to the data that is to be copied into the stream
|
||||
* buffer.
|
||||
*
|
||||
* @param xDataLengthBytes The maximum number of bytes to copy from pvTxData
|
||||
* into the stream buffer.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken It is possible that a stream buffer will
|
||||
* have a task blocked on it waiting for data. Calling
|
||||
* xStreamBufferSendFromISR() can make data available, and so cause a task that
|
||||
* was waiting for data to leave the Blocked state. If calling
|
||||
* xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the
|
||||
* unblocked task has a priority higher than the currently executing task (the
|
||||
* task that was interrupted), then, internally, xStreamBufferSendFromISR()
|
||||
* will set *pxHigherPriorityTaskWoken to pdTRUE. If
|
||||
* xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a
|
||||
* context switch should be performed before the interrupt is exited. This will
|
||||
* ensure that the interrupt returns directly to the highest priority Ready
|
||||
* state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it
|
||||
* is passed into the function. See the example code below for an example.
|
||||
*
|
||||
* @return The number of bytes actually written to the stream buffer, which will
|
||||
* be less than xDataLengthBytes if the stream buffer didn't have enough free
|
||||
* space for all the bytes to be written.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
// A stream buffer that has already been created.
|
||||
StreamBufferHandle_t xStreamBuffer;
|
||||
|
||||
void vAnInterruptServiceRoutine( void )
|
||||
{
|
||||
size_t xBytesSent;
|
||||
char *pcStringToSend = "String to send";
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
|
||||
// Attempt to send the string to the stream buffer.
|
||||
xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
|
||||
( void * ) pcStringToSend,
|
||||
strlen( pcStringToSend ),
|
||||
&xHigherPriorityTaskWoken );
|
||||
|
||||
if( xBytesSent != strlen( pcStringToSend ) )
|
||||
{
|
||||
// There was not enough free space in the stream buffer for the entire
|
||||
// string to be written, ut xBytesSent bytes were written.
|
||||
}
|
||||
|
||||
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||
// xStreamBufferSendFromISR() then a task that has a priority above the
|
||||
// priority of the currently executing task was unblocked and a context
|
||||
// switch should be performed to ensure the ISR returns to the unblocked
|
||||
// task. In most FreeRTOS ports this is done by simply passing
|
||||
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||
// variables value, and perform the context switch if necessary. Check the
|
||||
// documentation for the port in use for port specific instructions.
|
||||
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
TickType_t xTicksToWait );
|
||||
</pre>
|
||||
*
|
||||
* Receives bytes from a stream buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xStreamBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xStreamBufferReceive() to read from a stream buffer from a task. Use
|
||||
* xStreamBufferReceiveFromISR() to read from a stream buffer from an
|
||||
* interrupt service routine (ISR).
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer from which bytes are to
|
||||
* be received.
|
||||
*
|
||||
* @param pvRxData A pointer to the buffer into which the received bytes will be
|
||||
* copied.
|
||||
*
|
||||
* @param xBufferLengthBytes The length of the buffer pointed to by the
|
||||
* pvRxData parameter. This sets the maximum number of bytes to receive in one
|
||||
* call. xStreamBufferReceive will return as many bytes as possible up to a
|
||||
* maximum set by xBufferLengthBytes.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the task should remain in the
|
||||
* Blocked state to wait for data to become available if the stream buffer is
|
||||
* empty. xStreamBufferReceive() will return immediately if xTicksToWait is
|
||||
* zero. The block time is specified in tick periods, so the absolute time it
|
||||
* represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can
|
||||
* be used to convert a time specified in milliseconds into a time specified in
|
||||
* ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait
|
||||
* indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1
|
||||
* in FreeRTOSConfig.h. A task does not use any CPU time when it is in the
|
||||
* Blocked state.
|
||||
*
|
||||
* @return The number of bytes actually read from the stream buffer, which will
|
||||
* be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed
|
||||
* out before xBufferLengthBytes were available.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
void vAFunction( StreamBuffer_t xStreamBuffer )
|
||||
{
|
||||
uint8_t ucRxData[ 20 ];
|
||||
size_t xReceivedBytes;
|
||||
const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
||||
|
||||
// Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
|
||||
// Wait in the Blocked state (so not using any CPU processing time) for a
|
||||
// maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
|
||||
// available.
|
||||
xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
|
||||
( void * ) ucRxData,
|
||||
sizeof( ucRxData ),
|
||||
xBlockTime );
|
||||
|
||||
if( xReceivedBytes > 0 )
|
||||
{
|
||||
// A ucRxData contains another xRecievedBytes bytes of data, which can
|
||||
// be processed here....
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xStreamBufferReceive xStreamBufferReceive
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* An interrupt safe version of the API function that receives bytes from a
|
||||
* stream buffer.
|
||||
*
|
||||
* Use xStreamBufferReceive() to read bytes from a stream buffer from a task.
|
||||
* Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an
|
||||
* interrupt service routine (ISR).
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer from which a stream
|
||||
* is being received.
|
||||
*
|
||||
* @param pvRxData A pointer to the buffer into which the received bytes are
|
||||
* copied.
|
||||
*
|
||||
* @param xBufferLengthBytes The length of the buffer pointed to by the
|
||||
* pvRxData parameter. This sets the maximum number of bytes to receive in one
|
||||
* call. xStreamBufferReceive will return as many bytes as possible up to a
|
||||
* maximum set by xBufferLengthBytes.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken It is possible that a stream buffer will
|
||||
* have a task blocked on it waiting for space to become available. Calling
|
||||
* xStreamBufferReceiveFromISR() can make space available, and so cause a task
|
||||
* that is waiting for space to leave the Blocked state. If calling
|
||||
* xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and
|
||||
* the unblocked task has a priority higher than the currently executing task
|
||||
* (the task that was interrupted), then, internally,
|
||||
* xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE.
|
||||
* If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a
|
||||
* context switch should be performed before the interrupt is exited. That will
|
||||
* ensure the interrupt returns directly to the highest priority Ready state
|
||||
* task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is
|
||||
* passed into the function. See the code example below for an example.
|
||||
*
|
||||
* @return The number of bytes read from the stream buffer, if any.
|
||||
*
|
||||
* Example use:
|
||||
<pre>
|
||||
// A stream buffer that has already been created.
|
||||
StreamBuffer_t xStreamBuffer;
|
||||
|
||||
void vAnInterruptServiceRoutine( void )
|
||||
{
|
||||
uint8_t ucRxData[ 20 ];
|
||||
size_t xReceivedBytes;
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
|
||||
// Receive the next stream from the stream buffer.
|
||||
xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
|
||||
( void * ) ucRxData,
|
||||
sizeof( ucRxData ),
|
||||
&xHigherPriorityTaskWoken );
|
||||
|
||||
if( xReceivedBytes > 0 )
|
||||
{
|
||||
// ucRxData contains xReceivedBytes read from the stream buffer.
|
||||
// Process the stream here....
|
||||
}
|
||||
|
||||
// If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||
// xStreamBufferReceiveFromISR() then a task that has a priority above the
|
||||
// priority of the currently executing task was unblocked and a context
|
||||
// switch should be performed to ensure the ISR returns to the unblocked
|
||||
// task. In most FreeRTOS ports this is done by simply passing
|
||||
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
|
||||
// variables value, and perform the context switch if necessary. Check the
|
||||
// documentation for the port in use for port specific instructions.
|
||||
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Deletes a stream buffer that was previously created using a call to
|
||||
* xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream
|
||||
* buffer was created using dynamic memory (that is, by xStreamBufferCreate()),
|
||||
* then the allocated memory is freed.
|
||||
*
|
||||
* A stream buffer handle must not be used after the stream buffer has been
|
||||
* deleted.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to be deleted.
|
||||
*
|
||||
* \defgroup vStreamBufferDelete vStreamBufferDelete
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Queries a stream buffer to see if it is full. A stream buffer is full if it
|
||||
* does not have any free space, and therefore cannot accept any more data.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||
*
|
||||
* @return If the stream buffer is full then pdTRUE is returned. Otherwise
|
||||
* pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferIsFull xStreamBufferIsFull
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Queries a stream buffer to see if it is empty. A stream buffer is empty if
|
||||
* it does not contain any data.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||
*
|
||||
* @return If the stream buffer is empty then pdTRUE is returned. Otherwise
|
||||
* pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Resets a stream buffer to its initial, empty, state. Any data that was in
|
||||
* the stream buffer is discarded. A stream buffer can only be reset if there
|
||||
* are no tasks blocked waiting to either send to or receive from the stream
|
||||
* buffer.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being reset.
|
||||
*
|
||||
* @return If the stream buffer is reset then pdPASS is returned. If there was
|
||||
* a task blocked waiting to send to or read from the stream buffer then the
|
||||
* stream buffer is not reset and pdFAIL is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferReset xStreamBufferReset
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Queries a stream buffer to see how much free space it contains, which is
|
||||
* equal to the amount of data that can be sent to the stream buffer before it
|
||||
* is full.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||
*
|
||||
* @return The number of bytes that can be written to the stream buffer before
|
||||
* the stream buffer would be full.
|
||||
*
|
||||
* \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Queries a stream buffer to see how much data it contains, which is equal to
|
||||
* the number of bytes that can be read from the stream buffer before the stream
|
||||
* buffer would be empty.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||
*
|
||||
* @return The number of bytes that can be read from the stream buffer before
|
||||
* the stream buffer would be empty.
|
||||
*
|
||||
* \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
|
||||
</pre>
|
||||
*
|
||||
* A stream buffer's trigger level is the number of bytes that must be in the
|
||||
* stream buffer before a task that is blocked on the stream buffer to
|
||||
* wait for data is moved out of the blocked state. For example, if a task is
|
||||
* blocked on a read of an empty stream buffer that has a trigger level of 1
|
||||
* then the task will be unblocked when a single byte is written to the buffer
|
||||
* or the task's block time expires. As another example, if a task is blocked
|
||||
* on a read of an empty stream buffer that has a trigger level of 10 then the
|
||||
* task will not be unblocked until the stream buffer contains at least 10 bytes
|
||||
* or the task's block time expires. If a reading task's block time expires
|
||||
* before the trigger level is reached then the task will still receive however
|
||||
* many bytes are actually available. Setting a trigger level of 0 will result
|
||||
* in a trigger level of 1 being used. It is not valid to specify a trigger
|
||||
* level that is greater than the buffer size.
|
||||
*
|
||||
* A trigger level is set when the stream buffer is created, and can be modified
|
||||
* using xStreamBufferSetTriggerLevel().
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being updated.
|
||||
*
|
||||
* @param xTriggerLevel The new trigger level for the stream buffer.
|
||||
*
|
||||
* @return If xTriggerLevel was less than or equal to the stream buffer's length
|
||||
* then the trigger level will be updated and pdTRUE is returned. Otherwise
|
||||
* pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
* The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||
* data is sent to a message buffer or stream buffer. If there was a task that
|
||||
* was blocked on the message or stream buffer waiting for data to arrive then
|
||||
* the sbSEND_COMPLETED() macro sends a notification to the task to remove it
|
||||
* from the Blocked state. xStreamBufferSendCompletedFromISR() does the same
|
||||
* thing. It is provided to enable application writers to implement their own
|
||||
* version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME.
|
||||
*
|
||||
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||
* additional information.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to which data was
|
||||
* written.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||
* initialised to pdFALSE before it is passed into
|
||||
* xStreamBufferSendCompletedFromISR(). If calling
|
||||
* xStreamBufferSendCompletedFromISR() removes a task from the Blocked state,
|
||||
* and the task has a priority above the priority of the currently running task,
|
||||
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||
* context switch should be performed before exiting the ISR.
|
||||
*
|
||||
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||
* Otherwise pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
* The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||
* data is read out of a message buffer or stream buffer. If there was a task
|
||||
* that was blocked on the message or stream buffer waiting for data to arrive
|
||||
* then the sbRECEIVE_COMPLETED() macro sends a notification to the task to
|
||||
* remove it from the Blocked state. xStreamBufferReceiveCompletedFromISR()
|
||||
* does the same thing. It is provided to enable application writers to
|
||||
* implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT
|
||||
* ANY OTHER TIME.
|
||||
*
|
||||
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||
* additional information.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer from which data was
|
||||
* read.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||
* initialised to pdFALSE before it is passed into
|
||||
* xStreamBufferReceiveCompletedFromISR(). If calling
|
||||
* xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state,
|
||||
* and the task has a priority above the priority of the currently running task,
|
||||
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||
* context switch should be performed before exiting the ISR.
|
||||
*
|
||||
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||
* Otherwise pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/* Functions below here are not part of the public API. */
|
||||
StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xIsMessageBuffer,
|
||||
uint8_t * const pucStreamBufferStorageArea,
|
||||
StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#if( configUSE_TRACE_FACILITY == 1 )
|
||||
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
|
||||
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
#if defined( __cplusplus )
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !defined( STREAM_BUFFER_H ) */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,198 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "list.h"
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* PUBLIC LIST API documented in list.h
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
void vListInitialise( List_t * const pxList )
|
||||
{
|
||||
/* 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
|
||||
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. */
|
||||
|
||||
/* The list end value is the highest possible value in the list to
|
||||
ensure it remains at the end of the list. */
|
||||
pxList->xListEnd.xItemValue = portMAX_DELAY;
|
||||
|
||||
/* The list end next and previous pointers point to itself so we know
|
||||
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.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;
|
||||
|
||||
/* Write known values into the list if
|
||||
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
|
||||
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vListInitialiseItem( ListItem_t * const pxItem )
|
||||
{
|
||||
/* Make sure the list item is not recorded as being on a list. */
|
||||
pxItem->pxContainer = NULL;
|
||||
|
||||
/* Write known values into the list item if
|
||||
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
||||
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
|
||||
{
|
||||
ListItem_t * const pxIndex = pxList->pxIndex;
|
||||
|
||||
/* Only effective when configASSERT() is also defined, these tests may catch
|
||||
the list data structures being overwritten in memory. They will not catch
|
||||
data errors caused by incorrect configuration or use of FreeRTOS. */
|
||||
listTEST_LIST_INTEGRITY( pxList );
|
||||
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
||||
|
||||
/* 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
|
||||
listGET_OWNER_OF_NEXT_ENTRY(). */
|
||||
pxNewListItem->pxNext = pxIndex;
|
||||
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
||||
|
||||
/* Only used during decision coverage testing. */
|
||||
mtCOVERAGE_TEST_DELAY();
|
||||
|
||||
pxIndex->pxPrevious->pxNext = pxNewListItem;
|
||||
pxIndex->pxPrevious = pxNewListItem;
|
||||
|
||||
/* Remember which list the item is in. */
|
||||
pxNewListItem->pxContainer = pxList;
|
||||
|
||||
( pxList->uxNumberOfItems )++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
|
||||
{
|
||||
ListItem_t *pxIterator;
|
||||
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||
|
||||
/* Only effective when configASSERT() is also defined, these tests may catch
|
||||
the list data structures being overwritten in memory. They will not catch
|
||||
data errors caused by incorrect configuration or use of FreeRTOS. */
|
||||
listTEST_LIST_INTEGRITY( pxList );
|
||||
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
||||
|
||||
/* 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
|
||||
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
|
||||
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
|
||||
first, and the algorithm slightly modified if necessary. */
|
||||
if( xValueOfInsertion == portMAX_DELAY )
|
||||
{
|
||||
pxIterator = pxList->xListEnd.pxPrevious;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* *** NOTE ***********************************************************
|
||||
If you find your application is crashing here then likely causes are
|
||||
listed below. In addition see https://www.freertos.org/FAQHelp.html for
|
||||
more tips, and ensure configASSERT() is defined!
|
||||
https://www.freertos.org/a00110.html#configASSERT
|
||||
|
||||
1) Stack overflow -
|
||||
see https://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
||||
2) Incorrect interrupt priority assignment, especially on Cortex-M
|
||||
parts where numerically high priority values denote low actual
|
||||
interrupt priorities, which can seem counter intuitive. See
|
||||
https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
|
||||
of configMAX_SYSCALL_INTERRUPT_PRIORITY on
|
||||
https://www.freertos.org/a00110.html
|
||||
3) Calling an API function from within a critical section or when
|
||||
the scheduler is suspended, or calling an API function that does
|
||||
not end in "FromISR" from an interrupt.
|
||||
4) Using a queue or semaphore before it has been initialised or
|
||||
before the scheduler has been started (are interrupts firing
|
||||
before vTaskStartScheduler() has been called?).
|
||||
**********************************************************************/
|
||||
|
||||
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
|
||||
{
|
||||
/* There is nothing to do here, just iterating to the wanted
|
||||
insertion position. */
|
||||
}
|
||||
}
|
||||
|
||||
pxNewListItem->pxNext = pxIterator->pxNext;
|
||||
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
|
||||
pxNewListItem->pxPrevious = pxIterator;
|
||||
pxIterator->pxNext = pxNewListItem;
|
||||
|
||||
/* Remember which list the item is in. This allows fast removal of the
|
||||
item later. */
|
||||
pxNewListItem->pxContainer = pxList;
|
||||
|
||||
( pxList->uxNumberOfItems )++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
||||
{
|
||||
/* The list item knows which list it is in. Obtain the list from the list
|
||||
item. */
|
||||
List_t * const pxList = pxItemToRemove->pxContainer;
|
||||
|
||||
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
||||
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
||||
|
||||
/* Only used during decision coverage testing. */
|
||||
mtCOVERAGE_TEST_DELAY();
|
||||
|
||||
/* Make sure the index is left pointing to a valid item. */
|
||||
if( pxList->pxIndex == pxItemToRemove )
|
||||
{
|
||||
pxList->pxIndex = pxItemToRemove->pxPrevious;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
pxItemToRemove->pxContainer = NULL;
|
||||
( pxList->uxNumberOfItems )--;
|
||||
|
||||
return pxList->uxNumberOfItems;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -1,10 +0,0 @@
|
||||
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
|
||||
FreeRTOS/Source/portable/[compiler]/ARM_CM33_NNN directories prior to each
|
||||
FreeRTOS release.
|
||||
|
||||
If your Cortex-M33 application uses TrustZone then use the files from the
|
||||
FreeRTOS/Source/portable/[compiler]/ARM_CM33 directories.
|
||||
|
||||
If your Cortex-M33 application does not use TrustZone then use the files from
|
||||
the FreeRTOS/Source/portable/[compiler]/ARM_CM33_NTZ directories.
|
@ -1,103 +0,0 @@
|
||||
#/*
|
||||
# * FreeRTOS Kernel V10.2.1
|
||||
# * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
# *
|
||||
# * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# * this software and associated documentation files (the "Software"), to deal in
|
||||
# * the Software without restriction, including without limitation the rights to
|
||||
# * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
# * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
# * subject to the following conditions:
|
||||
# *
|
||||
# * The above copyright notice and this permission notice shall be included in all
|
||||
# * copies or substantial portions of the Software.
|
||||
# *
|
||||
# * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
# * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
# * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
# * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
# *
|
||||
# * http://www.FreeRTOS.org
|
||||
# * http://aws.amazon.com/freertos
|
||||
# *
|
||||
# * 1 tab == 4 spaces!
|
||||
# */
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
||||
_THIS_FILE_DIRECTORY_ = os.path.dirname(os.path.realpath(__file__))
|
||||
_FREERTOS_PORTABLE_DIRECTORY_ = os.path.dirname(_THIS_FILE_DIRECTORY_)
|
||||
|
||||
_COMPILERS_ = ['GCC', 'IAR']
|
||||
_ARCH_NS_ = ['ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ']
|
||||
_ARCH_S_ = ['ARM_CM33', 'ARM_CM23']
|
||||
|
||||
_SUPPORTED_CONFIGS_ = {
|
||||
'GCC' : ['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
|
||||
_SECURE_FILE_PATHS_ = [
|
||||
os.path.join('secure', 'context'),
|
||||
os.path.join('secure', 'context', 'portable', '_COMPILER_ARCH_'),
|
||||
os.path.join('secure', 'heap'),
|
||||
os.path.join('secure', 'init'),
|
||||
os.path.join('secure', 'macros')
|
||||
]
|
||||
|
||||
# Files to be complied in the Non-Secure Project
|
||||
_NONSECURE_FILE_PATHS_ = [
|
||||
'non_secure',
|
||||
os.path.join('non_secure', 'portable', '_COMPILER_ARCH_')
|
||||
]
|
||||
|
||||
|
||||
def is_supported_config(compiler, arch):
|
||||
return arch in _SUPPORTED_CONFIGS_[compiler]
|
||||
|
||||
|
||||
def copy_files_in_dir(src_abs_path, dst_abs_path):
|
||||
for src_file in os.listdir(src_abs_path):
|
||||
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 not os.path.exists(dst_abs_path):
|
||||
os.makedirs(dst_abs_path)
|
||||
print('Copying {}...'.format(os.path.basename(src_file_abs_path)))
|
||||
shutil.copy2(src_file_abs_path, dst_abs_path)
|
||||
|
||||
|
||||
def copy_files_for_compiler_and_arch(compiler, arch, src_paths, dst_path):
|
||||
_COMPILER_ARCH_ = os.path.join(compiler, arch)
|
||||
for src_path in src_paths:
|
||||
src_path_sanitized = src_path.replace('_COMPILER_ARCH_', _COMPILER_ARCH_ )
|
||||
|
||||
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)
|
||||
|
||||
copy_files_in_dir(src_abs_path, dst_abs_path)
|
||||
|
||||
|
||||
def copy_files():
|
||||
# Copy Secure Files
|
||||
for compiler in _COMPILERS_:
|
||||
for arch in _ARCH_S_:
|
||||
if is_supported_config(compiler, arch):
|
||||
copy_files_for_compiler_and_arch(compiler, arch, _SECURE_FILE_PATHS_, 'secure')
|
||||
|
||||
# Copy Non-Secure Files
|
||||
for compiler in _COMPILERS_:
|
||||
for arch in _ARCH_NS_:
|
||||
if is_supported_config(compiler, arch):
|
||||
copy_files_for_compiler_and_arch(compiler, arch, _NONSECURE_FILE_PATHS_, 'non_secure')
|
||||
|
||||
|
||||
def main():
|
||||
copy_files()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,11 +0,0 @@
|
||||
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
|
||||
FreeRTOS/Source/portable/[compiler]/ARM_CM33_NNN directories prior to each
|
||||
FreeRTOS release.
|
||||
|
||||
If your Cortex-M33 application uses TrustZone then use the files from the
|
||||
FreeRTOS/Source/portable/[compiler]/ARM_CM33 directories.
|
||||
|
||||
If your Cortex-M33 application does not use TrustZone then use the files from
|
||||
the FreeRTOS/Source/portable/[compiler]/ARM_CM33_NTZ directories.
|
||||
|
@ -1,899 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||
* all the API functions to use the MPU wrappers. That should only be done when
|
||||
* task.h is included from an application file. */
|
||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* MPU wrappers includes. */
|
||||
#include "mpu_wrappers.h"
|
||||
|
||||
/* Portasm includes. */
|
||||
#include "portasm.h"
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
/* Secure components includes. */
|
||||
#include "secure_context.h"
|
||||
#include "secure_init.h"
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/**
|
||||
* The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only
|
||||
* i.e. the processor boots as secure and never jumps to the non-secure side.
|
||||
* The Trust Zone support in the port must be disabled in order to run FreeRTOS
|
||||
* on the secure side. The following are the valid configuration seetings:
|
||||
*
|
||||
* 1. Run FreeRTOS on the Secure Side:
|
||||
* configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0
|
||||
*
|
||||
* 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support:
|
||||
* configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1
|
||||
*
|
||||
* 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support:
|
||||
* configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0
|
||||
*/
|
||||
#if( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) )
|
||||
#error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side.
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the NVIC.
|
||||
*/
|
||||
#define portNVIC_SYSTICK_CTRL ( ( volatile uint32_t * ) 0xe000e010 )
|
||||
#define portNVIC_SYSTICK_LOAD ( ( volatile uint32_t * ) 0xe000e014 )
|
||||
#define portNVIC_SYSTICK_CURRENT_VALUE ( ( volatile uint32_t * ) 0xe000e018 )
|
||||
#define portNVIC_INT_CTRL ( ( volatile uint32_t * ) 0xe000ed04 )
|
||||
#define portNVIC_SYSPRI2 ( ( volatile uint32_t * ) 0xe000ed20 )
|
||||
#define portNVIC_SYSTICK_CLK ( 0x00000004 )
|
||||
#define portNVIC_SYSTICK_INT ( 0x00000002 )
|
||||
#define portNVIC_SYSTICK_ENABLE ( 0x00000001 )
|
||||
#define portNVIC_PENDSVSET ( 0x10000000 )
|
||||
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
||||
#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( * ( volatile uint32_t * ) 0xe000ed24 )
|
||||
#define portSCB_MEM_FAULT_ENABLE ( 1UL << 16UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the FPU.
|
||||
*/
|
||||
#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */
|
||||
#define portCPACR_CP10_VALUE ( 3UL )
|
||||
#define portCPACR_CP11_VALUE portCPACR_CP10_VALUE
|
||||
#define portCPACR_CP10_POS ( 20UL )
|
||||
#define portCPACR_CP11_POS ( 22UL )
|
||||
|
||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */
|
||||
#define portFPCCR_ASPEN_POS ( 31UL )
|
||||
#define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS )
|
||||
#define portFPCCR_LSPEN_POS ( 30UL )
|
||||
#define portFPCCR_LSPEN_MASK ( 1UL << portFPCCR_LSPEN_POS )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the MPU.
|
||||
*/
|
||||
#define portMPU_TYPE_REG ( * ( ( volatile uint32_t * ) 0xe000ed90 ) )
|
||||
#define portMPU_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed94 ) )
|
||||
#define portMPU_RNR_REG ( * ( ( volatile uint32_t * ) 0xe000ed98 ) )
|
||||
|
||||
#define portMPU_RBAR_REG ( * ( ( volatile uint32_t * ) 0xe000ed9c ) )
|
||||
#define portMPU_RLAR_REG ( * ( ( volatile uint32_t * ) 0xe000eda0 ) )
|
||||
|
||||
#define portMPU_RBAR_A1_REG ( * ( ( volatile uint32_t * ) 0xe000eda4 ) )
|
||||
#define portMPU_RLAR_A1_REG ( * ( ( volatile uint32_t * ) 0xe000eda8 ) )
|
||||
|
||||
#define portMPU_RBAR_A2_REG ( * ( ( volatile uint32_t * ) 0xe000edac ) )
|
||||
#define portMPU_RLAR_A2_REG ( * ( ( volatile uint32_t * ) 0xe000edb0 ) )
|
||||
|
||||
#define portMPU_RBAR_A3_REG ( * ( ( volatile uint32_t * ) 0xe000edb4 ) )
|
||||
#define portMPU_RLAR_A3_REG ( * ( ( volatile uint32_t * ) 0xe000edb8 ) )
|
||||
|
||||
#define portMPU_MAIR0_REG ( * ( ( volatile uint32_t * ) 0xe000edc0 ) )
|
||||
#define portMPU_MAIR1_REG ( * ( ( volatile uint32_t * ) 0xe000edc4 ) )
|
||||
|
||||
#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
||||
#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
|
||||
|
||||
#define portMPU_MAIR_ATTR0_POS ( 0UL )
|
||||
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
|
||||
|
||||
#define portMPU_MAIR_ATTR1_POS ( 8UL )
|
||||
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
|
||||
|
||||
#define portMPU_MAIR_ATTR2_POS ( 16UL )
|
||||
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
|
||||
|
||||
#define portMPU_MAIR_ATTR3_POS ( 24UL )
|
||||
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
|
||||
|
||||
#define portMPU_MAIR_ATTR4_POS ( 0UL )
|
||||
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
|
||||
|
||||
#define portMPU_MAIR_ATTR5_POS ( 8UL )
|
||||
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
|
||||
|
||||
#define portMPU_MAIR_ATTR6_POS ( 16UL )
|
||||
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
|
||||
|
||||
#define portMPU_MAIR_ATTR7_POS ( 24UL )
|
||||
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
|
||||
|
||||
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
|
||||
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
|
||||
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
|
||||
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
|
||||
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
|
||||
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
|
||||
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
|
||||
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL )
|
||||
|
||||
#define portMPU_RLAR_REGION_ENABLE ( 1UL )
|
||||
|
||||
/* Enable privileged access to unmapped region. */
|
||||
#define portMPU_PRIV_BACKGROUND_ENABLE ( 1UL << 2UL )
|
||||
|
||||
/* Enable MPU. */
|
||||
#define portMPU_ENABLE ( 1UL << 0UL )
|
||||
|
||||
/* Expected value of the portMPU_TYPE register. */
|
||||
#define portEXPECTED_MPU_TYPE_VALUE ( 8UL << 8UL ) /* 8 regions, unified. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Constants required to set up the initial stack.
|
||||
*/
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
|
||||
#if( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||
/**
|
||||
* @brief Initial EXC_RETURN value.
|
||||
*
|
||||
* FF FF FF FD
|
||||
* 1111 1111 1111 1111 1111 1111 1111 1101
|
||||
*
|
||||
* Bit[6] - 1 --> The exception was taken from the Secure state.
|
||||
* Bit[5] - 1 --> Do not skip stacking of additional state context.
|
||||
* Bit[4] - 1 --> The PE did not allocate space on the stack for FP context.
|
||||
* Bit[3] - 1 --> Return to the Thread mode.
|
||||
* Bit[2] - 1 --> Restore registers from the process stack.
|
||||
* Bit[1] - 0 --> Reserved, 0.
|
||||
* Bit[0] - 1 --> The exception was taken to the Secure state.
|
||||
*/
|
||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||
#else
|
||||
/**
|
||||
* @brief Initial EXC_RETURN value.
|
||||
*
|
||||
* FF FF FF BC
|
||||
* 1111 1111 1111 1111 1111 1111 1011 1100
|
||||
*
|
||||
* Bit[6] - 0 --> The exception was taken from the Non-Secure state.
|
||||
* Bit[5] - 1 --> Do not skip stacking of additional state context.
|
||||
* Bit[4] - 1 --> The PE did not allocate space on the stack for FP context.
|
||||
* Bit[3] - 1 --> Return to the Thread mode.
|
||||
* Bit[2] - 1 --> Restore registers from the process stack.
|
||||
* Bit[1] - 0 --> Reserved, 0.
|
||||
* Bit[0] - 0 --> The exception was taken to the Non-Secure state.
|
||||
*/
|
||||
#define portINITIAL_EXC_RETURN ( 0xffffffbc )
|
||||
#endif /* configRUN_FREERTOS_SECURE_ONLY */
|
||||
|
||||
/**
|
||||
* @brief CONTROL register privileged bit mask.
|
||||
*
|
||||
* Bit[0] in CONTROL register tells the privilege:
|
||||
* Bit[0] = 0 ==> The task is privileged.
|
||||
* Bit[0] = 1 ==> The task is not privileged.
|
||||
*/
|
||||
#define portCONTROL_PRIVILEGED_MASK ( 1UL << 0UL )
|
||||
|
||||
/**
|
||||
* @brief Initial CONTROL register values.
|
||||
*/
|
||||
#define portINITIAL_CONTROL_UNPRIVILEGED ( 0x3 )
|
||||
#define portINITIAL_CONTROL_PRIVILEGED ( 0x2 )
|
||||
|
||||
/**
|
||||
* @brief Let the user override the pre-loading of the initial LR with the
|
||||
* address of prvTaskExitError() in case it messes up unwinding of the stack
|
||||
* in the debugger.
|
||||
*/
|
||||
#ifdef configTASK_RETURN_ADDRESS
|
||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||
#else
|
||||
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief If portPRELOAD_REGISTERS then registers will be given an initial value
|
||||
* when a task is created. This helps in debugging at the cost of code size.
|
||||
*/
|
||||
#define portPRELOAD_REGISTERS 1
|
||||
|
||||
/**
|
||||
* @brief A task is created without a secure context, and must call
|
||||
* portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes
|
||||
* any secure calls.
|
||||
*/
|
||||
#define portNO_SECURE_CONTEXT 0
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Setup the timer to generate the tick interrupts.
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* @brief Used to catch tasks that attempt to return from their implementing
|
||||
* function.
|
||||
*/
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
/**
|
||||
* @brief Setup the Memory Protection Unit (MPU).
|
||||
*/
|
||||
static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if( configENABLE_FPU == 1 )
|
||||
/**
|
||||
* @brief Setup the Floating Point Unit (FPU).
|
||||
*/
|
||||
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
|
||||
#endif /* configENABLE_FPU */
|
||||
|
||||
/**
|
||||
* @brief Yield the processor.
|
||||
*/
|
||||
void vPortYield( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* @brief Enter critical section.
|
||||
*/
|
||||
void vPortEnterCritical( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* @brief Exit from critical section.
|
||||
*/
|
||||
void vPortExitCritical( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* @brief SysTick handler.
|
||||
*/
|
||||
void SysTick_Handler( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* @brief C part of SVC handler.
|
||||
*/
|
||||
portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVILEGED_FUNCTION;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Each task maintains its own interrupt status in the critical nesting
|
||||
* variable.
|
||||
*/
|
||||
static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
/**
|
||||
* @brief Saved as part of the task context to indicate which context the
|
||||
* task is using on the secure side.
|
||||
*/
|
||||
portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* Stop and reset the SysTick. */
|
||||
*( portNVIC_SYSTICK_CTRL ) = 0UL;
|
||||
*( portNVIC_SYSTICK_CURRENT_VALUE ) = 0UL;
|
||||
|
||||
/* Configure SysTick to interrupt at the requested rate. */
|
||||
*( portNVIC_SYSTICK_LOAD ) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
||||
*( portNVIC_SYSTICK_CTRL ) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvTaskExitError( void )
|
||||
{
|
||||
volatile uint32_t ulDummy = 0UL;
|
||||
|
||||
/* A function that implements a task must not exit or attempt to return to
|
||||
* its caller as there is nothing to return to. If a task wants to exit it
|
||||
* should instead call vTaskDelete( NULL ). Artificially force an assert()
|
||||
* to be triggered if configASSERT() is defined, then stop here so
|
||||
* application writers can catch the error. */
|
||||
configASSERT( ulCriticalNesting == ~0UL );
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
while( ulDummy == 0 )
|
||||
{
|
||||
/* This file calls prvTaskExitError() after the scheduler has been
|
||||
* started to remove a compiler warning about the function being
|
||||
* defined but never called. ulDummy is used purely to quieten other
|
||||
* warnings about code appearing after this function is called - making
|
||||
* ulDummy volatile makes the compiler think the function could return
|
||||
* and therefore not output an 'unreachable code' warning for code that
|
||||
* appears after it. */
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
#if defined( __ARMCC_VERSION )
|
||||
/* Declaration when these variable are defined in code instead of being
|
||||
* exported from linker scripts. */
|
||||
extern uint32_t * __privileged_functions_start__;
|
||||
extern uint32_t * __privileged_functions_end__;
|
||||
extern uint32_t * __syscalls_flash_start__;
|
||||
extern uint32_t * __syscalls_flash_end__;
|
||||
extern uint32_t * __unprivileged_flash_start__;
|
||||
extern uint32_t * __unprivileged_flash_end__;
|
||||
extern uint32_t * __privileged_sram_start__;
|
||||
extern uint32_t * __privileged_sram_end__;
|
||||
#else
|
||||
/* Declaration when these variable are exported from linker scripts. */
|
||||
extern uint32_t __privileged_functions_start__[];
|
||||
extern uint32_t __privileged_functions_end__[];
|
||||
extern uint32_t __syscalls_flash_start__[];
|
||||
extern uint32_t __syscalls_flash_end__[];
|
||||
extern uint32_t __unprivileged_flash_start__[];
|
||||
extern uint32_t __unprivileged_flash_end__[];
|
||||
extern uint32_t __privileged_sram_start__[];
|
||||
extern uint32_t __privileged_sram_end__[];
|
||||
#endif /* defined( __ARMCC_VERSION ) */
|
||||
|
||||
/* Check that the MPU is present. */
|
||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
||||
{
|
||||
/* MAIR0 - Index 0. */
|
||||
portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
||||
/* MAIR0 - Index 1. */
|
||||
portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK );
|
||||
|
||||
/* Setup privileged flash as Read Only so that privileged tasks can
|
||||
* read it but not modify. */
|
||||
portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION;
|
||||
portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) |
|
||||
( portMPU_REGION_NON_SHAREABLE ) |
|
||||
( portMPU_REGION_PRIVILEGED_READ_ONLY );
|
||||
portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) |
|
||||
( portMPU_RLAR_ATTR_INDEX0 ) |
|
||||
( portMPU_RLAR_REGION_ENABLE );
|
||||
|
||||
/* Setup unprivileged flash as Read Only by both privileged and
|
||||
* unprivileged tasks. All tasks can read it but no-one can modify. */
|
||||
portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION;
|
||||
portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) |
|
||||
( portMPU_REGION_NON_SHAREABLE ) |
|
||||
( portMPU_REGION_READ_ONLY );
|
||||
portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) |
|
||||
( portMPU_RLAR_ATTR_INDEX0 ) |
|
||||
( portMPU_RLAR_REGION_ENABLE );
|
||||
|
||||
/* Setup unprivileged syscalls flash as Read Only by both privileged
|
||||
* and unprivileged tasks. All tasks can read it but no-one can modify. */
|
||||
portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION;
|
||||
portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) |
|
||||
( portMPU_REGION_NON_SHAREABLE ) |
|
||||
( portMPU_REGION_READ_ONLY );
|
||||
portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) |
|
||||
( portMPU_RLAR_ATTR_INDEX0 ) |
|
||||
( portMPU_RLAR_REGION_ENABLE );
|
||||
|
||||
/* Setup RAM containing kernel data for privileged access only. */
|
||||
portMPU_RNR_REG = portPRIVILEGED_RAM_REGION;
|
||||
portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) |
|
||||
( portMPU_REGION_NON_SHAREABLE ) |
|
||||
( portMPU_REGION_PRIVILEGED_READ_WRITE ) |
|
||||
( portMPU_REGION_EXECUTE_NEVER );
|
||||
portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) |
|
||||
( portMPU_RLAR_ATTR_INDEX0 ) |
|
||||
( portMPU_RLAR_REGION_ENABLE );
|
||||
|
||||
/* Enable mem fault. */
|
||||
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE;
|
||||
|
||||
/* Enable MPU with privileged background access i.e. unmapped
|
||||
* regions have privileged access. */
|
||||
portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE | portMPU_ENABLE );
|
||||
}
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_FPU == 1 )
|
||||
static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
{
|
||||
/* Enable non-secure access to the FPU. */
|
||||
SecureInit_EnableNSFPUAccess();
|
||||
}
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
/* CP10 = 11 ==> Full access to FPU i.e. both privileged and
|
||||
* unprivileged code should be able to access FPU. CP11 should be
|
||||
* programmed to the same value as CP10. */
|
||||
*( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) |
|
||||
( portCPACR_CP11_VALUE << portCPACR_CP11_POS )
|
||||
);
|
||||
|
||||
/* ASPEN = 1 ==> Hardware should automatically preserve floating point
|
||||
* context on exception entry and restore on exception return.
|
||||
* LSPEN = 1 ==> Enable lazy context save of FP state. */
|
||||
*( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK );
|
||||
}
|
||||
#endif /* configENABLE_FPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortYield( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* Set a PendSV to request a context switch. */
|
||||
*( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET;
|
||||
|
||||
/* Barriers are normally not required but do ensure the code is
|
||||
* completely within the specified behaviour for the architecture. */
|
||||
__asm volatile( "dsb" ::: "memory" );
|
||||
__asm volatile( "isb" );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
ulCriticalNesting++;
|
||||
|
||||
/* Barriers are normally not required but do ensure the code is
|
||||
* completely within the specified behaviour for the architecture. */
|
||||
__asm volatile( "dsb" ::: "memory" );
|
||||
__asm volatile( "isb" );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
configASSERT( ulCriticalNesting );
|
||||
ulCriticalNesting--;
|
||||
|
||||
if( ulCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
uint32_t ulPreviousMask;
|
||||
|
||||
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
/* Increment the RTOS tick. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
/* Pend a context switch. */
|
||||
*( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET;
|
||||
}
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */
|
||||
{
|
||||
#if( configENABLE_MPU == 1 )
|
||||
#if defined( __ARMCC_VERSION )
|
||||
/* Declaration when these variable are defined in code instead of being
|
||||
* exported from linker scripts. */
|
||||
extern uint32_t * __syscalls_flash_start__;
|
||||
extern uint32_t * __syscalls_flash_end__;
|
||||
#else
|
||||
/* Declaration when these variable are exported from linker scripts. */
|
||||
extern uint32_t __syscalls_flash_start__[];
|
||||
extern uint32_t __syscalls_flash_end__[];
|
||||
#endif /* defined( __ARMCC_VERSION ) */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
uint32_t ulPC;
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
uint32_t ulR0;
|
||||
#if( configENABLE_MPU == 1 )
|
||||
uint32_t ulControl, ulIsTaskPrivileged;
|
||||
#endif /* configENABLE_MPU */
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
uint8_t ucSVCNumber;
|
||||
|
||||
/* Register are stored on the stack in the following order - R0, R1, R2, R3,
|
||||
* R12, LR, PC, xPSR. */
|
||||
ulPC = pulCallerStackAddress[ 6 ];
|
||||
ucSVCNumber = ( ( uint8_t *) ulPC )[ -2 ];
|
||||
|
||||
switch( ucSVCNumber )
|
||||
{
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
case portSVC_ALLOCATE_SECURE_CONTEXT:
|
||||
{
|
||||
/* R0 contains the stack size passed as parameter to the
|
||||
* vPortAllocateSecureContext function. */
|
||||
ulR0 = pulCallerStackAddress[ 0 ];
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Read the CONTROL register value. */
|
||||
__asm volatile ( "mrs %0, control" : "=r" ( ulControl ) );
|
||||
|
||||
/* The task that raised the SVC is privileged if Bit[0]
|
||||
* in the CONTROL register is 0. */
|
||||
ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 );
|
||||
|
||||
/* Allocate and load a context for the secure task. */
|
||||
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* Allocate and load a context for the secure task. */
|
||||
xSecureContext = SecureContext_AllocateContext( ulR0 );
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
configASSERT( xSecureContext != NULL );
|
||||
SecureContext_LoadContext( xSecureContext );
|
||||
}
|
||||
break;
|
||||
|
||||
case portSVC_FREE_SECURE_CONTEXT:
|
||||
{
|
||||
/* R0 contains the secure context handle to be freed. */
|
||||
ulR0 = pulCallerStackAddress[ 0 ];
|
||||
|
||||
/* Free the secure context. */
|
||||
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 );
|
||||
}
|
||||
break;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
case portSVC_START_SCHEDULER:
|
||||
{
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
{
|
||||
/* De-prioritize the non-secure exceptions so that the
|
||||
* non-secure pendSV runs at the lowest priority. */
|
||||
SecureInit_DePrioritizeNSExceptions();
|
||||
|
||||
/* Initialize the secure context management system. */
|
||||
SecureContext_Init();
|
||||
}
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if( configENABLE_FPU == 1 )
|
||||
{
|
||||
/* Setup the Floating Point Unit (FPU). */
|
||||
prvSetupFPU();
|
||||
}
|
||||
#endif /* configENABLE_FPU */
|
||||
|
||||
/* Setup the context of the first task so that the first task starts
|
||||
* executing. */
|
||||
vRestoreContextOfFirstTask();
|
||||
}
|
||||
break;
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
case portSVC_RAISE_PRIVILEGE:
|
||||
{
|
||||
/* Only raise the privilege, if the svc was raised from any of
|
||||
* the system calls. */
|
||||
if( ulPC >= ( uint32_t ) __syscalls_flash_start__ &&
|
||||
ulPC <= ( uint32_t ) __syscalls_flash_end__ )
|
||||
{
|
||||
vRaisePrivilege();
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
default:
|
||||
{
|
||||
/* Incorrect SVC call. */
|
||||
configASSERT( pdFALSE );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */
|
||||
#else
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) /* PRIVILEGED_FUNCTION */
|
||||
#endif /* configENABLE_MPU */
|
||||
{
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
* interrupt. */
|
||||
#if( portPRELOAD_REGISTERS == 0 )
|
||||
{
|
||||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxCode; /* PC */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */
|
||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */
|
||||
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
if( xRunPrivileged == pdTRUE )
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
}
|
||||
else
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
}
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
||||
}
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
}
|
||||
#else /* portPRELOAD_REGISTERS */
|
||||
{
|
||||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxCode; /* PC */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN */
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
if( xRunPrivileged == pdTRUE )
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
}
|
||||
else
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_UNPRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
}
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
|
||||
}
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
}
|
||||
#endif /* portPRELOAD_REGISTERS */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
*( portNVIC_SYSPRI2 ) |= portNVIC_PENDSV_PRI;
|
||||
*( portNVIC_SYSPRI2 ) |= portNVIC_SYSTICK_PRI;
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Setup the Memory Protection Unit (MPU). */
|
||||
prvSetupMPU();
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
* here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Initialize the critical nesting count ready for the first task. */
|
||||
ulCriticalNesting = 0;
|
||||
|
||||
/* Start the first task. */
|
||||
vStartFirstTask();
|
||||
|
||||
/* Should never get here as the tasks will now be executing. Call the task
|
||||
* exit error function to prevent compiler warnings about a static function
|
||||
* not being called in the case that the application writer overrides this
|
||||
* functionality by defining configTASK_RETURN_ADDRESS. Call
|
||||
* vTaskSwitchContext() so link time optimization does not remove the
|
||||
* symbol. */
|
||||
vTaskSwitchContext();
|
||||
prvTaskExitError();
|
||||
|
||||
/* Should not get here. */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
* Artificially force an assert. */
|
||||
configASSERT( ulCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )
|
||||
{
|
||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||
int32_t lIndex = 0;
|
||||
|
||||
/* Setup MAIR0. */
|
||||
xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
|
||||
xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK );
|
||||
|
||||
/* This function is called automatically when the task is created - in
|
||||
* which case the stack region parameters will be valid. At all other
|
||||
* times the stack parameters will not be valid and it is assumed that
|
||||
* the stack region has already been configured. */
|
||||
if( ulStackDepth > 0 )
|
||||
{
|
||||
/* Define the region that allows access to the stack. */
|
||||
ulRegionStartAddress = ( ( uint32_t ) pxBottomOfStack ) & portMPU_RBAR_ADDRESS_MASK;
|
||||
ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1;
|
||||
ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;
|
||||
|
||||
xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |
|
||||
( portMPU_REGION_NON_SHAREABLE ) |
|
||||
( portMPU_REGION_READ_WRITE ) |
|
||||
( portMPU_REGION_EXECUTE_NEVER );
|
||||
|
||||
xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |
|
||||
( portMPU_RLAR_ATTR_INDEX0 ) |
|
||||
( portMPU_RLAR_REGION_ENABLE );
|
||||
}
|
||||
|
||||
/* User supplied configurable regions. */
|
||||
for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ )
|
||||
{
|
||||
/* If xRegions is NULL i.e. the task has not specified any MPU
|
||||
* region, the else part ensures that all the configurable MPU
|
||||
* regions are invalidated. */
|
||||
if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) )
|
||||
{
|
||||
/* Translate the generic region definition contained in xRegions
|
||||
* into the ARMv8 specific MPU settings that are then stored in
|
||||
* xMPUSettings. */
|
||||
ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK;
|
||||
ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1;
|
||||
ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;
|
||||
|
||||
/* Start address. */
|
||||
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) |
|
||||
( portMPU_REGION_NON_SHAREABLE );
|
||||
|
||||
/* RO/RW. */
|
||||
if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 )
|
||||
{
|
||||
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY );
|
||||
}
|
||||
else
|
||||
{
|
||||
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE );
|
||||
}
|
||||
|
||||
/* XN. */
|
||||
if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 )
|
||||
{
|
||||
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER );
|
||||
}
|
||||
|
||||
/* End Address. */
|
||||
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) |
|
||||
( portMPU_RLAR_REGION_ENABLE );
|
||||
|
||||
/* Normal memory/ Device memory. */
|
||||
if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 )
|
||||
{
|
||||
/* Attr1 in MAIR0 is configured as device memory. */
|
||||
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Attr1 in MAIR0 is configured as normal memory. */
|
||||
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalidate the region. */
|
||||
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL;
|
||||
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL;
|
||||
}
|
||||
|
||||
lIndex++;
|
||||
}
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
@ -1,468 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION
|
||||
* is defined correctly and privileged functions are placed in correct sections. */
|
||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/* Portasm includes. */
|
||||
#include "portasm.h"
|
||||
|
||||
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the
|
||||
* header files. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
#if( configENABLE_FPU == 1 )
|
||||
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
||||
#endif
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r5, #1 \n" /* r5 = 1. */
|
||||
" bics r4, r5 \n" /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
|
||||
" str r4, [r2] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" 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 r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r4, [r2] \n" /* Program MAIR0. */
|
||||
" ldr r2, xRNRConst2 \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||
" movs r5, #4 \n" /* r5 = 4. */
|
||||
" str r5, [r2] \n" /* Program RNR = 4. */
|
||||
" ldmia r3!, {r6,r7} \n" /* Read first set of RBAR/RLAR from TCB. */
|
||||
" ldr r4, xRBARConst2 \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r4!, {r6,r7} \n" /* Write first set of RBAR/RLAR registers. */
|
||||
" movs r5, #5 \n" /* r5 = 5. */
|
||||
" str r5, [r2] \n" /* Program RNR = 5. */
|
||||
" ldmia r3!, {r6,r7} \n" /* Read second set of RBAR/RLAR from TCB. */
|
||||
" ldr r4, xRBARConst2 \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r4!, {r6,r7} \n" /* Write second set of RBAR/RLAR registers. */
|
||||
" movs r5, #6 \n" /* r5 = 6. */
|
||||
" str r5, [r2] \n" /* Program RNR = 6. */
|
||||
" ldmia r3!, {r6,r7} \n" /* Read third set of RBAR/RLAR from TCB. */
|
||||
" ldr r4, xRBARConst2 \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r4!, {r6,r7} \n" /* Write third set of RBAR/RLAR registers. */
|
||||
" movs r5, #7 \n" /* r5 = 7. */
|
||||
" str r5, [r2] \n" /* Program RNR = 7. */
|
||||
" ldmia r3!, {r6,r7} \n" /* Read fourth set of RBAR/RLAR from TCB. */
|
||||
" ldr r4, xRBARConst2 \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r4!, {r6,r7} \n" /* Write fourth set of RBAR/RLAR registers. */
|
||||
" \n"
|
||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r5, #1 \n" /* r5 = 1. */
|
||||
" orrs r4, r5 \n" /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
|
||||
" str r4, [r2] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" ldm r0!, {r1-r4} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */
|
||||
" ldr r5, xSecureContextConst2 \n"
|
||||
" 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 control, r3 \n" /* Set this task's CONTROL value. */
|
||||
" 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. */
|
||||
" isb \n"
|
||||
" bx r4 \n" /* Finally, branch to EXC_RETURN. */
|
||||
#else /* configENABLE_MPU */
|
||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||
" ldr r4, xSecureContextConst2 \n"
|
||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" 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. */
|
||||
" isb \n"
|
||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst2: .word xSecureContext \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
"xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
"xRNRConst2: .word 0xe000ed98 \n"
|
||||
"xRBARConst2: .word 0xe000ed9c \n"
|
||||
#endif /* configENABLE_MPU */
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" movs r1, #1 \n" /* r1 = 1. */
|
||||
" 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. */
|
||||
" movs r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" bx lr \n" /* Return. */
|
||||
" running_privileged: \n"
|
||||
" movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n" /* Return. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
::: "r0", "r1", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||
" movs r1, #1 \n" /* r1 = 1. */
|
||||
" bics r0, r1 \n" /* Clear the bit 0. */
|
||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "r1", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" movs r1, #1 \n" /* r1 = 1. */
|
||||
" orrs r0, r1 \n" /* r0 = r0 | r1. */
|
||||
" msr control, r0 \n" /* CONTROL = r0. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
:::"r0", "r1", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" 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" /* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n" /* Globally enable interrupts. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" svc %0 \n" /* System call to start the first task. */
|
||||
" nop \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"xVTORConst: .word 0xe000ed08 \n"
|
||||
:: "i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, PRIMASK \n"
|
||||
" cpsid i \n"
|
||||
" bx lr \n"
|
||||
::: "memory"
|
||||
);
|
||||
|
||||
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
/* To avoid compiler warnings. The return statement will never be reached,
|
||||
* but some compilers warn if it is not included, while others won't compile
|
||||
* if it is. */
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr PRIMASK, r0 \n"
|
||||
" bx lr \n"
|
||||
::: "memory"
|
||||
);
|
||||
|
||||
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
/* Just to avoid compiler warning. ulMask is used from the asm code but
|
||||
* the compiler can't see that. Some compilers generate warnings without
|
||||
* the following line, while others generate warnings if the line is
|
||||
* included. */
|
||||
( void ) ulMask;
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" mrs r1, psp \n" /* Read PSP in r1. */
|
||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r2] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" push {r0-r2, r14} \n"
|
||||
" bl SecureContext_SaveContext \n"
|
||||
" pop {r0-r3} \n" /* LR is now in 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. */
|
||||
" 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 r2, [r3] \n" /* Read pxCurrentTCB. */
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" 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. */
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" mrs r3, control \n" /* r3 = CONTROL. */
|
||||
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
|
||||
" stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||
#else /* configENABLE_MPU */
|
||||
" 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. */
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" stmia r1!, {r0, r2-r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" b select_next_task \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r2, [r3] \n" /* Read pxCurrentTCB. */
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" 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. */
|
||||
" adds r1, r1, #16 \n" /* r1 = r1 + 16. */
|
||||
" stmia r1!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */
|
||||
" mov r4, r8 \n" /* r4 = r8. */
|
||||
" mov r5, r9 \n" /* r5 = r9. */
|
||||
" mov r6, r10 \n" /* r6 = r10. */
|
||||
" mov r7, r11 \n" /* r7 = r11. */
|
||||
" stmia r1!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" mrs r3, control \n" /* r3 = CONTROL. */
|
||||
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
|
||||
" subs r1, r1, #48 \n" /* r1 = r1 - 48. */
|
||||
" stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||
#else /* configENABLE_MPU */
|
||||
" 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. */
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" 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. */
|
||||
" mov r4, r8 \n" /* r4 = r8. */
|
||||
" mov r5, r9 \n" /* r5 = r9. */
|
||||
" mov r6, r10 \n" /* r6 = r10. */
|
||||
" mov r7, r11 \n" /* r7 = r11. */
|
||||
" stmia r1!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
" select_next_task: \n"
|
||||
" cpsid i \n"
|
||||
" bl vTaskSwitchContext \n"
|
||||
" cpsie i \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r5, #1 \n" /* r5 = 1. */
|
||||
" bics r4, r5 \n" /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
|
||||
" str r4, [r2] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" 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 r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r4, [r2] \n" /* Program MAIR0. */
|
||||
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||
" movs r5, #4 \n" /* r5 = 4. */
|
||||
" str r5, [r2] \n" /* Program RNR = 4. */
|
||||
" ldmia r3!, {r6,r7} \n" /* Read first set of RBAR/RLAR from TCB. */
|
||||
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r4!, {r6,r7} \n" /* Write first set of RBAR/RLAR registers. */
|
||||
" movs r5, #5 \n" /* r5 = 5. */
|
||||
" str r5, [r2] \n" /* Program RNR = 5. */
|
||||
" ldmia r3!, {r6,r7} \n" /* Read second set of RBAR/RLAR from TCB. */
|
||||
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r4!, {r6,r7} \n" /* Write second set of RBAR/RLAR registers. */
|
||||
" movs r5, #6 \n" /* r5 = 6. */
|
||||
" str r5, [r2] \n" /* Program RNR = 6. */
|
||||
" ldmia r3!, {r6,r7} \n" /* Read third set of RBAR/RLAR from TCB. */
|
||||
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r4!, {r6,r7} \n" /* Write third set of RBAR/RLAR registers. */
|
||||
" movs r5, #7 \n" /* r5 = 7. */
|
||||
" str r5, [r2] \n" /* Program RNR = 7. */
|
||||
" ldmia r3!, {r6,r7} \n" /* Read fourth set of RBAR/RLAR from TCB. */
|
||||
" ldr r4, xRBARConst \n" /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r4!, {r6,r7} \n" /* Write fourth set of RBAR/RLAR registers. */
|
||||
" \n"
|
||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r4, [r2] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r5, #1 \n" /* r5 = 1. */
|
||||
" orrs r4, r5 \n" /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
|
||||
" str r4, [r2] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" 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 control, r3 \n" /* Restore the CONTROL register value for the task. */
|
||||
" mov lr, r4 \n" /* LR = r4. */
|
||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( 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. */
|
||||
" push {r1,r4} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. */
|
||||
" pop {r1,r4} \n"
|
||||
" 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. */
|
||||
" 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. */
|
||||
" bx lr \n"
|
||||
#else /* configENABLE_MPU */
|
||||
" 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. */
|
||||
" mov lr, r3 \n" /* LR = r3. */
|
||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( 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. */
|
||||
" push {r1,r3} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. */
|
||||
" pop {r1,r3} \n"
|
||||
" 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. */
|
||||
" 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. */
|
||||
" bx lr \n"
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" adds r1, r1, #16 \n" /* Move to the high registers. */
|
||||
" ldmia r1!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
|
||||
" mov r8, r4 \n" /* r8 = r4. */
|
||||
" mov r9, r5 \n" /* r9 = r5. */
|
||||
" mov r10, r6 \n" /* r10 = r6. */
|
||||
" mov r11, r7 \n" /* r11 = r7. */
|
||||
" msr psp, r1 \n" /* Remember the new top of stack for the task. */
|
||||
" subs r1, r1, #32 \n" /* Go back to the low registers. */
|
||||
" ldmia r1!, {r4-r7} \n" /* Restore the low registers that are not automatically restored. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst: .word xSecureContext \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
"xMAIR0Const: .word 0xe000edc0 \n"
|
||||
"xRNRConst: .word 0xe000ed98 \n"
|
||||
"xRBARConst: .word 0xe000ed9c \n"
|
||||
#endif /* configENABLE_MPU */
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" movs r0, #4 \n"
|
||||
" mov r1, lr \n"
|
||||
" tst r0, r1 \n"
|
||||
" beq stacking_used_msp \n"
|
||||
" mrs r0, psp \n"
|
||||
" ldr r2, svchandler_address_const \n"
|
||||
" bx r2 \n"
|
||||
" stacking_used_msp: \n"
|
||||
" mrs r0, msp \n"
|
||||
" ldr r2, svchandler_address_const \n"
|
||||
" bx r2 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
|
||||
" bx lr \n" /* Return. */
|
||||
:: "i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" ldr r1, [r0] \n" /* The first item in the TCB is the top of the stack. */
|
||||
" ldr r0, [r1] \n" /* The first item on the stack is the task's xSecureContext. */
|
||||
" cmp r0, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
|
||||
" beq free_secure_context \n"
|
||||
" bx lr \n" /* There is no secure context (xSecureContext is NULL). */
|
||||
" free_secure_context: \n"
|
||||
" svc %0 \n" /* Secure context is freed in the supervisor call. */
|
||||
" bx lr \n" /* Return. */
|
||||
:: "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -1,299 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||
* and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_FPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Type definitions.
|
||||
*/
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 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. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M23"
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP()
|
||||
#define portINLINE __inline
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
||||
#endif
|
||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||
#define portDONT_DISCARD __attribute__(( used ))
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Extern declarations.
|
||||
*/
|
||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief MPU specific constants.
|
||||
*/
|
||||
#if( configENABLE_MPU == 1 )
|
||||
#define portUSING_MPU_WRAPPERS 1
|
||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||
#else
|
||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
|
||||
/* MPU regions. */
|
||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||
#define portSTACK_REGION ( 4UL )
|
||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||
#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. */
|
||||
|
||||
/* Device memory attributes used in MPU_MAIR registers.
|
||||
*
|
||||
* 8-bit values encoded as follows:
|
||||
* Bit[7:4] - 0000 - Device Memory
|
||||
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||
* 01 --> Device-nGnRE
|
||||
* 10 --> Device-nGRE
|
||||
* 11 --> Device-GRE
|
||||
* Bit[1:0] - 00, Reserved.
|
||||
*/
|
||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||
|
||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||
#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. */
|
||||
|
||||
/* Attributes used in MPU_RBAR registers. */
|
||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||
|
||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||
|
||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||
} xMPU_SETTINGS;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief SVC numbers.
|
||||
*/
|
||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||
#define portSVC_START_SCHEDULER 2
|
||||
#define portSVC_RAISE_PRIVILEGE 3
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Scheduler utilities.
|
||||
*/
|
||||
#define portYIELD() vPortYield()
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||
*/
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* 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 context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#else
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||
#define portCLEAN_UP_TCB( pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
#define portRAISE_PRIVILEGE()
|
||||
#define portRESET_PRIVILEGE()
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Barriers.
|
||||
*/
|
||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
@ -1,381 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION
|
||||
* is defined correctly and privileged functions are placed in correct sections. */
|
||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/* Portasm includes. */
|
||||
#include "portasm.h"
|
||||
|
||||
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the
|
||||
* header files. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
#if( configENABLE_FPU == 1 )
|
||||
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
||||
#endif
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r4, #1 \n" /* r4 = 1. */
|
||||
" bics r3, r4 \n" /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
|
||||
" str r3, [r2] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" 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 r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r4, [r2] \n" /* Program MAIR0. */
|
||||
" ldr r2, xRNRConst2 \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||
" movs r4, #4 \n" /* r4 = 4. */
|
||||
" str r4, [r2] \n" /* Program RNR = 4. */
|
||||
" ldmia r1!, {r5,r6} \n" /* Read first set of RBAR/RLAR from TCB. */
|
||||
" ldr r3, xRBARConst2 \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r3!, {r5,r6} \n" /* Write first set of RBAR/RLAR registers. */
|
||||
" movs r4, #5 \n" /* r4 = 5. */
|
||||
" str r4, [r2] \n" /* Program RNR = 5. */
|
||||
" ldmia r1!, {r5,r6} \n" /* Read second set of RBAR/RLAR from TCB. */
|
||||
" ldr r3, xRBARConst2 \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r3!, {r5,r6} \n" /* Write second set of RBAR/RLAR registers. */
|
||||
" movs r4, #6 \n" /* r4 = 6. */
|
||||
" str r4, [r2] \n" /* Program RNR = 6. */
|
||||
" ldmia r1!, {r5,r6} \n" /* Read third set of RBAR/RLAR from TCB. */
|
||||
" ldr r3, xRBARConst2 \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r3!, {r5,r6} \n" /* Write third set of RBAR/RLAR registers. */
|
||||
" movs r4, #7 \n" /* r4 = 7. */
|
||||
" str r4, [r2] \n" /* Program RNR = 7. */
|
||||
" ldmia r1!, {r5,r6} \n" /* Read fourth set of RBAR/RLAR from TCB. */
|
||||
" ldr r3, xRBARConst2 \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r3!, {r5,r6} \n" /* Write fourth set of RBAR/RLAR registers. */
|
||||
" \n"
|
||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r4, #1 \n" /* r4 = 1. */
|
||||
" orrs r3, r4 \n" /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
|
||||
" str r3, [r2] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" 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 control, r2 \n" /* Set this task's CONTROL value. */
|
||||
" 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. */
|
||||
" isb \n"
|
||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||
#else /* configENABLE_MPU */
|
||||
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" 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. */
|
||||
" isb \n"
|
||||
" bx r2 \n" /* Finally, branch to EXC_RETURN. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
"xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
"xRNRConst2: .word 0xe000ed98 \n"
|
||||
"xRBARConst2: .word 0xe000ed9c \n"
|
||||
#endif /* configENABLE_MPU */
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" movs r1, #1 \n" /* r1 = 1. */
|
||||
" 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. */
|
||||
" movs r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
" bx lr \n" /* Return. */
|
||||
" running_privileged: \n"
|
||||
" movs r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
" bx lr \n" /* Return. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
::: "r0", "r1", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||
" movs r1, #1 \n" /* r1 = 1. */
|
||||
" bics r0, r1 \n" /* Clear the bit 0. */
|
||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "r1", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" movs r1, #1 \n" /* r1 = 1. */
|
||||
" orrs r0, r1 \n" /* r0 = r0 | r1. */
|
||||
" msr control, r0 \n" /* CONTROL = r0. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
:::"r0", "r1", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" 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" /* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n" /* Globally enable interrupts. */
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" svc %0 \n" /* System call to start the first task. */
|
||||
" nop \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"xVTORConst: .word 0xe000ed08 \n"
|
||||
:: "i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, PRIMASK \n"
|
||||
" cpsid i \n"
|
||||
" bx lr \n"
|
||||
::: "memory"
|
||||
);
|
||||
|
||||
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
/* To avoid compiler warnings. The return statement will never be reached,
|
||||
* but some compilers warn if it is not included, while others won't compile
|
||||
* if it is. */
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr PRIMASK, r0 \n"
|
||||
" bx lr \n"
|
||||
::: "memory"
|
||||
);
|
||||
|
||||
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
/* Just to avoid compiler warning. ulMask is used from the asm code but
|
||||
* the compiler can't see that. Some compilers generate warnings without
|
||||
* the following line, while others generate warnings if the line is
|
||||
* included. */
|
||||
( void ) ulMask;
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, psp \n" /* Read PSP in r0. */
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" 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. */
|
||||
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
||||
" mrs r2, control \n" /* r2 = CONTROL. */
|
||||
" 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. */
|
||||
" mov r4, r8 \n" /* r4 = r8. */
|
||||
" mov r5, r9 \n" /* r5 = r9. */
|
||||
" mov r6, r10 \n" /* r6 = r10. */
|
||||
" mov r7, r11 \n" /* r7 = r11. */
|
||||
" stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
||||
#else /* configENABLE_MPU */
|
||||
" 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. */
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" 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. */
|
||||
" mov r4, r8 \n" /* r4 = r8. */
|
||||
" mov r5, r9 \n" /* r5 = r9. */
|
||||
" mov r6, r10 \n" /* r6 = r10. */
|
||||
" mov r7, r11 \n" /* r7 = r11. */
|
||||
" stmia r0!, {r4-r7} \n" /* Store the high registers that are not saved automatically. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
" cpsid i \n"
|
||||
" bl vTaskSwitchContext \n"
|
||||
" cpsie i \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r4, #1 \n" /* r4 = 1. */
|
||||
" bics r3, r4 \n" /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
|
||||
" str r3, [r2] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" 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 r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r4, [r2] \n" /* Program MAIR0. */
|
||||
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||
" movs r4, #4 \n" /* r4 = 4. */
|
||||
" str r4, [r2] \n" /* Program RNR = 4. */
|
||||
" ldmia r1!, {r5,r6} \n" /* Read first set of RBAR/RLAR from TCB. */
|
||||
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r3!, {r5,r6} \n" /* Write first set of RBAR/RLAR registers. */
|
||||
" movs r4, #5 \n" /* r4 = 5. */
|
||||
" str r4, [r2] \n" /* Program RNR = 5. */
|
||||
" ldmia r1!, {r5,r6} \n" /* Read second set of RBAR/RLAR from TCB. */
|
||||
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r3!, {r5,r6} \n" /* Write second set of RBAR/RLAR registers. */
|
||||
" movs r4, #6 \n" /* r4 = 6. */
|
||||
" str r4, [r2] \n" /* Program RNR = 6. */
|
||||
" ldmia r1!, {r5,r6} \n" /* Read third set of RBAR/RLAR from TCB. */
|
||||
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r3!, {r5,r6} \n" /* Write third set of RBAR/RLAR registers. */
|
||||
" movs r4, #7 \n" /* r4 = 7. */
|
||||
" str r4, [r2] \n" /* Program RNR = 7. */
|
||||
" ldmia r1!, {r5,r6} \n" /* Read fourth set of RBAR/RLAR from TCB. */
|
||||
" ldr r3, xRBARConst \n" /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
" stmia r3!, {r5,r6} \n" /* Write fourth set of RBAR/RLAR registers. */
|
||||
" \n"
|
||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
" ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */
|
||||
" movs r4, #1 \n" /* r4 = 1. */
|
||||
" orrs r3, r4 \n" /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
|
||||
" str r3, [r2] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" adds r0, r0, #28 \n" /* Move to the high registers. */
|
||||
" ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
|
||||
" mov r8, r4 \n" /* r8 = r4. */
|
||||
" mov r9, r5 \n" /* r9 = r5. */
|
||||
" mov r10, r6 \n" /* r10 = r6. */
|
||||
" mov r11, r7 \n" /* r11 = r7. */
|
||||
" 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. */
|
||||
" 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 control, r2 \n" /* Restore the CONTROL register value for the task. */
|
||||
" bx r3 \n"
|
||||
#else /* configENABLE_MPU */
|
||||
" adds r0, r0, #24 \n" /* Move to the high registers. */
|
||||
" ldmia r0!, {r4-r7} \n" /* Restore the high registers that are not automatically restored. */
|
||||
" mov r8, r4 \n" /* r8 = r4. */
|
||||
" mov r9, r5 \n" /* r9 = r5. */
|
||||
" mov r10, r6 \n" /* r10 = r6. */
|
||||
" mov r11, r7 \n" /* r11 = r7. */
|
||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||
" subs r0, r0, #40 \n" /* Move to the starting of the saved context. */
|
||||
" ldmia r0!, {r2-r7} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
|
||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
||||
" bx r3 \n"
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
"xMAIR0Const: .word 0xe000edc0 \n"
|
||||
"xRNRConst: .word 0xe000ed98 \n"
|
||||
"xRBARConst: .word 0xe000ed9c \n"
|
||||
#endif /* configENABLE_MPU */
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" movs r0, #4 \n"
|
||||
" mov r1, lr \n"
|
||||
" tst r0, r1 \n"
|
||||
" beq stacking_used_msp \n"
|
||||
" mrs r0, psp \n"
|
||||
" ldr r2, svchandler_address_const \n"
|
||||
" bx r2 \n"
|
||||
" stacking_used_msp: \n"
|
||||
" mrs r0, msp \n"
|
||||
" ldr r2, svchandler_address_const \n"
|
||||
" bx r2 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -1,299 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||
* and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_FPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Type definitions.
|
||||
*/
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 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. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M23"
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP()
|
||||
#define portINLINE __inline
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
||||
#endif
|
||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||
#define portDONT_DISCARD __attribute__(( used ))
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Extern declarations.
|
||||
*/
|
||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief MPU specific constants.
|
||||
*/
|
||||
#if( configENABLE_MPU == 1 )
|
||||
#define portUSING_MPU_WRAPPERS 1
|
||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||
#else
|
||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
|
||||
/* MPU regions. */
|
||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||
#define portSTACK_REGION ( 4UL )
|
||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||
#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. */
|
||||
|
||||
/* Device memory attributes used in MPU_MAIR registers.
|
||||
*
|
||||
* 8-bit values encoded as follows:
|
||||
* Bit[7:4] - 0000 - Device Memory
|
||||
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||
* 01 --> Device-nGnRE
|
||||
* 10 --> Device-nGRE
|
||||
* 11 --> Device-GRE
|
||||
* Bit[1:0] - 00, Reserved.
|
||||
*/
|
||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||
|
||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||
#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. */
|
||||
|
||||
/* Attributes used in MPU_RBAR registers. */
|
||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||
|
||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||
|
||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||
} xMPU_SETTINGS;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief SVC numbers.
|
||||
*/
|
||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||
#define portSVC_START_SCHEDULER 2
|
||||
#define portSVC_RAISE_PRIVILEGE 3
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Scheduler utilities.
|
||||
*/
|
||||
#define portYIELD() vPortYield()
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||
*/
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* 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 context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#else
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||
#define portCLEAN_UP_TCB( pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
#define portRAISE_PRIVILEGE()
|
||||
#define portRESET_PRIVILEGE()
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Barriers.
|
||||
*/
|
||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
@ -1,415 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION
|
||||
* is defined correctly and privileged functions are placed in correct sections. */
|
||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/* Portasm includes. */
|
||||
#include "portasm.h"
|
||||
|
||||
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the
|
||||
* header files. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location 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. */
|
||||
" str r4, [r2] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" 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 r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r4, [r2] \n" /* Program MAIR0. */
|
||||
" ldr r2, xRNRConst2 \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
" movs r4, #4 \n" /* r4 = 4. */
|
||||
" str r4, [r2] \n" /* Program RNR = 4. */
|
||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" 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. */
|
||||
" \n"
|
||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location 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. */
|
||||
" str r4, [r2] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" ldm r0!, {r1-r4} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */
|
||||
" ldr r5, xSecureContextConst2 \n"
|
||||
" 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 control, r3 \n" /* Set this task's CONTROL value. */
|
||||
" 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. */
|
||||
" isb \n"
|
||||
" bx r4 \n" /* Finally, branch to EXC_RETURN. */
|
||||
#else /* configENABLE_MPU */
|
||||
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||
" ldr r4, xSecureContextConst2 \n"
|
||||
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
||||
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" 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. */
|
||||
" isb \n"
|
||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst2: .word xSecureContext \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
"xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
"xRNRConst2: .word 0xe000ed98 \n"
|
||||
"xRBARConst2: .word 0xe000ed9c \n"
|
||||
#endif /* configENABLE_MPU */
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" ite ne \n"
|
||||
" 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. */
|
||||
" bx lr \n" /* Return. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||
" msr control, r0 \n" /* CONTROL = r0. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
:::"r0", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" 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" /* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n" /* Globally enable interrupts. */
|
||||
" cpsie f \n"
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" svc %0 \n" /* System call to start the first task. */
|
||||
" nop \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"xVTORConst: .word 0xe000ed08 \n"
|
||||
:: "i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, PRIMASK \n"
|
||||
" cpsid i \n"
|
||||
" bx lr \n"
|
||||
::: "memory"
|
||||
);
|
||||
|
||||
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
/* To avoid compiler warnings. The return statement will never be reached,
|
||||
* but some compilers warn if it is not included, while others won't compile
|
||||
* if it is. */
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr PRIMASK, r0 \n"
|
||||
" bx lr \n"
|
||||
::: "memory"
|
||||
);
|
||||
|
||||
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
/* Just to avoid compiler warning. ulMask is used from the asm code but
|
||||
* the compiler can't see that. Some compilers generate warnings without
|
||||
* the following line, while others generate warnings if the line is
|
||||
* included. */
|
||||
( void ) ulMask;
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" .extern SecureContext_SaveContext \n"
|
||||
" .extern SecureContext_LoadContext \n"
|
||||
" \n"
|
||||
" mrs r1, psp \n" /* Read PSP in r1. */
|
||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||
" ldr r0, [r2] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||
" \n"
|
||||
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||
" push {r0-r2, r14} \n"
|
||||
" bl SecureContext_SaveContext \n"
|
||||
" pop {r0-r3} \n" /* LR is now in 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. */
|
||||
" 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 r2, [r3] \n" /* Read pxCurrentTCB. */
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" 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. */
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" mrs r3, control \n" /* r3 = CONTROL. */
|
||||
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
|
||||
" stmia r1!, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||
#else /* configENABLE_MPU */
|
||||
" 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. */
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" stmia r1!, {r0, r2-r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" b select_next_task \n"
|
||||
" \n"
|
||||
" save_ns_context: \n"
|
||||
" ldr r3, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r2, [r3] \n" /* Read pxCurrentTCB. */
|
||||
#if( configENABLE_FPU == 1 )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r1!, {s16-s31} \n" /* Store the FPU registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU */
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" 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. */
|
||||
" adds r1, r1, #16 \n" /* r1 = r1 + 16. */
|
||||
" stm r1, {r4-r11} \n" /* Store the registers that are not saved automatically. */
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" mrs r3, control \n" /* r3 = CONTROL. */
|
||||
" mov r4, lr \n" /* r4 = LR/EXC_RETURN. */
|
||||
" subs r1, r1, #16 \n" /* r1 = r1 - 16. */
|
||||
" stm r1, {r0, r2-r4} \n" /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||
#else /* configENABLE_MPU */
|
||||
" 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. */
|
||||
" adds r1, r1, #12 \n" /* r1 = r1 + 12. */
|
||||
" stm r1, {r4-r11} \n" /* Store the registers that are not saved automatically. */
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||
" subs r1, r1, #12 \n" /* r1 = r1 - 12. */
|
||||
" stmia r1!, {r0, r2-r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
" select_next_task: \n"
|
||||
" cpsid i \n"
|
||||
" bl vTaskSwitchContext \n"
|
||||
" cpsie i \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location 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. */
|
||||
" str r4, [r2] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" 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 r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r4, [r2] \n" /* Program MAIR0. */
|
||||
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
" movs r4, #4 \n" /* r4 = 4. */
|
||||
" str r4, [r2] \n" /* Program RNR = 4. */
|
||||
" adds r3, #4 \n" /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" 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. */
|
||||
" \n"
|
||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location 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. */
|
||||
" str r4, [r2] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" 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 control, r3 \n" /* Restore the CONTROL register value for the task. */
|
||||
" mov lr, r4 \n" /* LR = r4. */
|
||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( 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. */
|
||||
" push {r1,r4} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. */
|
||||
" pop {r1,r4} \n"
|
||||
" 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. */
|
||||
" 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. */
|
||||
" bx lr \n"
|
||||
#else /* configENABLE_MPU */
|
||||
" 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. */
|
||||
" mov lr, r3 \n" /* LR = r3. */
|
||||
" ldr r2, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( 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. */
|
||||
" push {r1,r3} \n"
|
||||
" bl SecureContext_LoadContext \n" /* Restore the secure context. */
|
||||
" pop {r1,r3} \n"
|
||||
" 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. */
|
||||
" 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. */
|
||||
" bx lr \n"
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
" restore_ns_context: \n"
|
||||
" ldmia r1!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */
|
||||
#if( configENABLE_FPU == 1 )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r1!, {s16-s31} \n" /* Restore the FPU registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU */
|
||||
" msr psp, r1 \n" /* Remember the new top of stack for the task. */
|
||||
" bx lr \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
"xSecureContextConst: .word xSecureContext \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
"xMAIR0Const: .word 0xe000edc0 \n"
|
||||
"xRNRConst: .word 0xe000ed98 \n"
|
||||
"xRBARConst: .word 0xe000ed9c \n"
|
||||
#endif /* configENABLE_MPU */
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
|
||||
" bx lr \n" /* Return. */
|
||||
:: "i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" ldr r1, [r0] \n" /* The first item in the TCB is the top of the stack. */
|
||||
" 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. */
|
||||
" it ne \n"
|
||||
" svcne %0 \n" /* Secure context is freed in the supervisor call. */
|
||||
" bx lr \n" /* Return. */
|
||||
:: "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -1,299 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||
* and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_FPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Type definitions.
|
||||
*/
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 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. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M33"
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP()
|
||||
#define portINLINE __inline
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
||||
#endif
|
||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||
#define portDONT_DISCARD __attribute__(( used ))
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Extern declarations.
|
||||
*/
|
||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief MPU specific constants.
|
||||
*/
|
||||
#if( configENABLE_MPU == 1 )
|
||||
#define portUSING_MPU_WRAPPERS 1
|
||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||
#else
|
||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
|
||||
/* MPU regions. */
|
||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||
#define portSTACK_REGION ( 4UL )
|
||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||
#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. */
|
||||
|
||||
/* Device memory attributes used in MPU_MAIR registers.
|
||||
*
|
||||
* 8-bit values encoded as follows:
|
||||
* Bit[7:4] - 0000 - Device Memory
|
||||
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||
* 01 --> Device-nGnRE
|
||||
* 10 --> Device-nGRE
|
||||
* 11 --> Device-GRE
|
||||
* Bit[1:0] - 00, Reserved.
|
||||
*/
|
||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||
|
||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||
#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. */
|
||||
|
||||
/* Attributes used in MPU_RBAR registers. */
|
||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||
|
||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||
|
||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||
} xMPU_SETTINGS;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief SVC numbers.
|
||||
*/
|
||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||
#define portSVC_START_SCHEDULER 2
|
||||
#define portSVC_RAISE_PRIVILEGE 3
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Scheduler utilities.
|
||||
*/
|
||||
#define portYIELD() vPortYield()
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||
*/
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* 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 context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#else
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||
#define portCLEAN_UP_TCB( pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
#define portRAISE_PRIVILEGE()
|
||||
#define portRESET_PRIVILEGE()
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Barriers.
|
||||
*/
|
||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
@ -1,321 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION
|
||||
* is defined correctly and privileged functions are placed in correct sections. */
|
||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/* Portasm includes. */
|
||||
#include "portasm.h"
|
||||
|
||||
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the
|
||||
* header files. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n" /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location 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. */
|
||||
" str r4, [r2] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" 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 r2, xMAIR0Const2 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r3, [r2] \n" /* Program MAIR0. */
|
||||
" ldr r2, xRNRConst2 \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r2] \n" /* Program RNR = 4. */
|
||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||
" ldr r2, xRBARConst2 \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" 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. */
|
||||
" \n"
|
||||
" ldr r2, xMPUCTRLConst2 \n" /* r2 = 0xe000ed94 [Location 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. */
|
||||
" str r4, [r2] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" 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 control, r2 \n" /* Set this task's CONTROL value. */
|
||||
" 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. */
|
||||
" isb \n"
|
||||
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||
#else /* configENABLE_MPU */
|
||||
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
||||
" movs r1, #2 \n" /* r1 = 2. */
|
||||
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
|
||||
" 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. */
|
||||
" isb \n"
|
||||
" bx r2 \n" /* Finally, branch to EXC_RETURN. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
"xMPUCTRLConst2: .word 0xe000ed94 \n"
|
||||
"xMAIR0Const2: .word 0xe000edc0 \n"
|
||||
"xRNRConst2: .word 0xe000ed98 \n"
|
||||
"xRBARConst2: .word 0xe000ed9c \n"
|
||||
#endif /* configENABLE_MPU */
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
" ite ne \n"
|
||||
" 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. */
|
||||
" bx lr \n" /* Return. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
::: "r0", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||
" msr control, r0 \n" /* CONTROL = r0. */
|
||||
" bx lr \n" /* Return to the caller. */
|
||||
:::"r0", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" 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" /* The first entry in vector table is stack pointer. */
|
||||
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||
" cpsie i \n" /* Globally enable interrupts. */
|
||||
" cpsie f \n"
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" svc %0 \n" /* System call to start the first task. */
|
||||
" nop \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"xVTORConst: .word 0xe000ed08 \n"
|
||||
:: "i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r0, PRIMASK \n"
|
||||
" cpsid i \n"
|
||||
" bx lr \n"
|
||||
::: "memory"
|
||||
);
|
||||
|
||||
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
/* To avoid compiler warnings. The return statement will never be reached,
|
||||
* but some compilers warn if it is not included, while others won't compile
|
||||
* if it is. */
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr PRIMASK, r0 \n"
|
||||
" bx lr \n"
|
||||
::: "memory"
|
||||
);
|
||||
|
||||
#if !defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
/* Just to avoid compiler warning. ulMask is used from the asm code but
|
||||
* the compiler can't see that. Some compilers generate warnings without
|
||||
* the following line, while others generate warnings if the line is
|
||||
* included. */
|
||||
( void ) ulMask;
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r0, psp \n" /* Read PSP in r0. */
|
||||
#if( configENABLE_FPU == 1 )
|
||||
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
||||
" it eq \n"
|
||||
" vstmdbeq r0!, {s16-s31} \n" /* Store the FPU registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU */
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" mrs r1, psplim \n" /* r1 = PSPLIM. */
|
||||
" mrs r2, control \n" /* r2 = CONTROL. */
|
||||
" 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. */
|
||||
#else /* configENABLE_MPU */
|
||||
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||
" 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. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
||||
" \n"
|
||||
" cpsid i \n"
|
||||
" bl vTaskSwitchContext \n"
|
||||
" cpsie i \n"
|
||||
" \n"
|
||||
" ldr r2, pxCurrentTCBConst \n" /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location 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. */
|
||||
" str r4, [r2] \n" /* Disable MPU. */
|
||||
" \n"
|
||||
" 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 r2, xMAIR0Const \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
" str r3, [r2] \n" /* Program MAIR0. */
|
||||
" ldr r2, xRNRConst \n" /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
" movs r3, #4 \n" /* r3 = 4. */
|
||||
" str r3, [r2] \n" /* Program RNR = 4. */
|
||||
" adds r1, #4 \n" /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||
" ldr r2, xRBARConst \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
" 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. */
|
||||
" \n"
|
||||
" ldr r2, xMPUCTRLConst \n" /* r2 = 0xe000ed94 [Location 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. */
|
||||
" str r4, [r2] \n" /* Enable MPU. */
|
||||
" dsb \n" /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" ldmia r0!, {r1-r11} \n" /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */
|
||||
#else /* configENABLE_MPU */
|
||||
" ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" \n"
|
||||
#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. */
|
||||
" it eq \n"
|
||||
" vldmiaeq r0!, {s16-s31} \n" /* Restore the FPU registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU */
|
||||
" \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */
|
||||
" msr control, r2 \n" /* Restore the CONTROL register value for the task. */
|
||||
#else /* configENABLE_MPU */
|
||||
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||
" bx r3 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||
#if( configENABLE_MPU == 1 )
|
||||
"xMPUCTRLConst: .word 0xe000ed94 \n"
|
||||
"xMAIR0Const: .word 0xe000edc0 \n"
|
||||
"xRNRConst: .word 0xe000ed98 \n"
|
||||
"xRBARConst: .word 0xe000ed9c \n"
|
||||
#endif /* configENABLE_MPU */
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" tst lr, #4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0, msp \n"
|
||||
" mrsne r0, psp \n"
|
||||
" ldr r1, svchandler_address_const \n"
|
||||
" bx r1 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"svchandler_address_const: .word vPortSVCHandler_C \n"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -1,299 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||
* and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_FPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Type definitions.
|
||||
*/
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 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. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M33"
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP()
|
||||
#define portINLINE __inline
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
||||
#endif
|
||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||
#define portDONT_DISCARD __attribute__(( used ))
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Extern declarations.
|
||||
*/
|
||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief MPU specific constants.
|
||||
*/
|
||||
#if( configENABLE_MPU == 1 )
|
||||
#define portUSING_MPU_WRAPPERS 1
|
||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||
#else
|
||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
|
||||
/* MPU regions. */
|
||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||
#define portSTACK_REGION ( 4UL )
|
||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||
#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. */
|
||||
|
||||
/* Device memory attributes used in MPU_MAIR registers.
|
||||
*
|
||||
* 8-bit values encoded as follows:
|
||||
* Bit[7:4] - 0000 - Device Memory
|
||||
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||
* 01 --> Device-nGnRE
|
||||
* 10 --> Device-nGRE
|
||||
* 11 --> Device-GRE
|
||||
* Bit[1:0] - 00, Reserved.
|
||||
*/
|
||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||
|
||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||
#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. */
|
||||
|
||||
/* Attributes used in MPU_RBAR registers. */
|
||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||
|
||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||
|
||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||
} xMPU_SETTINGS;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief SVC numbers.
|
||||
*/
|
||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||
#define portSVC_START_SCHEDULER 2
|
||||
#define portSVC_RAISE_PRIVILEGE 3
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Scheduler utilities.
|
||||
*/
|
||||
#define portYIELD() vPortYield()
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||
*/
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* 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 context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#else
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||
#define portCLEAN_UP_TCB( pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
#define portRAISE_PRIVILEGE()
|
||||
#define portRESET_PRIVILEGE()
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Barriers.
|
||||
*/
|
||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
@ -1,377 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
EXTERN pxCurrentTCB
|
||||
EXTERN xSecureContext
|
||||
EXTERN vTaskSwitchContext
|
||||
EXTERN vPortSVCHandler_C
|
||||
EXTERN SecureContext_SaveContext
|
||||
EXTERN SecureContext_LoadContext
|
||||
|
||||
PUBLIC xIsPrivileged
|
||||
PUBLIC vResetPrivilege
|
||||
PUBLIC vPortAllocateSecureContext
|
||||
PUBLIC vRestoreContextOfFirstTask
|
||||
PUBLIC vRaisePrivilege
|
||||
PUBLIC vStartFirstTask
|
||||
PUBLIC ulSetInterruptMaskFromISR
|
||||
PUBLIC vClearInterruptMaskFromISR
|
||||
PUBLIC PendSV_Handler
|
||||
PUBLIC SVC_Handler
|
||||
PUBLIC vPortFreeSecureContext
|
||||
|
||||
#if ( configENABLE_FPU == 1 )
|
||||
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*---------------- Unprivileged Functions -------------------*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
THUMB
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
xIsPrivileged:
|
||||
mrs r0, control /* r0 = CONTROL. */
|
||||
movs r1, #1 /* r1 = 1. */
|
||||
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. */
|
||||
movs r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
bx lr /* Return. */
|
||||
running_privileged:
|
||||
movs r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
bx lr /* Return. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vResetPrivilege:
|
||||
mrs r0, control /* r0 = CONTROL. */
|
||||
movs r1, #1 /* r1 = 1. */
|
||||
orrs r0, r1 /* r0 = r0 | r1. */
|
||||
msr control, r0 /* CONTROL = r0. */
|
||||
bx lr /* Return to the caller. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vPortAllocateSecureContext:
|
||||
svc 0 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 0. */
|
||||
bx lr /* Return. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*----------------- Privileged Functions --------------------*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SECTION privileged_functions:CODE:NOROOT(2)
|
||||
THUMB
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vRestoreContextOfFirstTask:
|
||||
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
dmb /* Complete outstanding transfers before disabling MPU. */
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
ldr r4, [r2] /* Read the value of MPU_CTRL. */
|
||||
movs r5, #1 /* r5 = 1. */
|
||||
bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
|
||||
str r4, [r2] /* Disable MPU. */
|
||||
|
||||
adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
||||
ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */
|
||||
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
str r4, [r2] /* Program MAIR0. */
|
||||
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||
movs r5, #4 /* r5 = 4. */
|
||||
str r5, [r2] /* Program RNR = 4. */
|
||||
ldmia r3!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */
|
||||
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r4!, {r6,r7} /* Write first set of RBAR/RLAR registers. */
|
||||
movs r5, #5 /* r5 = 5. */
|
||||
str r5, [r2] /* Program RNR = 5. */
|
||||
ldmia r3!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */
|
||||
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r4!, {r6,r7} /* Write second set of RBAR/RLAR registers. */
|
||||
movs r5, #6 /* r5 = 6. */
|
||||
str r5, [r2] /* Program RNR = 6. */
|
||||
ldmia r3!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */
|
||||
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r4!, {r6,r7} /* Write third set of RBAR/RLAR registers. */
|
||||
movs r5, #7 /* r5 = 7. */
|
||||
str r5, [r2] /* Program RNR = 7. */
|
||||
ldmia r3!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */
|
||||
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r4!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */
|
||||
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
ldr r4, [r2] /* Read the value of MPU_CTRL. */
|
||||
movs r5, #1 /* r5 = 1. */
|
||||
orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
|
||||
str r4, [r2] /* Enable MPU. */
|
||||
dsb /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */
|
||||
ldr r5, =xSecureContext
|
||||
str r1, [r5] /* Set xSecureContext to this task's value for the same. */
|
||||
msr psplim, r2 /* Set this task's PSPLIM value. */
|
||||
msr control, r3 /* Set this task's CONTROL value. */
|
||||
adds r0, #32 /* Discard everything up to r0. */
|
||||
msr psp, r0 /* This is now the new top of stack to use in the task. */
|
||||
isb
|
||||
bx r4 /* Finally, branch to EXC_RETURN. */
|
||||
#else /* configENABLE_MPU */
|
||||
ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||
ldr r4, =xSecureContext
|
||||
str r1, [r4] /* Set xSecureContext to this task's value for the same. */
|
||||
msr psplim, r2 /* Set this task's PSPLIM value. */
|
||||
movs r1, #2 /* r1 = 2. */
|
||||
msr CONTROL, r1 /* Switch to use PSP in the thread mode. */
|
||||
adds r0, #32 /* Discard everything up to r0. */
|
||||
msr psp, r0 /* This is now the new top of stack to use in the task. */
|
||||
isb
|
||||
bx r3 /* Finally, branch to EXC_RETURN. */
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vRaisePrivilege:
|
||||
mrs r0, control /* Read the CONTROL register. */
|
||||
movs r1, #1 /* r1 = 1. */
|
||||
bics r0, r1 /* Clear the bit 0. */
|
||||
msr control, r0 /* Write back the new CONTROL value. */
|
||||
bx lr /* Return to the caller. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vStartFirstTask:
|
||||
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] /* The first entry in vector table is stack pointer. */
|
||||
msr msp, r0 /* Set the MSP back to the start of the stack. */
|
||||
cpsie i /* Globally enable interrupts. */
|
||||
dsb
|
||||
isb
|
||||
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
ulSetInterruptMaskFromISR:
|
||||
mrs r0, PRIMASK
|
||||
cpsid i
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vClearInterruptMaskFromISR:
|
||||
msr PRIMASK, r0
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
PendSV_Handler:
|
||||
mrs r1, psp /* Read PSP in r1. */
|
||||
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. */
|
||||
|
||||
cbz r0, save_ns_context /* No secure context to save. */
|
||||
push {r0-r2, r14}
|
||||
bl SecureContext_SaveContext
|
||||
pop {r0-r3} /* LR is now in 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. */
|
||||
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 r2, [r3] /* Read pxCurrentTCB. */
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
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. */
|
||||
mrs r2, psplim /* r2 = PSPLIM. */
|
||||
mrs r3, control /* r3 = CONTROL. */
|
||||
mov r4, lr /* r4 = LR/EXC_RETURN. */
|
||||
stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||
#else /* configENABLE_MPU */
|
||||
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. */
|
||||
mrs r2, psplim /* r2 = PSPLIM. */
|
||||
mov r3, lr /* r3 = LR/EXC_RETURN. */
|
||||
stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
#endif /* configENABLE_MPU */
|
||||
b select_next_task
|
||||
|
||||
save_ns_context:
|
||||
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
ldr r2, [r3] /* Read pxCurrentTCB. */
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
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. */
|
||||
adds r1, r1, #16 /* r1 = r1 + 16. */
|
||||
stmia r1!, {r4-r7} /* Store the low registers that are not saved automatically. */
|
||||
mov r4, r8 /* r4 = r8. */
|
||||
mov r5, r9 /* r5 = r9. */
|
||||
mov r6, r10 /* r6 = r10. */
|
||||
mov r7, r11 /* r7 = r11. */
|
||||
stmia r1!, {r4-r7} /* Store the high registers that are not saved automatically. */
|
||||
mrs r2, psplim /* r2 = PSPLIM. */
|
||||
mrs r3, control /* r3 = CONTROL. */
|
||||
mov r4, lr /* r4 = LR/EXC_RETURN. */
|
||||
subs r1, r1, #48 /* r1 = r1 - 48. */
|
||||
stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||
#else /* configENABLE_MPU */
|
||||
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. */
|
||||
mrs r2, psplim /* r2 = PSPLIM. */
|
||||
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. */
|
||||
mov r4, r8 /* r4 = r8. */
|
||||
mov r5, r9 /* r5 = r9. */
|
||||
mov r6, r10 /* r6 = r10. */
|
||||
mov r7, r11 /* r7 = r11. */
|
||||
stmia r1!, {r4-r7} /* Store the high registers that are not saved automatically. */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
select_next_task:
|
||||
cpsid i
|
||||
bl vTaskSwitchContext
|
||||
cpsie i
|
||||
|
||||
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
dmb /* Complete outstanding transfers before disabling MPU. */
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
ldr r4, [r2] /* Read the value of MPU_CTRL. */
|
||||
movs r5, #1 /* r5 = 1. */
|
||||
bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */
|
||||
str r4, [r2] /* Disable MPU. */
|
||||
|
||||
adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
||||
ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */
|
||||
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
str r4, [r2] /* Program MAIR0. */
|
||||
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||
movs r5, #4 /* r5 = 4. */
|
||||
str r5, [r2] /* Program RNR = 4. */
|
||||
ldmia r3!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */
|
||||
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r4!, {r6,r7} /* Write first set of RBAR/RLAR registers. */
|
||||
movs r5, #5 /* r5 = 5. */
|
||||
str r5, [r2] /* Program RNR = 5. */
|
||||
ldmia r3!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */
|
||||
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r4!, {r6,r7} /* Write second set of RBAR/RLAR registers. */
|
||||
movs r5, #6 /* r5 = 6. */
|
||||
str r5, [r2] /* Program RNR = 6. */
|
||||
ldmia r3!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */
|
||||
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r4!, {r6,r7} /* Write third set of RBAR/RLAR registers. */
|
||||
movs r5, #7 /* r5 = 7. */
|
||||
str r5, [r2] /* Program RNR = 7. */
|
||||
ldmia r3!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */
|
||||
ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r4!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */
|
||||
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
ldr r4, [r2] /* Read the value of MPU_CTRL. */
|
||||
movs r5, #1 /* r5 = 1. */
|
||||
orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */
|
||||
str r4, [r2] /* Enable MPU. */
|
||||
dsb /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
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 control, r3 /* Restore the CONTROL register value for the task. */
|
||||
mov lr, r4 /* LR = r4. */
|
||||
ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( 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. */
|
||||
push {r1,r4}
|
||||
bl SecureContext_LoadContext /* Restore the secure context. */
|
||||
pop {r1,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. */
|
||||
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. */
|
||||
bx lr
|
||||
#else /* configENABLE_MPU */
|
||||
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. */
|
||||
mov lr, r3 /* LR = r3. */
|
||||
ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( 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. */
|
||||
push {r1,r3}
|
||||
bl SecureContext_LoadContext /* Restore the secure context. */
|
||||
pop {r1,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. */
|
||||
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. */
|
||||
bx lr
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
restore_ns_context:
|
||||
adds r1, r1, #16 /* Move to the high registers. */
|
||||
ldmia r1!, {r4-r7} /* Restore the high registers that are not automatically restored. */
|
||||
mov r8, r4 /* r8 = r4. */
|
||||
mov r9, r5 /* r9 = r5. */
|
||||
mov r10, r6 /* r10 = r6. */
|
||||
mov r11, r7 /* r11 = r7. */
|
||||
msr psp, r1 /* Remember the new top of stack for the task. */
|
||||
subs r1, r1, #32 /* Go back to the low registers. */
|
||||
ldmia r1!, {r4-r7} /* Restore the low registers that are not automatically restored. */
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SVC_Handler:
|
||||
movs r0, #4
|
||||
mov r1, lr
|
||||
tst r0, r1
|
||||
beq stacking_used_msp
|
||||
mrs r0, psp
|
||||
b vPortSVCHandler_C
|
||||
stacking_used_msp:
|
||||
mrs r0, msp
|
||||
b vPortSVCHandler_C
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vPortFreeSecureContext:
|
||||
ldr r1, [r0] /* The first item in the TCB is the top of the stack. */
|
||||
ldr r0, [r1] /* The first item on the stack is the task's xSecureContext. */
|
||||
cmp r0, #0 /* Raise svc if task's xSecureContext is not NULL. */
|
||||
beq free_secure_context
|
||||
bx lr /* There is no secure context (xSecureContext is NULL). */
|
||||
free_secure_context:
|
||||
svc 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */
|
||||
bx lr /* Return. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
END
|
@ -1,299 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||
* and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_FPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Type definitions.
|
||||
*/
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 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. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M23"
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP()
|
||||
#define portINLINE __inline
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
||||
#endif
|
||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||
#define portDONT_DISCARD __root
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Extern declarations.
|
||||
*/
|
||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief MPU specific constants.
|
||||
*/
|
||||
#if( configENABLE_MPU == 1 )
|
||||
#define portUSING_MPU_WRAPPERS 1
|
||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||
#else
|
||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
|
||||
/* MPU regions. */
|
||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||
#define portSTACK_REGION ( 4UL )
|
||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||
#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. */
|
||||
|
||||
/* Device memory attributes used in MPU_MAIR registers.
|
||||
*
|
||||
* 8-bit values encoded as follows:
|
||||
* Bit[7:4] - 0000 - Device Memory
|
||||
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||
* 01 --> Device-nGnRE
|
||||
* 10 --> Device-nGRE
|
||||
* 11 --> Device-GRE
|
||||
* Bit[1:0] - 00, Reserved.
|
||||
*/
|
||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||
|
||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||
#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. */
|
||||
|
||||
/* Attributes used in MPU_RBAR registers. */
|
||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||
|
||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||
|
||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||
} xMPU_SETTINGS;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief SVC numbers.
|
||||
*/
|
||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||
#define portSVC_START_SCHEDULER 2
|
||||
#define portSVC_RAISE_PRIVILEGE 3
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Scheduler utilities.
|
||||
*/
|
||||
#define portYIELD() vPortYield()
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||
*/
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* 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 context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#else
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||
#define portCLEAN_UP_TCB( pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
#define portRAISE_PRIVILEGE()
|
||||
#define portRESET_PRIVILEGE()
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Barriers.
|
||||
*/
|
||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
@ -1,303 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
EXTERN pxCurrentTCB
|
||||
EXTERN vTaskSwitchContext
|
||||
EXTERN vPortSVCHandler_C
|
||||
|
||||
PUBLIC xIsPrivileged
|
||||
PUBLIC vResetPrivilege
|
||||
PUBLIC vRestoreContextOfFirstTask
|
||||
PUBLIC vRaisePrivilege
|
||||
PUBLIC vStartFirstTask
|
||||
PUBLIC ulSetInterruptMaskFromISR
|
||||
PUBLIC vClearInterruptMaskFromISR
|
||||
PUBLIC PendSV_Handler
|
||||
PUBLIC SVC_Handler
|
||||
|
||||
#if ( configENABLE_FPU == 1 )
|
||||
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*---------------- Unprivileged Functions -------------------*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
THUMB
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
xIsPrivileged:
|
||||
mrs r0, control /* r0 = CONTROL. */
|
||||
movs r1, #1 /* r1 = 1. */
|
||||
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. */
|
||||
movs r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
bx lr /* Return. */
|
||||
running_privileged:
|
||||
movs r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||
bx lr /* Return. */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vResetPrivilege:
|
||||
mrs r0, control /* r0 = CONTROL. */
|
||||
movs r1, #1 /* r1 = 1. */
|
||||
orrs r0, r1 /* r0 = r0 | r1. */
|
||||
msr control, r0 /* CONTROL = r0. */
|
||||
bx lr /* Return to the caller. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*----------------- Privileged Functions --------------------*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SECTION privileged_functions:CODE:NOROOT(2)
|
||||
THUMB
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vRestoreContextOfFirstTask:
|
||||
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
dmb /* Complete outstanding transfers before disabling MPU. */
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
ldr r3, [r2] /* Read the value of MPU_CTRL. */
|
||||
movs r4, #1 /* r4 = 1. */
|
||||
bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
|
||||
str r3, [r2] /* Disable MPU. */
|
||||
|
||||
adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
||||
ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */
|
||||
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
str r4, [r2] /* Program MAIR0. */
|
||||
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||
movs r4, #4 /* r4 = 4. */
|
||||
str r4, [r2] /* Program RNR = 4. */
|
||||
ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */
|
||||
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */
|
||||
movs r4, #5 /* r4 = 5. */
|
||||
str r4, [r2] /* Program RNR = 5. */
|
||||
ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */
|
||||
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */
|
||||
movs r4, #6 /* r4 = 6. */
|
||||
str r4, [r2] /* Program RNR = 6. */
|
||||
ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */
|
||||
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */
|
||||
movs r4, #7 /* r4 = 7. */
|
||||
str r4, [r2] /* Program RNR = 7. */
|
||||
ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */
|
||||
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */
|
||||
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
ldr r3, [r2] /* Read the value of MPU_CTRL. */
|
||||
movs r4, #1 /* r4 = 1. */
|
||||
orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
|
||||
str r3, [r2] /* Enable MPU. */
|
||||
dsb /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
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 control, r2 /* Set this task's CONTROL value. */
|
||||
adds r0, #32 /* Discard everything up to r0. */
|
||||
msr psp, r0 /* This is now the new top of stack to use in the task. */
|
||||
isb
|
||||
bx r3 /* Finally, branch to EXC_RETURN. */
|
||||
#else /* configENABLE_MPU */
|
||||
ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||
msr psplim, r1 /* Set this task's PSPLIM value. */
|
||||
movs r1, #2 /* r1 = 2. */
|
||||
msr CONTROL, r1 /* Switch to use PSP in the thread mode. */
|
||||
adds r0, #32 /* Discard everything up to r0. */
|
||||
msr psp, r0 /* This is now the new top of stack to use in the task. */
|
||||
isb
|
||||
bx r2 /* Finally, branch to EXC_RETURN. */
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vRaisePrivilege:
|
||||
mrs r0, control /* Read the CONTROL register. */
|
||||
movs r1, #1 /* r1 = 1. */
|
||||
bics r0, r1 /* Clear the bit 0. */
|
||||
msr control, r0 /* Write back the new CONTROL value. */
|
||||
bx lr /* Return to the caller. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vStartFirstTask:
|
||||
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] /* The first entry in vector table is stack pointer. */
|
||||
msr msp, r0 /* Set the MSP back to the start of the stack. */
|
||||
cpsie i /* Globally enable interrupts. */
|
||||
dsb
|
||||
isb
|
||||
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
|
||||
nop
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
ulSetInterruptMaskFromISR:
|
||||
mrs r0, PRIMASK
|
||||
cpsid i
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vClearInterruptMaskFromISR:
|
||||
msr PRIMASK, r0
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
PendSV_Handler:
|
||||
mrs r0, psp /* Read PSP in r0. */
|
||||
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
ldr r1, [r2] /* Read pxCurrentTCB. */
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
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. */
|
||||
mrs r1, psplim /* r1 = PSPLIM. */
|
||||
mrs r2, control /* r2 = CONTROL. */
|
||||
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. */
|
||||
mov r4, r8 /* r4 = r8. */
|
||||
mov r5, r9 /* r5 = r9. */
|
||||
mov r6, r10 /* r6 = r10. */
|
||||
mov r7, r11 /* r7 = r11. */
|
||||
stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */
|
||||
#else /* configENABLE_MPU */
|
||||
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. */
|
||||
mrs r2, psplim /* r2 = PSPLIM. */
|
||||
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. */
|
||||
mov r4, r8 /* r4 = r8. */
|
||||
mov r5, r9 /* r5 = r9. */
|
||||
mov r6, r10 /* r6 = r10. */
|
||||
mov r7, r11 /* r7 = r11. */
|
||||
stmia r0!, {r4-r7} /* Store the high registers that are not saved automatically. */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
cpsid i
|
||||
bl vTaskSwitchContext
|
||||
cpsie i
|
||||
|
||||
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
dmb /* Complete outstanding transfers before disabling MPU. */
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
ldr r3, [r2] /* Read the value of MPU_CTRL. */
|
||||
movs r4, #1 /* r4 = 1. */
|
||||
bics r3, r4 /* r3 = r3 & ~r4 i.e. Clear the bit 0 in r3. */
|
||||
str r3, [r2] /* Disable MPU. */
|
||||
|
||||
adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
||||
ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */
|
||||
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
str r4, [r2] /* Program MAIR0. */
|
||||
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||
movs r4, #4 /* r4 = 4. */
|
||||
str r4, [r2] /* Program RNR = 4. */
|
||||
ldmia r1!, {r5,r6} /* Read first set of RBAR/RLAR from TCB. */
|
||||
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r3!, {r5,r6} /* Write first set of RBAR/RLAR registers. */
|
||||
movs r4, #5 /* r4 = 5. */
|
||||
str r4, [r2] /* Program RNR = 5. */
|
||||
ldmia r1!, {r5,r6} /* Read second set of RBAR/RLAR from TCB. */
|
||||
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r3!, {r5,r6} /* Write second set of RBAR/RLAR registers. */
|
||||
movs r4, #6 /* r4 = 6. */
|
||||
str r4, [r2] /* Program RNR = 6. */
|
||||
ldmia r1!, {r5,r6} /* Read third set of RBAR/RLAR from TCB. */
|
||||
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r3!, {r5,r6} /* Write third set of RBAR/RLAR registers. */
|
||||
movs r4, #7 /* r4 = 7. */
|
||||
str r4, [r2] /* Program RNR = 7. */
|
||||
ldmia r1!, {r5,r6} /* Read fourth set of RBAR/RLAR from TCB. */
|
||||
ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */
|
||||
stmia r3!, {r5,r6} /* Write fourth set of RBAR/RLAR registers. */
|
||||
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||
ldr r3, [r2] /* Read the value of MPU_CTRL. */
|
||||
movs r4, #1 /* r4 = 1. */
|
||||
orrs r3, r4 /* r3 = r3 | r4 i.e. Set the bit 0 in r3. */
|
||||
str r3, [r2] /* Enable MPU. */
|
||||
dsb /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
adds r0, r0, #28 /* Move to the high registers. */
|
||||
ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */
|
||||
mov r8, r4 /* r8 = r4. */
|
||||
mov r9, r5 /* r9 = r5. */
|
||||
mov r10, r6 /* r10 = r6. */
|
||||
mov r11, r7 /* r11 = r7. */
|
||||
msr psp, r0 /* Remember the new top of stack for the task. */
|
||||
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. */
|
||||
msr psplim, r1 /* Restore the PSPLIM register value for the task. */
|
||||
msr control, r2 /* Restore the CONTROL register value for the task. */
|
||||
bx r3
|
||||
#else /* configENABLE_MPU */
|
||||
adds r0, r0, #24 /* Move to the high registers. */
|
||||
ldmia r0!, {r4-r7} /* Restore the high registers that are not automatically restored. */
|
||||
mov r8, r4 /* r8 = r4. */
|
||||
mov r9, r5 /* r9 = r5. */
|
||||
mov r10, r6 /* r10 = r6. */
|
||||
mov r11, r7 /* r11 = r7. */
|
||||
msr psp, r0 /* Remember the new top of stack for the task. */
|
||||
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. */
|
||||
msr psplim, r2 /* Restore the PSPLIM register value for the task. */
|
||||
bx r3
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SVC_Handler:
|
||||
movs r0, #4
|
||||
mov r1, lr
|
||||
tst r0, r1
|
||||
beq stacking_used_msp
|
||||
mrs r0, psp
|
||||
b vPortSVCHandler_C
|
||||
stacking_used_msp:
|
||||
mrs r0, msp
|
||||
b vPortSVCHandler_C
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
END
|
@ -1,299 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||
* and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_FPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Type definitions.
|
||||
*/
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 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. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M23"
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP()
|
||||
#define portINLINE __inline
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
||||
#endif
|
||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||
#define portDONT_DISCARD __root
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Extern declarations.
|
||||
*/
|
||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief MPU specific constants.
|
||||
*/
|
||||
#if( configENABLE_MPU == 1 )
|
||||
#define portUSING_MPU_WRAPPERS 1
|
||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||
#else
|
||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
|
||||
/* MPU regions. */
|
||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||
#define portSTACK_REGION ( 4UL )
|
||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||
#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. */
|
||||
|
||||
/* Device memory attributes used in MPU_MAIR registers.
|
||||
*
|
||||
* 8-bit values encoded as follows:
|
||||
* Bit[7:4] - 0000 - Device Memory
|
||||
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||
* 01 --> Device-nGnRE
|
||||
* 10 --> Device-nGRE
|
||||
* 11 --> Device-GRE
|
||||
* Bit[1:0] - 00, Reserved.
|
||||
*/
|
||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||
|
||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||
#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. */
|
||||
|
||||
/* Attributes used in MPU_RBAR registers. */
|
||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||
|
||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||
|
||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||
} xMPU_SETTINGS;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief SVC numbers.
|
||||
*/
|
||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||
#define portSVC_START_SCHEDULER 2
|
||||
#define portSVC_RAISE_PRIVILEGE 3
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Scheduler utilities.
|
||||
*/
|
||||
#define portYIELD() vPortYield()
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||
*/
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* 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 context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#else
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||
#define portCLEAN_UP_TCB( pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
#define portRAISE_PRIVILEGE()
|
||||
#define portRESET_PRIVILEGE()
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Barriers.
|
||||
*/
|
||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
@ -1,326 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
EXTERN pxCurrentTCB
|
||||
EXTERN xSecureContext
|
||||
EXTERN vTaskSwitchContext
|
||||
EXTERN vPortSVCHandler_C
|
||||
EXTERN SecureContext_SaveContext
|
||||
EXTERN SecureContext_LoadContext
|
||||
|
||||
PUBLIC xIsPrivileged
|
||||
PUBLIC vResetPrivilege
|
||||
PUBLIC vPortAllocateSecureContext
|
||||
PUBLIC vRestoreContextOfFirstTask
|
||||
PUBLIC vRaisePrivilege
|
||||
PUBLIC vStartFirstTask
|
||||
PUBLIC ulSetInterruptMaskFromISR
|
||||
PUBLIC vClearInterruptMaskFromISR
|
||||
PUBLIC PendSV_Handler
|
||||
PUBLIC SVC_Handler
|
||||
PUBLIC vPortFreeSecureContext
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*---------------- Unprivileged Functions -------------------*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
THUMB
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
xIsPrivileged:
|
||||
mrs r0, control /* r0 = CONTROL. */
|
||||
tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
ite ne
|
||||
movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */
|
||||
bx lr /* Return. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vResetPrivilege:
|
||||
mrs r0, control /* r0 = CONTROL. */
|
||||
orr r0, r0, #1 /* r0 = r0 | 1. */
|
||||
msr control, r0 /* CONTROL = r0. */
|
||||
bx lr /* Return to the caller. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vPortAllocateSecureContext:
|
||||
svc 0 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 0. */
|
||||
bx lr /* Return. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*----------------- Privileged Functions --------------------*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SECTION privileged_functions:CODE:NOROOT(2)
|
||||
THUMB
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vRestoreContextOfFirstTask:
|
||||
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
dmb /* Complete outstanding transfers before disabling MPU. */
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location 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. */
|
||||
str r4, [r2] /* Disable MPU. */
|
||||
|
||||
adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
||||
ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */
|
||||
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
str r4, [r2] /* Program MAIR0. */
|
||||
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
movs r4, #4 /* r4 = 4. */
|
||||
str r4, [r2] /* Program RNR = 4. */
|
||||
adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
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. */
|
||||
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location 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. */
|
||||
str r4, [r2] /* Enable MPU. */
|
||||
dsb /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
ldm r0!, {r1-r4} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */
|
||||
ldr r5, =xSecureContext
|
||||
str r1, [r5] /* Set xSecureContext to this task's value for the same. */
|
||||
msr psplim, r2 /* Set this task's PSPLIM value. */
|
||||
msr control, r3 /* Set this task's CONTROL value. */
|
||||
adds r0, #32 /* Discard everything up to r0. */
|
||||
msr psp, r0 /* This is now the new top of stack to use in the task. */
|
||||
isb
|
||||
bx r4 /* Finally, branch to EXC_RETURN. */
|
||||
#else /* configENABLE_MPU */
|
||||
ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||
ldr r4, =xSecureContext
|
||||
str r1, [r4] /* Set xSecureContext to this task's value for the same. */
|
||||
msr psplim, r2 /* Set this task's PSPLIM value. */
|
||||
movs r1, #2 /* r1 = 2. */
|
||||
msr CONTROL, r1 /* Switch to use PSP in the thread mode. */
|
||||
adds r0, #32 /* Discard everything up to r0. */
|
||||
msr psp, r0 /* This is now the new top of stack to use in the task. */
|
||||
isb
|
||||
bx r3 /* Finally, branch to EXC_RETURN. */
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vRaisePrivilege:
|
||||
mrs r0, control /* Read the CONTROL register. */
|
||||
bic r0, r0, #1 /* Clear the bit 0. */
|
||||
msr control, r0 /* Write back the new CONTROL value. */
|
||||
bx lr /* Return to the caller. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vStartFirstTask:
|
||||
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] /* The first entry in vector table is stack pointer. */
|
||||
msr msp, r0 /* Set the MSP back to the start of the stack. */
|
||||
cpsie i /* Globally enable interrupts. */
|
||||
cpsie f
|
||||
dsb
|
||||
isb
|
||||
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
ulSetInterruptMaskFromISR:
|
||||
mrs r0, PRIMASK
|
||||
cpsid i
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vClearInterruptMaskFromISR:
|
||||
msr PRIMASK, r0
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
PendSV_Handler:
|
||||
mrs r1, psp /* Read PSP in r1. */
|
||||
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. */
|
||||
|
||||
cbz r0, save_ns_context /* No secure context to save. */
|
||||
push {r0-r2, r14}
|
||||
bl SecureContext_SaveContext
|
||||
pop {r0-r3} /* LR is now in 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. */
|
||||
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 r2, [r3] /* Read pxCurrentTCB. */
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
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. */
|
||||
mrs r2, psplim /* r2 = PSPLIM. */
|
||||
mrs r3, control /* r3 = CONTROL. */
|
||||
mov r4, lr /* r4 = LR/EXC_RETURN. */
|
||||
stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||
#else /* configENABLE_MPU */
|
||||
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. */
|
||||
mrs r2, psplim /* r2 = PSPLIM. */
|
||||
mov r3, lr /* r3 = LR/EXC_RETURN. */
|
||||
stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
#endif /* configENABLE_MPU */
|
||||
b select_next_task
|
||||
|
||||
save_ns_context:
|
||||
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
ldr r2, [r3] /* Read pxCurrentTCB. */
|
||||
#if ( configENABLE_FPU == 1 )
|
||||
tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
||||
it eq
|
||||
vstmdbeq r1!, {s16-s31} /* Store the FPU registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU */
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
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. */
|
||||
adds r1, r1, #16 /* r1 = r1 + 16. */
|
||||
stm r1, {r4-r11} /* Store the registers that are not saved automatically. */
|
||||
mrs r2, psplim /* r2 = PSPLIM. */
|
||||
mrs r3, control /* r3 = CONTROL. */
|
||||
mov r4, lr /* r4 = LR/EXC_RETURN. */
|
||||
subs r1, r1, #16 /* r1 = r1 - 16. */
|
||||
stm r1, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */
|
||||
#else /* configENABLE_MPU */
|
||||
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. */
|
||||
adds r1, r1, #12 /* r1 = r1 + 12. */
|
||||
stm r1, {r4-r11} /* Store the registers that are not saved automatically. */
|
||||
mrs r2, psplim /* r2 = PSPLIM. */
|
||||
mov r3, lr /* r3 = LR/EXC_RETURN. */
|
||||
subs r1, r1, #12 /* r1 = r1 - 12. */
|
||||
stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
select_next_task:
|
||||
cpsid i
|
||||
bl vTaskSwitchContext
|
||||
cpsie i
|
||||
|
||||
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
dmb /* Complete outstanding transfers before disabling MPU. */
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location 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. */
|
||||
str r4, [r2] /* Disable MPU. */
|
||||
|
||||
adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */
|
||||
ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */
|
||||
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
str r4, [r2] /* Program MAIR0. */
|
||||
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
movs r4, #4 /* r4 = 4. */
|
||||
str r4, [r2] /* Program RNR = 4. */
|
||||
adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */
|
||||
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
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. */
|
||||
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location 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. */
|
||||
str r4, [r2] /* Enable MPU. */
|
||||
dsb /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
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 control, r3 /* Restore the CONTROL register value for the task. */
|
||||
mov lr, r4 /* LR = r4. */
|
||||
ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( 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. */
|
||||
push {r1,r4}
|
||||
bl SecureContext_LoadContext /* Restore the secure context. */
|
||||
pop {r1,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. */
|
||||
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. */
|
||||
bx lr
|
||||
#else /* configENABLE_MPU */
|
||||
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. */
|
||||
mov lr, r3 /* LR = r3. */
|
||||
ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( 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. */
|
||||
push {r1,r3}
|
||||
bl SecureContext_LoadContext /* Restore the secure context. */
|
||||
pop {r1,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. */
|
||||
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. */
|
||||
bx lr
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
restore_ns_context:
|
||||
ldmia r1!, {r4-r11} /* Restore the registers that are not automatically restored. */
|
||||
#if ( configENABLE_FPU == 1 )
|
||||
tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
||||
it eq
|
||||
vldmiaeq r1!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU */
|
||||
msr psp, r1 /* Remember the new top of stack for the task. */
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SVC_Handler:
|
||||
tst lr, #4
|
||||
ite eq
|
||||
mrseq r0, msp
|
||||
mrsne r0, psp
|
||||
b vPortSVCHandler_C
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vPortFreeSecureContext:
|
||||
/* r0 = uint32_t *pulTCB. */
|
||||
ldr r1, [r0] /* The first item in the TCB is the top of the stack. */
|
||||
ldr r0, [r1] /* The first item on the stack is the task's xSecureContext. */
|
||||
cmp r0, #0 /* Raise svc if task's xSecureContext is not NULL. */
|
||||
it ne
|
||||
svcne 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */
|
||||
bx lr /* Return. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
END
|
@ -1,299 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||
* and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_FPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Type definitions.
|
||||
*/
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 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. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M33"
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP()
|
||||
#define portINLINE __inline
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
||||
#endif
|
||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||
#define portDONT_DISCARD __root
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Extern declarations.
|
||||
*/
|
||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief MPU specific constants.
|
||||
*/
|
||||
#if( configENABLE_MPU == 1 )
|
||||
#define portUSING_MPU_WRAPPERS 1
|
||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||
#else
|
||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
|
||||
/* MPU regions. */
|
||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||
#define portSTACK_REGION ( 4UL )
|
||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||
#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. */
|
||||
|
||||
/* Device memory attributes used in MPU_MAIR registers.
|
||||
*
|
||||
* 8-bit values encoded as follows:
|
||||
* Bit[7:4] - 0000 - Device Memory
|
||||
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||
* 01 --> Device-nGnRE
|
||||
* 10 --> Device-nGRE
|
||||
* 11 --> Device-GRE
|
||||
* Bit[1:0] - 00, Reserved.
|
||||
*/
|
||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||
|
||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||
#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. */
|
||||
|
||||
/* Attributes used in MPU_RBAR registers. */
|
||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||
|
||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||
|
||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||
} xMPU_SETTINGS;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief SVC numbers.
|
||||
*/
|
||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||
#define portSVC_START_SCHEDULER 2
|
||||
#define portSVC_RAISE_PRIVILEGE 3
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Scheduler utilities.
|
||||
*/
|
||||
#define portYIELD() vPortYield()
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||
*/
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* 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 context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#else
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||
#define portCLEAN_UP_TCB( pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
#define portRAISE_PRIVILEGE()
|
||||
#define portRESET_PRIVILEGE()
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Barriers.
|
||||
*/
|
||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
@ -1,242 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
EXTERN pxCurrentTCB
|
||||
EXTERN vTaskSwitchContext
|
||||
EXTERN vPortSVCHandler_C
|
||||
|
||||
PUBLIC xIsPrivileged
|
||||
PUBLIC vResetPrivilege
|
||||
PUBLIC vRestoreContextOfFirstTask
|
||||
PUBLIC vRaisePrivilege
|
||||
PUBLIC vStartFirstTask
|
||||
PUBLIC ulSetInterruptMaskFromISR
|
||||
PUBLIC vClearInterruptMaskFromISR
|
||||
PUBLIC PendSV_Handler
|
||||
PUBLIC SVC_Handler
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*---------------- Unprivileged Functions -------------------*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
THUMB
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
xIsPrivileged:
|
||||
mrs r0, control /* r0 = CONTROL. */
|
||||
tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||
ite ne
|
||||
movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||
moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */
|
||||
bx lr /* Return. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vResetPrivilege:
|
||||
mrs r0, control /* r0 = CONTROL. */
|
||||
orr r0, r0, #1 /* r0 = r0 | 1. */
|
||||
msr control, r0 /* CONTROL = r0. */
|
||||
bx lr /* Return to the caller. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*----------------- Privileged Functions --------------------*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SECTION privileged_functions:CODE:NOROOT(2)
|
||||
THUMB
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vRestoreContextOfFirstTask:
|
||||
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
dmb /* Complete outstanding transfers before disabling MPU. */
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location 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. */
|
||||
str r4, [r2] /* Disable MPU. */
|
||||
|
||||
adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
||||
ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */
|
||||
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
str r3, [r2] /* Program MAIR0. */
|
||||
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
movs r3, #4 /* r3 = 4. */
|
||||
str r3, [r2] /* Program RNR = 4. */
|
||||
adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
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. */
|
||||
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location 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. */
|
||||
str r4, [r2] /* Enable MPU. */
|
||||
dsb /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
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 control, r2 /* Set this task's CONTROL value. */
|
||||
adds r0, #32 /* Discard everything up to r0. */
|
||||
msr psp, r0 /* This is now the new top of stack to use in the task. */
|
||||
isb
|
||||
bx r3 /* Finally, branch to EXC_RETURN. */
|
||||
#else /* configENABLE_MPU */
|
||||
ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||
msr psplim, r1 /* Set this task's PSPLIM value. */
|
||||
movs r1, #2 /* r1 = 2. */
|
||||
msr CONTROL, r1 /* Switch to use PSP in the thread mode. */
|
||||
adds r0, #32 /* Discard everything up to r0. */
|
||||
msr psp, r0 /* This is now the new top of stack to use in the task. */
|
||||
isb
|
||||
bx r2 /* Finally, branch to EXC_RETURN. */
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vRaisePrivilege:
|
||||
mrs r0, control /* Read the CONTROL register. */
|
||||
bic r0, r0, #1 /* Clear the bit 0. */
|
||||
msr control, r0 /* Write back the new CONTROL value. */
|
||||
bx lr /* Return to the caller. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vStartFirstTask:
|
||||
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] /* The first entry in vector table is stack pointer. */
|
||||
msr msp, r0 /* Set the MSP back to the start of the stack. */
|
||||
cpsie i /* Globally enable interrupts. */
|
||||
cpsie f
|
||||
dsb
|
||||
isb
|
||||
svc 2 /* System call to start the first task. portSVC_START_SCHEDULER = 2. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
ulSetInterruptMaskFromISR:
|
||||
mrs r0, PRIMASK
|
||||
cpsid i
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vClearInterruptMaskFromISR:
|
||||
msr PRIMASK, r0
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
PendSV_Handler:
|
||||
mrs r0, psp /* Read PSP in r0. */
|
||||
#if ( configENABLE_FPU == 1 )
|
||||
tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */
|
||||
it eq
|
||||
vstmdbeq r0!, {s16-s31} /* Store the FPU registers which are not saved automatically. */
|
||||
#endif /* configENABLE_FPU */
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
mrs r1, psplim /* r1 = PSPLIM. */
|
||||
mrs r2, control /* r2 = CONTROL. */
|
||||
mov r3, lr /* r3 = LR/EXC_RETURN. */
|
||||
stmdb r0!, {r1-r11} /* Store on the stack - PSPLIM, CONTROL, LR and registers that are not automatically saved. */
|
||||
#else /* configENABLE_MPU */
|
||||
mrs r2, psplim /* r2 = PSPLIM. */
|
||||
mov r3, lr /* r3 = LR/EXC_RETURN. */
|
||||
stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||
ldr r1, [r2] /* Read pxCurrentTCB. */
|
||||
str r0, [r1] /* Save the new top of stack in TCB. */
|
||||
|
||||
cpsid i
|
||||
bl vTaskSwitchContext
|
||||
cpsie i
|
||||
|
||||
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( 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. */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
dmb /* Complete outstanding transfers before disabling MPU. */
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location 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. */
|
||||
str r4, [r2] /* Disable MPU. */
|
||||
|
||||
adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */
|
||||
ldr r3, [r1] /* r3 = *r1 i.e. r3 = MAIR0. */
|
||||
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||
str r3, [r2] /* Program MAIR0. */
|
||||
ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */
|
||||
movs r3, #4 /* r3 = 4. */
|
||||
str r3, [r2] /* Program RNR = 4. */
|
||||
adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */
|
||||
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||
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. */
|
||||
|
||||
ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location 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. */
|
||||
str r4, [r2] /* Enable MPU. */
|
||||
dsb /* Force memory writes before continuing. */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
ldmia r0!, {r1-r11} /* Read from stack - r1 = PSPLIM, r2 = CONTROL, r3 = LR and r4-r11 restored. */
|
||||
#else /* configENABLE_MPU */
|
||||
ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#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. */
|
||||
it eq
|
||||
vldmiaeq r0!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */
|
||||
#endif /* configENABLE_FPU */
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
msr psplim, r1 /* Restore the PSPLIM register value for the task. */
|
||||
msr control, r2 /* Restore the CONTROL register value for the task. */
|
||||
#else /* configENABLE_MPU */
|
||||
msr psplim, r2 /* Restore the PSPLIM register value for the task. */
|
||||
#endif /* configENABLE_MPU */
|
||||
msr psp, r0 /* Remember the new top of stack for the task. */
|
||||
bx r3
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SVC_Handler:
|
||||
tst lr, #4
|
||||
ite eq
|
||||
mrseq r0, msp
|
||||
mrsne r0, psp
|
||||
b vPortSVCHandler_C
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
END
|
@ -1,299 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||
* and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_FPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Type definitions.
|
||||
*/
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 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. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portARCH_NAME "Cortex-M33"
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP()
|
||||
#define portINLINE __inline
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
||||
#endif
|
||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||
#define portDONT_DISCARD __root
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Extern declarations.
|
||||
*/
|
||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief MPU specific constants.
|
||||
*/
|
||||
#if( configENABLE_MPU == 1 )
|
||||
#define portUSING_MPU_WRAPPERS 1
|
||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||
#else
|
||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
|
||||
/* MPU regions. */
|
||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||
#define portSTACK_REGION ( 4UL )
|
||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||
#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. */
|
||||
|
||||
/* Device memory attributes used in MPU_MAIR registers.
|
||||
*
|
||||
* 8-bit values encoded as follows:
|
||||
* Bit[7:4] - 0000 - Device Memory
|
||||
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||
* 01 --> Device-nGnRE
|
||||
* 10 --> Device-nGRE
|
||||
* 11 --> Device-GRE
|
||||
* Bit[1:0] - 00, Reserved.
|
||||
*/
|
||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||
|
||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||
#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. */
|
||||
|
||||
/* Attributes used in MPU_RBAR registers. */
|
||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||
|
||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||
|
||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||
} xMPU_SETTINGS;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief SVC numbers.
|
||||
*/
|
||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||
#define portSVC_START_SCHEDULER 2
|
||||
#define portSVC_RAISE_PRIVILEGE 3
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Scheduler utilities.
|
||||
*/
|
||||
#define portYIELD() vPortYield()
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||
*/
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* 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 context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#else
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||
#define portCLEAN_UP_TCB( pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
#define portRAISE_PRIVILEGE()
|
||||
#define portRESET_PRIVILEGE()
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Barriers.
|
||||
*/
|
||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef __PORT_ASM_H__
|
||||
#define __PORT_ASM_H__
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
/* MPU wrappers includes. */
|
||||
#include "mpu_wrappers.h"
|
||||
|
||||
/**
|
||||
* @brief Restore the context of the first task so that the first task starts
|
||||
* executing.
|
||||
*/
|
||||
void vRestoreContextOfFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
BaseType_t xIsPrivileged( void ) __attribute__ (( naked ));
|
||||
|
||||
/**
|
||||
* @brief Raises the privilege level by clearing the bit 0 of the CONTROL
|
||||
* register.
|
||||
*
|
||||
* @note This is a privileged function and should only be called from the kenrel
|
||||
* code.
|
||||
*
|
||||
* Bit 0 of the CONTROL register defines the privilege level of Thread Mode.
|
||||
* Bit[0] = 0 --> The processor is running privileged
|
||||
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||
*/
|
||||
void vRaisePrivilege( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*
|
||||
* Bit 0 of the CONTROL register defines the privilege level of Thread Mode.
|
||||
* Bit[0] = 0 --> The processor is running privileged
|
||||
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||
*/
|
||||
void vResetPrivilege( void ) __attribute__ (( naked ));
|
||||
|
||||
/**
|
||||
* @brief Starts the first task.
|
||||
*/
|
||||
void vStartFirstTask( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* @brief Disables interrupts.
|
||||
*/
|
||||
uint32_t ulSetInterruptMaskFromISR( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* @brief Enables interrupts.
|
||||
*/
|
||||
void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__(( naked )) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* @brief PendSV Exception handler.
|
||||
*/
|
||||
void PendSV_Handler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* @brief SVC Handler.
|
||||
*/
|
||||
void SVC_Handler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* @brief Allocate a Secure context for the calling task.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the stack to be allocated on the
|
||||
* secure side for the calling task.
|
||||
*/
|
||||
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__ (( naked ));
|
||||
|
||||
/**
|
||||
* @brief Free the task's secure context.
|
||||
*
|
||||
* @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task.
|
||||
*/
|
||||
void vPortFreeSecureContext( uint32_t *pulTCB ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;
|
||||
|
||||
#endif /* __PORT_ASM_H__ */
|
@ -1,295 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.0
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||
* and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_FPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#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.
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Type definitions.
|
||||
*/
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 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. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Architecture specifics.
|
||||
*/
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP()
|
||||
#define portINLINE __inline
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE inline __attribute__(( always_inline ))
|
||||
#endif
|
||||
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Extern declarations.
|
||||
*/
|
||||
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||
|
||||
extern uint32_t ulSetInterruptMaskFromISR( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize );
|
||||
extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* PRIVILEGED_FUNCTION */;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief MPU specific constants.
|
||||
*/
|
||||
#if( configENABLE_MPU == 1 )
|
||||
#define portUSING_MPU_WRAPPERS 1
|
||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||
#else
|
||||
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
|
||||
/* MPU regions. */
|
||||
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||
#define portPRIVILEGED_RAM_REGION ( 2UL )
|
||||
#define portUNPRIVILEGED_DEVICE_REGION ( 3UL )
|
||||
#define portSTACK_REGION ( 4UL )
|
||||
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||
#define portLAST_CONFIGURABLE_REGION ( 7UL )
|
||||
#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. */
|
||||
|
||||
/* Devices Region. */
|
||||
#define portDEVICE_REGION_START_ADDRESS ( 0x50000000 )
|
||||
#define portDEVICE_REGION_END_ADDRESS ( 0x5FFFFFFF )
|
||||
|
||||
/* Device memory attributes used in MPU_MAIR registers.
|
||||
*
|
||||
* 8-bit values encoded as follows:
|
||||
* Bit[7:4] - 0000 - Device Memory
|
||||
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||
* 01 --> Device-nGnRE
|
||||
* 10 --> Device-nGRE
|
||||
* 11 --> Device-GRE
|
||||
* Bit[1:0] - 00, Reserved.
|
||||
*/
|
||||
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||
|
||||
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||
#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. */
|
||||
|
||||
/* Attributes used in MPU_RBAR registers. */
|
||||
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||
|
||||
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||
|
||||
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Settings to define an MPU region.
|
||||
*/
|
||||
typedef struct MPURegionSettings
|
||||
{
|
||||
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||
} MPURegionSettings_t;
|
||||
|
||||
/**
|
||||
* @brief MPU settings as stored in the TCB.
|
||||
*/
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||
} xMPU_SETTINGS;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief SVC numbers.
|
||||
*/
|
||||
#define portSVC_ALLOCATE_SECURE_CONTEXT 0
|
||||
#define portSVC_FREE_SECURE_CONTEXT 1
|
||||
#define portSVC_START_SCHEDULER 2
|
||||
#define portSVC_RAISE_PRIVILEGE 3
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Scheduler utilities.
|
||||
*/
|
||||
#define portYIELD() vPortYield()
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Critical section management.
|
||||
*/
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||
*/
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_TRUSTZONE == 1 )
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
* 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 context before it calls any secure function.
|
||||
*
|
||||
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||
*/
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||
|
||||
/**
|
||||
* @brief Called when a task is deleted to delete the task's secure context,
|
||||
* if it has one.
|
||||
*
|
||||
* @param[in] pxTCB The TCB of the task being deleted.
|
||||
*/
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||
#else
|
||||
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize )
|
||||
#define portCLEAN_UP_TCB( pxTCB )
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Raise an SVC request to raise privilege.
|
||||
*
|
||||
* The SVC handler checks that the SVC was raised from a system call and only
|
||||
* then it raises the privilege. If this is called from any other place,
|
||||
* the privilege is not raised.
|
||||
*/
|
||||
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||
|
||||
/**
|
||||
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||
* register.
|
||||
*/
|
||||
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||
#else
|
||||
#define portIS_PRIVILEGED()
|
||||
#define portRAISE_PRIVILEGE()
|
||||
#define portRESET_PRIVILEGE()
|
||||
#endif /* configENABLE_MPU */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
@ -1,10 +0,0 @@
|
||||
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
|
||||
FreeRTOS/Source/portable/[compiler]/ARM_CM33_NNN directories prior to each
|
||||
FreeRTOS release.
|
||||
|
||||
If your Cortex-M33 application uses TrustZone then use the files from the
|
||||
FreeRTOS/Source/portable/[compiler]/ARM_CM33 directories.
|
||||
|
||||
If your Cortex-M33 application does not use TrustZone then use the files from
|
||||
the FreeRTOS/Source/portable/[compiler]/ARM_CM33_NTZ directories.
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Secure context includes. */
|
||||
#include "secure_context.h"
|
||||
|
||||
/* Secure port macros. */
|
||||
#include "secure_port_macros.h"
|
||||
|
||||
#if( configENABLE_FPU == 1 )
|
||||
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
||||
#endif
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
|
||||
{
|
||||
/* xSecureContextHandle value is in r0. */
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
||||
" 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. */
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
||||
" msr control, r3 \n" /* CONTROL = r3. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" msr psplim, r2 \n" /* PSPLIM = r2. */
|
||||
" msr psp, r1 \n" /* PSP = r1. */
|
||||
" \n"
|
||||
" load_ctx_therad_mode: \n"
|
||||
" nop \n"
|
||||
" \n"
|
||||
:::"r0", "r1", "r2"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
|
||||
{
|
||||
/* xSecureContextHandle value is in r0. */
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
||||
" cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
||||
" mrs r1, psp \n" /* r1 = PSP. */
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" mrs r2, control \n" /* r2 = CONTROL. */
|
||||
" 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. */
|
||||
" stmia r1!, {r2} \n" /* Store CONTROL value on the stack. */
|
||||
#else /* configENABLE_MPU */
|
||||
" str r1, [r0] \n" /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" movs r1, %0 \n" /* r1 = 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. */
|
||||
" \n"
|
||||
" save_ctx_therad_mode: \n"
|
||||
" nop \n"
|
||||
" \n"
|
||||
:: "i" ( securecontextNO_STACK ) : "r1", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Secure context includes. */
|
||||
#include "secure_context.h"
|
||||
|
||||
/* Secure port macros. */
|
||||
#include "secure_port_macros.h"
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
|
||||
{
|
||||
/* xSecureContextHandle value is in r0. */
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
||||
" 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. */
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
||||
" msr control, r3 \n" /* CONTROL = r3. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" msr psplim, r2 \n" /* PSPLIM = r2. */
|
||||
" msr psp, r1 \n" /* PSP = r1. */
|
||||
" \n"
|
||||
" load_ctx_therad_mode: \n"
|
||||
" nop \n"
|
||||
" \n"
|
||||
:::"r0", "r1", "r2"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
|
||||
{
|
||||
/* xSecureContextHandle value is in r0. */
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" \n"
|
||||
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
||||
" cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
||||
" mrs r1, psp \n" /* r1 = PSP. */
|
||||
#if( configENABLE_FPU == 1 )
|
||||
" vstmdb r1!, {s0} \n" /* Trigger the defferred stacking of FPU registers. */
|
||||
" vldmia r1!, {s0} \n" /* Nullify the effect of the pervious statement. */
|
||||
#endif /* configENABLE_FPU */
|
||||
#if( configENABLE_MPU == 1 )
|
||||
" mrs r2, control \n" /* r2 = CONTROL. */
|
||||
" stmdb r1!, {r2} \n" /* Store CONTROL value on the stack. */
|
||||
#endif /* configENABLE_MPU */
|
||||
" str r1, [r0] \n" /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
||||
" movs r1, %0 \n" /* r1 = 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. */
|
||||
" \n"
|
||||
" save_ctx_therad_mode: \n"
|
||||
" nop \n"
|
||||
" \n"
|
||||
:: "i" ( securecontextNO_STACK ) : "r1", "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Secure context includes. */
|
||||
#include "secure_context.h"
|
||||
|
||||
/* Secure port macros. */
|
||||
#include "secure_port_macros.h"
|
||||
|
||||
/* Functions implemented in assembler file. */
|
||||
extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle );
|
||||
extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle );
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
|
||||
{
|
||||
SecureContext_LoadContextAsm( xSecureContextHandle );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
|
||||
{
|
||||
SecureContext_SaveContextAsm( xSecureContextHandle );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
THUMB
|
||||
|
||||
PUBLIC SecureContext_LoadContextAsm
|
||||
PUBLIC SecureContext_SaveContextAsm
|
||||
|
||||
#if ( configENABLE_FPU == 1 )
|
||||
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SecureContext_LoadContextAsm:
|
||||
/* xSecureContextHandle value is in r0. */
|
||||
mrs r1, ipsr /* r1 = IPSR. */
|
||||
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. */
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
||||
msr control, r3 /* CONTROL = r3. */
|
||||
#endif /* configENABLE_MPU */
|
||||
msr psplim, r2 /* PSPLIM = r2. */
|
||||
msr psp, r1 /* PSP = r1. */
|
||||
|
||||
load_ctx_therad_mode:
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SecureContext_SaveContextAsm:
|
||||
/* xSecureContextHandle value is in r0. */
|
||||
mrs r1, ipsr /* r1 = IPSR. */
|
||||
cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
|
||||
mrs r1, psp /* r1 = PSP. */
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
mrs r2, control /* r2 = CONTROL. */
|
||||
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. */
|
||||
stmia r1!, {r2} /* Store CONTROL value on the stack. */
|
||||
#else /* configENABLE_MPU */
|
||||
str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
||||
#endif /* configENABLE_MPU */
|
||||
movs r1, #0 /* r1 = 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. */
|
||||
|
||||
save_ctx_therad_mode:
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
END
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Secure context includes. */
|
||||
#include "secure_context.h"
|
||||
|
||||
/* Secure port macros. */
|
||||
#include "secure_port_macros.h"
|
||||
|
||||
/* Functions implemented in assembler file. */
|
||||
extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle );
|
||||
extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle );
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
|
||||
{
|
||||
SecureContext_LoadContextAsm( xSecureContextHandle );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
|
||||
{
|
||||
SecureContext_SaveContextAsm( xSecureContextHandle );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
THUMB
|
||||
|
||||
PUBLIC SecureContext_LoadContextAsm
|
||||
PUBLIC SecureContext_SaveContextAsm
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SecureContext_LoadContextAsm:
|
||||
/* xSecureContextHandle value is in r0. */
|
||||
mrs r1, ipsr /* r1 = IPSR. */
|
||||
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. */
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
||||
msr control, r3 /* CONTROL = r3. */
|
||||
#endif /* configENABLE_MPU */
|
||||
msr psplim, r2 /* PSPLIM = r2. */
|
||||
msr psp, r1 /* PSP = r1. */
|
||||
|
||||
load_ctx_therad_mode:
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
SecureContext_SaveContextAsm:
|
||||
/* xSecureContextHandle value is in r0. */
|
||||
mrs r1, ipsr /* r1 = IPSR. */
|
||||
cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
|
||||
mrs r1, psp /* r1 = PSP. */
|
||||
#if ( configENABLE_FPU == 1 )
|
||||
vstmdb r1!, {s0} /* Trigger the defferred stacking of FPU registers. */
|
||||
vldmia r1!, {s0} /* Nullify the effect of the pervious statement. */
|
||||
#endif /* configENABLE_FPU */
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
mrs r2, control /* r2 = CONTROL. */
|
||||
stmdb r1!, {r2} /* Store CONTROL value on the stack. */
|
||||
#endif /* configENABLE_MPU */
|
||||
str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
|
||||
movs r1, #0 /* r1 = 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. */
|
||||
|
||||
save_ctx_therad_mode:
|
||||
bx lr
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
END
|
@ -1,204 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Secure context includes. */
|
||||
#include "secure_context.h"
|
||||
|
||||
/* Secure heap includes. */
|
||||
#include "secure_heap.h"
|
||||
|
||||
/* Secure port macros. */
|
||||
#include "secure_port_macros.h"
|
||||
|
||||
/**
|
||||
* @brief CONTROL value for privileged tasks.
|
||||
*
|
||||
* Bit[0] - 0 --> Thread mode is privileged.
|
||||
* Bit[1] - 1 --> Thread mode uses PSP.
|
||||
*/
|
||||
#define securecontextCONTROL_VALUE_PRIVILEGED 0x02
|
||||
|
||||
/**
|
||||
* @brief CONTROL value for un-privileged tasks.
|
||||
*
|
||||
* Bit[0] - 1 --> Thread mode is un-privileged.
|
||||
* Bit[1] - 1 --> Thread mode uses PSP.
|
||||
*/
|
||||
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Structure to represent secure context.
|
||||
*
|
||||
* @note Since stack grows down, pucStackStart is the highest address while
|
||||
* pucStackLimit is the first addess of the allocated memory.
|
||||
*/
|
||||
typedef struct SecureContext
|
||||
{
|
||||
uint8_t *pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
|
||||
uint8_t *pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
|
||||
uint8_t *pucStackStart; /**< First location of the stack memory. */
|
||||
} SecureContext_t;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
{
|
||||
uint32_t ulIPSR;
|
||||
|
||||
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||
secureportREAD_IPSR( ulIPSR );
|
||||
|
||||
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||
* when the processor is running in the Thread Mode. */
|
||||
if( ulIPSR != 0 )
|
||||
{
|
||||
/* No stack for thread mode until a task's context is loaded. */
|
||||
secureportSET_PSPLIM( securecontextNO_STACK );
|
||||
secureportSET_PSP( securecontextNO_STACK );
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||
}
|
||||
#else /* configENABLE_MPU */
|
||||
{
|
||||
/* Configure thread mode to use PSP and to be privileged.. */
|
||||
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged )
|
||||
#else /* configENABLE_MPU */
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
|
||||
#endif /* configENABLE_MPU */
|
||||
{
|
||||
uint8_t *pucStackMemory = NULL;
|
||||
uint32_t ulIPSR;
|
||||
SecureContextHandle_t xSecureContextHandle = NULL;
|
||||
#if( configENABLE_MPU == 1 )
|
||||
uint32_t *pulCurrentStackPointer = NULL;
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||
secureportREAD_IPSR( ulIPSR );
|
||||
|
||||
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||
* when the processor is running in the Thread Mode. */
|
||||
if( ulIPSR != 0 )
|
||||
{
|
||||
/* Allocate the context structure. */
|
||||
xSecureContextHandle = ( SecureContextHandle_t ) pvPortMalloc( sizeof( SecureContext_t ) );
|
||||
|
||||
if( xSecureContextHandle != NULL )
|
||||
{
|
||||
/* Allocate the stack space. */
|
||||
pucStackMemory = pvPortMalloc( ulSecureStackSize );
|
||||
|
||||
if( pucStackMemory != NULL )
|
||||
{
|
||||
/* Since stack grows down, the starting point will be the last
|
||||
* location. Note that this location is next to the last
|
||||
* allocated byte because the hardware decrements the stack
|
||||
* pointer before writing i.e. if stack pointer is 0x2, a push
|
||||
* operation will decrement the stack pointer to 0x1 and then
|
||||
* write at 0x1. */
|
||||
xSecureContextHandle->pucStackStart = pucStackMemory + ulSecureStackSize;
|
||||
|
||||
/* The stack cannot go beyond this location. This value is
|
||||
* programmed in the PSPLIM register on context switch.*/
|
||||
xSecureContextHandle->pucStackLimit = pucStackMemory;
|
||||
|
||||
#if( configENABLE_MPU == 1 )
|
||||
{
|
||||
/* Store the correct CONTROL value for the task on the stack.
|
||||
* This value is programmed in the CONTROL register on
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||
}
|
||||
|
||||
/* Store the current stack pointer. This value is programmed in
|
||||
* the PSP register on context switch. */
|
||||
xSecureContextHandle->pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||
}
|
||||
#else /* configENABLE_MPU */
|
||||
{
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
|
||||
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Free the context to avoid memory leak and make sure to return
|
||||
* NULL to indicate failure. */
|
||||
vPortFree( xSecureContextHandle );
|
||||
xSecureContextHandle = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xSecureContextHandle;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle )
|
||||
{
|
||||
uint32_t ulIPSR;
|
||||
|
||||
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||
secureportREAD_IPSR( ulIPSR );
|
||||
|
||||
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||
* when the processor is running in the Thread Mode. */
|
||||
if( ulIPSR != 0 )
|
||||
{
|
||||
/* Ensure that valid parameters are passed. */
|
||||
secureportASSERT( xSecureContextHandle != NULL );
|
||||
|
||||
/* Free the stack space. */
|
||||
vPortFree( xSecureContextHandle->pucStackLimit );
|
||||
|
||||
/* Free the context itself. */
|
||||
vPortFree( xSecureContextHandle );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef __SECURE_CONTEXT_H__
|
||||
#define __SECURE_CONTEXT_H__
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOSConfig.h"
|
||||
|
||||
/**
|
||||
* @brief PSP value when no task's context is loaded.
|
||||
*/
|
||||
#define securecontextNO_STACK 0x0
|
||||
|
||||
/**
|
||||
* @brief Opaque handle.
|
||||
*/
|
||||
struct SecureContext;
|
||||
typedef struct SecureContext* SecureContextHandle_t;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the secure context management system.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @note This function must be called in the handler mode. It is no-op if called
|
||||
* in the thread mode.
|
||||
*/
|
||||
void SecureContext_Init( void );
|
||||
|
||||
/**
|
||||
* @brief Allocates a context on the secure side.
|
||||
*
|
||||
* @note This function must be called in the handler mode. It is no-op if called
|
||||
* in the thread mode.
|
||||
*
|
||||
* @param[in] ulSecureStackSize Size of the stack to allocate on secure side.
|
||||
* @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise.
|
||||
*
|
||||
* @return Opaque context handle if context is successfully allocated, NULL
|
||||
* otherwise.
|
||||
*/
|
||||
#if( configENABLE_MPU == 1 )
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged );
|
||||
#else /* configENABLE_MPU */
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
/**
|
||||
* @brief Frees the given context.
|
||||
*
|
||||
* @note This function must be called in the handler mode. It is no-op if called
|
||||
* in the thread mode.
|
||||
*
|
||||
* @param[in] xSecureContextHandle Context handle corresponding to the
|
||||
* context to be freed.
|
||||
*/
|
||||
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle );
|
||||
|
||||
/**
|
||||
* @brief Loads the given context.
|
||||
*
|
||||
* @note This function must be called in the handler mode. It is no-op if called
|
||||
* in the thread mode.
|
||||
*
|
||||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be loaded.
|
||||
*/
|
||||
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle );
|
||||
|
||||
/**
|
||||
* @brief Saves the given context.
|
||||
*
|
||||
* @note This function must be called in the handler mode. It is no-op if called
|
||||
* in the thread mode.
|
||||
*
|
||||
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||
* to be saved.
|
||||
*/
|
||||
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle );
|
||||
|
||||
#endif /* __SECURE_CONTEXT_H__ */
|
@ -1,450 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* Secure context heap includes. */
|
||||
#include "secure_heap.h"
|
||||
|
||||
/* Secure port macros. */
|
||||
#include "secure_port_macros.h"
|
||||
|
||||
/**
|
||||
* @brief Total heap size.
|
||||
*/
|
||||
#define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
|
||||
|
||||
/* No test marker by default. */
|
||||
#ifndef mtCOVERAGE_TEST_MARKER
|
||||
#define mtCOVERAGE_TEST_MARKER()
|
||||
#endif
|
||||
|
||||
/* No tracing by default. */
|
||||
#ifndef traceMALLOC
|
||||
#define traceMALLOC( pvReturn, xWantedSize )
|
||||
#endif
|
||||
|
||||
/* No tracing by default. */
|
||||
#ifndef traceFREE
|
||||
#define traceFREE( pv, xBlockSize )
|
||||
#endif
|
||||
|
||||
/* Block sizes must not get too small. */
|
||||
#define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
|
||||
|
||||
/* Assumes 8bit bytes! */
|
||||
#define secureheapBITS_PER_BYTE ( ( size_t ) 8 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Allocate the memory for the heap. */
|
||||
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
|
||||
/* The application writer has already defined the array used for the RTOS
|
||||
* heap - probably so it can be placed in a special segment or address. */
|
||||
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||
#else /* configAPPLICATION_ALLOCATED_HEAP */
|
||||
static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||
#endif /* configAPPLICATION_ALLOCATED_HEAP */
|
||||
|
||||
/**
|
||||
* @brief The linked list structure.
|
||||
*
|
||||
* This is used to link free blocks in order of their memory address.
|
||||
*/
|
||||
typedef struct A_BLOCK_LINK
|
||||
{
|
||||
struct A_BLOCK_LINK *pxNextFreeBlock; /**< The next free block in the list. */
|
||||
size_t xBlockSize; /**< The size of the free block. */
|
||||
} BlockLink_t;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Called automatically to setup the required heap structures the first
|
||||
* time pvPortMalloc() is called.
|
||||
*/
|
||||
static void prvHeapInit( void );
|
||||
|
||||
/**
|
||||
* @brief Inserts a block of memory that is being freed into the correct
|
||||
* position in the list of free memory blocks.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @param[in] pxBlockToInsert The block being freed.
|
||||
*/
|
||||
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief The size of the structure placed at the beginning of each allocated
|
||||
* 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 );
|
||||
|
||||
/**
|
||||
* @brief Create a couple of list links to mark the start and end of the list.
|
||||
*/
|
||||
static BlockLink_t xStart, *pxEnd = NULL;
|
||||
|
||||
/**
|
||||
* @brief Keeps track of the number of free bytes remaining, but says nothing
|
||||
* about fragmentation.
|
||||
*/
|
||||
static size_t xFreeBytesRemaining = 0U;
|
||||
static size_t xMinimumEverFreeBytesRemaining = 0U;
|
||||
|
||||
/**
|
||||
* @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
|
||||
* then the block belongs to the application. When the bit is free the block is
|
||||
* still part of the free heap space.
|
||||
*/
|
||||
static size_t xBlockAllocatedBit = 0;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvHeapInit( void )
|
||||
{
|
||||
BlockLink_t *pxFirstFreeBlock;
|
||||
uint8_t *pucAlignedHeap;
|
||||
size_t uxAddress;
|
||||
size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE;
|
||||
|
||||
/* Ensure the heap starts on a correctly aligned boundary. */
|
||||
uxAddress = ( size_t ) ucHeap;
|
||||
|
||||
if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 )
|
||||
{
|
||||
uxAddress += ( secureportBYTE_ALIGNMENT - 1 );
|
||||
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||
xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
|
||||
}
|
||||
|
||||
pucAlignedHeap = ( uint8_t * ) uxAddress;
|
||||
|
||||
/* 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. */
|
||||
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
|
||||
xStart.xBlockSize = ( size_t ) 0;
|
||||
|
||||
/* pxEnd is used to mark the end of the list of free blocks and is inserted
|
||||
* at the end of the heap space. */
|
||||
uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
|
||||
uxAddress -= xHeapStructSize;
|
||||
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||
pxEnd = ( void * ) uxAddress;
|
||||
pxEnd->xBlockSize = 0;
|
||||
pxEnd->pxNextFreeBlock = NULL;
|
||||
|
||||
/* 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. */
|
||||
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
|
||||
pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
|
||||
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
|
||||
|
||||
/* Only one block exists - and it covers the entire usable heap space. */
|
||||
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||
xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||
|
||||
/* Work out the position of the top bit in a size_t variable. */
|
||||
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert )
|
||||
{
|
||||
BlockLink_t *pxIterator;
|
||||
uint8_t *puc;
|
||||
|
||||
/* Iterate through the list until a block is found that has a higher address
|
||||
* than the block being inserted. */
|
||||
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
|
||||
{
|
||||
/* Nothing to do here, just iterate to the right position. */
|
||||
}
|
||||
|
||||
/* Do the block being inserted, and the block it is being inserted after
|
||||
* make a contiguous block of memory? */
|
||||
puc = ( uint8_t * ) pxIterator;
|
||||
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
|
||||
{
|
||||
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
|
||||
pxBlockToInsert = pxIterator;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* Do the block being inserted, and the block it is being inserted before
|
||||
* make a contiguous block of memory? */
|
||||
puc = ( uint8_t * ) pxBlockToInsert;
|
||||
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
|
||||
{
|
||||
if( pxIterator->pxNextFreeBlock != pxEnd )
|
||||
{
|
||||
/* Form one big block from the two blocks. */
|
||||
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
|
||||
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
|
||||
}
|
||||
else
|
||||
{
|
||||
pxBlockToInsert->pxNextFreeBlock = pxEnd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
|
||||
}
|
||||
|
||||
/* 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
|
||||
* already been set, and should not be set here as that would make it point
|
||||
* to itself. */
|
||||
if( pxIterator != pxBlockToInsert )
|
||||
{
|
||||
pxIterator->pxNextFreeBlock = pxBlockToInsert;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void *pvPortMalloc( size_t xWantedSize )
|
||||
{
|
||||
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
|
||||
void *pvReturn = NULL;
|
||||
|
||||
/* If this is the first call to malloc then the heap will require
|
||||
* initialisation to setup the list of free blocks. */
|
||||
if( pxEnd == NULL )
|
||||
{
|
||||
prvHeapInit();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* 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
|
||||
* to determine who owns the block - the application or the kernel, so it
|
||||
* must be free. */
|
||||
if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
|
||||
{
|
||||
/* The wanted size is increased so it can contain a BlockLink_t
|
||||
* structure in addition to the requested amount of bytes. */
|
||||
if( xWantedSize > 0 )
|
||||
{
|
||||
xWantedSize += xHeapStructSize;
|
||||
|
||||
/* Ensure that blocks are always aligned to the required number of
|
||||
* bytes. */
|
||||
if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 )
|
||||
{
|
||||
/* Byte alignment required. */
|
||||
xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) );
|
||||
secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
|
||||
{
|
||||
/* Traverse the list from the start (lowest address) block until
|
||||
* one of adequate size is found. */
|
||||
pxPreviousBlock = &xStart;
|
||||
pxBlock = xStart.pxNextFreeBlock;
|
||||
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
|
||||
{
|
||||
pxPreviousBlock = pxBlock;
|
||||
pxBlock = pxBlock->pxNextFreeBlock;
|
||||
}
|
||||
|
||||
/* If the end marker was reached then a block of adequate size was
|
||||
* not found. */
|
||||
if( pxBlock != pxEnd )
|
||||
{
|
||||
/* Return the memory space pointed to - jumping over the
|
||||
* BlockLink_t structure at its start. */
|
||||
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
|
||||
|
||||
/* This block is being returned for use so must be taken out
|
||||
* of the list of free blocks. */
|
||||
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
|
||||
|
||||
/* If the block is larger than required it can be split into
|
||||
* two. */
|
||||
if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE )
|
||||
{
|
||||
/* This block is to be split into two. Create a new
|
||||
* block following the number of bytes requested. The void
|
||||
* cast is used to prevent byte alignment warnings from the
|
||||
* compiler. */
|
||||
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
|
||||
secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
|
||||
/* Calculate the sizes of two blocks split from the single
|
||||
* block. */
|
||||
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
|
||||
pxBlock->xBlockSize = xWantedSize;
|
||||
|
||||
/* Insert the new block into the list of free blocks. */
|
||||
prvInsertBlockIntoFreeList( pxNewBlockLink );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
xFreeBytesRemaining -= pxBlock->xBlockSize;
|
||||
|
||||
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
|
||||
{
|
||||
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* The block is being returned - it is allocated and owned by
|
||||
* the application and has no "next" block. */
|
||||
pxBlock->xBlockSize |= xBlockAllocatedBit;
|
||||
pxBlock->pxNextFreeBlock = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
traceMALLOC( pvReturn, xWantedSize );
|
||||
|
||||
#if( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||
{
|
||||
if( pvReturn == NULL )
|
||||
{
|
||||
extern void vApplicationMallocFailedHook( void );
|
||||
vApplicationMallocFailedHook();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
return pvReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortFree( void *pv )
|
||||
{
|
||||
uint8_t *puc = ( uint8_t * ) pv;
|
||||
BlockLink_t *pxLink;
|
||||
|
||||
if( pv != NULL )
|
||||
{
|
||||
/* The memory being freed will have an BlockLink_t structure immediately
|
||||
* before it. */
|
||||
puc -= xHeapStructSize;
|
||||
|
||||
/* This casting is to keep the compiler from issuing warnings. */
|
||||
pxLink = ( void * ) puc;
|
||||
|
||||
/* Check the block is actually allocated. */
|
||||
secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
|
||||
secureportASSERT( pxLink->pxNextFreeBlock == NULL );
|
||||
|
||||
if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
|
||||
{
|
||||
if( pxLink->pxNextFreeBlock == NULL )
|
||||
{
|
||||
/* The block is being returned to the heap - it is no longer
|
||||
* allocated. */
|
||||
pxLink->xBlockSize &= ~xBlockAllocatedBit;
|
||||
|
||||
secureportDISABLE_NON_SECURE_INTERRUPTS();
|
||||
{
|
||||
/* Add this block to the list of free blocks. */
|
||||
xFreeBytesRemaining += pxLink->xBlockSize;
|
||||
traceFREE( pv, pxLink->xBlockSize );
|
||||
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
|
||||
}
|
||||
secureportENABLE_NON_SECURE_INTERRUPTS();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
size_t xPortGetFreeHeapSize( void )
|
||||
{
|
||||
return xFreeBytesRemaining;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
size_t xPortGetMinimumEverFreeHeapSize( void )
|
||||
{
|
||||
return xMinimumEverFreeBytesRemaining;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortInitialiseBlocks( void )
|
||||
{
|
||||
/* This just exists to keep the linker quiet. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef __SECURE_HEAP_H__
|
||||
#define __SECURE_HEAP_H__
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* @brief Allocates memory from heap.
|
||||
*
|
||||
* @param[in] xWantedSize The size of the memory to be allocated.
|
||||
*
|
||||
* @return Pointer to the memory region if the allocation is successful, NULL
|
||||
* otherwise.
|
||||
*/
|
||||
void *pvPortMalloc( size_t xWantedSize );
|
||||
|
||||
/**
|
||||
* @brief Frees the previously allocated memory.
|
||||
*
|
||||
* @param[in] pv Pointer to the memory to be freed.
|
||||
*/
|
||||
void vPortFree( void *pv );
|
||||
|
||||
#endif /* __SECURE_HEAP_H__ */
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* Secure init includes. */
|
||||
#include "secure_init.h"
|
||||
|
||||
/* Secure port macros. */
|
||||
#include "secure_port_macros.h"
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the SCB.
|
||||
*/
|
||||
#define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */
|
||||
#define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL )
|
||||
#define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS )
|
||||
#define secureinitSCB_AIRCR_PRIS_POS ( 14UL )
|
||||
#define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS )
|
||||
|
||||
/**
|
||||
* @brief Constants required to manipulate the FPU.
|
||||
*/
|
||||
#define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */
|
||||
#define secureinitFPCCR_LSPENS_POS ( 29UL )
|
||||
#define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS )
|
||||
#define secureinitFPCCR_TS_POS ( 26UL )
|
||||
#define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS )
|
||||
|
||||
#define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */
|
||||
#define secureinitNSACR_CP10_POS ( 10UL )
|
||||
#define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS )
|
||||
#define secureinitNSACR_CP11_POS ( 11UL )
|
||||
#define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void )
|
||||
{
|
||||
uint32_t ulIPSR;
|
||||
|
||||
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||
secureportREAD_IPSR( ulIPSR );
|
||||
|
||||
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||
* when the processor is running in the Thread Mode. */
|
||||
if( ulIPSR != 0 )
|
||||
{
|
||||
*( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) |
|
||||
( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) |
|
||||
( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
|
||||
{
|
||||
uint32_t ulIPSR;
|
||||
|
||||
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||
secureportREAD_IPSR( ulIPSR );
|
||||
|
||||
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||
* when the processor is running in the Thread Mode. */
|
||||
if( ulIPSR != 0 )
|
||||
{
|
||||
/* CP10 = 1 ==> Non-secure access to the Floating Point Unit is
|
||||
* permitted. CP11 should be programmed to the same value as CP10. */
|
||||
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
|
||||
|
||||
/* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures
|
||||
* that we can enable/disable lazy stacking in port.c file. */
|
||||
*( secureinitFPCCR ) &= ~ ( secureinitFPCCR_LSPENS_MASK );
|
||||
|
||||
/* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP
|
||||
* registers (S16-S31) are also pushed to stack on exception entry and
|
||||
* restored on exception return. */
|
||||
*( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef __SECURE_INIT_H__
|
||||
#define __SECURE_INIT_H__
|
||||
|
||||
/**
|
||||
* @brief De-prioritizes the non-secure exceptions.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @note This function must be called in the handler mode. It is no-op if called
|
||||
* in the thread mode.
|
||||
*/
|
||||
void SecureInit_DePrioritizeNSExceptions( void );
|
||||
|
||||
/**
|
||||
* @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
|
||||
* 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
|
||||
* in the thread mode.
|
||||
*/
|
||||
void SecureInit_EnableNSFPUAccess( void );
|
||||
|
||||
#endif /* __SECURE_INIT_H__ */
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef __SECURE_PORT_MACROS_H__
|
||||
#define __SECURE_PORT_MACROS_H__
|
||||
|
||||
/**
|
||||
* @brief Byte alignment requirements.
|
||||
*/
|
||||
#define secureportBYTE_ALIGNMENT 8
|
||||
#define secureportBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||
|
||||
/**
|
||||
* @brief Macro to declare a function as non-secure callable.
|
||||
*/
|
||||
#if defined( __IAR_SYSTEMS_ICC__ )
|
||||
#define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root
|
||||
#else
|
||||
#define secureportNON_SECURE_CALLABLE __attribute__((cmse_nonsecure_entry)) __attribute__((used))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set the secure PRIMASK value.
|
||||
*/
|
||||
#define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \
|
||||
__asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" )
|
||||
|
||||
/**
|
||||
* @brief Set the non-secure PRIMASK value.
|
||||
*/
|
||||
#define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \
|
||||
__asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" )
|
||||
|
||||
/**
|
||||
* @brief Read the PSP value in the given variable.
|
||||
*/
|
||||
#define secureportREAD_PSP( pucOutCurrentStackPointer ) \
|
||||
__asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) )
|
||||
|
||||
/**
|
||||
* @brief Set the PSP to the given value.
|
||||
*/
|
||||
#define secureportSET_PSP( pucCurrentStackPointer ) \
|
||||
__asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) )
|
||||
|
||||
/**
|
||||
* @brief Set the PSPLIM to the given value.
|
||||
*/
|
||||
#define secureportSET_PSPLIM( pucStackLimit ) \
|
||||
__asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) )
|
||||
|
||||
/**
|
||||
* @brief Set the NonSecure MSP to the given value.
|
||||
*/
|
||||
#define secureportSET_MSP_NS( pucMainStackPointer ) \
|
||||
__asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) )
|
||||
|
||||
/**
|
||||
* @brief Set the CONTROL register to the given value.
|
||||
*/
|
||||
#define secureportSET_CONTROL( ulControl ) \
|
||||
__asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" )
|
||||
|
||||
/**
|
||||
* @brief Read the Interrupt Program Status Register (IPSR) value in the given
|
||||
* variable.
|
||||
*/
|
||||
#define secureportREAD_IPSR( ulIPSR ) \
|
||||
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) )
|
||||
|
||||
/**
|
||||
* @brief PRIMASK value to enable interrupts.
|
||||
*/
|
||||
#define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0
|
||||
|
||||
/**
|
||||
* @brief PRIMASK value to disable interrupts.
|
||||
*/
|
||||
#define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1
|
||||
|
||||
/**
|
||||
* @brief Disable secure interrupts.
|
||||
*/
|
||||
#define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
|
||||
|
||||
/**
|
||||
* @brief Disable non-secure interrupts.
|
||||
*
|
||||
* This effectively disables context switches.
|
||||
*/
|
||||
#define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
|
||||
|
||||
/**
|
||||
* @brief Enable non-secure interrupts.
|
||||
*/
|
||||
#define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL )
|
||||
|
||||
/**
|
||||
* @brief Assert definition.
|
||||
*/
|
||||
#define secureportASSERT( x ) \
|
||||
if( ( x ) == 0 ) \
|
||||
{ \
|
||||
secureportDISABLE_SECURE_INTERRUPTS(); \
|
||||
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
|
||||
for( ;; ); \
|
||||
}
|
||||
|
||||
#endif /* __SECURE_PORT_MACROS_H__ */
|
@ -1,244 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V1.00:
|
||||
|
||||
+ Call to taskYIELD() from within tick ISR has been replaced by the more
|
||||
efficient portSWITCH_CONTEXT().
|
||||
+ ISR function definitions renamed to include the prv prefix.
|
||||
|
||||
Changes from V2.6.1
|
||||
|
||||
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
||||
macro to be consistent with the later ports.
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the Flashlite 186
|
||||
* port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#include <dos.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "portasm.h"
|
||||
|
||||
/*lint -e950 Non ANSI reserved words okay in this file only. */
|
||||
|
||||
#define portTIMER_EOI_TYPE ( 8 )
|
||||
#define portRESET_PIC() portOUTPUT_WORD( ( uint16_t ) 0xff22, portTIMER_EOI_TYPE )
|
||||
#define portTIMER_INT_NUMBER 0x12
|
||||
|
||||
#define portTIMER_1_CONTROL_REGISTER ( ( uint16_t ) 0xff5e )
|
||||
#define portTIMER_0_CONTROL_REGISTER ( ( uint16_t ) 0xff56 )
|
||||
#define portTIMER_INTERRUPT_ENABLE ( ( uint16_t ) 0x2000 )
|
||||
|
||||
/* Setup the hardware to generate the required tick frequency. */
|
||||
static void prvSetTickFrequency( uint32_t ulTickRateHz );
|
||||
|
||||
/* Set the hardware back to the state as per before the scheduler started. */
|
||||
static void prvExitFunction( void );
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||
is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
being used. */
|
||||
static void __interrupt __far prvPreemptiveTick( void );
|
||||
#else
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
being used. */
|
||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||
#endif
|
||||
|
||||
/* Trap routine used by taskYIELD() to manually cause a context switch. */
|
||||
static void __interrupt __far prvYieldProcessor( void );
|
||||
|
||||
/*lint -e956 File scopes necessary here. */
|
||||
|
||||
/* Set true when the vectors are set so the scheduler will service the tick. */
|
||||
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(). */
|
||||
static void ( __interrupt __far *pxOldSwitchISR )();
|
||||
|
||||
/* Used to restore the original DOS context when the scheduler is ended. */
|
||||
static jmp_buf xJumpBuf;
|
||||
|
||||
/*lint +e956 */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* This is called with interrupts already disabled. */
|
||||
|
||||
/* Remember what was on the interrupts we are going to use
|
||||
so we can put them back later if required. */
|
||||
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
||||
|
||||
/* Put our manual switch (yield) function on a known
|
||||
vector. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
{
|
||||
/* Put our tick switch function on the timer interrupt. */
|
||||
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* We want the timer interrupt to just increment the tick count. */
|
||||
_dos_setvect( portTIMER_INT_NUMBER, prvNonPreemptiveTick );
|
||||
}
|
||||
#endif
|
||||
|
||||
prvSetTickFrequency( configTICK_RATE_HZ );
|
||||
|
||||
/* Clean up function if we want to return to DOS. */
|
||||
if( setjmp( xJumpBuf ) != 0 )
|
||||
{
|
||||
prvExitFunction();
|
||||
xSchedulerRunning = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xSchedulerRunning = pdTRUE;
|
||||
|
||||
/* Kick off the scheduler by setting up the context of the first task. */
|
||||
portFIRST_CONTEXT();
|
||||
}
|
||||
|
||||
return xSchedulerRunning;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||
is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
static void __interrupt __far prvPreemptiveTick( void )
|
||||
{
|
||||
/* Get the scheduler to update the task states following the tick. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
/* Switch in the context of the next task to be run. */
|
||||
portSWITCH_CONTEXT();
|
||||
}
|
||||
|
||||
/* Reset the PIC ready for the next time. */
|
||||
portRESET_PIC();
|
||||
}
|
||||
#else
|
||||
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||
{
|
||||
/* 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. */
|
||||
xTaskIncrementTick();
|
||||
portRESET_PIC();
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void __interrupt __far prvYieldProcessor( void )
|
||||
{
|
||||
/* Switch in the context of the next task to be run. */
|
||||
portSWITCH_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Jump back to the processor state prior to starting the
|
||||
scheduler. This means we are not going to be using a
|
||||
task stack frame so the task can be deleted. */
|
||||
longjmp( xJumpBuf, 1 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvExitFunction( void )
|
||||
{
|
||||
const uint16_t usTimerDisable = 0x0000;
|
||||
uint16_t usTimer0Control;
|
||||
|
||||
/* Interrupts should be disabled here anyway - but no
|
||||
harm in making sure. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
if( xSchedulerRunning == pdTRUE )
|
||||
{
|
||||
/* Put back the switch interrupt routines that was in place
|
||||
before the scheduler started. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
||||
}
|
||||
|
||||
/* Disable the timer used for the tick to ensure the scheduler is
|
||||
not called before restoring interrupts. There was previously nothing
|
||||
on this timer so there is no old ISR to restore. */
|
||||
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerDisable );
|
||||
|
||||
/* Restart the DOS tick. */
|
||||
usTimer0Control = portINPUT_WORD( portTIMER_0_CONTROL_REGISTER );
|
||||
usTimer0Control |= portTIMER_INTERRUPT_ENABLE;
|
||||
portOUTPUT_WORD( portTIMER_0_CONTROL_REGISTER, usTimer0Control );
|
||||
|
||||
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
||||
{
|
||||
const uint16_t usMaxCountRegister = 0xff5a;
|
||||
const uint16_t usTimerPriorityRegister = 0xff32;
|
||||
const uint16_t usTimerEnable = 0xC000;
|
||||
const uint16_t usRetrigger = 0x0001;
|
||||
const uint16_t usTimerHighPriority = 0x0000;
|
||||
uint16_t usTimer0Control;
|
||||
|
||||
/* ( CPU frequency / 4 ) / clock 2 max count [inpw( 0xff62 ) = 7] */
|
||||
|
||||
const uint32_t ulClockFrequency = ( uint32_t ) 0x7f31a0UL;
|
||||
|
||||
uint32_t ulTimerCount = ulClockFrequency / ulTickRateHz;
|
||||
|
||||
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerEnable | portTIMER_INTERRUPT_ENABLE | usRetrigger );
|
||||
portOUTPUT_WORD( usMaxCountRegister, ( uint16_t ) ulTimerCount );
|
||||
portOUTPUT_WORD( usTimerPriorityRegister, usTimerHighPriority );
|
||||
|
||||
/* Stop the DOS tick - don't do this if you want to maintain a TOD clock. */
|
||||
usTimer0Control = portINPUT_WORD( portTIMER_0_CONTROL_REGISTER );
|
||||
usTimer0Control &= ~portTIMER_INTERRUPT_ENABLE;
|
||||
portOUTPUT_WORD( portTIMER_0_CONTROL_REGISTER, usTimer0Control );
|
||||
}
|
||||
|
||||
|
||||
/*lint +e950 */
|
||||
|
@ -1,97 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE long
|
||||
#define portLONG long
|
||||
#define portSHORT int
|
||||
#define portSTACK_TYPE uint16_t
|
||||
#define portBASE_TYPE portSHORT
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef short BaseType_t;
|
||||
typedef unsigned short UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section handling. */
|
||||
#define portENTER_CRITICAL() __asm{ pushf } \
|
||||
__asm{ cli } \
|
||||
|
||||
#define portEXIT_CRITICAL() __asm{ popf }
|
||||
|
||||
#define portDISABLE_INTERRUPTS() __asm{ cli }
|
||||
|
||||
#define portENABLE_INTERRUPTS() __asm{ sti }
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portNOP() __asm{ nop }
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portSWITCH_INT_NUMBER 0x80
|
||||
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 2
|
||||
#define portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Compiler specifics. */
|
||||
#define portINPUT_BYTE( xAddr ) inp( xAddr )
|
||||
#define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue )
|
||||
#define portINPUT_WORD( xAddr ) inpw( xAddr )
|
||||
#define portOUTPUT_WORD( xAddr, usValue ) outpw( xAddr, usValue )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void *pvParameters )
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
@ -1,288 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V2.6.1
|
||||
|
||||
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
||||
macro to be consistent with the later ports.
|
||||
|
||||
Changes from V4.0.1
|
||||
|
||||
+ Add function prvSetTickFrequencyDefault() to set the DOS tick back to
|
||||
its proper value when the scheduler exits.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <dos.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "portasm.h"
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the industrial
|
||||
* PC port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*lint -e950 Non ANSI reserved words okay in this file only. */
|
||||
|
||||
#define portTIMER_INT_NUMBER 0x08
|
||||
|
||||
/* Setup hardware for required tick interrupt rate. */
|
||||
static void prvSetTickFrequency( uint32_t ulTickRateHz );
|
||||
|
||||
/* Restore hardware to as it was prior to starting the scheduler. */
|
||||
static void prvExitFunction( void );
|
||||
|
||||
/* 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
|
||||
tick rate. */
|
||||
static void prvPortResetPIC( void );
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
being used. */
|
||||
static void __interrupt __far prvPreemptiveTick( void );
|
||||
#else
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
being used. */
|
||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||
#endif
|
||||
|
||||
/* Trap routine used by taskYIELD() to manually cause a context switch. */
|
||||
static void __interrupt __far prvYieldProcessor( void );
|
||||
|
||||
/* Set the tick frequency back so the floppy drive works correctly when the
|
||||
scheduler exits. */
|
||||
static void prvSetTickFrequencyDefault( void );
|
||||
|
||||
/*lint -e956 File scopes necessary here. */
|
||||
|
||||
/* Used to signal when to chain to the DOS tick, and when to just clear the PIC ourselves. */
|
||||
static int16_t sDOSTickCounter;
|
||||
|
||||
/* Set true when the vectors are set so the scheduler will service the tick. */
|
||||
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(). */
|
||||
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(). */
|
||||
static void ( __interrupt __far *pxOldSwitchISRPlus1 )();
|
||||
|
||||
/* Used to restore the original DOS context when the scheduler is ended. */
|
||||
static jmp_buf xJumpBuf;
|
||||
|
||||
/*lint +e956 */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
pxISR pxOriginalTickISR;
|
||||
|
||||
/* This is called with interrupts already disabled. */
|
||||
|
||||
/* Remember what was on the interrupts we are going to use
|
||||
so we can put them back later if required. */
|
||||
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
|
||||
pxOriginalTickISR = _dos_getvect( portTIMER_INT_NUMBER );
|
||||
pxOldSwitchISRPlus1 = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
|
||||
|
||||
prvSetTickFrequency( configTICK_RATE_HZ );
|
||||
|
||||
/* Put our manual switch (yield) function on a known
|
||||
vector. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||
|
||||
/* Put the old tick on a different interrupt number so we can
|
||||
call it when we want. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOriginalTickISR );
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
{
|
||||
/* Put our tick switch function on the timer interrupt. */
|
||||
_dos_setvect( portTIMER_INT_NUMBER, prvPreemptiveTick );
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* We want the timer interrupt to just increment the tick count. */
|
||||
_dos_setvect( portTIMER_INT_NUMBER, prvNonPreemptiveTick );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
frequency. */
|
||||
sDOSTickCounter = portTICKS_PER_DOS_TICK;
|
||||
|
||||
/* Clean up function if we want to return to DOS. */
|
||||
if( setjmp( xJumpBuf ) != 0 )
|
||||
{
|
||||
prvExitFunction();
|
||||
xSchedulerRunning = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xSchedulerRunning = pdTRUE;
|
||||
|
||||
/* Kick off the scheduler by setting up the context of the first task. */
|
||||
portFIRST_CONTEXT();
|
||||
}
|
||||
|
||||
return xSchedulerRunning;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
#if( configUSE_PREEMPTION == 1 )
|
||||
static void __interrupt __far prvPreemptiveTick( void )
|
||||
{
|
||||
/* Get the scheduler to update the task states following the tick. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
/* Switch in the context of the next task to be run. */
|
||||
portSWITCH_CONTEXT();
|
||||
}
|
||||
|
||||
/* Reset the PIC ready for the next time. */
|
||||
prvPortResetPIC();
|
||||
}
|
||||
#else
|
||||
static void __interrupt __far prvNonPreemptiveTick( void )
|
||||
{
|
||||
/* 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. */
|
||||
xTaskIncrementTick();
|
||||
prvPortResetPIC();
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void __interrupt __far prvYieldProcessor( void )
|
||||
{
|
||||
/* Switch in the context of the next task to be run. */
|
||||
portSWITCH_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvPortResetPIC( void )
|
||||
{
|
||||
/* We are going to call the DOS tick interrupt at as close a
|
||||
frequency to the normal DOS tick as possible. */
|
||||
|
||||
/* WE SHOULD NOT DO THIS IF YIELD WAS CALLED. */
|
||||
--sDOSTickCounter;
|
||||
if( sDOSTickCounter <= 0 )
|
||||
{
|
||||
sDOSTickCounter = ( int16_t ) portTICKS_PER_DOS_TICK;
|
||||
__asm{ int portSWITCH_INT_NUMBER + 1 };
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset the PIC as the DOS tick is not being called to
|
||||
do it. */
|
||||
__asm
|
||||
{
|
||||
mov al, 20H
|
||||
out 20H, al
|
||||
};
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Jump back to the processor state prior to starting the
|
||||
scheduler. This means we are not going to be using a
|
||||
task stack frame so the task can be deleted. */
|
||||
longjmp( xJumpBuf, 1 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvExitFunction( void )
|
||||
{
|
||||
void ( __interrupt __far *pxOriginalTickISR )();
|
||||
|
||||
/* Interrupts should be disabled here anyway - but no
|
||||
harm in making sure. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
if( xSchedulerRunning == pdTRUE )
|
||||
{
|
||||
/* Set the DOS tick back onto the timer ticker. */
|
||||
pxOriginalTickISR = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
|
||||
_dos_setvect( portTIMER_INT_NUMBER, pxOriginalTickISR );
|
||||
prvSetTickFrequencyDefault();
|
||||
|
||||
/* Put back the switch interrupt routines that was in place
|
||||
before the scheduler started. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
||||
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOldSwitchISRPlus1 );
|
||||
}
|
||||
/* The tick timer is back how DOS wants it. We can re-enable
|
||||
interrupts without the scheduler being called. */
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetTickFrequency( uint32_t ulTickRateHz )
|
||||
{
|
||||
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
||||
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
||||
const uint32_t ulPIT_CONST = ( uint32_t ) 1193180UL;
|
||||
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
||||
uint32_t ulOutput;
|
||||
|
||||
/* Setup the 8245 to tick at the wanted frequency. */
|
||||
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
||||
ulOutput = ulPIT_CONST / ulTickRateHz;
|
||||
portOUTPUT_BYTE( usPIT0, ( uint16_t )( ulOutput & ( uint32_t ) 0xff ) );
|
||||
ulOutput >>= 8;
|
||||
portOUTPUT_BYTE( usPIT0, ( uint16_t ) ( ulOutput & ( uint32_t ) 0xff ) );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetTickFrequencyDefault( void )
|
||||
{
|
||||
const uint16_t usPIT_MODE = ( uint16_t ) 0x43;
|
||||
const uint16_t usPIT0 = ( uint16_t ) 0x40;
|
||||
const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
||||
|
||||
portOUTPUT_BYTE( usPIT_MODE, us8254_CTR0_MODE3 );
|
||||
portOUTPUT_BYTE( usPIT0,0 );
|
||||
portOUTPUT_BYTE( usPIT0,0 );
|
||||
}
|
||||
|
||||
|
||||
/*lint +e950 */
|
||||
|
@ -1,97 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT long
|
||||
#define portDOUBLE long
|
||||
#define portLONG long
|
||||
#define portSHORT int
|
||||
#define portSTACK_TYPE uint16_t
|
||||
#define portBASE_TYPE portSHORT
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef short BaseType_t;
|
||||
typedef unsigned short UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
#define portENTER_CRITICAL() __asm{ pushf } \
|
||||
__asm{ cli } \
|
||||
|
||||
#define portEXIT_CRITICAL() __asm{ popf }
|
||||
|
||||
#define portDISABLE_INTERRUPTS() __asm{ cli }
|
||||
|
||||
#define portENABLE_INTERRUPTS() __asm{ sti }
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portNOP() __asm{ nop }
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portSWITCH_INT_NUMBER 0x80
|
||||
#define portYIELD() __asm{ int portSWITCH_INT_NUMBER }
|
||||
#define portDOS_TICK_RATE ( 18.20648 )
|
||||
#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 portINITIAL_SW ( ( portSTACK_TYPE ) 0x0202 ) /* Start the tasks with interrupts enabled. */
|
||||
#define portBYTE_ALIGNMENT ( 2 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Compiler specifics. */
|
||||
#define portINPUT_BYTE( xAddr ) inp( xAddr )
|
||||
#define portOUTPUT_BYTE( xAddr, ucValue ) outp( xAddr, ucValue )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void *pvParameters )
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORT_ASM_H
|
||||
#define PORT_ASM_H
|
||||
|
||||
typedef void TCB_t;
|
||||
extern volatile TCB_t * volatile pxCurrentTCB;
|
||||
extern void vTaskSwitchContext( void );
|
||||
|
||||
/*
|
||||
* Saves the stack pointer for one task into its TCB, calls
|
||||
* vTaskSwitchContext() to update the TCB being used, then restores the stack
|
||||
* from the new TCB read to run the task.
|
||||
*/
|
||||
void portSWITCH_CONTEXT( void );
|
||||
|
||||
/*
|
||||
* 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
|
||||
* stack.
|
||||
*/
|
||||
void portFIRST_CONTEXT( void );
|
||||
|
||||
/* There are slightly different versions depending on whether you are building
|
||||
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
|
||||
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. */
|
||||
|
||||
#define portSWITCH_CONTEXT() \
|
||||
asm { mov ax, seg pxCurrentTCB } \
|
||||
asm { mov ds, ax } \
|
||||
asm { les bx, pxCurrentTCB } /* Save the stack pointer into the TCB. */ \
|
||||
asm { mov es:0x2[ bx ], ss } \
|
||||
asm { mov es:[ bx ], sp } \
|
||||
asm { call far ptr vTaskSwitchContext } /* Perform the switch. */ \
|
||||
asm { mov ax, seg pxCurrentTCB } /* Restore the stack pointer from the TCB. */ \
|
||||
asm { mov ds, ax } \
|
||||
asm { les bx, dword ptr pxCurrentTCB } \
|
||||
asm { mov ss, es:[ bx + 2 ] } \
|
||||
asm { mov sp, es:[ bx ] }
|
||||
|
||||
#define portFIRST_CONTEXT() \
|
||||
__asm { mov ax, seg pxCurrentTCB } \
|
||||
__asm { mov ds, ax } \
|
||||
__asm { les bx, dword ptr pxCurrentTCB } \
|
||||
__asm { mov ss, es:[ bx + 2 ] } \
|
||||
__asm { mov sp, es:[ bx ] } \
|
||||
__asm { pop bp } \
|
||||
__asm { pop di } \
|
||||
__asm { pop si } \
|
||||
__asm { pop ds } \
|
||||
__asm { pop es } \
|
||||
__asm { pop dx } \
|
||||
__asm { pop cx } \
|
||||
__asm { pop bx } \
|
||||
__asm { pop ax } \
|
||||
__asm { iret }
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,120 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V1.00:
|
||||
|
||||
+ pxPortInitialiseStack() now initialises the stack of new tasks to the
|
||||
same format used by the compiler. This allows the compiler generated
|
||||
interrupt mechanism to be used for context switches.
|
||||
|
||||
Changes from V2.6.1
|
||||
|
||||
+ Move usPortCheckFreeStackSpace() to tasks.c.
|
||||
*/
|
||||
|
||||
|
||||
#include <dos.h>
|
||||
#include <stdlib.h>
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* See header file for description. */
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
StackType_t DS_Reg = 0;
|
||||
|
||||
/* Place a few bytes of known values on the bottom of the stack.
|
||||
This is just useful for debugging. */
|
||||
|
||||
*pxTopOfStack = 0x1111;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x2222;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x3333;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x4444;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x5555;
|
||||
pxTopOfStack--;
|
||||
|
||||
|
||||
/*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
|
||||
instruction to load the program counter, so first there would be the
|
||||
function call with parameters preamble. */
|
||||
|
||||
*pxTopOfStack = FP_SEG( pvParameters );
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = FP_OFF( pvParameters );
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = FP_SEG( pxCode );
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = FP_OFF( pxCode );
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Next the status register and interrupt return address. */
|
||||
*pxTopOfStack = portINITIAL_SW;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = FP_SEG( pxCode );
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = FP_OFF( pxCode );
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The remaining registers would be pushed on the stack by our context
|
||||
switch function. These are loaded with values simply to make debugging
|
||||
easier. */
|
||||
*pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xCCCC; /* CX */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xDDDD; /* DX */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xEEEE; /* ES */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* We need the true data segment. */
|
||||
__asm{ MOV DS_Reg, DS };
|
||||
|
||||
*pxTopOfStack = DS_Reg; /* DS */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x0123; /* SI */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xDDDD; /* DI */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BP */
|
||||
|
||||
/*lint +e950 +e611 +e923 */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -1,621 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the ARM CM4F port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#if( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 )
|
||||
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html
|
||||
#endif
|
||||
|
||||
#ifndef configSYSTICK_CLOCK_HZ
|
||||
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
||||
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||
#else
|
||||
/* The way the SysTick is clocked is not modified in case it is not the same
|
||||
as the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||
#endif
|
||||
|
||||
/* Constants required to manipulate the core. Registers first... */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||
#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||
/* ...then bits in the registers. */
|
||||
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
||||
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
|
||||
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
||||
|
||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
||||
|
||||
/* Constants required to check the validity of an interrupt priority. */
|
||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||
#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) )
|
||||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||
#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 )
|
||||
#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 )
|
||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
||||
#define portPRIGROUP_SHIFT ( 8UL )
|
||||
|
||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||
|
||||
/* Constants required to set up the initial stack. */
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
|
||||
/* The systick is a 24-bit counter. */
|
||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
||||
|
||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
||||
occurred while the SysTick counter is stopped during tickless idle
|
||||
calculations. */
|
||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
||||
|
||||
/* For strict compliance with the Cortex-M spec the task start address should
|
||||
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||
|
||||
/*
|
||||
* Setup the timer to generate the tick interrupts. The implementation in this
|
||||
* file is weak to allow application writers to change the timer used to
|
||||
* generate the tick interrupt.
|
||||
*/
|
||||
void vPortSetupTimerInterrupt( void );
|
||||
|
||||
/*
|
||||
* Exception handlers.
|
||||
*/
|
||||
void xPortSysTickHandler( void );
|
||||
|
||||
/*
|
||||
* Start first task is a separate function so it can be tested in isolation.
|
||||
*/
|
||||
extern void vPortStartFirstTask( void );
|
||||
|
||||
/*
|
||||
* Used to catch tasks that attempt to return from their implementing function.
|
||||
*/
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
setting. */
|
||||
const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. */
|
||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
|
||||
/*
|
||||
* The number of SysTick increments that make up one tick period.
|
||||
*/
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
static uint32_t ulTimerCountsForOneTick = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/*
|
||||
* The maximum number of tick periods that can be suppressed is limited by the
|
||||
* 24 bit resolution of the SysTick timer.
|
||||
*/
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/*
|
||||
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
||||
* power functionality only.
|
||||
*/
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
static uint32_t ulStoppedTimerCompensation = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/*
|
||||
* Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
|
||||
* FreeRTOS API functions are not called from interrupts that have been assigned
|
||||
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
*/
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
static uint8_t ucMaxSysCallPriority = 0;
|
||||
static uint32_t ulMaxPRIGROUPValue = 0;
|
||||
static const volatile uint8_t * const pcInterruptPriorityRegisters = ( uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16;
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
interrupt. */
|
||||
|
||||
/* Offset added to account for the way the MCU uses the stack on entry/exit
|
||||
of interrupts, and to ensure alignment. */
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */
|
||||
|
||||
/* Save code space by skipping register initialisation. */
|
||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
|
||||
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvTaskExitError( void )
|
||||
{
|
||||
/* A function that implements a task must not exit or attempt to return to
|
||||
its caller as there is nothing to return to. If a task wants to exit it
|
||||
should instead call vTaskDelete( NULL ).
|
||||
|
||||
Artificially force an assert() to be triggered if configASSERT() is
|
||||
defined, then stop here so application writers can catch the error. */
|
||||
configASSERT( uxCriticalNesting == ~0UL );
|
||||
portDISABLE_INTERRUPTS();
|
||||
for( ;; );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||
functions can be called. ISR safe functions are those that end in
|
||||
"FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
ensure interrupt entry is as fast and simple as possible.
|
||||
|
||||
Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
possible bits. */
|
||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
ucMaxPriorityValue = *pucFirstUserPriorityRegister;
|
||||
|
||||
/* Use the same mask on the maximum system call priority. */
|
||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
of bits read back. */
|
||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulMaxPRIGROUPValue--;
|
||||
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
|
||||
}
|
||||
|
||||
#ifdef __NVIC_PRIO_BITS
|
||||
{
|
||||
/* Check the CMSIS configuration that defines the number of
|
||||
priority bits matches the number of priority bits actually queried
|
||||
from the hardware. */
|
||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef configPRIO_BITS
|
||||
{
|
||||
/* Check the FreeRTOS configuration that defines the number of
|
||||
priority bits matches the number of priority bits actually queried
|
||||
from the hardware. */
|
||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Shift the priority group value back to its position within the AIRCR
|
||||
register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
value. */
|
||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||
}
|
||||
#endif /* conifgASSERT_DEFINED */
|
||||
|
||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
vPortSetupTimerInterrupt();
|
||||
|
||||
/* Initialise the critical nesting count ready for the first task. */
|
||||
uxCriticalNesting = 0;
|
||||
|
||||
/* Start the first task. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
configASSERT( uxCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
|
||||
/* This is not the interrupt safe version of the enter critical function so
|
||||
assert() if it is being called from an interrupt context. Only API
|
||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||
the critical nesting count is 1 to protect against recursive calls if the
|
||||
assert function also uses a critical section. */
|
||||
if( uxCriticalNesting == 1 )
|
||||
{
|
||||
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
configASSERT( uxCriticalNesting );
|
||||
uxCriticalNesting--;
|
||||
if( uxCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void xPortSysTickHandler( void )
|
||||
{
|
||||
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
||||
executes all interrupts must be unmasked. There is therefore no need to
|
||||
save and then restore the interrupt mask value as its value is already
|
||||
known. */
|
||||
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
/* Increment the RTOS tick. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
/* A context switch is required. Context switching is performed in
|
||||
the PendSV interrupt. Pend the PendSV interrupt. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
}
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
|
||||
#pragma WEAK( vPortSuppressTicksAndSleep )
|
||||
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||
{
|
||||
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
||||
TickType_t xModifiableIdleTime;
|
||||
|
||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
|
||||
{
|
||||
xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
|
||||
}
|
||||
|
||||
/* Stop the SysTick momentarily. The time the SysTick is stopped for
|
||||
is accounted for as best it can be, but using the tickless mode will
|
||||
inevitably result in some tiny drift of the time maintained by the
|
||||
kernel with respect to calendar time. */
|
||||
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
||||
|
||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||
tick periods. -1 is used because this code will execute part way
|
||||
through one of the tick periods. */
|
||||
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
||||
if( ulReloadValue > ulStoppedTimerCompensation )
|
||||
{
|
||||
ulReloadValue -= ulStoppedTimerCompensation;
|
||||
}
|
||||
|
||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||
method as that will mask interrupts that should exit sleep mode. */
|
||||
__asm( " cpsid i" );
|
||||
__asm( " dsb" );
|
||||
__asm( " isb" );
|
||||
|
||||
|
||||
/* If a context switch is pending or a task is waiting for the scheduler
|
||||
to be unsuspended then abandon the low power entry. */
|
||||
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
||||
{
|
||||
/* Restart from whatever is left in the count register to complete
|
||||
this tick period. */
|
||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||
|
||||
/* Restart SysTick. */
|
||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||
|
||||
/* Reset the reload register to the value required for normal tick
|
||||
periods. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||
|
||||
/* Re-enable interrupts - see comments above __disable_interrupt()
|
||||
call above. */
|
||||
__asm( " cpsie i" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the new reload value. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
||||
|
||||
/* Clear the SysTick count flag and set the count value back to
|
||||
zero. */
|
||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||
|
||||
/* Restart SysTick. */
|
||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||
|
||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||
set its parameter to 0 to indicate that its implementation contains
|
||||
its own wait for interrupt or wait for event instruction, and so wfi
|
||||
should not be executed again. However, the original expected idle
|
||||
time variable must remain unmodified, so a copy is taken. */
|
||||
xModifiableIdleTime = xExpectedIdleTime;
|
||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||
if( xModifiableIdleTime > 0 )
|
||||
{
|
||||
__asm( " dsb" );
|
||||
__asm( " wfi" );
|
||||
__asm( " isb" );
|
||||
}
|
||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||
|
||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||
out of sleep mode to execute immediately. see comments above
|
||||
__disable_interrupt() call above. */
|
||||
__asm( " cpsie i" );
|
||||
__asm( " dsb" );
|
||||
__asm( " isb" );
|
||||
|
||||
/* Disable interrupts again because the clock is about to be stopped
|
||||
and interrupts that execute while the clock is stopped will increase
|
||||
any slippage between the time maintained by the RTOS and calendar
|
||||
time. */
|
||||
__asm( " cpsid i" );
|
||||
__asm( " dsb" );
|
||||
__asm( " isb" );
|
||||
|
||||
/* Disable the SysTick clock without reading the
|
||||
portNVIC_SYSTICK_CTRL_REG register to ensure the
|
||||
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
|
||||
the time the SysTick is stopped for is accounted for as best it can
|
||||
be, but using the tickless mode will inevitably result in some tiny
|
||||
drift of the time maintained by the kernel with respect to calendar
|
||||
time*/
|
||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
|
||||
|
||||
/* Determine if the SysTick clock has already counted to zero and
|
||||
been set back to the current reload value (the reload back being
|
||||
correct for the entire expected idle time) or if the SysTick is yet
|
||||
to count to zero (in which case an interrupt other than the SysTick
|
||||
must have brought the system out of sleep mode). */
|
||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||
{
|
||||
uint32_t ulCalculatedLoadValue;
|
||||
|
||||
/* The tick interrupt is already pending, and the SysTick count
|
||||
reloaded with ulReloadValue. Reset the
|
||||
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
||||
period. */
|
||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
||||
|
||||
/* Don't allow a tiny value, or values that have somehow
|
||||
underflowed because the post sleep hook did something
|
||||
that took too long. */
|
||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
||||
{
|
||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
||||
}
|
||||
|
||||
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
||||
|
||||
/* As the pending tick will be processed as soon as this
|
||||
function exits, the tick value maintained by the tick is stepped
|
||||
forward by one less than the time spent waiting. */
|
||||
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Something other than the tick interrupt ended the sleep.
|
||||
Work out how long the sleep lasted rounded to complete tick
|
||||
periods (not the ulReload value which accounted for part
|
||||
ticks). */
|
||||
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||
|
||||
/* How many complete tick periods passed while the processor
|
||||
was waiting? */
|
||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
||||
|
||||
/* The reload value is set to whatever fraction of a single tick
|
||||
period remains. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
||||
}
|
||||
|
||||
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
||||
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
||||
value. */
|
||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||
vTaskStepTick( ulCompleteTickPeriods );
|
||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||
|
||||
/* Exit with interrpts enabled. */
|
||||
__asm( " cpsie i" );
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Setup the systick timer to generate the tick interrupts at the required
|
||||
* frequency.
|
||||
*/
|
||||
#pragma WEAK( vPortSetupTimerInterrupt )
|
||||
void vPortSetupTimerInterrupt( void )
|
||||
{
|
||||
/* Calculate the constants required to configure the tick interrupt. */
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
{
|
||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||
ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
|
||||
}
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/* Stop and clear the SysTick. */
|
||||
portNVIC_SYSTICK_CTRL_REG = 0UL;
|
||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||
|
||||
/* Configure SysTick to interrupt at the requested rate. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
|
||||
void vPortValidateInterruptPriority( void )
|
||||
{
|
||||
extern uint32_t ulPortGetIPSR( void );
|
||||
uint32_t ulCurrentInterrupt;
|
||||
uint8_t ucCurrentPriority;
|
||||
|
||||
ulCurrentInterrupt = ulPortGetIPSR();
|
||||
|
||||
/* Is the interrupt number a user defined interrupt? */
|
||||
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
||||
{
|
||||
/* Look up the interrupt's priority. */
|
||||
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
|
||||
|
||||
/* The following assertion will fail if a service routine (ISR) for
|
||||
an interrupt that has been assigned a priority above
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||
function. ISR safe FreeRTOS API functions must *only* be called
|
||||
from interrupts that have been assigned a priority at or below
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
|
||||
Numerically low interrupt priority numbers represent logically high
|
||||
interrupt priorities, therefore the priority of the interrupt must
|
||||
be set to a value equal to or numerically *higher* than
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
|
||||
Interrupts that use the FreeRTOS API must not be left at their
|
||||
default priority of zero as that is the highest possible priority,
|
||||
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
||||
and therefore also guaranteed to be invalid.
|
||||
|
||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
interrupt entry is as fast and simple as possible.
|
||||
|
||||
The following links provide detailed information:
|
||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html
|
||||
http://www.freertos.org/FAQHelp.html */
|
||||
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
|
||||
}
|
||||
|
||||
/* Priority grouping: The interrupt controller (NVIC) allows the bits
|
||||
that define each interrupt's priority to be split between bits that
|
||||
define the interrupt's pre-emption priority bits and bits that define
|
||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
||||
to be pre-emption priority bits. The following assertion will fail if
|
||||
this is not the case (if some bits represent a sub-priority).
|
||||
|
||||
If the application only uses CMSIS libraries for interrupt
|
||||
configuration then the correct setting can be achieved on all Cortex-M
|
||||
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||
scheduler. Note however that some vendor specific peripheral libraries
|
||||
assume a non-zero priority group setting, in which cases using a value
|
||||
of zero will result in unpredictable behaviour. */
|
||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
||||
}
|
||||
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,144 +0,0 @@
|
||||
;/*
|
||||
; * FreeRTOS Kernel V10.2.1
|
||||
; * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
; *
|
||||
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; * this software and associated documentation files (the "Software"), to deal in
|
||||
; * the Software without restriction, including without limitation the rights to
|
||||
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; * subject to the following conditions:
|
||||
; *
|
||||
; * The above copyright notice and this permission notice shall be included in all
|
||||
; * copies or substantial portions of the Software.
|
||||
; *
|
||||
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
; *
|
||||
; * http://www.FreeRTOS.org
|
||||
; * http://aws.amazon.com/freertos
|
||||
; *
|
||||
; * 1 tab == 4 spaces!
|
||||
; */
|
||||
|
||||
.thumb
|
||||
|
||||
.ref pxCurrentTCB
|
||||
.ref vTaskSwitchContext
|
||||
.ref ulMaxSyscallInterruptPriority
|
||||
|
||||
.def xPortPendSVHandler
|
||||
.def ulPortGetIPSR
|
||||
.def vPortSVCHandler
|
||||
.def vPortStartFirstTask
|
||||
|
||||
NVICOffsetConst: .word 0xE000ED08
|
||||
CPACRConst: .word 0xE000ED88
|
||||
pxCurrentTCBConst: .word pxCurrentTCB
|
||||
ulMaxSyscallInterruptPriorityConst: .word ulMaxSyscallInterruptPriority
|
||||
|
||||
; -----------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
ulPortGetIPSR: .asmfunc
|
||||
mrs r0, ipsr
|
||||
bx r14
|
||||
.endasmfunc
|
||||
; -----------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
vPortSetInterruptMask: .asmfunc
|
||||
push {r0}
|
||||
ldr r0, ulMaxSyscallInterruptPriorityConst
|
||||
msr basepri, r0
|
||||
pop {r0}
|
||||
bx r14
|
||||
.endasmfunc
|
||||
; -----------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
xPortPendSVHandler: .asmfunc
|
||||
mrs r0, psp
|
||||
isb
|
||||
|
||||
;/* Get the location of the current TCB. */
|
||||
ldr r3, pxCurrentTCBConst
|
||||
ldr r2, [r3]
|
||||
|
||||
;/* Save the core registers. */
|
||||
stmdb r0!, {r4-r11}
|
||||
|
||||
;/* Save the new top of stack into the first member of the TCB. */
|
||||
str r0, [r2]
|
||||
|
||||
stmdb sp!, {r3, r14}
|
||||
ldr r0, ulMaxSyscallInterruptPriorityConst
|
||||
ldr r1, [r0]
|
||||
msr basepri, r1
|
||||
dsb
|
||||
isb
|
||||
bl vTaskSwitchContext
|
||||
mov r0, #0
|
||||
msr basepri, r0
|
||||
ldmia sp!, {r3, r14}
|
||||
|
||||
;/* The first item in pxCurrentTCB is the task top of stack. */
|
||||
ldr r1, [r3]
|
||||
ldr r0, [r1]
|
||||
|
||||
;/* Pop the core registers. */
|
||||
ldmia r0!, {r4-r11}
|
||||
|
||||
msr psp, r0
|
||||
isb
|
||||
bx r14
|
||||
.endasmfunc
|
||||
|
||||
; -----------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
vPortSVCHandler: .asmfunc
|
||||
;/* Get the location of the current TCB. */
|
||||
ldr r3, pxCurrentTCBConst
|
||||
ldr r1, [r3]
|
||||
ldr r0, [r1]
|
||||
;/* Pop the core registers. */
|
||||
ldmia r0!, {r4-r11}
|
||||
msr psp, r0
|
||||
isb
|
||||
mov r0, #0
|
||||
msr basepri, r0
|
||||
orr r14, #0xd
|
||||
bx r14
|
||||
.endasmfunc
|
||||
|
||||
; -----------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
vPortStartFirstTask: .asmfunc
|
||||
;/* Use the NVIC offset register to locate the stack. */
|
||||
ldr r0, NVICOffsetConst
|
||||
ldr r0, [r0]
|
||||
ldr r0, [r0]
|
||||
;/* Set the msp back to the start of the stack. */
|
||||
msr msp, r0
|
||||
;/* 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
|
||||
;unnecessary leaving of space in the SVC stack for lazy saving of FPU
|
||||
;registers. */
|
||||
mov r0, #0
|
||||
msr control, r0
|
||||
;/* Call SVC to start the first task. */
|
||||
cpsie i
|
||||
cpsie f
|
||||
dsb
|
||||
isb
|
||||
svc #0
|
||||
.endasmfunc
|
||||
|
||||
; -----------------------------------------------------------
|
||||
|
@ -1,171 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 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. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Compiler directives. */
|
||||
#define portWEAK_SYMBOL __attribute__((weak))
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler utilities. */
|
||||
#define portYIELD() \
|
||||
{ \
|
||||
/* Set a PendSV to request a context switch. */ \
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||
__asm( " dsb" ); \
|
||||
__asm( " isb" ); \
|
||||
}
|
||||
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Check the configuration. */
|
||||
#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.
|
||||
#endif
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_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 ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
{ \
|
||||
_set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \
|
||||
__asm( " dsb" ); \
|
||||
__asm( " isb" ); \
|
||||
}
|
||||
|
||||
#define portENABLE_INTERRUPTS() _set_interrupt_priority( 0 )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
#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 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Tickless idle/low power functionality. */
|
||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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
|
||||
(which build with all the ports) will build. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif
|
||||
|
||||
/* portNOP() is not required by this port. */
|
||||
#define portNOP()
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
@ -1,644 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the ARM CM4F port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#ifndef __TI_VFP_SUPPORT__
|
||||
#error This port can only be used when the project options are configured to enable hardware floating point support.
|
||||
#endif
|
||||
|
||||
#if( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 )
|
||||
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html
|
||||
#endif
|
||||
|
||||
#ifndef configSYSTICK_CLOCK_HZ
|
||||
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
||||
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||
#else
|
||||
/* The way the SysTick is clocked is not modified in case it is not the same
|
||||
as the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||
#endif
|
||||
|
||||
/* Constants required to manipulate the core. Registers first... */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||
#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||
/* ...then bits in the registers. */
|
||||
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
||||
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
|
||||
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
||||
|
||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
||||
|
||||
/* Constants required to check the validity of an interrupt priority. */
|
||||
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
|
||||
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
|
||||
#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) )
|
||||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||
#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 )
|
||||
#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 )
|
||||
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
|
||||
#define portPRIGROUP_SHIFT ( 8UL )
|
||||
|
||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||
|
||||
/* Constants required to manipulate the VFP. */
|
||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||
#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL )
|
||||
|
||||
/* Constants required to set up the initial stack. */
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||
|
||||
/* The systick is a 24-bit counter. */
|
||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
||||
|
||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
||||
occurred while the SysTick counter is stopped during tickless idle
|
||||
calculations. */
|
||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
||||
|
||||
/* For strict compliance with the Cortex-M spec the task start address should
|
||||
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||
|
||||
/*
|
||||
* Setup the timer to generate the tick interrupts. The implementation in this
|
||||
* file is weak to allow application writers to change the timer used to
|
||||
* generate the tick interrupt.
|
||||
*/
|
||||
void vPortSetupTimerInterrupt( void );
|
||||
|
||||
/*
|
||||
* Exception handlers.
|
||||
*/
|
||||
void xPortSysTickHandler( void );
|
||||
|
||||
/*
|
||||
* Start first task is a separate function so it can be tested in isolation.
|
||||
*/
|
||||
extern void vPortStartFirstTask( void );
|
||||
|
||||
/*
|
||||
* Turn the VFP on.
|
||||
*/
|
||||
extern void vPortEnableVFP( void );
|
||||
|
||||
/*
|
||||
* Used to catch tasks that attempt to return from their implementing function.
|
||||
*/
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
setting. */
|
||||
const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. */
|
||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
|
||||
/*
|
||||
* The number of SysTick increments that make up one tick period.
|
||||
*/
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
static uint32_t ulTimerCountsForOneTick = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/*
|
||||
* The maximum number of tick periods that can be suppressed is limited by the
|
||||
* 24 bit resolution of the SysTick timer.
|
||||
*/
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/*
|
||||
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
||||
* power functionality only.
|
||||
*/
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
static uint32_t ulStoppedTimerCompensation = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/*
|
||||
* Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
|
||||
* FreeRTOS API functions are not called from interrupts that have been assigned
|
||||
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
*/
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
static uint8_t ucMaxSysCallPriority = 0;
|
||||
static uint32_t ulMaxPRIGROUPValue = 0;
|
||||
static const volatile uint8_t * const pcInterruptPriorityRegisters = ( uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16;
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
interrupt. */
|
||||
|
||||
/* Offset added to account for the way the MCU uses the stack on entry/exit
|
||||
of interrupts, and to ensure alignment. */
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */
|
||||
|
||||
/* Save code space by skipping register initialisation. */
|
||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
|
||||
/* A save method is being used that requires each task to maintain its
|
||||
own exec return value. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
||||
|
||||
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvTaskExitError( void )
|
||||
{
|
||||
/* A function that implements a task must not exit or attempt to return to
|
||||
its caller as there is nothing to return to. If a task wants to exit it
|
||||
should instead call vTaskDelete( NULL ).
|
||||
|
||||
Artificially force an assert() to be triggered if configASSERT() is
|
||||
defined, then stop here so application writers can catch the error. */
|
||||
configASSERT( uxCriticalNesting == ~0UL );
|
||||
portDISABLE_INTERRUPTS();
|
||||
for( ;; );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint32_t ulOriginalPriority;
|
||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||
functions can be called. ISR safe functions are those that end in
|
||||
"FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||
ensure interrupt entry is as fast and simple as possible.
|
||||
|
||||
Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||
|
||||
/* Determine the number of priority bits available. First write to all
|
||||
possible bits. */
|
||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
ucMaxPriorityValue = *pucFirstUserPriorityRegister;
|
||||
|
||||
/* Use the same mask on the maximum system call priority. */
|
||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
of bits read back. */
|
||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulMaxPRIGROUPValue--;
|
||||
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
|
||||
}
|
||||
|
||||
#ifdef __NVIC_PRIO_BITS
|
||||
{
|
||||
/* Check the CMSIS configuration that defines the number of
|
||||
priority bits matches the number of priority bits actually queried
|
||||
from the hardware. */
|
||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef configPRIO_BITS
|
||||
{
|
||||
/* Check the FreeRTOS configuration that defines the number of
|
||||
priority bits matches the number of priority bits actually queried
|
||||
from the hardware. */
|
||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Shift the priority group value back to its position within the AIRCR
|
||||
register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
value. */
|
||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||
}
|
||||
#endif /* conifgASSERT_DEFINED */
|
||||
|
||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
vPortSetupTimerInterrupt();
|
||||
|
||||
/* Initialise the critical nesting count ready for the first task. */
|
||||
uxCriticalNesting = 0;
|
||||
|
||||
/* Ensure the VFP is enabled - it should be anyway. */
|
||||
vPortEnableVFP();
|
||||
|
||||
/* Lazy save always. */
|
||||
*( portFPCCR ) |= portASPEN_AND_LSPEN_BITS;
|
||||
|
||||
/* Start the first task. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
configASSERT( uxCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
|
||||
/* This is not the interrupt safe version of the enter critical function so
|
||||
assert() if it is being called from an interrupt context. Only API
|
||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||
the critical nesting count is 1 to protect against recursive calls if the
|
||||
assert function also uses a critical section. */
|
||||
if( uxCriticalNesting == 1 )
|
||||
{
|
||||
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
configASSERT( uxCriticalNesting );
|
||||
uxCriticalNesting--;
|
||||
if( uxCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void xPortSysTickHandler( void )
|
||||
{
|
||||
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
||||
executes all interrupts must be unmasked. There is therefore no need to
|
||||
save and then restore the interrupt mask value as its value is already
|
||||
known. */
|
||||
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
/* Increment the RTOS tick. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
/* A context switch is required. Context switching is performed in
|
||||
the PendSV interrupt. Pend the PendSV interrupt. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
}
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
|
||||
#pragma WEAK( vPortSuppressTicksAndSleep )
|
||||
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||
{
|
||||
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
||||
TickType_t xModifiableIdleTime;
|
||||
|
||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
|
||||
{
|
||||
xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
|
||||
}
|
||||
|
||||
/* Stop the SysTick momentarily. The time the SysTick is stopped for
|
||||
is accounted for as best it can be, but using the tickless mode will
|
||||
inevitably result in some tiny drift of the time maintained by the
|
||||
kernel with respect to calendar time. */
|
||||
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
|
||||
|
||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||
tick periods. -1 is used because this code will execute part way
|
||||
through one of the tick periods. */
|
||||
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
||||
if( ulReloadValue > ulStoppedTimerCompensation )
|
||||
{
|
||||
ulReloadValue -= ulStoppedTimerCompensation;
|
||||
}
|
||||
|
||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||
method as that will mask interrupts that should exit sleep mode. */
|
||||
__asm( " cpsid i" );
|
||||
__asm( " dsb" );
|
||||
__asm( " isb" );
|
||||
|
||||
|
||||
/* If a context switch is pending or a task is waiting for the scheduler
|
||||
to be unsuspended then abandon the low power entry. */
|
||||
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
||||
{
|
||||
/* Restart from whatever is left in the count register to complete
|
||||
this tick period. */
|
||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||
|
||||
/* Restart SysTick. */
|
||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||
|
||||
/* Reset the reload register to the value required for normal tick
|
||||
periods. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||
|
||||
/* Re-enable interrupts - see comments above __disable_interrupt()
|
||||
call above. */
|
||||
__asm( " cpsie i" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the new reload value. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
||||
|
||||
/* Clear the SysTick count flag and set the count value back to
|
||||
zero. */
|
||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||
|
||||
/* Restart SysTick. */
|
||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||
|
||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||
set its parameter to 0 to indicate that its implementation contains
|
||||
its own wait for interrupt or wait for event instruction, and so wfi
|
||||
should not be executed again. However, the original expected idle
|
||||
time variable must remain unmodified, so a copy is taken. */
|
||||
xModifiableIdleTime = xExpectedIdleTime;
|
||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||
if( xModifiableIdleTime > 0 )
|
||||
{
|
||||
__asm( " dsb" );
|
||||
__asm( " wfi" );
|
||||
__asm( " isb" );
|
||||
}
|
||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||
|
||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||
out of sleep mode to execute immediately. see comments above
|
||||
__disable_interrupt() call above. */
|
||||
__asm( " cpsie i" );
|
||||
__asm( " dsb" );
|
||||
__asm( " isb" );
|
||||
|
||||
/* Disable interrupts again because the clock is about to be stopped
|
||||
and interrupts that execute while the clock is stopped will increase
|
||||
any slippage between the time maintained by the RTOS and calendar
|
||||
time. */
|
||||
__asm( " cpsid i" );
|
||||
__asm( " dsb" );
|
||||
__asm( " isb" );
|
||||
|
||||
/* Disable the SysTick clock without reading the
|
||||
portNVIC_SYSTICK_CTRL_REG register to ensure the
|
||||
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
|
||||
the time the SysTick is stopped for is accounted for as best it can
|
||||
be, but using the tickless mode will inevitably result in some tiny
|
||||
drift of the time maintained by the kernel with respect to calendar
|
||||
time*/
|
||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
|
||||
|
||||
/* Determine if the SysTick clock has already counted to zero and
|
||||
been set back to the current reload value (the reload back being
|
||||
correct for the entire expected idle time) or if the SysTick is yet
|
||||
to count to zero (in which case an interrupt other than the SysTick
|
||||
must have brought the system out of sleep mode). */
|
||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||
{
|
||||
uint32_t ulCalculatedLoadValue;
|
||||
|
||||
/* The tick interrupt is already pending, and the SysTick count
|
||||
reloaded with ulReloadValue. Reset the
|
||||
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
||||
period. */
|
||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
||||
|
||||
/* Don't allow a tiny value, or values that have somehow
|
||||
underflowed because the post sleep hook did something
|
||||
that took too long. */
|
||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
||||
{
|
||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
||||
}
|
||||
|
||||
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
||||
|
||||
/* As the pending tick will be processed as soon as this
|
||||
function exits, the tick value maintained by the tick is stepped
|
||||
forward by one less than the time spent waiting. */
|
||||
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Something other than the tick interrupt ended the sleep.
|
||||
Work out how long the sleep lasted rounded to complete tick
|
||||
periods (not the ulReload value which accounted for part
|
||||
ticks). */
|
||||
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||
|
||||
/* How many complete tick periods passed while the processor
|
||||
was waiting? */
|
||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
||||
|
||||
/* The reload value is set to whatever fraction of a single tick
|
||||
period remains. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
||||
}
|
||||
|
||||
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
||||
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
||||
value. */
|
||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||
vTaskStepTick( ulCompleteTickPeriods );
|
||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||
|
||||
/* Exit with interrpts enabled. */
|
||||
__asm( " cpsie i" );
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Setup the systick timer to generate the tick interrupts at the required
|
||||
* frequency.
|
||||
*/
|
||||
#pragma WEAK( vPortSetupTimerInterrupt )
|
||||
void vPortSetupTimerInterrupt( void )
|
||||
{
|
||||
/* Calculate the constants required to configure the tick interrupt. */
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
{
|
||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||
ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
|
||||
}
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/* Stop and clear the SysTick. */
|
||||
portNVIC_SYSTICK_CTRL_REG = 0UL;
|
||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||
|
||||
/* Configure SysTick to interrupt at the requested rate. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
|
||||
void vPortValidateInterruptPriority( void )
|
||||
{
|
||||
extern uint32_t ulPortGetIPSR( void );
|
||||
uint32_t ulCurrentInterrupt;
|
||||
uint8_t ucCurrentPriority;
|
||||
|
||||
ulCurrentInterrupt = ulPortGetIPSR();
|
||||
|
||||
/* Is the interrupt number a user defined interrupt? */
|
||||
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
||||
{
|
||||
/* Look up the interrupt's priority. */
|
||||
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
|
||||
|
||||
/* The following assertion will fail if a service routine (ISR) for
|
||||
an interrupt that has been assigned a priority above
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||
function. ISR safe FreeRTOS API functions must *only* be called
|
||||
from interrupts that have been assigned a priority at or below
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
|
||||
Numerically low interrupt priority numbers represent logically high
|
||||
interrupt priorities, therefore the priority of the interrupt must
|
||||
be set to a value equal to or numerically *higher* than
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
|
||||
Interrupts that use the FreeRTOS API must not be left at their
|
||||
default priority of zero as that is the highest possible priority,
|
||||
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
||||
and therefore also guaranteed to be invalid.
|
||||
|
||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
interrupt entry is as fast and simple as possible.
|
||||
|
||||
The following links provide detailed information:
|
||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html
|
||||
http://www.freertos.org/FAQHelp.html */
|
||||
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
|
||||
}
|
||||
|
||||
/* Priority grouping: The interrupt controller (NVIC) allows the bits
|
||||
that define each interrupt's priority to be split between bits that
|
||||
define the interrupt's pre-emption priority bits and bits that define
|
||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
||||
to be pre-emption priority bits. The following assertion will fail if
|
||||
this is not the case (if some bits represent a sub-priority).
|
||||
|
||||
If the application only uses CMSIS libraries for interrupt
|
||||
configuration then the correct setting can be achieved on all Cortex-M
|
||||
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||
scheduler. Note however that some vendor specific peripheral libraries
|
||||
assume a non-zero priority group setting, in which cases using a value
|
||||
of zero will result in unpredictable behaviour. */
|
||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
||||
}
|
||||
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,171 +0,0 @@
|
||||
;/*
|
||||
; * FreeRTOS Kernel V10.2.1
|
||||
; * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
; *
|
||||
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; * this software and associated documentation files (the "Software"), to deal in
|
||||
; * the Software without restriction, including without limitation the rights to
|
||||
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; * subject to the following conditions:
|
||||
; *
|
||||
; * The above copyright notice and this permission notice shall be included in all
|
||||
; * copies or substantial portions of the Software.
|
||||
; *
|
||||
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
; *
|
||||
; * http://www.FreeRTOS.org
|
||||
; * http://aws.amazon.com/freertos
|
||||
; *
|
||||
; * 1 tab == 4 spaces!
|
||||
; */
|
||||
|
||||
.thumb
|
||||
|
||||
.ref pxCurrentTCB
|
||||
.ref vTaskSwitchContext
|
||||
.ref ulMaxSyscallInterruptPriority
|
||||
|
||||
.def xPortPendSVHandler
|
||||
.def ulPortGetIPSR
|
||||
.def vPortSVCHandler
|
||||
.def vPortStartFirstTask
|
||||
.def vPortEnableVFP
|
||||
|
||||
NVICOffsetConst: .word 0xE000ED08
|
||||
CPACRConst: .word 0xE000ED88
|
||||
pxCurrentTCBConst: .word pxCurrentTCB
|
||||
ulMaxSyscallInterruptPriorityConst: .word ulMaxSyscallInterruptPriority
|
||||
|
||||
; -----------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
ulPortGetIPSR: .asmfunc
|
||||
mrs r0, ipsr
|
||||
bx r14
|
||||
.endasmfunc
|
||||
; -----------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
vPortSetInterruptMask: .asmfunc
|
||||
push {r0}
|
||||
ldr r0, ulMaxSyscallInterruptPriorityConst
|
||||
msr basepri, r0
|
||||
pop {r0}
|
||||
bx r14
|
||||
.endasmfunc
|
||||
; -----------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
xPortPendSVHandler: .asmfunc
|
||||
mrs r0, psp
|
||||
isb
|
||||
|
||||
;/* Get the location of the current TCB. */
|
||||
ldr r3, pxCurrentTCBConst
|
||||
ldr r2, [r3]
|
||||
|
||||
;/* Is the task using the FPU context? If so, push high vfp registers. */
|
||||
tst r14, #0x10
|
||||
it eq
|
||||
vstmdbeq r0!, {s16-s31}
|
||||
|
||||
;/* Save the core registers. */
|
||||
stmdb r0!, {r4-r11, r14}
|
||||
|
||||
;/* Save the new top of stack into the first member of the TCB. */
|
||||
str r0, [r2]
|
||||
|
||||
stmdb sp!, {r0, r3}
|
||||
ldr r0, ulMaxSyscallInterruptPriorityConst
|
||||
ldr r1, [r0]
|
||||
msr basepri, r1
|
||||
dsb
|
||||
isb
|
||||
bl vTaskSwitchContext
|
||||
mov r0, #0
|
||||
msr basepri, r0
|
||||
ldmia sp!, {r0, r3}
|
||||
|
||||
;/* The first item in pxCurrentTCB is the task top of stack. */
|
||||
ldr r1, [r3]
|
||||
ldr r0, [r1]
|
||||
|
||||
;/* Pop the core registers. */
|
||||
ldmia r0!, {r4-r11, r14}
|
||||
|
||||
;/* Is the task using the FPU context? If so, pop the high vfp registers
|
||||
;too. */
|
||||
tst r14, #0x10
|
||||
it eq
|
||||
vldmiaeq r0!, {s16-s31}
|
||||
|
||||
msr psp, r0
|
||||
isb
|
||||
bx r14
|
||||
.endasmfunc
|
||||
|
||||
; -----------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
vPortSVCHandler: .asmfunc
|
||||
;/* Get the location of the current TCB. */
|
||||
ldr r3, pxCurrentTCBConst
|
||||
ldr r1, [r3]
|
||||
ldr r0, [r1]
|
||||
;/* Pop the core registers. */
|
||||
ldmia r0!, {r4-r11, r14}
|
||||
msr psp, r0
|
||||
isb
|
||||
mov r0, #0
|
||||
msr basepri, r0
|
||||
bx r14
|
||||
.endasmfunc
|
||||
|
||||
; -----------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
vPortStartFirstTask: .asmfunc
|
||||
;/* Use the NVIC offset register to locate the stack. */
|
||||
ldr r0, NVICOffsetConst
|
||||
ldr r0, [r0]
|
||||
ldr r0, [r0]
|
||||
;/* Set the msp back to the start of the stack. */
|
||||
msr msp, r0
|
||||
;/* 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
|
||||
;unnecessary leaving of space in the SVC stack for lazy saving of FPU
|
||||
;registers. */
|
||||
mov r0, #0
|
||||
msr control, r0
|
||||
;/* Call SVC to start the first task. */
|
||||
cpsie i
|
||||
cpsie f
|
||||
dsb
|
||||
isb
|
||||
svc #0
|
||||
.endasmfunc
|
||||
|
||||
; -----------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
vPortEnableVFP: .asmfunc
|
||||
;/* The FPU enable bits are in the CPACR. */
|
||||
ldr.w r0, CPACRConst
|
||||
ldr r1, [r0]
|
||||
|
||||
;/* Enable CP10 and CP11 coprocessors, then save back. */
|
||||
orr r1, r1, #( 0xf << 20 )
|
||||
str r1, [r0]
|
||||
bx r14
|
||||
.endasmfunc
|
||||
|
||||
.end
|
||||
|
||||
; -----------------------------------------------------------
|
||||
|
@ -1,165 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 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. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler utilities. */
|
||||
#define portYIELD() \
|
||||
{ \
|
||||
/* Set a PendSV to request a context switch. */ \
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||
__asm( " dsb" ); \
|
||||
__asm( " isb" ); \
|
||||
}
|
||||
|
||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Check the configuration. */
|
||||
#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.
|
||||
#endif
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_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 ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
{ \
|
||||
_set_interrupt_priority( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \
|
||||
__asm( " dsb" ); \
|
||||
__asm( " isb" ); \
|
||||
}
|
||||
|
||||
#define portENABLE_INTERRUPTS() _set_interrupt_priority( 0 )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
#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 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Tickless idle/low power functionality. */
|
||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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
|
||||
(which build with all the ports) will build. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif
|
||||
|
||||
/* portNOP() is not required by this port. */
|
||||
#define portNOP()
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
@ -1,312 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Count of the critical section nesting depth. */
|
||||
uint32_t ulCriticalNesting = 9999;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Registers required to configure the RTI. */
|
||||
#define portRTI_GCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC00 ) )
|
||||
#define portRTI_TBCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC04 ) )
|
||||
#define portRTI_COMPCTRL_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC0C ) )
|
||||
#define portRTI_CNT0_FRC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC10 ) )
|
||||
#define portRTI_CNT0_UC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC14 ) )
|
||||
#define portRTI_CNT0_CPUC0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC18 ) )
|
||||
#define portRTI_CNT0_COMP0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC50 ) )
|
||||
#define portRTI_CNT0_UDCP0_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC54 ) )
|
||||
#define portRTI_SETINTENA_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC80 ) )
|
||||
#define portRTI_CLEARINTENA_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC84 ) )
|
||||
#define portRTI_INTFLAG_REG ( * ( ( volatile uint32_t * ) 0xFFFFFC88 ) )
|
||||
|
||||
|
||||
/* Constants required to set up the initial stack of each task. */
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1F )
|
||||
#define portINITIAL_FPSCR ( ( StackType_t ) 0x00 )
|
||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 0x04 )
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
|
||||
/* The number of words on the stack frame between the saved Top Of Stack and
|
||||
R0 (in which the parameters are passed. */
|
||||
#define portSPACE_BETWEEN_TOS_AND_PARAMETERS ( 12 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* vPortStartFirstSTask() is defined in portASM.asm */
|
||||
extern void vPortStartFirstTask( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Saved as part of the task context. Set to pdFALSE if the task does not
|
||||
require an FPU context. */
|
||||
uint32_t ulTaskHasFPUContext = 0;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
StackType_t *pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
#if __TI_VFP_SUPPORT__
|
||||
{
|
||||
/* Ensure the stack is correctly aligned on exit. */
|
||||
pxTopOfStack--;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* 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
|
||||
address appear as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
|
||||
#ifdef portPRELOAD_TASK_REGISTERS
|
||||
{
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
}
|
||||
#else
|
||||
{
|
||||
pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Function parameters are passed in R0. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Set the status register for system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( StackType_t ) ( ( _get_CPSR() & ~0xFF ) | portINITIAL_SPSR );
|
||||
|
||||
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
||||
{
|
||||
/* The task will start in thumb mode. */
|
||||
*pxTopOfStack |= portTHUMB_MODE_BIT;
|
||||
}
|
||||
|
||||
#ifdef __TI_VFP_SUPPORT__
|
||||
{
|
||||
pxTopOfStack--;
|
||||
|
||||
/* 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
|
||||
registers. */
|
||||
*pxTopOfStack = pdFALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupTimerInterrupt(void)
|
||||
{
|
||||
/* Disable timer 0. */
|
||||
portRTI_GCTRL_REG &= 0xFFFFFFFEUL;
|
||||
|
||||
/* Use the internal counter. */
|
||||
portRTI_TBCTRL_REG = 0x00000000U;
|
||||
|
||||
/* COMPSEL0 will use the RTIFRC0 counter. */
|
||||
portRTI_COMPCTRL_REG = 0x00000000U;
|
||||
|
||||
/* Initialise the counter and the prescale counter registers. */
|
||||
portRTI_CNT0_UC0_REG = 0x00000000U;
|
||||
portRTI_CNT0_FRC0_REG = 0x00000000U;
|
||||
|
||||
/* Set Prescalar for RTI clock. */
|
||||
portRTI_CNT0_CPUC0_REG = 0x00000001U;
|
||||
portRTI_CNT0_COMP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ;
|
||||
portRTI_CNT0_UDCP0_REG = ( configCPU_CLOCK_HZ / 2 ) / configTICK_RATE_HZ;
|
||||
|
||||
/* Clear interrupts. */
|
||||
portRTI_INTFLAG_REG = 0x0007000FU;
|
||||
portRTI_CLEARINTENA_REG = 0x00070F0FU;
|
||||
|
||||
/* Enable the compare 0 interrupt. */
|
||||
portRTI_SETINTENA_REG = 0x00000001U;
|
||||
portRTI_GCTRL_REG |= 0x00000001U;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
BaseType_t xPortStartScheduler(void)
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Reset the critical section nesting count read to execute the first task. */
|
||||
ulCriticalNesting = 0;
|
||||
|
||||
/* Start the first task. This is done from portASM.asm as ARM mode must be
|
||||
used. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* Should not get here! */
|
||||
return pdFAIL;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
void vPortEndScheduler(void)
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
configASSERT( ulCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
* simply increment the system tick. */
|
||||
__interrupt void vPortNonPreemptiveTick( void )
|
||||
{
|
||||
/* clear clock interrupt flag */
|
||||
portRTI_INTFLAG_REG = 0x00000001;
|
||||
|
||||
/* Increment the tick count - this may make a delaying task ready
|
||||
to run - but a context switch is not performed. */
|
||||
xTaskIncrementTick();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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
|
||||
* is set to 1 in portmacro.h
|
||||
**************************************************************************
|
||||
*/
|
||||
void vPortPreemptiveTick( void );
|
||||
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/*
|
||||
* Disable interrupts, and keep a count of the nesting depth.
|
||||
*/
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Decrement the critical nesting count, and if it has reached zero, re-enable
|
||||
* interrupts.
|
||||
*/
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting > 0 )
|
||||
{
|
||||
/* Decrement the nesting count as we are leaving a critical section. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
if( ulCriticalNesting == 0 )
|
||||
{
|
||||
/* Enable interrupts as per portENABLE_INTERRUPTS(). */
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if __TI_VFP_SUPPORT__
|
||||
|
||||
void vPortTaskUsesFPU( void )
|
||||
{
|
||||
extern void vPortInitialiseFPSCR( void );
|
||||
|
||||
/* A task is registering the fact that it needs an FPU context. Set the
|
||||
FPU flag (saved as part of the task context. */
|
||||
ulTaskHasFPUContext = pdTRUE;
|
||||
|
||||
/* Initialise the floating point status register. */
|
||||
vPortInitialiseFPSCR();
|
||||
}
|
||||
|
||||
#endif /* __TI_VFP_SUPPORT__ */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -1,229 +0,0 @@
|
||||
;/*
|
||||
; * FreeRTOS Kernel V10.2.1
|
||||
; * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
; *
|
||||
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; * this software and associated documentation files (the "Software"), to deal in
|
||||
; * the Software without restriction, including without limitation the rights to
|
||||
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; * subject to the following conditions:
|
||||
; *
|
||||
; * The above copyright notice and this permission notice shall be included in all
|
||||
; * copies or substantial portions of the Software.
|
||||
; *
|
||||
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
; *
|
||||
; * http://www.FreeRTOS.org
|
||||
; * http://aws.amazon.com/freertos
|
||||
; *
|
||||
; * 1 tab == 4 spaces!
|
||||
; */
|
||||
|
||||
.text
|
||||
.arm
|
||||
.ref vTaskSwitchContext
|
||||
.ref xTaskIncrementTick
|
||||
.ref ulTaskHasFPUContext
|
||||
.ref pxCurrentTCB
|
||||
|
||||
;/*-----------------------------------------------------------*/
|
||||
;
|
||||
; Save Task Context
|
||||
;
|
||||
portSAVE_CONTEXT .macro
|
||||
DSB
|
||||
|
||||
; Push R0 as we are going to use it
|
||||
STMDB SP!, {R0}
|
||||
|
||||
; Set R0 to point to the task stack pointer.
|
||||
STMDB SP,{SP}^
|
||||
SUB SP, SP, #4
|
||||
LDMIA SP!,{R0}
|
||||
|
||||
; Push the return address onto the stack.
|
||||
STMDB R0!, {LR}
|
||||
|
||||
; Now LR has been saved, it can be used instead of R0.
|
||||
MOV LR, R0
|
||||
|
||||
; Pop R0 so it can be saved onto the task stack.
|
||||
LDMIA SP!, {R0}
|
||||
|
||||
; Push all the system mode registers onto the task stack.
|
||||
STMDB LR,{R0-LR}^
|
||||
SUB LR, LR, #60
|
||||
|
||||
; Push the SPSR onto the task stack.
|
||||
MRS R0, SPSR
|
||||
STMDB LR!, {R0}
|
||||
|
||||
.if (__TI_VFP_SUPPORT__)
|
||||
;Determine if the task maintains an FPU context.
|
||||
LDR R0, ulFPUContextConst
|
||||
LDR R0, [R0]
|
||||
|
||||
; Test the flag
|
||||
CMP R0, #0
|
||||
|
||||
; If the task is not using a floating point context then skip the
|
||||
; saving of the FPU registers.
|
||||
BEQ $+16
|
||||
FSTMDBD LR!, {D0-D15}
|
||||
FMRX R1, FPSCR
|
||||
STMFD LR!, {R1}
|
||||
|
||||
; Save the flag
|
||||
STMDB LR!, {R0}
|
||||
.endif
|
||||
|
||||
; Store the new top of stack for the task.
|
||||
LDR R0, pxCurrentTCBConst
|
||||
LDR R0, [R0]
|
||||
STR LR, [R0]
|
||||
|
||||
.endm
|
||||
|
||||
;/*-----------------------------------------------------------*/
|
||||
;
|
||||
; Restore Task Context
|
||||
;
|
||||
portRESTORE_CONTEXT .macro
|
||||
LDR R0, pxCurrentTCBConst
|
||||
LDR R0, [R0]
|
||||
LDR LR, [R0]
|
||||
|
||||
.if (__TI_VFP_SUPPORT__)
|
||||
; The floating point context flag is the first thing on the stack.
|
||||
LDR R0, ulFPUContextConst
|
||||
LDMFD LR!, {R1}
|
||||
STR R1, [R0]
|
||||
|
||||
; Test the flag
|
||||
CMP R1, #0
|
||||
|
||||
; If the task is not using a floating point context then skip the
|
||||
; VFP register loads.
|
||||
BEQ $+16
|
||||
|
||||
; Restore the floating point context.
|
||||
LDMFD LR!, {R0}
|
||||
FLDMIAD LR!, {D0-D15}
|
||||
FMXR FPSCR, R0
|
||||
.endif
|
||||
|
||||
; Get the SPSR from the stack.
|
||||
LDMFD LR!, {R0}
|
||||
MSR SPSR_CSXF, R0
|
||||
|
||||
; Restore all system mode registers for the task.
|
||||
LDMFD LR, {R0-R14}^
|
||||
|
||||
; Restore the return address.
|
||||
LDR LR, [LR, #+60]
|
||||
|
||||
; And return - correcting the offset in the LR to obtain the
|
||||
; correct address.
|
||||
SUBS PC, LR, #4
|
||||
.endm
|
||||
|
||||
;/*-----------------------------------------------------------*/
|
||||
; Start the first task by restoring its context.
|
||||
|
||||
.def vPortStartFirstTask
|
||||
|
||||
vPortStartFirstTask:
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
;/*-----------------------------------------------------------*/
|
||||
; Yield to another task.
|
||||
|
||||
.def vPortYieldProcessor
|
||||
|
||||
vPortYieldProcessor:
|
||||
; 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
|
||||
; return code can be used.
|
||||
ADD LR, LR, #4
|
||||
|
||||
; First save the context of the current task.
|
||||
portSAVE_CONTEXT
|
||||
|
||||
; Select the next task to execute. */
|
||||
BL vTaskSwitchContext
|
||||
|
||||
; Restore the context of the task selected to execute.
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
;/*-----------------------------------------------------------*/
|
||||
; Yield to another task from within the FreeRTOS API
|
||||
|
||||
.def vPortYeildWithinAPI
|
||||
|
||||
vPortYeildWithinAPI:
|
||||
; Save the context of the current task.
|
||||
|
||||
portSAVE_CONTEXT
|
||||
; Clear SSI flag.
|
||||
MOVW R0, #0xFFF4
|
||||
MOVT R0, #0xFFFF
|
||||
LDR R0, [R0]
|
||||
|
||||
; Select the next task to execute. */
|
||||
BL vTaskSwitchContext
|
||||
|
||||
; Restore the context of the task selected to execute.
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
;/*-----------------------------------------------------------*/
|
||||
; Preemptive Tick
|
||||
|
||||
.def vPortPreemptiveTick
|
||||
|
||||
vPortPreemptiveTick:
|
||||
|
||||
; Save the context of the current task.
|
||||
portSAVE_CONTEXT
|
||||
|
||||
; Clear interrupt flag
|
||||
MOVW R0, #0xFC88
|
||||
MOVT R0, #0xFFFF
|
||||
MOV R1, #1
|
||||
STR R1, [R0]
|
||||
|
||||
; Increment the tick count, making any adjustments to the blocked lists
|
||||
; that may be necessary.
|
||||
BL xTaskIncrementTick
|
||||
|
||||
; Select the next task to execute.
|
||||
CMP R0, #0
|
||||
BLNE vTaskSwitchContext
|
||||
|
||||
; Restore the context of the task selected to execute.
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
.if (__TI_VFP_SUPPORT__)
|
||||
|
||||
.def vPortInitialiseFPSCR
|
||||
|
||||
vPortInitialiseFPSCR:
|
||||
|
||||
MOV R0, #0
|
||||
FMXR FPSCR, R0
|
||||
BX LR
|
||||
|
||||
.endif ;__TI_VFP_SUPPORT__
|
||||
|
||||
|
||||
pxCurrentTCBConst .word pxCurrentTCB
|
||||
ulFPUContextConst .word ulTaskHasFPUContext
|
||||
;-------------------------------------------------------------------------------
|
||||
|
@ -1,117 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef __PORTMACRO_H__
|
||||
#define __PORTMACRO_H__
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if (configUSE_16_BIT_TICKS == 1)
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY (TickType_t) 0xFFFF
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY (TickType_t) 0xFFFFFFFFF
|
||||
|
||||
/* 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. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH (-1)
|
||||
#define portTICK_PERIOD_MS ((TickType_t) 1000 / configTICK_RATE_HZ)
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
|
||||
/* Critical section handling. */
|
||||
extern void vPortEnterCritical(void);
|
||||
extern void vPortExitCritical(void);
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
#define portDISABLE_INTERRUPTS() asm( " CPSID I" )
|
||||
#define portENABLE_INTERRUPTS() asm( " CPSIE I" )
|
||||
|
||||
/* Scheduler utilities. */
|
||||
#pragma SWI_ALIAS( vPortYield, 0 )
|
||||
extern void vPortYield( void );
|
||||
#define portYIELD() vPortYield()
|
||||
#define portSYS_SSIR1_REG ( * ( ( volatile uint32_t * ) 0xFFFFFFB0 ) )
|
||||
#define portSYS_SSIR1_SSKEY ( 0x7500UL )
|
||||
#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; }
|
||||
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Check the configuration. */
|
||||
#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.
|
||||
#endif
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_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 ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters)
|
||||
#define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters)
|
||||
|
||||
#endif /* __PORTMACRO_H__ */
|
||||
|
@ -1,53 +0,0 @@
|
||||
;/*
|
||||
; * FreeRTOS Kernel V10.2.1
|
||||
; * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
; *
|
||||
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; * this software and associated documentation files (the "Software"), to deal in
|
||||
; * the Software without restriction, including without limitation the rights to
|
||||
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; * subject to the following conditions:
|
||||
; *
|
||||
; * The above copyright notice and this permission notice shall be included in all
|
||||
; * copies or substantial portions of the Software.
|
||||
; *
|
||||
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
; *
|
||||
; * http://www.FreeRTOS.org
|
||||
; * http://aws.amazon.com/freertos
|
||||
; *
|
||||
; * 1 tab == 4 spaces!
|
||||
; */
|
||||
|
||||
.if $DEFINED( __LARGE_DATA_MODEL__ )
|
||||
.define "pushm.a", pushm_x
|
||||
.define "popm.a", popm_x
|
||||
.define "push.a", push_x
|
||||
.define "pop.a", pop_x
|
||||
.define "mov.a", mov_x
|
||||
.else
|
||||
.define "pushm.w", pushm_x
|
||||
.define "popm.w", popm_x
|
||||
.define "push.w", push_x
|
||||
.define "pop.w", pop_x
|
||||
.define "mov.w", mov_x
|
||||
.endif
|
||||
|
||||
.if $DEFINED( __LARGE_CODE_MODEL__ )
|
||||
.define "calla", call_x
|
||||
.define "reta", ret_x
|
||||
.else
|
||||
.define "call", call_x
|
||||
.define "ret", ret_x
|
||||
.endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,187 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the MSP430X port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
|
||||
not the MCLK. */
|
||||
#define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 )
|
||||
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
|
||||
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 )
|
||||
|
||||
/* We require the address of the pxCurrentTCB variable, but don't want to know
|
||||
any details of its type. */
|
||||
typedef void TCB_t;
|
||||
extern volatile TCB_t * volatile pxCurrentTCB;
|
||||
|
||||
/* 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
|
||||
critical section is exited the count is decremented - with interrupts only
|
||||
being re-enabled if the count is zero.
|
||||
|
||||
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
|
||||
sequence. */
|
||||
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
void vPortSetupTimerInterrupt( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the stack of a task to look exactly as if a call to
|
||||
* portSAVE_CONTEXT had been called.
|
||||
*
|
||||
* See the header file portable.h.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
uint16_t *pusTopOfStack;
|
||||
uint32_t *pulTopOfStack, ulTemp;
|
||||
|
||||
/*
|
||||
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.
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x1111;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x2222;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x3333;
|
||||
pxTopOfStack--;
|
||||
*/
|
||||
|
||||
/* Data types are need either 16 bits or 32 bits depending on the data
|
||||
and code model used. */
|
||||
if( sizeof( pxCode ) == sizeof( uint16_t ) )
|
||||
{
|
||||
pusTopOfStack = ( uint16_t * ) pxTopOfStack;
|
||||
ulTemp = ( uint32_t ) pxCode;
|
||||
*pusTopOfStack = ( uint16_t ) ulTemp;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make room for a 20 bit value stored as a 32 bit value. */
|
||||
pusTopOfStack = ( uint16_t * ) pxTopOfStack;
|
||||
pusTopOfStack--;
|
||||
pulTopOfStack = ( uint32_t * ) pusTopOfStack;
|
||||
*pulTopOfStack = ( uint32_t ) pxCode;
|
||||
}
|
||||
|
||||
pusTopOfStack--;
|
||||
*pusTopOfStack = portFLAGS_INT_ENABLED;
|
||||
pusTopOfStack -= ( sizeof( StackType_t ) / 2 );
|
||||
|
||||
/* From here on the size of stacked items depends on the memory model. */
|
||||
pxTopOfStack = ( StackType_t * ) pusTopOfStack;
|
||||
|
||||
/* Next the general purpose registers. */
|
||||
#ifdef PRELOAD_REGISTER_VALUES
|
||||
*pxTopOfStack = ( StackType_t ) 0xffff;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xeeee;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xdddd;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xbbbb;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xaaaa;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x9999;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x8888;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x5555;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x6666;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x5555;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x4444;
|
||||
pxTopOfStack--;
|
||||
#else
|
||||
pxTopOfStack -= 3;
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||
pxTopOfStack -= 9;
|
||||
#endif
|
||||
|
||||
/* A variable is used to keep track of the critical section nesting.
|
||||
This variable has to be stored as part of the task context and is
|
||||
initially set to zero. */
|
||||
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
|
||||
|
||||
/* 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. */
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the MSP430 port will get stopped. If required simply
|
||||
disable the tick interrupt here. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Hardware initialisation to generate the RTOS tick.
|
||||
*/
|
||||
void vPortSetupTimerInterrupt( void )
|
||||
{
|
||||
vApplicationSetupTimerInterrupt();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#pragma vector=configTICK_VECTOR
|
||||
interrupt void vTickISREntry( void )
|
||||
{
|
||||
extern void vPortTickISR( void );
|
||||
|
||||
__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
|
||||
#if configUSE_PREEMPTION == 1
|
||||
extern void vPortPreemptiveTickISR( void );
|
||||
vPortPreemptiveTickISR();
|
||||
#else
|
||||
extern void vPortCooperativeTickISR( void );
|
||||
vPortCooperativeTickISR();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1,159 +0,0 @@
|
||||
;/*
|
||||
; * FreeRTOS Kernel V10.2.1
|
||||
; * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
; *
|
||||
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; * this software and associated documentation files (the "Software"), to deal in
|
||||
; * the Software without restriction, including without limitation the rights to
|
||||
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; * subject to the following conditions:
|
||||
; *
|
||||
; * The above copyright notice and this permission notice shall be included in all
|
||||
; * copies or substantial portions of the Software.
|
||||
; *
|
||||
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
; *
|
||||
; * http://www.FreeRTOS.org
|
||||
; * http://aws.amazon.com/freertos
|
||||
; *
|
||||
; * 1 tab == 4 spaces!
|
||||
; */
|
||||
|
||||
; * The definition of the "register test" tasks, as described at the top of
|
||||
; * main.c
|
||||
|
||||
.include data_model.h
|
||||
|
||||
.global xTaskIncrementTick
|
||||
.global vTaskSwitchContext
|
||||
.global vPortSetupTimerInterrupt
|
||||
.global pxCurrentTCB
|
||||
.global usCriticalNesting
|
||||
|
||||
.def vPortPreemptiveTickISR
|
||||
.def vPortCooperativeTickISR
|
||||
.def vPortYield
|
||||
.def xPortStartScheduler
|
||||
|
||||
;-----------------------------------------------------------
|
||||
|
||||
portSAVE_CONTEXT .macro
|
||||
|
||||
;Save the remaining registers.
|
||||
pushm_x #12, r15
|
||||
mov.w &usCriticalNesting, r14
|
||||
push_x r14
|
||||
mov_x &pxCurrentTCB, r12
|
||||
mov_x sp, 0( r12 )
|
||||
.endm
|
||||
;-----------------------------------------------------------
|
||||
|
||||
portRESTORE_CONTEXT .macro
|
||||
|
||||
mov_x &pxCurrentTCB, r12
|
||||
mov_x @r12, sp
|
||||
pop_x r15
|
||||
mov.w r15, &usCriticalNesting
|
||||
popm_x #12, r15
|
||||
nop
|
||||
pop.w sr
|
||||
nop
|
||||
ret_x
|
||||
.endm
|
||||
;-----------------------------------------------------------
|
||||
|
||||
;*
|
||||
;* The RTOS tick ISR.
|
||||
;*
|
||||
;* If the cooperative scheduler is in use this simply increments the tick
|
||||
;* count.
|
||||
;*
|
||||
;* If the preemptive scheduler is in use a context switch can also occur.
|
||||
;*/
|
||||
|
||||
.text
|
||||
.align 2
|
||||
|
||||
vPortPreemptiveTickISR: .asmfunc
|
||||
|
||||
; The sr is not saved in portSAVE_CONTEXT() because vPortYield() needs
|
||||
;to save it manually before it gets modified (interrupts get disabled).
|
||||
push.w sr
|
||||
portSAVE_CONTEXT
|
||||
|
||||
call_x #xTaskIncrementTick
|
||||
call_x #vTaskSwitchContext
|
||||
|
||||
portRESTORE_CONTEXT
|
||||
.endasmfunc
|
||||
;-----------------------------------------------------------
|
||||
|
||||
.align 2
|
||||
|
||||
vPortCooperativeTickISR: .asmfunc
|
||||
|
||||
; The sr is not saved in portSAVE_CONTEXT() because vPortYield() needs
|
||||
;to save it manually before it gets modified (interrupts get disabled).
|
||||
push.w sr
|
||||
portSAVE_CONTEXT
|
||||
|
||||
call_x #xTaskIncrementTick
|
||||
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
.endasmfunc
|
||||
;-----------------------------------------------------------
|
||||
|
||||
;
|
||||
; Manual context switch called by the portYIELD() macro.
|
||||
;
|
||||
|
||||
.align 2
|
||||
|
||||
vPortYield: .asmfunc
|
||||
|
||||
; The sr needs saving before it is modified.
|
||||
push.w sr
|
||||
|
||||
; Now the SR is stacked we can disable interrupts.
|
||||
dint
|
||||
nop
|
||||
|
||||
; Save the context of the current task.
|
||||
portSAVE_CONTEXT
|
||||
|
||||
; Select the next task to run.
|
||||
call_x #vTaskSwitchContext
|
||||
|
||||
; Restore the context of the new task.
|
||||
portRESTORE_CONTEXT
|
||||
.endasmfunc
|
||||
;-----------------------------------------------------------
|
||||
|
||||
|
||||
;
|
||||
; Start off the scheduler by initialising the RTOS tick timer, then restoring
|
||||
; the context of the first task.
|
||||
;
|
||||
|
||||
.align 2
|
||||
|
||||
xPortStartScheduler: .asmfunc
|
||||
|
||||
; Setup the hardware to generate the tick. Interrupts are disabled
|
||||
; when this function is called.
|
||||
call_x #vPortSetupTimerInterrupt
|
||||
|
||||
; Restore the context of the first task that is going to run.
|
||||
portRESTORE_CONTEXT
|
||||
.endasmfunc
|
||||
;-----------------------------------------------------------
|
||||
|
||||
.end
|
||||
|
@ -1,143 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Hardware includes. */
|
||||
#include "msp430.h"
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT int
|
||||
#define portBASE_TYPE portSHORT
|
||||
|
||||
/* The stack type changes depending on the data model. */
|
||||
#ifdef __LARGE_DATA_MODEL__
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#else
|
||||
#define portSTACK_TYPE uint16_t
|
||||
#define portPOINTER_SIZE_TYPE uint16_t
|
||||
#endif
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef short BaseType_t;
|
||||
typedef unsigned short UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Interrupt control macros. */
|
||||
#define portDISABLE_INTERRUPTS() _disable_interrupt(); _nop()
|
||||
#define portENABLE_INTERRUPTS() _enable_interrupt(); _nop()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section control macros. */
|
||||
#define portNO_CRITICAL_SECTION_NESTING ( ( uint16_t ) 0 )
|
||||
|
||||
#define portENTER_CRITICAL() \
|
||||
{ \
|
||||
extern volatile uint16_t usCriticalNesting; \
|
||||
\
|
||||
portDISABLE_INTERRUPTS(); \
|
||||
\
|
||||
/* Now interrupts are disabled usCriticalNesting can be accessed */ \
|
||||
/* directly. Increment ulCriticalNesting to keep a count of how many */ \
|
||||
/* times portENTER_CRITICAL() has been called. */ \
|
||||
usCriticalNesting++; \
|
||||
}
|
||||
|
||||
#define portEXIT_CRITICAL() \
|
||||
{ \
|
||||
extern volatile uint16_t usCriticalNesting; \
|
||||
\
|
||||
if( usCriticalNesting > portNO_CRITICAL_SECTION_NESTING ) \
|
||||
{ \
|
||||
/* Decrement the nesting count as we are leaving a critical section. */ \
|
||||
usCriticalNesting--; \
|
||||
\
|
||||
/* If the nesting level has reached zero then interrupts should be */ \
|
||||
/* re-enabled. */ \
|
||||
if( usCriticalNesting == portNO_CRITICAL_SECTION_NESTING ) \
|
||||
{ \
|
||||
portENABLE_INTERRUPTS(); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
|
||||
/*
|
||||
* Manual context switch called by portYIELD or taskYIELD.
|
||||
*/
|
||||
extern void vPortYield( void );
|
||||
#define portYIELD() vPortYield()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portBYTE_ALIGNMENT 2
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portNOP() __no_operation()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
|
||||
extern void vTaskSwitchContext( void );
|
||||
#define portYIELD_FROM_ISR( x ) if( x ) vPortYield()
|
||||
|
||||
void vApplicationSetupTimerInterrupt( void );
|
||||
|
||||
/* sizeof( int ) != sizeof( long ) so a full printf() library is required if
|
||||
run time stats information is to be displayed. */
|
||||
#define portLU_PRINTF_SPECIFIER_REQUIRED
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
@ -1,183 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Kernel includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
|
||||
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
||||
|
||||
/* Supervisor mode set. */
|
||||
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000)
|
||||
|
||||
/* The clock prescale into the timer peripheral. */
|
||||
#define portPRESCALE_VALUE ( ( uint8_t ) 10 )
|
||||
|
||||
/* The clock frequency into the RTC. */
|
||||
#define portRTC_CLOCK_HZ ( ( uint32_t ) 1000 )
|
||||
|
||||
asm void interrupt VectorNumber_VL1swi vPortYieldISR( void );
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/* 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. */
|
||||
static uint32_t ulCriticalNesting = 0x9999UL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
|
||||
uint32_t ulOriginalA5;
|
||||
|
||||
__asm{ MOVE.L A5, ulOriginalA5 };
|
||||
|
||||
|
||||
*pxTopOfStack = (StackType_t) 0xDEADBEEF;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Exception stack frame starts with the return address. */
|
||||
*pxTopOfStack = ( StackType_t ) pxCode;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( portINITIAL_FORMAT_VECTOR << 16UL ) | ( portINITIAL_STATUS_REGISTER );
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x0; /*FP*/
|
||||
pxTopOfStack -= 14; /* A5 to D0. */
|
||||
|
||||
/* Parameter in A0. */
|
||||
*( pxTopOfStack + 8 ) = ( StackType_t ) pvParameters;
|
||||
|
||||
/* A5 must be maintained as it is resurved by the compiler. */
|
||||
*( pxTopOfStack + 13 ) = ulOriginalA5;
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
extern void vPortStartFirstTask( void );
|
||||
|
||||
ulCriticalNesting = 0UL;
|
||||
|
||||
/* Configure a timer to generate the tick interrupt. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task executing. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
/* Prescale by 1 - ie no prescale. */
|
||||
RTCSC |= 8;
|
||||
|
||||
/* Compare match value. */
|
||||
RTCMOD = portRTC_CLOCK_HZ / configTICK_RATE_HZ;
|
||||
|
||||
/* Enable the RTC to generate interrupts - interrupts are already disabled
|
||||
when this code executes. */
|
||||
RTCSC_RTIE = 1;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented as there is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting == 0UL )
|
||||
{
|
||||
/* Guard against context switches being pended simultaneously with a
|
||||
critical section being entered. */
|
||||
do
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
if( INTC_FRC == 0UL )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
} while( 1 );
|
||||
}
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
ulCriticalNesting--;
|
||||
if( ulCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortYieldHandler( void )
|
||||
{
|
||||
uint32_t ulSavedInterruptMask;
|
||||
|
||||
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
/* Note this will clear all forced interrupts - this is done for speed. */
|
||||
INTC_CFRC = 0x3E;
|
||||
vTaskSwitchContext();
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void interrupt VectorNumber_Vrtc vPortTickISR( void )
|
||||
{
|
||||
uint32_t ulSavedInterruptMask;
|
||||
|
||||
/* Clear the interrupt. */
|
||||
RTCSC |= RTCSC_RTIF_MASK;
|
||||
|
||||
/* Increment the RTOS tick. */
|
||||
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
taskYIELD();
|
||||
}
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||
}
|
||||
|
@ -1,130 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
* Purpose: Lowest level routines for all ColdFire processors.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* ulPortSetIPL() and mcf5xxx_wr_cacr() copied with permission from FreeScale
|
||||
* supplied source files.
|
||||
*/
|
||||
|
||||
.global ulPortSetIPL
|
||||
.global _ulPortSetIPL
|
||||
.global mcf5xxx_wr_cacrx
|
||||
.global _mcf5xxx_wr_cacrx
|
||||
.global vPortYieldISR
|
||||
.global _vPortYieldISR
|
||||
.global vPortStartFirstTask
|
||||
.global _vPortStartFirstTask
|
||||
.extern _pxCurrentTCB
|
||||
.extern _vPortYieldHandler
|
||||
|
||||
.text
|
||||
|
||||
.macro portSAVE_CONTEXT
|
||||
|
||||
lea.l (-60, sp), sp
|
||||
movem.l d0-a6, (sp)
|
||||
move.l _pxCurrentTCB, a0
|
||||
move.l sp, (a0)
|
||||
|
||||
.endm
|
||||
|
||||
.macro portRESTORE_CONTEXT
|
||||
|
||||
move.l _pxCurrentTCB, a0
|
||||
move.l (a0), sp
|
||||
movem.l (sp), d0-a6
|
||||
lea.l (60, sp), sp
|
||||
rte
|
||||
|
||||
.endm
|
||||
|
||||
/********************************************************************/
|
||||
/*
|
||||
* This routines changes the IPL to the value passed into the routine.
|
||||
* It also returns the old IPL value back.
|
||||
* Calling convention from C:
|
||||
* old_ipl = asm_set_ipl(new_ipl);
|
||||
* For the Diab Data C compiler, it passes return value thru D0.
|
||||
* Note that only the least significant three bits of the passed
|
||||
* value are used.
|
||||
*/
|
||||
|
||||
ulPortSetIPL:
|
||||
_ulPortSetIPL:
|
||||
link A6,#-8
|
||||
movem.l D6-D7,(SP)
|
||||
|
||||
move.w SR,D7 /* current sr */
|
||||
|
||||
move.l D7,D6 /* prepare return value */
|
||||
andi.l #0x0700,D6 /* mask out IPL */
|
||||
lsr.l #8,D6 /* IPL */
|
||||
|
||||
andi.l #0x07,D0 /* least significant three bits */
|
||||
lsl.l #8,D0 /* move over to make mask */
|
||||
|
||||
andi.l #0x0000F8FF,D7 /* zero out current IPL */
|
||||
or.l D0,D7 /* place new IPL in sr */
|
||||
move.w D7,SR
|
||||
|
||||
move.l D6, D0 /* Return value in D0. */
|
||||
movem.l (SP),D6-D7
|
||||
lea 8(SP),SP
|
||||
unlk A6
|
||||
rts
|
||||
/********************************************************************/
|
||||
|
||||
mcf5xxx_wr_cacrx:
|
||||
_mcf5xxx_wr_cacrx:
|
||||
move.l 4(sp),d0
|
||||
.long 0x4e7b0002 /* movec d0,cacr */
|
||||
nop
|
||||
rts
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
/* Yield interrupt. */
|
||||
_vPortYieldISR:
|
||||
vPortYieldISR:
|
||||
portSAVE_CONTEXT
|
||||
jsr _vPortYieldHandler
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
|
||||
vPortStartFirstTask:
|
||||
_vPortStartFirstTask:
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
.end
|
||||
|
||||
|
@ -1,115 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portBYTE_ALIGNMENT 4
|
||||
#define portSTACK_GROWTH -1
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t ulPortSetIPL( uint32_t );
|
||||
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
||||
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
|
||||
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
||||
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
#define portNOP() asm volatile ( "nop" )
|
||||
|
||||
/* Context switches are requested using the force register. */
|
||||
#define portYIELD() INTC_SFRC = 0x3E; portNOP(); portNOP(); portNOP(); portNOP(); portNOP()
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
portYIELD(); \
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
@ -1,147 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Kernel includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
|
||||
#define portINITIAL_FORMAT_VECTOR ( ( StackType_t ) 0x4000 )
|
||||
|
||||
/* Supervisor mode set. */
|
||||
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000)
|
||||
|
||||
/* 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. */
|
||||
static uint32_t ulCriticalNesting = 0x9999UL;
|
||||
|
||||
|
||||
#define portSAVE_CONTEXT() \
|
||||
lea.l (-60, %sp), %sp; \
|
||||
movem.l %d0-%fp, (%sp); \
|
||||
move.l pxCurrentTCB, %a0; \
|
||||
move.l %sp, (%a0);
|
||||
|
||||
#define portRESTORE_CONTEXT() \
|
||||
move.l pxCurrentTCB, %a0; \
|
||||
move.l (%a0), %sp; \
|
||||
movem.l (%sp), %d0-%fp; \
|
||||
lea.l %sp@(60), %sp; \
|
||||
rte
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = (StackType_t) 0xDEADBEEF;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Exception stack frame starts with the return address. */
|
||||
*pxTopOfStack = ( StackType_t ) pxCode;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( portINITIAL_FORMAT_VECTOR << 16UL ) | ( portINITIAL_STATUS_REGISTER );
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x0; /*FP*/
|
||||
pxTopOfStack -= 14; /* A5 to D0. */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
extern void vPortStartFirstTask( void );
|
||||
|
||||
ulCriticalNesting = 0UL;
|
||||
|
||||
/* Configure the interrupts used by this port. */
|
||||
vApplicationSetupInterrupts();
|
||||
|
||||
/* Start the first task executing. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented as there is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting == 0UL )
|
||||
{
|
||||
/* Guard against context switches being pended simultaneously with a
|
||||
critical section being entered. */
|
||||
do
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
if( MCF_INTC0_INTFRCH == 0UL )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
} while( 1 );
|
||||
}
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
ulCriticalNesting--;
|
||||
if( ulCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortYieldHandler( void )
|
||||
{
|
||||
uint32_t ulSavedInterruptMask;
|
||||
|
||||
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
/* Note this will clear all forced interrupts - this is done for speed. */
|
||||
MCF_INTC0_INTFRCL = 0;
|
||||
vTaskSwitchContext();
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -1,130 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
* Purpose: Lowest level routines for all ColdFire processors.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* ulPortSetIPL() and mcf5xxx_wr_cacr() copied with permission from FreeScale
|
||||
* supplied source files.
|
||||
*/
|
||||
|
||||
.global ulPortSetIPL
|
||||
.global _ulPortSetIPL
|
||||
.global mcf5xxx_wr_cacrx
|
||||
.global _mcf5xxx_wr_cacrx
|
||||
.global vPortYieldISR
|
||||
.global _vPortYieldISR
|
||||
.global vPortStartFirstTask
|
||||
.global _vPortStartFirstTask
|
||||
.extern _pxCurrentTCB
|
||||
.extern _vPortYieldHandler
|
||||
|
||||
.text
|
||||
|
||||
.macro portSAVE_CONTEXT
|
||||
|
||||
lea.l (-60, sp), sp
|
||||
movem.l d0-a6, (sp)
|
||||
move.l _pxCurrentTCB, a0
|
||||
move.l sp, (a0)
|
||||
|
||||
.endm
|
||||
|
||||
.macro portRESTORE_CONTEXT
|
||||
|
||||
move.l _pxCurrentTCB, a0
|
||||
move.l (a0), sp
|
||||
movem.l (sp), d0-a6
|
||||
lea.l (60, sp), sp
|
||||
rte
|
||||
|
||||
.endm
|
||||
|
||||
/********************************************************************/
|
||||
/*
|
||||
* This routines changes the IPL to the value passed into the routine.
|
||||
* It also returns the old IPL value back.
|
||||
* Calling convention from C:
|
||||
* old_ipl = asm_set_ipl(new_ipl);
|
||||
* For the Diab Data C compiler, it passes return value thru D0.
|
||||
* Note that only the least significant three bits of the passed
|
||||
* value are used.
|
||||
*/
|
||||
|
||||
ulPortSetIPL:
|
||||
_ulPortSetIPL:
|
||||
link A6,#-8
|
||||
movem.l D6-D7,(SP)
|
||||
|
||||
move.w SR,D7 /* current sr */
|
||||
|
||||
move.l D7,D0 /* prepare return value */
|
||||
andi.l #0x0700,D0 /* mask out IPL */
|
||||
lsr.l #8,D0 /* IPL */
|
||||
|
||||
move.l 8(A6),D6 /* get argument */
|
||||
andi.l #0x07,D6 /* least significant three bits */
|
||||
lsl.l #8,D6 /* move over to make mask */
|
||||
|
||||
andi.l #0x0000F8FF,D7 /* zero out current IPL */
|
||||
or.l D6,D7 /* place new IPL in sr */
|
||||
move.w D7,SR
|
||||
|
||||
movem.l (SP),D6-D7
|
||||
lea 8(SP),SP
|
||||
unlk A6
|
||||
rts
|
||||
/********************************************************************/
|
||||
|
||||
mcf5xxx_wr_cacrx:
|
||||
_mcf5xxx_wr_cacrx:
|
||||
move.l 4(sp),d0
|
||||
.long 0x4e7b0002 /* movec d0,cacr */
|
||||
nop
|
||||
rts
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
/* Yield interrupt. */
|
||||
_vPortYieldISR:
|
||||
vPortYieldISR:
|
||||
portSAVE_CONTEXT
|
||||
jsr _vPortYieldHandler
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
|
||||
vPortStartFirstTask:
|
||||
_vPortStartFirstTask:
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
.end
|
||||
|
||||
|
@ -1,114 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portBYTE_ALIGNMENT 4
|
||||
#define portSTACK_GROWTH -1
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
/*-----------------------------------------------------------*/
|
||||
uint32_t ulPortSetIPL( uint32_t );
|
||||
#define portDISABLE_INTERRUPTS() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
#define portENABLE_INTERRUPTS() ulPortSetIPL( 0 )
|
||||
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
|
||||
extern UBaseType_t uxPortSetInterruptMaskFromISR( void );
|
||||
extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetIPL( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusRegister ) ulPortSetIPL( uxSavedStatusRegister )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
|
||||
#define portNOP() asm volatile ( "nop" )
|
||||
|
||||
/* 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. */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
portYIELD(); \
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
@ -1,237 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the HCS12 port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
|
||||
/*
|
||||
* Configure a timer to generate the RTOS tick at the frequency specified
|
||||
* within FreeRTOSConfig.h.
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/* Interrupt service routines have to be in non-banked memory - as does the
|
||||
scheduler startup function. */
|
||||
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
||||
|
||||
/* Manual context switch function. This is the SWI ISR. */
|
||||
void interrupt vPortYield( void );
|
||||
|
||||
/* Tick context switch function. This is the timer ISR. */
|
||||
void interrupt vPortTickInterrupt( void );
|
||||
|
||||
/* Simply called by xPortStartScheduler(). xPortStartScheduler() does not
|
||||
start the scheduler directly because the header file containing the
|
||||
xPortStartScheduler() prototype is part of the common kernel code, and
|
||||
therefore cannot use the CODE_SEG pragma. */
|
||||
static BaseType_t xBankedStartScheduler( void );
|
||||
|
||||
#pragma CODE_SEG DEFAULT
|
||||
|
||||
/* 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)
|
||||
until the nesting depth reaches 0. This variable simply tracks the nesting
|
||||
depth. Each task maintains it's own critical nesting depth variable so
|
||||
uxCriticalNesting is saved and restored from the task stack during a context
|
||||
switch. */
|
||||
volatile UBaseType_t uxCriticalNesting = 0xff;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
/*
|
||||
Place a few bytes of known values on the bottom of the stack.
|
||||
This can be uncommented to provide useful stack markers when debugging.
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x11;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x22;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x33;
|
||||
pxTopOfStack--;
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* 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 HCS12 RTI instruction. */
|
||||
|
||||
|
||||
/* The address of the task function is placed in the stack byte at a time. */
|
||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pxCode) ) + 1 );
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pxCode) ) + 0 );
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Next are all the registers that form part of the task context. */
|
||||
|
||||
/* Y register */
|
||||
*pxTopOfStack = ( StackType_t ) 0xff;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xee;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* X register */
|
||||
*pxTopOfStack = ( StackType_t ) 0xdd;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xcc;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* A register contains parameter high byte. */
|
||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pvParameters) ) + 0 );
|
||||
pxTopOfStack--;
|
||||
|
||||
/* B register contains parameter low byte. */
|
||||
*pxTopOfStack = ( StackType_t ) *( ((StackType_t *) (&pvParameters) ) + 1 );
|
||||
pxTopOfStack--;
|
||||
|
||||
/* CCR: Note that when the task starts interrupts will be enabled since
|
||||
"I" bit of CCR is cleared */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||
pxTopOfStack--;
|
||||
|
||||
#ifdef BANKED_MODEL
|
||||
/* The page of the task. */
|
||||
*pxTopOfStack = ( StackType_t ) ( ( int ) pxCode );
|
||||
pxTopOfStack--;
|
||||
#endif
|
||||
|
||||
/* Finally the critical nesting depth is initialised with 0 (not within
|
||||
a critical section). */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the HCS12 port will get stopped. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
TickTimer_SetFreqHz( configTICK_RATE_HZ );
|
||||
TickTimer_Enable();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* xPortStartScheduler() does not start the scheduler directly because
|
||||
the header file containing the xPortStartScheduler() prototype is part
|
||||
of the common kernel code, and therefore cannot use the CODE_SEG pragma.
|
||||
Instead it simply calls the locally defined xBankedStartScheduler() -
|
||||
which does use the CODE_SEG pragma. */
|
||||
|
||||
return xBankedStartScheduler();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
||||
|
||||
static BaseType_t xBankedStartScheduler( void )
|
||||
{
|
||||
/* Configure the timer that will generate the RTOS tick. Interrupts are
|
||||
disabled when this function is called. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Restore the context of the first task. */
|
||||
portRESTORE_CONTEXT();
|
||||
|
||||
/* Simulate the end of an interrupt to start the scheduler off. */
|
||||
__asm( "rti" );
|
||||
|
||||
/* Should not get here! */
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Context switch functions. These are both interrupt service routines.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Manual context switch forced by calling portYIELD(). This is the SWI
|
||||
* handler.
|
||||
*/
|
||||
void interrupt vPortYield( void )
|
||||
{
|
||||
portSAVE_CONTEXT();
|
||||
vTaskSwitchContext();
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* RTOS tick interrupt service routine. If the cooperative scheduler is
|
||||
* being used then this simply increments the tick count. If the
|
||||
* preemptive scheduler is being used a context switch can occur.
|
||||
*/
|
||||
void interrupt vPortTickInterrupt( void )
|
||||
{
|
||||
#if configUSE_PREEMPTION == 1
|
||||
{
|
||||
/* A context switch might happen so save the context. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Increment the tick ... */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
vTaskSwitchContext();
|
||||
}
|
||||
|
||||
TFLG1 = 1;
|
||||
|
||||
/* Restore the context of a task - which may be a different task
|
||||
to that interrupted. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
#else
|
||||
{
|
||||
xTaskIncrementTick();
|
||||
TFLG1 = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma CODE_SEG DEFAULT
|
||||
|
||||
|
@ -1,202 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint8_t
|
||||
#define portBASE_TYPE char
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef signed char BaseType_t;
|
||||
typedef unsigned char UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portBYTE_ALIGNMENT 1
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portYIELD() __asm( "swi" );
|
||||
#define portNOP() __asm( "nop" );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section handling. */
|
||||
#define portENABLE_INTERRUPTS() __asm( "cli" )
|
||||
#define portDISABLE_INTERRUPTS() __asm( "sei" )
|
||||
|
||||
/*
|
||||
* Disable interrupts before incrementing the count of critical section nesting.
|
||||
* The nesting count is maintained so we know when interrupts should be
|
||||
* re-enabled. Once interrupts are disabled the nesting count can be accessed
|
||||
* directly. Each task maintains its own nesting count.
|
||||
*/
|
||||
#define portENTER_CRITICAL() \
|
||||
{ \
|
||||
extern volatile UBaseType_t uxCriticalNesting; \
|
||||
\
|
||||
portDISABLE_INTERRUPTS(); \
|
||||
uxCriticalNesting++; \
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* section and interrupts can be re-enabled.
|
||||
*/
|
||||
#define portEXIT_CRITICAL() \
|
||||
{ \
|
||||
extern volatile UBaseType_t uxCriticalNesting; \
|
||||
\
|
||||
uxCriticalNesting--; \
|
||||
if( uxCriticalNesting == 0 ) \
|
||||
{ \
|
||||
portENABLE_INTERRUPTS(); \
|
||||
} \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
|
||||
/*
|
||||
* These macros are very simple as the processor automatically saves and
|
||||
* restores its registers as interrupts are entered and exited. In
|
||||
* addition to the (automatically stacked) registers we also stack the
|
||||
* critical nesting count. Each task maintains its own critical nesting
|
||||
* 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
|
||||
* register is also stored as part of the tasks context.
|
||||
*/
|
||||
|
||||
#ifdef BANKED_MODEL
|
||||
/*
|
||||
* Load the stack pointer for the task, then pull the critical nesting
|
||||
* count and PPAGE register from the stack. The remains of the
|
||||
* context are restored by the RTI instruction.
|
||||
*/
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * pxCurrentTCB; \
|
||||
extern volatile UBaseType_t uxCriticalNesting; \
|
||||
\
|
||||
__asm( "ldx pxCurrentTCB" ); \
|
||||
__asm( "lds 0, x" ); \
|
||||
__asm( "pula" ); \
|
||||
__asm( "staa uxCriticalNesting" ); \
|
||||
__asm( "pula" ); \
|
||||
__asm( "staa 0x30" ); /* 0x30 = PPAGE */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* By the time this macro is called the processor has already stacked the
|
||||
* registers. Simply stack the nesting count and PPAGE value, then save
|
||||
* the task stack pointer.
|
||||
*/
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * pxCurrentTCB; \
|
||||
extern volatile UBaseType_t uxCriticalNesting; \
|
||||
\
|
||||
__asm( "ldaa 0x30" ); /* 0x30 = PPAGE */ \
|
||||
__asm( "psha" ); \
|
||||
__asm( "ldaa uxCriticalNesting" ); \
|
||||
__asm( "psha" ); \
|
||||
__asm( "ldx pxCurrentTCB" ); \
|
||||
__asm( "sts 0, x" ); \
|
||||
}
|
||||
#else
|
||||
|
||||
/*
|
||||
* These macros are as per the BANKED versions above, but without saving
|
||||
* and restoring the PPAGE register.
|
||||
*/
|
||||
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * pxCurrentTCB; \
|
||||
extern volatile UBaseType_t uxCriticalNesting; \
|
||||
\
|
||||
__asm( "ldx pxCurrentTCB" ); \
|
||||
__asm( "lds 0, x" ); \
|
||||
__asm( "pula" ); \
|
||||
__asm( "staa uxCriticalNesting" ); \
|
||||
}
|
||||
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * pxCurrentTCB; \
|
||||
extern volatile UBaseType_t uxCriticalNesting; \
|
||||
\
|
||||
__asm( "ldaa uxCriticalNesting" ); \
|
||||
__asm( "psha" ); \
|
||||
__asm( "ldx pxCurrentTCB" ); \
|
||||
__asm( "sts 0, x" ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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
|
||||
* the ISR does not use any local (stack) variables. If the ISR uses stack
|
||||
* variables portYIELD() should be used in it's place.
|
||||
*/
|
||||
#define portTASK_SWITCH_FROM_ISR() \
|
||||
portSAVE_CONTEXT(); \
|
||||
vTaskSwitchContext(); \
|
||||
portRESTORE_CONTEXT();
|
||||
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,59 +0,0 @@
|
||||
/*
|
||||
FreeRTOS Kernel V10.2.1
|
||||
Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
http://aws.amazon.com/freertos
|
||||
http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
( void ) pxTopOfStack;
|
||||
( void ) pxCode;
|
||||
( void ) pvParameters;
|
||||
|
||||
/* FIX ME. */
|
||||
return ( StackType_t * ) NULL;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* FIX ME. */
|
||||
return pdFAIL;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Do not implement. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -1,106 +0,0 @@
|
||||
/*
|
||||
FreeRTOS Kernel V10.2.1
|
||||
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
http://aws.amazon.com/freertos
|
||||
http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Type definitions. */
|
||||
#define portSTACK_TYPE uint32_t
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 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. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8 /* FIX ME. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler utilities. */
|
||||
#define portYIELD() 0 /* FIX ME. */
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) 0 /* FIX ME. */
|
||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) 0 /* FIX ME. */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = 0 /* FIX ME. */
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() 0 /* FIX ME. */
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) 0 /* FIX ME. */
|
||||
#define portDISABLE_INTERRUPTS() 0 /* FIX ME. */
|
||||
#define portENABLE_INTERRUPTS() 0 /* FIX ME. */
|
||||
#define portENTER_CRITICAL() 0 /* FIX ME. */
|
||||
#define portEXIT_CRITICAL() 0 /* FIX ME. */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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
|
||||
(which build with all the ports) will build. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
@ -1,238 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the Atmel AT91R40008
|
||||
* port.
|
||||
*
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in this file. The ISR routines, which can only be compiled
|
||||
* to ARM mode are contained in portISR.c.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Hardware specific definitions. */
|
||||
#include "AT91R40008.h"
|
||||
#include "pio.h"
|
||||
#include "aic.h"
|
||||
#include "tc.h"
|
||||
|
||||
/* Constants required to setup the task context. */
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||
#define portTICK_PRIORITY_6 ( 6 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Setup the timer to generate the tick interrupts. */
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/*
|
||||
* The scheduler can only be started from ARM mode, so
|
||||
* vPortISRStartFirstSTask() is defined in portISR.c.
|
||||
*/
|
||||
extern void vPortISRStartFirstTask( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the stack of a task to look exactly as if a call to
|
||||
* portSAVE_CONTEXT had been called.
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
StackType_t *pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||
is not really required. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* 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
|
||||
as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The last thing onto the stack is the status register, which is set for
|
||||
system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||
|
||||
#ifdef THUMB_INTERWORK
|
||||
{
|
||||
/* We want the task to start in thumb mode. */
|
||||
*pxTopOfStack |= portTHUMB_MODE_BIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Some optimisation levels use the stack differently to others. This
|
||||
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
|
||||
tasks context. */
|
||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
vPortISRStartFirstTask();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Setup the tick timer to generate the tick interrupts at the required frequency.
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
volatile uint32_t ulDummy;
|
||||
|
||||
/* Enable clock to the tick timer... */
|
||||
AT91C_BASE_PS->PS_PCER = portTIMER_CLK_ENABLE_BIT;
|
||||
|
||||
/* Stop the tick timer... */
|
||||
portTIMER_REG_BASE_PTR->TC_CCR = TC_CLKDIS;
|
||||
|
||||
/* Start with tick timer interrupts disabled... */
|
||||
portTIMER_REG_BASE_PTR->TC_IDR = 0xFFFFFFFF;
|
||||
|
||||
/* Clear any pending tick timer interrupts... */
|
||||
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||
|
||||
/* Store interrupt handler function address in tick timer vector register...
|
||||
The ISR installed depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
#if configUSE_PREEMPTION == 1
|
||||
{
|
||||
extern void ( vPreemptiveTick )( void );
|
||||
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( uint32_t ) vPreemptiveTick;
|
||||
}
|
||||
#else // else use cooperative scheduler
|
||||
{
|
||||
extern void ( vNonPreemptiveTick )( void );
|
||||
AT91C_BASE_AIC->AIC_SVR[portTIMER_AIC_CHANNEL] = ( uint32_t ) vNonPreemptiveTick;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Tick timer interrupt level-sensitive, priority 6... */
|
||||
AT91C_BASE_AIC->AIC_SMR[ portTIMER_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | portTICK_PRIORITY_6;
|
||||
|
||||
/* Enable the tick timer interrupt...
|
||||
|
||||
First at timer level */
|
||||
portTIMER_REG_BASE_PTR->TC_IER = TC_CPCS;
|
||||
|
||||
/* Then at the AIC level. */
|
||||
AT91C_BASE_AIC->AIC_IECR = (1 << portTIMER_AIC_CHANNEL);
|
||||
|
||||
/* Calculate timer compare value to achieve the desired tick rate... */
|
||||
if( (configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2) ) <= 0xFFFF )
|
||||
{
|
||||
/* The tick rate is fast enough for us to use the faster timer input
|
||||
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_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We must use a slower timer input clock (main clock / 8) because the
|
||||
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_RC = configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 8);
|
||||
}
|
||||
|
||||
/* Start tick timer... */
|
||||
portTIMER_REG_BASE_PTR->TC_CCR = TC_SWTRG | TC_CLKEN;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -1,233 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in port.c The ISR routines, which can only be compiled
|
||||
* to ARM mode, are contained in this file.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.4
|
||||
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
than each line having its own asm block.
|
||||
*/
|
||||
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Constants required to handle interrupts. */
|
||||
#define portCLEAR_AIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||
|
||||
/* Constants required to handle critical sections. */
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||
|
||||
/*
|
||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||
* function here.
|
||||
*/
|
||||
void vPortISRStartFirstTask( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortISRStartFirstTask( void )
|
||||
{
|
||||
/* Simply start the scheduler. This is included here as it can only be
|
||||
called from ARM mode. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Called by portYIELD() or taskYIELD() to manually force a context switch.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
void vPortYieldProcessor( void )
|
||||
{
|
||||
/* 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
|
||||
ISR return code can be used in both cases. */
|
||||
asm volatile ( "ADD LR, LR, #4" );
|
||||
|
||||
/* Perform the context switch. First save the context of the current task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Find the highest priority task that is ready to run. */
|
||||
vTaskSwitchContext();
|
||||
|
||||
/* Restore the context of the new task. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The ISR used for the scheduler tick depends on whether the cooperative or
|
||||
* the preemptive scheduler is being used.
|
||||
*/
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
simply increment the system tick. */
|
||||
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
||||
void vNonPreemptiveTick( void )
|
||||
{
|
||||
static volatile uint32_t ulDummy;
|
||||
|
||||
/* Clear tick timer interrupt indication. */
|
||||
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||
|
||||
xTaskIncrementTick();
|
||||
|
||||
/* Acknowledge the interrupt at AIC level... */
|
||||
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
|
||||
}
|
||||
|
||||
#else /* else preemption is turned on */
|
||||
|
||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||
saved on entry as part of the context switch. */
|
||||
void vPreemptiveTick( void ) __attribute__((naked));
|
||||
void vPreemptiveTick( void )
|
||||
{
|
||||
/* Save the context of the interrupted task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* WARNING - Do not use local (stack) variables here. Use globals
|
||||
if you must! */
|
||||
static volatile uint32_t ulDummy;
|
||||
|
||||
/* Clear tick timer interrupt indication. */
|
||||
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
|
||||
|
||||
/* Increment the RTOS tick count, then look for the highest priority
|
||||
task that is ready to run. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
vTaskSwitchContext();
|
||||
}
|
||||
|
||||
/* Acknowledge the interrupt at AIC level... */
|
||||
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
|
||||
|
||||
/* Restore the context of the new task. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The interrupt management utilities can only be called from ARM mode. When
|
||||
* 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
|
||||
* the utilities are defined as macros in portmacro.h - as per other ports.
|
||||
*/
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void )
|
||||
{
|
||||
asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
void vPortEnableInterruptsFromThumb( void )
|
||||
{
|
||||
asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||
different optimisation levels. The interrupt flags can therefore not always
|
||||
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. */
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||
asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as we are leaving a critical section. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||
asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,255 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.3
|
||||
|
||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||
|
||||
Changes from V3.2.4
|
||||
|
||||
+ Removed the use of the %0 parameter within the assembler macros and
|
||||
replaced them with hard coded registers. This will ensure the
|
||||
assembler does not select the link register as the temp register as
|
||||
was occasionally happening previously.
|
||||
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
than each line having its own asm block.
|
||||
|
||||
Changes from V4.5.0
|
||||
|
||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||
macros as per the V4.5.1 demo code.
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portYIELD() asm volatile ( "SWI 0" )
|
||||
#define portNOP() asm volatile ( "NOP" )
|
||||
|
||||
/*
|
||||
* 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"
|
||||
* and "portisr.c".
|
||||
*/
|
||||
#define portTIMER_REG_BASE_PTR AT91C_BASE_TC0
|
||||
#define portTIMER_CLK_ENABLE_BIT AT91C_PS_TC0
|
||||
#define portTIMER_AIC_CHANNEL ( ( uint32_t ) 4 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
|
||||
/*
|
||||
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
|
||||
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
|
||||
* are included here for efficiency. An attempt to call one from
|
||||
* THUMB mode code will result in a compile time error.
|
||||
*/
|
||||
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Set the LR to the task stack. */ \
|
||||
asm volatile ( \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"LDR LR, [R0] \n\t" \
|
||||
\
|
||||
/* The critical nesting depth is the first item on the stack. */ \
|
||||
/* Load it into the ulCriticalNesting variable. */ \
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDMFD LR!, {R1} \n\t" \
|
||||
"STR R1, [R0] \n\t" \
|
||||
\
|
||||
/* Get the SPSR from the stack. */ \
|
||||
"LDMFD LR!, {R0} \n\t" \
|
||||
"MSR SPSR, R0 \n\t" \
|
||||
\
|
||||
/* Restore all system mode registers for the task. */ \
|
||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
\
|
||||
/* Restore the return address. */ \
|
||||
"LDR LR, [LR, #+60] \n\t" \
|
||||
\
|
||||
/* And return - correcting the offset in the LR to obtain the */ \
|
||||
/* correct address. */ \
|
||||
"SUBS PC, LR, #4 \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Push R0 as we are going to use the register. */ \
|
||||
asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Set R0 to point to the task stack pointer. */ \
|
||||
"STMDB SP,{SP}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB SP, SP, #4 \n\t" \
|
||||
"LDMIA SP!,{R0} \n\t" \
|
||||
\
|
||||
/* Push the return address onto the stack. */ \
|
||||
"STMDB R0!, {LR} \n\t" \
|
||||
\
|
||||
/* Now we have saved LR we can use it instead of R0. */ \
|
||||
"MOV LR, R0 \n\t" \
|
||||
\
|
||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||
"LDMIA SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Push all the system mode registers onto the task stack. */ \
|
||||
"STMDB LR,{R0-LR}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB LR, LR, #60 \n\t" \
|
||||
\
|
||||
/* Push the SPSR onto the task stack. */ \
|
||||
"MRS R0, SPSR \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
/* Store the new top of stack for the task. */ \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STR LR, [R0] \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
|
||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||
|
||||
/* Critical section handling. */
|
||||
|
||||
/*
|
||||
* The interrupt management utilities can only be called from ARM mode. When
|
||||
* 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
|
||||
* defined then the utilities are defined as macros here - as per other ports.
|
||||
*/
|
||||
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
|
||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||
|
||||
#else
|
||||
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,51 +0,0 @@
|
||||
//* ----------------------------------------------------------------------------
|
||||
//* ATMEL Microcontroller Software Support - ROUSSET -
|
||||
//* ----------------------------------------------------------------------------
|
||||
//* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
//* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
//* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
//* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
//* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
//* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
//* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
//* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//* ----------------------------------------------------------------------------
|
||||
//* File Name : lib_AT91SAM7X256.h
|
||||
//* Object : AT91SAM7X256 inlined functions
|
||||
//* 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_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_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_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_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_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_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_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_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_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_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_pdc.h/1.2/Tue Jul 2 13:29:40 2002//
|
||||
//* ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "AT91SAM7X256.h"
|
||||
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_AIC_ConfigureIt
|
||||
//* \brief Interrupt Handler Initialization
|
||||
//*----------------------------------------------------------------------------
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,213 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||
*
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in this file. The ISR routines, which can only be compiled
|
||||
* to ARM mode are contained in portISR.c.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Processor constants. */
|
||||
#include "AT91SAM7X256.h"
|
||||
|
||||
/* Constants required to setup the task context. */
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||
|
||||
/* Constants required to setup the tick ISR. */
|
||||
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
||||
#define portPRESCALE_VALUE 0x00
|
||||
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
||||
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
||||
|
||||
/* Constants required to setup the PIT. */
|
||||
#define portPIT_CLOCK_DIVISOR ( ( uint32_t ) 16 )
|
||||
#define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_PERIOD_MS )
|
||||
|
||||
#define portINT_LEVEL_SENSITIVE 0
|
||||
#define portPIT_ENABLE ( ( uint16_t ) 0x1 << 24 )
|
||||
#define portPIT_INT_ENABLE ( ( uint16_t ) 0x1 << 25 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Setup the timer to generate the tick interrupts. */
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/*
|
||||
* The scheduler can only be started from ARM mode, so
|
||||
* vPortISRStartFirstSTask() is defined in portISR.c.
|
||||
*/
|
||||
extern void vPortISRStartFirstTask( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the stack of a task to look exactly as if a call to
|
||||
* portSAVE_CONTEXT had been called.
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
StackType_t *pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||
is not really required. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* 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
|
||||
as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The last thing onto the stack is the status register, which is set for
|
||||
system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||
|
||||
#ifdef THUMB_INTERWORK
|
||||
{
|
||||
/* We want the task to start in thumb mode. */
|
||||
*pxTopOfStack |= portTHUMB_MODE_BIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Some optimisation levels use the stack differently to others. This
|
||||
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
|
||||
tasks context. */
|
||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
vPortISRStartFirstTask();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Setup the timer 0 to generate the tick interrupts at the required frequency.
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
|
||||
|
||||
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
|
||||
on whether the preemptive or cooperative scheduler is being used. */
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
extern void ( vNonPreemptiveTick ) ( void );
|
||||
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vNonPreemptiveTick );
|
||||
|
||||
#else
|
||||
|
||||
extern void ( vPreemptiveTick )( void );
|
||||
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vPreemptiveTick );
|
||||
|
||||
#endif
|
||||
|
||||
/* Configure the PIT period. */
|
||||
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
|
||||
|
||||
/* Enable the interrupt. Global interrupts are disables at this point so
|
||||
this is safe. */
|
||||
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
@ -1,227 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in port.c The ISR routines, which can only be compiled
|
||||
* to ARM mode, are contained in this file.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.4
|
||||
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
than each line having its own asm block.
|
||||
*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#include "AT91SAM7X256.h"
|
||||
|
||||
/* Constants required to handle interrupts. */
|
||||
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
||||
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||
|
||||
/* Constants required to handle critical sections. */
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||
|
||||
/*
|
||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||
* function here.
|
||||
*/
|
||||
void vPortISRStartFirstTask( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortISRStartFirstTask( void )
|
||||
{
|
||||
/* Simply start the scheduler. This is included here as it can only be
|
||||
called from ARM mode. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Called by portYIELD() or taskYIELD() to manually force a context switch.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
void vPortYieldProcessor( void )
|
||||
{
|
||||
/* 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
|
||||
ISR return code can be used in both cases. */
|
||||
__asm volatile ( "ADD LR, LR, #4" );
|
||||
|
||||
/* Perform the context switch. First save the context of the current task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Find the highest priority task that is ready to run. */
|
||||
vTaskSwitchContext();
|
||||
|
||||
/* Restore the context of the new task. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The ISR used for the scheduler tick depends on whether the cooperative or
|
||||
* the preemptive scheduler is being used.
|
||||
*/
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
simply increment the system tick. */
|
||||
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
||||
void vNonPreemptiveTick( void )
|
||||
{
|
||||
uint32_t ulDummy;
|
||||
|
||||
/* Increment the tick count - which may wake some tasks but as the
|
||||
preemptive scheduler is not being used any woken task is not given
|
||||
processor time no matter what its priority. */
|
||||
xTaskIncrementTick();
|
||||
|
||||
/* Clear the PIT interrupt. */
|
||||
ulDummy = AT91C_BASE_PITC->PITC_PIVR;
|
||||
|
||||
/* End the interrupt in the AIC. */
|
||||
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||
saved on entry as part of the context switch. */
|
||||
void vPreemptiveTick( void ) __attribute__((naked));
|
||||
void vPreemptiveTick( void )
|
||||
{
|
||||
/* Save the context of the current task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Increment the tick count - this may wake a task. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
/* Find the highest priority task that is ready to run. */
|
||||
vTaskSwitchContext();
|
||||
}
|
||||
|
||||
/* End the interrupt in the AIC. */
|
||||
AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR;
|
||||
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The interrupt management utilities can only be called from ARM mode. When
|
||||
* 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
|
||||
* the utilities are defined as macros in portmacro.h - as per other ports.
|
||||
*/
|
||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void )
|
||||
{
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
void vPortEnableInterruptsFromThumb( void )
|
||||
{
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
|
||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||
different optimisation levels. The interrupt flags can therefore not always
|
||||
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. */
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as we are leaving a critical section. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,249 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.3
|
||||
|
||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||
|
||||
Changes from V3.2.4
|
||||
|
||||
+ Removed the use of the %0 parameter within the assembler macros and
|
||||
replaced them with hard coded registers. This will ensure the
|
||||
assembler does not select the link register as the temp register as
|
||||
was occasionally happening previously.
|
||||
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
than each line having its own asm block.
|
||||
|
||||
Changes from V4.5.0
|
||||
|
||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||
macros as per the V4.5.1 demo code.
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE portLONG
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP() __asm volatile ( "NOP" );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Scheduler utilities. */
|
||||
|
||||
/*
|
||||
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
|
||||
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
|
||||
* are included here for efficiency. An attempt to call one from
|
||||
* THUMB mode code will result in a compile time error.
|
||||
*/
|
||||
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Set the LR to the task stack. */ \
|
||||
__asm volatile ( \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"LDR LR, [R0] \n\t" \
|
||||
\
|
||||
/* The critical nesting depth is the first item on the stack. */ \
|
||||
/* Load it into the ulCriticalNesting variable. */ \
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDMFD LR!, {R1} \n\t" \
|
||||
"STR R1, [R0] \n\t" \
|
||||
\
|
||||
/* Get the SPSR from the stack. */ \
|
||||
"LDMFD LR!, {R0} \n\t" \
|
||||
"MSR SPSR, R0 \n\t" \
|
||||
\
|
||||
/* Restore all system mode registers for the task. */ \
|
||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
\
|
||||
/* Restore the return address. */ \
|
||||
"LDR LR, [LR, #+60] \n\t" \
|
||||
\
|
||||
/* And return - correcting the offset in the LR to obtain the */ \
|
||||
/* correct address. */ \
|
||||
"SUBS PC, LR, #4 \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Push R0 as we are going to use the register. */ \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Set R0 to point to the task stack pointer. */ \
|
||||
"STMDB SP,{SP}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB SP, SP, #4 \n\t" \
|
||||
"LDMIA SP!,{R0} \n\t" \
|
||||
\
|
||||
/* Push the return address onto the stack. */ \
|
||||
"STMDB R0!, {LR} \n\t" \
|
||||
\
|
||||
/* Now we have saved LR we can use it instead of R0. */ \
|
||||
"MOV LR, R0 \n\t" \
|
||||
\
|
||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||
"LDMIA SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Push all the system mode registers onto the task stack. */ \
|
||||
"STMDB LR,{R0-LR}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB LR, LR, #60 \n\t" \
|
||||
\
|
||||
/* Push the SPSR onto the task stack. */ \
|
||||
"MRS R0, SPSR \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
/* Store the new top of stack for the task. */ \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STR LR, [R0] \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
|
||||
|
||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Critical section management. */
|
||||
|
||||
/*
|
||||
* The interrupt management utilities can only be called from ARM mode. When
|
||||
* 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
|
||||
* defined then the utilities are defined as macros here - as per other ports.
|
||||
*/
|
||||
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
|
||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||
|
||||
#else
|
||||
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
@ -1,221 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||
*
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in this file. The ISR routines, which can only be compiled
|
||||
* to ARM mode are contained in portISR.c.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Constants required to setup the task context. */
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||
|
||||
/* Constants required to setup the tick ISR. */
|
||||
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
||||
#define portPRESCALE_VALUE 0x00
|
||||
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
||||
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
||||
|
||||
/* Constants required to setup the VIC for the tick ISR. */
|
||||
#define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 )
|
||||
#define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 )
|
||||
#define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Setup the timer to generate the tick interrupts. */
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/*
|
||||
* The scheduler can only be started from ARM mode, so
|
||||
* vPortISRStartFirstSTask() is defined in portISR.c.
|
||||
*/
|
||||
extern void vPortISRStartFirstTask( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the stack of a task to look exactly as if a call to
|
||||
* portSAVE_CONTEXT had been called.
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
StackType_t *pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||
is not really required. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* 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
|
||||
as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0xaaaaaaaa; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The last thing onto the stack is the status register, which is set for
|
||||
system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||
|
||||
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
||||
{
|
||||
/* We want the task to start in thumb mode. */
|
||||
*pxTopOfStack |= portTHUMB_MODE_BIT;
|
||||
}
|
||||
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Some optimisation levels use the stack differently to others. This
|
||||
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
|
||||
tasks context. */
|
||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
vPortISRStartFirstTask();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Setup the timer 0 to generate the tick interrupts at the required frequency.
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
uint32_t ulCompareMatch;
|
||||
extern void ( vTickISR )( void );
|
||||
|
||||
/* A 1ms tick does not require the use of the timer prescale. This is
|
||||
defaulted to zero but can be used if necessary. */
|
||||
T0_PR = portPRESCALE_VALUE;
|
||||
|
||||
/* Calculate the match value required for our wanted tick rate. */
|
||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||
|
||||
/* Protect against divide by zero. Using an if() statement still results
|
||||
in a warning - hence the #if. */
|
||||
#if portPRESCALE_VALUE != 0
|
||||
{
|
||||
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||
}
|
||||
#endif
|
||||
T0_MR0 = ulCompareMatch;
|
||||
|
||||
/* Generate tick with timer 0 compare match. */
|
||||
T0_MCR = portRESET_COUNT_ON_MATCH | portINTERRUPT_ON_MATCH;
|
||||
|
||||
/* Setup the VIC for the timer. */
|
||||
VICIntSelect &= ~( portTIMER_VIC_CHANNEL_BIT );
|
||||
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
|
||||
|
||||
/* The ISR installed depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
|
||||
VICVectAddr0 = ( int32_t ) vTickISR;
|
||||
VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
|
||||
|
||||
/* Start the timer - interrupts are disabled when this function is called
|
||||
so it is okay to do this here. */
|
||||
T0_TCR = portENABLE_TIMER;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
@ -1,215 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in port.c The ISR routines, which can only be compiled
|
||||
* to ARM mode, are contained in this file.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Changes from V2.5.2
|
||||
|
||||
+ The critical section management functions have been changed. These no
|
||||
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.
|
||||
|
||||
Changes from V2.6.0
|
||||
|
||||
+ Removed the 'static' from the definition of vNonPreemptiveTick() to
|
||||
allow the demo to link when using the cooperative scheduler.
|
||||
|
||||
Changes from V3.2.4
|
||||
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
than each line having its own asm block.
|
||||
*/
|
||||
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
/* Constants required to handle interrupts. */
|
||||
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
||||
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||
|
||||
/* Constants required to handle critical sections. */
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||
|
||||
/*
|
||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||
* function here.
|
||||
*/
|
||||
void vPortISRStartFirstTask( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortISRStartFirstTask( void )
|
||||
{
|
||||
/* Simply start the scheduler. This is included here as it can only be
|
||||
called from ARM mode. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Called by portYIELD() or taskYIELD() to manually force a context switch.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
void vPortYieldProcessor( void )
|
||||
{
|
||||
/* 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
|
||||
ISR return code can be used in both cases. */
|
||||
__asm volatile ( "ADD LR, LR, #4" );
|
||||
|
||||
/* Perform the context switch. First save the context of the current task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Find the highest priority task that is ready to run. */
|
||||
__asm volatile ( "bl vTaskSwitchContext" );
|
||||
|
||||
/* Restore the context of the new task. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The ISR used for the scheduler tick.
|
||||
*/
|
||||
void vTickISR( void ) __attribute__((naked));
|
||||
void vTickISR( void )
|
||||
{
|
||||
/* Save the context of the interrupted task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Increment the RTOS tick count, then look for the highest priority
|
||||
task that is ready to run. */
|
||||
__asm volatile
|
||||
(
|
||||
" bl xTaskIncrementTick \t\n" \
|
||||
" cmp r0, #0 \t\n" \
|
||||
" beq SkipContextSwitch \t\n" \
|
||||
" bl vTaskSwitchContext \t\n" \
|
||||
"SkipContextSwitch: \t\n"
|
||||
);
|
||||
|
||||
/* Ready for the next interrupt. */
|
||||
T0_IR = portTIMER_MATCH_ISR_BIT;
|
||||
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
||||
|
||||
/* Restore the context of the new task. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The interrupt management utilities can only be called from ARM mode. When
|
||||
* 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
|
||||
* the utilities are defined as macros in portmacro.h - as per other ports.
|
||||
*/
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void )
|
||||
{
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
void vPortEnableInterruptsFromThumb( void )
|
||||
{
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||
different optimisation levels. The interrupt flags can therefore not always
|
||||
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. */
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as we are leaving a critical section. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
}
|
||||
}
|
||||
}
|
@ -1,226 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE portLONG
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP() __asm volatile ( "NOP" );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Scheduler utilities. */
|
||||
|
||||
/*
|
||||
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
|
||||
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
|
||||
* are included here for efficiency. An attempt to call one from
|
||||
* THUMB mode code will result in a compile time error.
|
||||
*/
|
||||
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Set the LR to the task stack. */ \
|
||||
__asm volatile ( \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"LDR LR, [R0] \n\t" \
|
||||
\
|
||||
/* The critical nesting depth is the first item on the stack. */ \
|
||||
/* Load it into the ulCriticalNesting variable. */ \
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDMFD LR!, {R1} \n\t" \
|
||||
"STR R1, [R0] \n\t" \
|
||||
\
|
||||
/* Get the SPSR from the stack. */ \
|
||||
"LDMFD LR!, {R0} \n\t" \
|
||||
"MSR SPSR, R0 \n\t" \
|
||||
\
|
||||
/* Restore all system mode registers for the task. */ \
|
||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
\
|
||||
/* Restore the return address. */ \
|
||||
"LDR LR, [LR, #+60] \n\t" \
|
||||
\
|
||||
/* And return - correcting the offset in the LR to obtain the */ \
|
||||
/* correct address. */ \
|
||||
"SUBS PC, LR, #4 \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Push R0 as we are going to use the register. */ \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Set R0 to point to the task stack pointer. */ \
|
||||
"STMDB SP,{SP}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB SP, SP, #4 \n\t" \
|
||||
"LDMIA SP!,{R0} \n\t" \
|
||||
\
|
||||
/* Push the return address onto the stack. */ \
|
||||
"STMDB R0!, {LR} \n\t" \
|
||||
\
|
||||
/* Now we have saved LR we can use it instead of R0. */ \
|
||||
"MOV LR, R0 \n\t" \
|
||||
\
|
||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||
"LDMIA SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Push all the system mode registers onto the task stack. */ \
|
||||
"STMDB LR,{R0-LR}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB LR, LR, #60 \n\t" \
|
||||
\
|
||||
/* Push the SPSR onto the task stack. */ \
|
||||
"MRS R0, SPSR \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
/* Store the new top of stack for the task. */ \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STR LR, [R0] \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
|
||||
extern void vTaskSwitchContext( void );
|
||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Critical section management. */
|
||||
|
||||
/*
|
||||
* The interrupt management utilities can only be called from ARM mode. When
|
||||
* 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
|
||||
* defined then the utilities are defined as macros here - as per other ports.
|
||||
*/
|
||||
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
|
||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||
|
||||
#else
|
||||
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
@ -1,233 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the ARM7 port.
|
||||
*
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in this file. The ISR routines, which can only be compiled
|
||||
* to ARM mode are contained in portISR.c.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Constants required to setup the task context. */
|
||||
#define portINITIAL_SPSR ( ( StackType_t ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
|
||||
#define portINSTRUCTION_SIZE ( ( StackType_t ) 4 )
|
||||
#define portNO_CRITICAL_SECTION_NESTING ( ( StackType_t ) 0 )
|
||||
|
||||
/* Constants required to setup the tick ISR. */
|
||||
#define portENABLE_TIMER ( ( uint8_t ) 0x01 )
|
||||
#define portPRESCALE_VALUE 0x00
|
||||
#define portINTERRUPT_ON_MATCH ( ( uint32_t ) 0x01 )
|
||||
#define portRESET_COUNT_ON_MATCH ( ( uint32_t ) 0x02 )
|
||||
|
||||
/* Constants required to setup the VIC for the tick ISR. */
|
||||
#define portTIMER_VIC_CHANNEL ( ( uint32_t ) 0x0004 )
|
||||
#define portTIMER_VIC_CHANNEL_BIT ( ( uint32_t ) 0x0010 )
|
||||
#define portTIMER_VIC_ENABLE ( ( uint32_t ) 0x0020 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Setup the timer to generate the tick interrupts. */
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/*
|
||||
* The scheduler can only be started from ARM mode, so
|
||||
* vPortISRStartFirstSTask() is defined in portISR.c.
|
||||
*/
|
||||
extern void vPortISRStartFirstTask( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the stack of a task to look exactly as if a call to
|
||||
* portSAVE_CONTEXT had been called.
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
StackType_t *pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||
is not really required. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* 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
|
||||
as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0x00000000; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The last thing onto the stack is the status register, which is set for
|
||||
system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||
|
||||
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
||||
{
|
||||
/* We want the task to start in thumb mode. */
|
||||
*pxTopOfStack |= portTHUMB_MODE_BIT;
|
||||
}
|
||||
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Some optimisation levels use the stack differently to others. This
|
||||
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
|
||||
tasks context. */
|
||||
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
vPortISRStartFirstTask();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Setup the timer 0 to generate the tick interrupts at the required frequency.
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
uint32_t ulCompareMatch;
|
||||
|
||||
PCLKSEL0 = (PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
|
||||
T0TCR = 2; /* Stop and reset the timer */
|
||||
T0CTCR = 0; /* Timer mode */
|
||||
|
||||
/* A 1ms tick does not require the use of the timer prescale. This is
|
||||
defaulted to zero but can be used if necessary. */
|
||||
T0PR = portPRESCALE_VALUE;
|
||||
|
||||
/* Calculate the match value required for our wanted tick rate. */
|
||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||
|
||||
/* Protect against divide by zero. Using an if() statement still results
|
||||
in a warning - hence the #if. */
|
||||
#if portPRESCALE_VALUE != 0
|
||||
{
|
||||
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||
}
|
||||
#endif
|
||||
T0MR1 = ulCompareMatch;
|
||||
|
||||
/* Generate tick with timer 0 compare match. */
|
||||
T0MCR = (3 << 3); /* Reset timer on match and generate interrupt */
|
||||
|
||||
/* Setup the VIC for the timer. */
|
||||
VICIntEnable = 0x00000010;
|
||||
|
||||
/* The ISR installed depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
#if configUSE_PREEMPTION == 1
|
||||
{
|
||||
extern void ( vPreemptiveTick )( void );
|
||||
VICVectAddr4 = ( int32_t ) vPreemptiveTick;
|
||||
}
|
||||
#else
|
||||
{
|
||||
extern void ( vNonPreemptiveTick )( void );
|
||||
VICVectAddr4 = ( int32_t ) vNonPreemptiveTick;
|
||||
}
|
||||
#endif
|
||||
|
||||
VICVectCntl4 = 1;
|
||||
|
||||
/* Start the timer - interrupts are disabled when this function is called
|
||||
so it is okay to do this here. */
|
||||
T0TCR = portENABLE_TIMER;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
@ -1,218 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Components that can be compiled to either ARM or THUMB mode are
|
||||
* contained in port.c The ISR routines, which can only be compiled
|
||||
* to ARM mode, are contained in this file.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Constants required to handle interrupts. */
|
||||
#define portTIMER_MATCH_ISR_BIT ( ( uint8_t ) 0x01 )
|
||||
#define portCLEAR_VIC_INTERRUPT ( ( uint32_t ) 0 )
|
||||
|
||||
/* Constants required to handle critical sections. */
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* ISR to handle manual context switches (from a call to taskYIELD()). */
|
||||
void vPortYieldProcessor( void ) __attribute__((interrupt("SWI"), naked));
|
||||
|
||||
/*
|
||||
* The scheduler can only be started from ARM mode, hence the inclusion of this
|
||||
* function here.
|
||||
*/
|
||||
void vPortISRStartFirstTask( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortISRStartFirstTask( void )
|
||||
{
|
||||
/* Simply start the scheduler. This is included here as it can only be
|
||||
called from ARM mode. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Called by portYIELD() or taskYIELD() to manually force a context switch.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
void vPortYieldProcessor( void )
|
||||
{
|
||||
/* 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
|
||||
ISR return code can be used in both cases. */
|
||||
__asm volatile ( "ADD LR, LR, #4" );
|
||||
|
||||
/* Perform the context switch. First save the context of the current task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Find the highest priority task that is ready to run. */
|
||||
__asm volatile( "bl vTaskSwitchContext" );
|
||||
|
||||
/* Restore the context of the new task. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The ISR used for the scheduler tick depends on whether the cooperative or
|
||||
* the preemptive scheduler is being used.
|
||||
*/
|
||||
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
simply increment the system tick. */
|
||||
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
|
||||
void vNonPreemptiveTick( void )
|
||||
{
|
||||
xTaskIncrementTick();
|
||||
T0IR = 2;
|
||||
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||
saved on entry as part of the context switch. */
|
||||
void vPreemptiveTick( void ) __attribute__((naked));
|
||||
void vPreemptiveTick( void )
|
||||
{
|
||||
/* Save the context of the interrupted task. */
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Increment the RTOS tick count, then look for the highest priority
|
||||
task that is ready to run. */
|
||||
__asm volatile
|
||||
(
|
||||
" bl xTaskIncrementTick \t\n" \
|
||||
" cmp r0, #0 \t\n" \
|
||||
" beq SkipContextSwitch \t\n" \
|
||||
" bl vTaskSwitchContext \t\n" \
|
||||
"SkipContextSwitch: \t\n"
|
||||
);
|
||||
|
||||
/* Ready for the next interrupt. */
|
||||
T0IR = 2;
|
||||
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
||||
|
||||
/* Restore the context of the new task. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The interrupt management utilities can only be called from ARM mode. When
|
||||
* 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
|
||||
* the utilities are defined as macros in portmacro.h - as per other ports.
|
||||
*/
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
|
||||
void vPortDisableInterruptsFromThumb( void )
|
||||
{
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
void vPortEnableInterruptsFromThumb( void )
|
||||
{
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0} \n\t" /* Pop R0. */
|
||||
"BX R14" ); /* Return back to thumb. */
|
||||
}
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||
different optimisation levels. The interrupt flags can therefore not always
|
||||
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. */
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as we are leaving a critical section. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||
__asm volatile (
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */
|
||||
"LDMIA SP!, {R0}" ); /* Pop R0. */
|
||||
}
|
||||
}
|
||||
}
|
@ -1,249 +0,0 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.3
|
||||
|
||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||
|
||||
Changes from V3.2.4
|
||||
|
||||
+ Removed the use of the %0 parameter within the assembler macros and
|
||||
replaced them with hard coded registers. This will ensure the
|
||||
assembler does not select the link register as the temp register as
|
||||
was occasionally happening previously.
|
||||
|
||||
+ The assembler statements are now included in a single asm block rather
|
||||
than each line having its own asm block.
|
||||
|
||||
Changes from V4.5.0
|
||||
|
||||
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
|
||||
and replaced them with portYIELD_FROM_ISR() macro. Application code
|
||||
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
|
||||
macros as per the V4.5.1 demo code.
|
||||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE portLONG
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portNOP() __asm volatile ( "NOP" );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Scheduler utilities. */
|
||||
|
||||
/*
|
||||
* portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
|
||||
* and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
|
||||
* are included here for efficiency. An attempt to call one from
|
||||
* THUMB mode code will result in a compile time error.
|
||||
*/
|
||||
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Set the LR to the task stack. */ \
|
||||
__asm volatile ( \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"LDR LR, [R0] \n\t" \
|
||||
\
|
||||
/* The critical nesting depth is the first item on the stack. */ \
|
||||
/* Load it into the ulCriticalNesting variable. */ \
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDMFD LR!, {R1} \n\t" \
|
||||
"STR R1, [R0] \n\t" \
|
||||
\
|
||||
/* Get the SPSR from the stack. */ \
|
||||
"LDMFD LR!, {R0} \n\t" \
|
||||
"MSR SPSR, R0 \n\t" \
|
||||
\
|
||||
/* Restore all system mode registers for the task. */ \
|
||||
"LDMFD LR, {R0-R14}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
\
|
||||
/* Restore the return address. */ \
|
||||
"LDR LR, [LR, #+60] \n\t" \
|
||||
\
|
||||
/* And return - correcting the offset in the LR to obtain the */ \
|
||||
/* correct address. */ \
|
||||
"SUBS PC, LR, #4 \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portSAVE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile void * volatile pxCurrentTCB; \
|
||||
extern volatile uint32_t ulCriticalNesting; \
|
||||
\
|
||||
/* Push R0 as we are going to use the register. */ \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Set R0 to point to the task stack pointer. */ \
|
||||
"STMDB SP,{SP}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB SP, SP, #4 \n\t" \
|
||||
"LDMIA SP!,{R0} \n\t" \
|
||||
\
|
||||
/* Push the return address onto the stack. */ \
|
||||
"STMDB R0!, {LR} \n\t" \
|
||||
\
|
||||
/* Now we have saved LR we can use it instead of R0. */ \
|
||||
"MOV LR, R0 \n\t" \
|
||||
\
|
||||
/* Pop R0 so we can save it onto the system mode stack. */ \
|
||||
"LDMIA SP!, {R0} \n\t" \
|
||||
\
|
||||
/* Push all the system mode registers onto the task stack. */ \
|
||||
"STMDB LR,{R0-LR}^ \n\t" \
|
||||
"NOP \n\t" \
|
||||
"SUB LR, LR, #60 \n\t" \
|
||||
\
|
||||
/* Push the SPSR onto the task stack. */ \
|
||||
"MRS R0, SPSR \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
"LDR R0, =ulCriticalNesting \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STMDB LR!, {R0} \n\t" \
|
||||
\
|
||||
/* Store the new top of stack for the task. */ \
|
||||
"LDR R0, =pxCurrentTCB \n\t" \
|
||||
"LDR R0, [R0] \n\t" \
|
||||
"STR LR, [R0] \n\t" \
|
||||
); \
|
||||
( void ) ulCriticalNesting; \
|
||||
( void ) pxCurrentTCB; \
|
||||
}
|
||||
|
||||
|
||||
#define portYIELD_FROM_ISR() vTaskSwitchContext()
|
||||
#define portYIELD() __asm volatile ( "SWI 0" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Critical section management. */
|
||||
|
||||
/*
|
||||
* The interrupt management utilities can only be called from ARM mode. When
|
||||
* 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
|
||||
* defined then the utilities are defined as macros here - as per other ports.
|
||||
*/
|
||||
|
||||
#ifdef THUMB_INTERWORK
|
||||
|
||||
extern void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
extern void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
|
||||
|
||||
#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
|
||||
#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
|
||||
|
||||
#else
|
||||
|
||||
#define portDISABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#define portENABLE_INTERRUPTS() \
|
||||
__asm volatile ( \
|
||||
"STMDB SP!, {R0} \n\t" /* Push R0. */ \
|
||||
"MRS R0, CPSR \n\t" /* Get CPSR. */ \
|
||||
"BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
|
||||
"MSR CPSR, R0 \n\t" /* Write back modified value. */ \
|
||||
"LDMIA SP!, {R0} " ) /* Pop R0. */
|
||||
|
||||
#endif /* THUMB_INTERWORK */
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user