mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-11-16 12:34:29 +00:00
Style: uncrusitfy
This commit is contained in:
committed by
alfred gedeon
parent
a5dbc2b1de
commit
718178c68a
59
croutine.c
59
croutine.c
@@ -98,17 +98,20 @@ static void prvCheckDelayedList( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex )
|
||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode,
|
||||
UBaseType_t uxPriority,
|
||||
UBaseType_t uxIndex )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
CRCB_t * pxCoRoutine;
|
||||
|
||||
/* Allocate the memory that will store the co-routine control block. */
|
||||
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
|
||||
|
||||
if( pxCoRoutine )
|
||||
{
|
||||
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
||||
be created and the co-routine data structures need initialising. */
|
||||
* be created and the co-routine data structures need initialising. */
|
||||
if( pxCurrentCoRoutine == NULL )
|
||||
{
|
||||
pxCurrentCoRoutine = pxCoRoutine;
|
||||
@@ -132,8 +135,8 @@ CRCB_t *pxCoRoutine;
|
||||
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
||||
|
||||
/* Set the co-routine control block as a link back from the ListItem_t.
|
||||
This is so we can get back to the containing CRCB from a generic item
|
||||
in a list. */
|
||||
* This is so we can get back to the containing CRCB from a generic item
|
||||
* in a list. */
|
||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
||||
|
||||
@@ -141,7 +144,7 @@ CRCB_t *pxCoRoutine;
|
||||
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
|
||||
|
||||
/* Now the co-routine has been initialised it can be added to the ready
|
||||
list at the correct priority. */
|
||||
* list at the correct priority. */
|
||||
prvAddCoRoutineToReadyQueue( pxCoRoutine );
|
||||
|
||||
xReturn = pdPASS;
|
||||
@@ -155,17 +158,18 @@ CRCB_t *pxCoRoutine;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
|
||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
|
||||
List_t * pxEventList )
|
||||
{
|
||||
TickType_t xTimeToWake;
|
||||
|
||||
/* Calculate the time to wake - this may overflow but this is
|
||||
not a problem. */
|
||||
* not a problem. */
|
||||
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
|
||||
|
||||
/* We must remove ourselves from the ready list before adding
|
||||
ourselves to the blocked list as the same list item is used for
|
||||
both lists. */
|
||||
* ourselves to the blocked list as the same list item is used for
|
||||
* both lists. */
|
||||
( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||
|
||||
/* The list item will be inserted in wake time order. */
|
||||
@@ -174,20 +178,20 @@ TickType_t xTimeToWake;
|
||||
if( xTimeToWake < xCoRoutineTickCount )
|
||||
{
|
||||
/* Wake time has overflowed. Place this item in the
|
||||
overflow list. */
|
||||
* overflow list. */
|
||||
vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The wake time has not overflowed, so we can use the
|
||||
current block list. */
|
||||
* current block list. */
|
||||
vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||
}
|
||||
|
||||
if( pxEventList )
|
||||
{
|
||||
/* Also add the co-routine to an event list. If this is done then the
|
||||
function must be called with interrupts disabled. */
|
||||
* function must be called with interrupts disabled. */
|
||||
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
|
||||
}
|
||||
}
|
||||
@@ -196,8 +200,8 @@ TickType_t xTimeToWake;
|
||||
static void prvCheckPendingReadyList( void )
|
||||
{
|
||||
/* Are there any co-routines waiting to get moved to the ready list? These
|
||||
are co-routines that have been readied by an ISR. The ISR cannot access
|
||||
the ready lists itself. */
|
||||
* are co-routines that have been readied by an ISR. The ISR cannot access
|
||||
* the ready lists itself. */
|
||||
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
||||
{
|
||||
CRCB_t * pxUnblockedCRCB;
|
||||
@@ -221,6 +225,7 @@ static void prvCheckDelayedList( void )
|
||||
CRCB_t * pxCRCB;
|
||||
|
||||
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
||||
|
||||
while( xPassedTicks )
|
||||
{
|
||||
xCoRoutineTickCount++;
|
||||
@@ -232,7 +237,7 @@ CRCB_t *pxCRCB;
|
||||
List_t * pxTemp;
|
||||
|
||||
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
||||
any items in pxDelayedCoRoutineList here then there is an error! */
|
||||
* any items in pxDelayedCoRoutineList here then there is an error! */
|
||||
pxTemp = pxDelayedCoRoutineList;
|
||||
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
|
||||
pxOverflowDelayedCoRoutineList = pxTemp;
|
||||
@@ -252,10 +257,10 @@ CRCB_t *pxCRCB;
|
||||
portDISABLE_INTERRUPTS();
|
||||
{
|
||||
/* The event could have occurred just before this critical
|
||||
section. If this is the case then the generic list item will
|
||||
have been moved to the pending ready list and the following
|
||||
line is still valid. Also the pvContainer parameter will have
|
||||
been set to NULL so the following lines are also valid. */
|
||||
* section. If this is the case then the generic list item will
|
||||
* have been moved to the pending ready list and the following
|
||||
* line is still valid. Also the pvContainer parameter will have
|
||||
* been set to NULL so the following lines are also valid. */
|
||||
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
|
||||
|
||||
/* Is the co-routine waiting on an event also? */
|
||||
@@ -277,8 +282,8 @@ CRCB_t *pxCRCB;
|
||||
void vCoRoutineSchedule( void )
|
||||
{
|
||||
/* Only run a co-routine after prvInitialiseCoRoutineLists() has been
|
||||
called. prvInitialiseCoRoutineLists() is called automatically when a
|
||||
co-routine is created. */
|
||||
* called. prvInitialiseCoRoutineLists() is called automatically when a
|
||||
* co-routine is created. */
|
||||
if( pxDelayedCoRoutineList != NULL )
|
||||
{
|
||||
/* See if any co-routines readied by events need moving to the ready lists. */
|
||||
@@ -295,18 +300,17 @@ void vCoRoutineSchedule( void )
|
||||
/* No more co-routines to check. */
|
||||
return;
|
||||
}
|
||||
|
||||
--uxTopCoRoutineReadyPriority;
|
||||
}
|
||||
|
||||
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
|
||||
of the same priority get an equal share of the processor time. */
|
||||
* of the same priority get an equal share of the processor time. */
|
||||
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
|
||||
|
||||
/* Call the co-routine. */
|
||||
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -324,7 +328,7 @@ UBaseType_t uxPriority;
|
||||
vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
|
||||
|
||||
/* Start with pxDelayedCoRoutineList using list1 and the
|
||||
pxOverflowDelayedCoRoutineList using list2. */
|
||||
* pxOverflowDelayedCoRoutineList using list2. */
|
||||
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
|
||||
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
|
||||
}
|
||||
@@ -336,8 +340,8 @@ CRCB_t *pxUnblockedCRCB;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* This function is called from within an interrupt. It can only access
|
||||
event lists and the pending ready list. This function assumes that a
|
||||
check has already been made to ensure pxEventList is not empty. */
|
||||
* event lists and the pending ready list. This function assumes that a
|
||||
* check has already been made to ensure pxEventList is not empty. */
|
||||
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
||||
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||
vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
||||
@@ -355,4 +359,3 @@ BaseType_t xReturn;
|
||||
}
|
||||
|
||||
#endif /* configUSE_CO_ROUTINES == 0 */
|
||||
|
||||
|
||||
193
event_groups.c
193
event_groups.c
@@ -28,8 +28,8 @@
|
||||
#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. */
|
||||
* 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. */
|
||||
@@ -39,14 +39,14 @@ task.h is included from an application file. */
|
||||
#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. */
|
||||
* 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. */
|
||||
* 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
|
||||
@@ -83,7 +83,9 @@ typedef struct EventGroupDef_t
|
||||
* 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;
|
||||
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -99,8 +101,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
||||
#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. */
|
||||
* 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. */
|
||||
@@ -117,8 +119,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
||||
#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. */
|
||||
* this event group was created statically in case the event group
|
||||
* is later deleted. */
|
||||
pxEventBits->ucStaticallyAllocated = pdTRUE;
|
||||
}
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
@@ -128,8 +130,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
||||
else
|
||||
{
|
||||
/* xEventGroupCreateStatic should only ever be called with
|
||||
pxEventGroupBuffer pointing to a pre-allocated (compile time
|
||||
allocated) StaticEventGroup_t variable. */
|
||||
* pxEventGroupBuffer pointing to a pre-allocated (compile time
|
||||
* allocated) StaticEventGroup_t variable. */
|
||||
traceEVENT_GROUP_CREATE_FAILED();
|
||||
}
|
||||
|
||||
@@ -146,18 +148,18 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
||||
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. */
|
||||
* 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 )
|
||||
@@ -168,8 +170,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
||||
#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. */
|
||||
* event group was allocated statically in case the event group is
|
||||
* later deleted. */
|
||||
pxEventBits->ucStaticallyAllocated = pdFALSE;
|
||||
}
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
@@ -187,7 +189,10 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
|
||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
TickType_t xTicksToWait )
|
||||
{
|
||||
EventBits_t uxOriginalBitValue, uxReturn;
|
||||
EventGroup_t * pxEventBits = xEventGroup;
|
||||
@@ -214,7 +219,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
uxReturn = ( uxOriginalBitValue | uxBitsToSet );
|
||||
|
||||
/* Rendezvous always clear the bits. They will have been cleared
|
||||
already unless this is the only task in the rendezvous. */
|
||||
* already unless this is the only task in the rendezvous. */
|
||||
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||
|
||||
xTicksToWait = 0;
|
||||
@@ -226,20 +231,20 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* specified - just return the current event bit value. */
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
xTimeoutOccurred = pdTRUE;
|
||||
}
|
||||
@@ -259,9 +264,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
* 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 )
|
||||
@@ -272,9 +277,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
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. */
|
||||
* 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;
|
||||
@@ -294,7 +299,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
}
|
||||
|
||||
/* Control bits might be set as the task had blocked should not be
|
||||
returned. */
|
||||
* returned. */
|
||||
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||
}
|
||||
|
||||
@@ -307,7 +312,11 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
|
||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xClearOnExit,
|
||||
const BaseType_t xWaitForAllBits,
|
||||
TickType_t xTicksToWait )
|
||||
{
|
||||
EventGroup_t * pxEventBits = xEventGroup;
|
||||
EventBits_t uxReturn, uxControlBits = 0;
|
||||
@@ -315,7 +324,7 @@ 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. */
|
||||
* itself, and that at least one bit is being requested. */
|
||||
configASSERT( xEventGroup );
|
||||
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
configASSERT( uxBitsToWaitFor != 0 );
|
||||
@@ -335,7 +344,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
if( xWaitConditionMet != pdFALSE )
|
||||
{
|
||||
/* The wait condition has already been met so there is no need to
|
||||
block. */
|
||||
* block. */
|
||||
uxReturn = uxCurrentEventBits;
|
||||
xTicksToWait = ( TickType_t ) 0;
|
||||
|
||||
@@ -352,16 +361,16 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
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. */
|
||||
* 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. */
|
||||
* 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;
|
||||
@@ -381,13 +390,13 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
* 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. */
|
||||
* 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 );
|
||||
@@ -407,9 +416,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
* 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 )
|
||||
@@ -420,7 +429,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
|
||||
/* It is possible that the event bits were updated between this
|
||||
task leaving the Blocked state and running again. */
|
||||
* task leaving the Blocked state and running again. */
|
||||
if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
|
||||
{
|
||||
if( xClearOnExit != pdFALSE )
|
||||
@@ -436,6 +445,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
xTimeoutOccurred = pdTRUE;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
@@ -448,6 +458,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
/* 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. */
|
||||
@@ -457,13 +468,14 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear )
|
||||
{
|
||||
EventGroup_t * pxEventBits = xEventGroup;
|
||||
EventBits_t uxReturn;
|
||||
|
||||
/* Check the user is not attempting to clear the bits used by the kernel
|
||||
itself. */
|
||||
* itself. */
|
||||
configASSERT( xEventGroup );
|
||||
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
|
||||
@@ -472,7 +484,7 @@ EventBits_t uxReturn;
|
||||
traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
|
||||
|
||||
/* The value returned is the event group value prior to the bits being
|
||||
cleared. */
|
||||
* cleared. */
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
|
||||
/* Clear the bits. */
|
||||
@@ -486,7 +498,8 @@ EventBits_t uxReturn;
|
||||
|
||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||
|
||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
@@ -496,7 +509,7 @@ EventBits_t uxReturn;
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
|
||||
@@ -515,7 +528,8 @@ EventBits_t 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 )
|
||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet )
|
||||
{
|
||||
ListItem_t * pxListItem, * pxNext;
|
||||
ListItem_t const * pxListEnd;
|
||||
@@ -525,7 +539,7 @@ EventGroup_t *pxEventBits = xEventGroup;
|
||||
BaseType_t xMatchFound = pdFALSE;
|
||||
|
||||
/* Check the user is not attempting to set the bits used by the kernel
|
||||
itself. */
|
||||
* itself. */
|
||||
configASSERT( xEventGroup );
|
||||
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
|
||||
@@ -586,21 +600,21 @@ BaseType_t xMatchFound = pdFALSE;
|
||||
}
|
||||
|
||||
/* Store the actual event flag value in the task's event list
|
||||
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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* bit was set in the control word. */
|
||||
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||
}
|
||||
( void ) xTaskResumeAll();
|
||||
@@ -621,7 +635,7 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||
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. */
|
||||
* 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 );
|
||||
}
|
||||
@@ -629,13 +643,13 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
|
||||
{
|
||||
/* The event group can only have been allocated dynamically - free
|
||||
it again. */
|
||||
* 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. */
|
||||
* dynamically, so check before attempting to free the memory. */
|
||||
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
|
||||
{
|
||||
vPortFree( pxEventBits );
|
||||
@@ -652,29 +666,33 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* For internal use only - execute a 'set bits' command that was pended from
|
||||
an interrupt. */
|
||||
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
|
||||
* 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 )
|
||||
* 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 )
|
||||
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? */
|
||||
* set. Is one already set? */
|
||||
if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
|
||||
{
|
||||
xWaitConditionMet = pdTRUE;
|
||||
@@ -687,7 +705,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
||||
else
|
||||
{
|
||||
/* Task has to wait for all the bits in uxBitsToWaitFor to be set.
|
||||
Are they set already? */
|
||||
* Are they set already? */
|
||||
if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||
{
|
||||
xWaitConditionMet = pdTRUE;
|
||||
@@ -704,7 +722,9 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
||||
|
||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||
|
||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
|
||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet,
|
||||
BaseType_t * pxHigherPriorityTaskWoken )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
@@ -714,7 +734,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
@@ -741,12 +761,11 @@ BaseType_t xWaitConditionMet = pdFALSE;
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber )
|
||||
void vEventGroupSetNumber( void * xEventGroup,
|
||||
UBaseType_t uxEventGroupNumber )
|
||||
{
|
||||
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
|
||||
}
|
||||
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ extern "C" {
|
||||
#if ( configUSE_NEWLIB_REENTRANT == 1 )
|
||||
#include <reent.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check all the required application specific macros have been defined.
|
||||
* These macros are application specific and (as downloaded) are defined
|
||||
@@ -241,10 +242,10 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* configPRECONDITION should be defined as configASSERT.
|
||||
The CBMC proofs need a way to track assumptions and assertions.
|
||||
A configPRECONDITION statement should express an implicit invariant or
|
||||
assumption made. A configASSERT statement should express an invariant that must
|
||||
hold explicit before calling the code. */
|
||||
* The CBMC proofs need a way to track assumptions and assertions.
|
||||
* A configPRECONDITION statement should express an implicit invariant or
|
||||
* assumption made. A configASSERT statement should express an invariant that must
|
||||
* hold explicit before calling the code. */
|
||||
#ifndef configPRECONDITION
|
||||
#define configPRECONDITION( X ) configASSERT( X )
|
||||
#define configPRECONDITION_DEFINED 0
|
||||
@@ -313,26 +314,30 @@ hold explicit before calling the code. */
|
||||
|
||||
/* Remove any unused trace macros. */
|
||||
#ifndef traceSTART
|
||||
|
||||
/* Used to perform any necessary initialisation - for example, open a file
|
||||
into which trace is to be written. */
|
||||
* into which trace is to be written. */
|
||||
#define traceSTART()
|
||||
#endif
|
||||
|
||||
#ifndef traceEND
|
||||
|
||||
/* Use to close a trace, for example close a file into which trace has been
|
||||
written. */
|
||||
* written. */
|
||||
#define traceEND()
|
||||
#endif
|
||||
|
||||
#ifndef traceTASK_SWITCHED_IN
|
||||
|
||||
/* Called after a task has been selected to run. pxCurrentTCB holds a pointer
|
||||
to the task control block of the selected task. */
|
||||
* to the task control block of the selected task. */
|
||||
#define traceTASK_SWITCHED_IN()
|
||||
#endif
|
||||
|
||||
#ifndef traceINCREASE_TICK_COUNT
|
||||
|
||||
/* Called before stepping the tick count after waking from tickless idle
|
||||
sleep. */
|
||||
* sleep. */
|
||||
#define traceINCREASE_TICK_COUNT( x )
|
||||
#endif
|
||||
|
||||
@@ -347,49 +352,55 @@ hold explicit before calling the code. */
|
||||
#endif
|
||||
|
||||
#ifndef traceTASK_SWITCHED_OUT
|
||||
|
||||
/* Called before a task has been selected to run. pxCurrentTCB holds a pointer
|
||||
to the task control block of the task being switched out. */
|
||||
* to the task control block of the task being switched out. */
|
||||
#define traceTASK_SWITCHED_OUT()
|
||||
#endif
|
||||
|
||||
#ifndef traceTASK_PRIORITY_INHERIT
|
||||
|
||||
/* Called when a task attempts to take a mutex that is already held by a
|
||||
lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task
|
||||
that holds the mutex. uxInheritedPriority is the priority the mutex holder
|
||||
will inherit (the priority of the task that is attempting to obtain the
|
||||
muted. */
|
||||
* lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task
|
||||
* that holds the mutex. uxInheritedPriority is the priority the mutex holder
|
||||
* will inherit (the priority of the task that is attempting to obtain the
|
||||
* muted. */
|
||||
#define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority )
|
||||
#endif
|
||||
|
||||
#ifndef traceTASK_PRIORITY_DISINHERIT
|
||||
|
||||
/* Called when a task releases a mutex, the holding of which had resulted in
|
||||
the task inheriting the priority of a higher priority task.
|
||||
pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the
|
||||
mutex. uxOriginalPriority is the task's configured (base) priority. */
|
||||
* the task inheriting the priority of a higher priority task.
|
||||
* pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the
|
||||
* mutex. uxOriginalPriority is the task's configured (base) priority. */
|
||||
#define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority )
|
||||
#endif
|
||||
|
||||
#ifndef traceBLOCKING_ON_QUEUE_RECEIVE
|
||||
|
||||
/* Task is about to block because it cannot read from a
|
||||
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
||||
upon which the read was attempted. pxCurrentTCB points to the TCB of the
|
||||
task that attempted the read. */
|
||||
* queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
||||
* upon which the read was attempted. pxCurrentTCB points to the TCB of the
|
||||
* task that attempted the read. */
|
||||
#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
|
||||
#endif
|
||||
|
||||
#ifndef traceBLOCKING_ON_QUEUE_PEEK
|
||||
|
||||
/* Task is about to block because it cannot read from a
|
||||
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
||||
upon which the read was attempted. pxCurrentTCB points to the TCB of the
|
||||
task that attempted the read. */
|
||||
* queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
||||
* upon which the read was attempted. pxCurrentTCB points to the TCB of the
|
||||
* task that attempted the read. */
|
||||
#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue )
|
||||
#endif
|
||||
|
||||
#ifndef traceBLOCKING_ON_QUEUE_SEND
|
||||
|
||||
/* Task is about to block because it cannot write to a
|
||||
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
||||
upon which the write was attempted. pxCurrentTCB points to the TCB of the
|
||||
task that attempted the write. */
|
||||
* queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
||||
* upon which the write was attempted. pxCurrentTCB points to the TCB of the
|
||||
* task that attempted the write. */
|
||||
#define traceBLOCKING_ON_QUEUE_SEND( pxQueue )
|
||||
#endif
|
||||
|
||||
@@ -864,15 +875,17 @@ hold explicit before calling the code. */
|
||||
#endif
|
||||
|
||||
#ifndef configSTACK_DEPTH_TYPE
|
||||
|
||||
/* Defaults to uint16_t for backward compatibility, but can be overridden
|
||||
in FreeRTOSConfig.h if uint16_t is too restrictive. */
|
||||
* in FreeRTOSConfig.h if uint16_t is too restrictive. */
|
||||
#define configSTACK_DEPTH_TYPE uint16_t
|
||||
#endif
|
||||
|
||||
#ifndef configMESSAGE_BUFFER_LENGTH_TYPE
|
||||
|
||||
/* Defaults to size_t for backward compatibility, but can be overridden
|
||||
in FreeRTOSConfig.h if lengths will always be less than the number of bytes
|
||||
in a size_t. */
|
||||
* in FreeRTOSConfig.h if lengths will always be less than the number of bytes
|
||||
* in a size_t. */
|
||||
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
|
||||
#endif
|
||||
|
||||
@@ -896,51 +909,56 @@ hold explicit before calling the code. */
|
||||
#endif
|
||||
|
||||
#if ( portTICK_TYPE_IS_ATOMIC == 0 )
|
||||
|
||||
/* Either variables of tick type cannot be read atomically, or
|
||||
portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when
|
||||
the tick count is returned to the standard critical section macros. */
|
||||
* portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when
|
||||
* the tick count is returned to the standard critical section macros. */
|
||||
#define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL()
|
||||
#define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL()
|
||||
#define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()
|
||||
#define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) )
|
||||
#else
|
||||
|
||||
/* The tick type can be read atomically, so critical sections used when the
|
||||
tick count is returned can be defined away. */
|
||||
* tick count is returned can be defined away. */
|
||||
#define portTICK_TYPE_ENTER_CRITICAL()
|
||||
#define portTICK_TYPE_EXIT_CRITICAL()
|
||||
#define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0
|
||||
#define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) x
|
||||
#endif
|
||||
#endif /* if ( portTICK_TYPE_IS_ATOMIC == 0 ) */
|
||||
|
||||
/* Definitions to allow backward compatibility with FreeRTOS versions prior to
|
||||
V8 if desired. */
|
||||
* V8 if desired. */
|
||||
#ifndef configENABLE_BACKWARD_COMPATIBILITY
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||
#endif
|
||||
|
||||
#ifndef configPRINTF
|
||||
|
||||
/* configPRINTF() was not defined, so define it away to nothing. To use
|
||||
configPRINTF() then define it as follows (where MyPrintFunction() is
|
||||
provided by the application writer):
|
||||
|
||||
void MyPrintFunction(const char *pcFormat, ... );
|
||||
* configPRINTF() then define it as follows (where MyPrintFunction() is
|
||||
* provided by the application writer):
|
||||
*
|
||||
* void MyPrintFunction(const char *pcFormat, ... );
|
||||
#define configPRINTF( X ) MyPrintFunction X
|
||||
|
||||
Then call like a standard printf() function, but placing brackets around
|
||||
all parameters so they are passed as a single parameter. For example:
|
||||
configPRINTF( ("Value = %d", MyVariable) ); */
|
||||
*
|
||||
* Then call like a standard printf() function, but placing brackets around
|
||||
* all parameters so they are passed as a single parameter. For example:
|
||||
* configPRINTF( ("Value = %d", MyVariable) ); */
|
||||
#define configPRINTF( X )
|
||||
#endif
|
||||
|
||||
#ifndef configMAX
|
||||
|
||||
/* The application writer has not provided their own MAX macro, so define
|
||||
the following generic implementation. */
|
||||
* the following generic implementation. */
|
||||
#define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
|
||||
#endif
|
||||
|
||||
#ifndef configMIN
|
||||
|
||||
/* The application writer has not provided their own MAX macro, so define
|
||||
the following generic implementation. */
|
||||
* the following generic implementation. */
|
||||
#define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
|
||||
#endif
|
||||
|
||||
@@ -967,14 +985,14 @@ V8 if desired. */
|
||||
#define xTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter
|
||||
|
||||
/* Backward compatibility within the scheduler code only - these definitions
|
||||
are not really required but are included for completeness. */
|
||||
* are not really required but are included for completeness. */
|
||||
#define tmrTIMER_CALLBACK TimerCallbackFunction_t
|
||||
#define pdTASK_CODE TaskFunction_t
|
||||
#define xListItem ListItem_t
|
||||
#define xList List_t
|
||||
|
||||
/* For libraries that break the list data hiding, and access list structure
|
||||
members directly (which is not supposed to be done). */
|
||||
* members directly (which is not supposed to be done). */
|
||||
#define pxContainer pvContainer
|
||||
#endif /* configENABLE_BACKWARD_COMPATIBILITY */
|
||||
|
||||
@@ -983,33 +1001,33 @@ V8 if desired. */
|
||||
#endif
|
||||
|
||||
/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even
|
||||
if floating point hardware is otherwise supported by the FreeRTOS port in use.
|
||||
This constant is not supported by all FreeRTOS ports that include floating
|
||||
point support. */
|
||||
* if floating point hardware is otherwise supported by the FreeRTOS port in use.
|
||||
* This constant is not supported by all FreeRTOS ports that include floating
|
||||
* point support. */
|
||||
#ifndef configUSE_TASK_FPU_SUPPORT
|
||||
#define configUSE_TASK_FPU_SUPPORT 1
|
||||
#endif
|
||||
|
||||
/* Set configENABLE_MPU to 1 to enable MPU support and 0 to disable it. This is
|
||||
currently used in ARMv8M ports. */
|
||||
* currently used in ARMv8M ports. */
|
||||
#ifndef configENABLE_MPU
|
||||
#define configENABLE_MPU 0
|
||||
#endif
|
||||
|
||||
/* Set configENABLE_FPU to 1 to enable FPU support and 0 to disable it. This is
|
||||
currently used in ARMv8M ports. */
|
||||
* currently used in ARMv8M ports. */
|
||||
#ifndef configENABLE_FPU
|
||||
#define configENABLE_FPU 1
|
||||
#endif
|
||||
|
||||
/* Set configENABLE_TRUSTZONE to 1 enable TrustZone support and 0 to disable it.
|
||||
This is currently used in ARMv8M ports. */
|
||||
* This is currently used in ARMv8M ports. */
|
||||
#ifndef configENABLE_TRUSTZONE
|
||||
#define configENABLE_TRUSTZONE 1
|
||||
#endif
|
||||
|
||||
/* Set configRUN_FREERTOS_SECURE_ONLY to 1 to run the FreeRTOS ARMv8M port on
|
||||
the Secure Side only. */
|
||||
* the Secure Side only. */
|
||||
#ifndef configRUN_FREERTOS_SECURE_ONLY
|
||||
#define configRUN_FREERTOS_SECURE_ONLY 0
|
||||
#endif
|
||||
@@ -1056,7 +1074,8 @@ the Secure Side only. */
|
||||
* | | | | xTaskCreateRestrictedStatic | | | |
|
||||
* +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+
|
||||
*/
|
||||
#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( ( portUSING_MPU_WRAPPERS == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) || \
|
||||
#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE \
|
||||
( ( ( portUSING_MPU_WRAPPERS == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) || \
|
||||
( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) )
|
||||
|
||||
/*
|
||||
@@ -1210,7 +1229,6 @@ typedef struct xSTATIC_QUEUE
|
||||
UBaseType_t uxDummy8;
|
||||
uint8_t ucDummy9;
|
||||
#endif
|
||||
|
||||
} StaticQueue_t;
|
||||
typedef StaticQueue_t StaticSemaphore_t;
|
||||
|
||||
@@ -1240,7 +1258,6 @@ typedef struct xSTATIC_EVENT_GROUP
|
||||
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
uint8_t ucDummy4;
|
||||
#endif
|
||||
|
||||
} StaticEventGroup_t;
|
||||
|
||||
/*
|
||||
@@ -1268,7 +1285,6 @@ typedef struct xSTATIC_TIMER
|
||||
UBaseType_t uxDummy7;
|
||||
#endif
|
||||
uint8_t ucDummy8;
|
||||
|
||||
} StaticTimer_t;
|
||||
|
||||
/*
|
||||
@@ -1303,4 +1319,3 @@ typedef StaticStreamBuffer_t StaticMessageBuffer_t;
|
||||
#endif
|
||||
|
||||
#endif /* INC_FREERTOS_H */
|
||||
|
||||
|
||||
@@ -129,4 +129,3 @@
|
||||
|
||||
|
||||
#endif /* STACK_MACROS_H */
|
||||
|
||||
|
||||
@@ -38,12 +38,13 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Used to hide the implementation of the co-routine control block. The
|
||||
control block structure however has to be included in the header due to
|
||||
the macro implementation of the co-routine functionality. */
|
||||
* control block structure however has to be included in the header due to
|
||||
* the macro implementation of the co-routine functionality. */
|
||||
typedef void * CoRoutineHandle_t;
|
||||
|
||||
/* Defines the prototype to which co-routine functions must conform. */
|
||||
typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t );
|
||||
typedef void (* crCOROUTINE_CODE)( CoRoutineHandle_t,
|
||||
UBaseType_t );
|
||||
|
||||
typedef struct corCoRoutineControlBlock
|
||||
{
|
||||
@@ -58,11 +59,11 @@ typedef struct corCoRoutineControlBlock
|
||||
/**
|
||||
* croutine. h
|
||||
*<pre>
|
||||
BaseType_t xCoRoutineCreate(
|
||||
crCOROUTINE_CODE pxCoRoutineCode,
|
||||
UBaseType_t uxPriority,
|
||||
UBaseType_t uxIndex
|
||||
);</pre>
|
||||
* BaseType_t xCoRoutineCreate(
|
||||
* crCOROUTINE_CODE pxCoRoutineCode,
|
||||
* UBaseType_t uxPriority,
|
||||
* UBaseType_t uxIndex
|
||||
* );</pre>
|
||||
*
|
||||
* Create a new co-routine and add it to the list of co-routines that are
|
||||
* ready to run.
|
||||
@@ -82,58 +83,60 @@ typedef struct corCoRoutineControlBlock
|
||||
* list, otherwise an error code defined with ProjDefs.h.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine to be created.
|
||||
void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
// This may not be necessary for const variables.
|
||||
static const char cLedToFlash[ 2 ] = { 5, 6 };
|
||||
static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
|
||||
|
||||
// Must start every co-routine with a call to crSTART();
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// This co-routine just delays for a fixed period, then toggles
|
||||
// an LED. Two co-routines are created using this function, so
|
||||
// the uxIndex parameter is used to tell the co-routine which
|
||||
// LED to flash and how int32_t to delay. This assumes xQueue has
|
||||
// already been created.
|
||||
vParTestToggleLED( cLedToFlash[ uxIndex ] );
|
||||
crDELAY( xHandle, uxFlashRates[ uxIndex ] );
|
||||
}
|
||||
|
||||
// Must end every co-routine with a call to crEND();
|
||||
crEND();
|
||||
}
|
||||
|
||||
// Function that creates two co-routines.
|
||||
void vOtherFunction( void )
|
||||
{
|
||||
uint8_t ucParameterToPass;
|
||||
TaskHandle_t xHandle;
|
||||
|
||||
// Create two co-routines at priority 0. The first is given index 0
|
||||
// so (from the code above) toggles LED 5 every 200 ticks. The second
|
||||
// is given index 1 so toggles LED 6 every 400 ticks.
|
||||
for( uxIndex = 0; uxIndex < 2; uxIndex++ )
|
||||
{
|
||||
xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* // Co-routine to be created.
|
||||
* void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
* // This may not be necessary for const variables.
|
||||
* static const char cLedToFlash[ 2 ] = { 5, 6 };
|
||||
* static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
|
||||
*
|
||||
* // Must start every co-routine with a call to crSTART();
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // This co-routine just delays for a fixed period, then toggles
|
||||
* // an LED. Two co-routines are created using this function, so
|
||||
* // the uxIndex parameter is used to tell the co-routine which
|
||||
* // LED to flash and how int32_t to delay. This assumes xQueue has
|
||||
* // already been created.
|
||||
* vParTestToggleLED( cLedToFlash[ uxIndex ] );
|
||||
* crDELAY( xHandle, uxFlashRates[ uxIndex ] );
|
||||
* }
|
||||
*
|
||||
* // Must end every co-routine with a call to crEND();
|
||||
* crEND();
|
||||
* }
|
||||
*
|
||||
* // Function that creates two co-routines.
|
||||
* void vOtherFunction( void )
|
||||
* {
|
||||
* uint8_t ucParameterToPass;
|
||||
* TaskHandle_t xHandle;
|
||||
*
|
||||
* // Create two co-routines at priority 0. The first is given index 0
|
||||
* // so (from the code above) toggles LED 5 every 200 ticks. The second
|
||||
* // is given index 1 so toggles LED 6 every 400 ticks.
|
||||
* for( uxIndex = 0; uxIndex < 2; uxIndex++ )
|
||||
* {
|
||||
* xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xCoRoutineCreate xCoRoutineCreate
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex );
|
||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode,
|
||||
UBaseType_t uxPriority,
|
||||
UBaseType_t uxIndex );
|
||||
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
*<pre>
|
||||
void vCoRoutineSchedule( void );</pre>
|
||||
* void vCoRoutineSchedule( void );</pre>
|
||||
*
|
||||
* Run a co-routine.
|
||||
*
|
||||
@@ -147,25 +150,25 @@ BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPri
|
||||
* hook).
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// This idle task hook will schedule a co-routine each time it is called.
|
||||
// The rest of the idle task will execute between co-routine calls.
|
||||
void vApplicationIdleHook( void )
|
||||
{
|
||||
vCoRoutineSchedule();
|
||||
}
|
||||
|
||||
// Alternatively, if you do not require any other part of the idle task to
|
||||
// execute, the idle task hook can call vCoRoutineSchedule() within an
|
||||
// infinite loop.
|
||||
void vApplicationIdleHook( void )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
vCoRoutineSchedule();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* // This idle task hook will schedule a co-routine each time it is called.
|
||||
* // The rest of the idle task will execute between co-routine calls.
|
||||
* void vApplicationIdleHook( void )
|
||||
* {
|
||||
* vCoRoutineSchedule();
|
||||
* }
|
||||
*
|
||||
* // Alternatively, if you do not require any other part of the idle task to
|
||||
* // execute, the idle task hook can call vCoRoutineSchedule() within an
|
||||
* // infinite loop.
|
||||
* void vApplicationIdleHook( void )
|
||||
* {
|
||||
* for( ;; )
|
||||
* {
|
||||
* vCoRoutineSchedule();
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup vCoRoutineSchedule vCoRoutineSchedule
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
@@ -174,60 +177,62 @@ void vCoRoutineSchedule( void );
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crSTART( CoRoutineHandle_t xHandle );</pre>
|
||||
* crSTART( CoRoutineHandle_t xHandle );</pre>
|
||||
*
|
||||
* This macro MUST always be called at the start of a co-routine function.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine to be created.
|
||||
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
static int32_t ulAVariable;
|
||||
|
||||
// Must start every co-routine with a call to crSTART();
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Co-routine functionality goes here.
|
||||
}
|
||||
|
||||
// Must end every co-routine with a call to crEND();
|
||||
crEND();
|
||||
}</pre>
|
||||
* <pre>
|
||||
* // Co-routine to be created.
|
||||
* void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
* static int32_t ulAVariable;
|
||||
*
|
||||
* // Must start every co-routine with a call to crSTART();
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Co-routine functionality goes here.
|
||||
* }
|
||||
*
|
||||
* // Must end every co-routine with a call to crEND();
|
||||
* crEND();
|
||||
* }</pre>
|
||||
* \defgroup crSTART crSTART
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0:
|
||||
#define crSTART( pxCRCB ) \
|
||||
switch( ( ( CRCB_t * ) ( pxCRCB ) )->uxState ) { \
|
||||
case 0:
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crEND();</pre>
|
||||
* crEND();</pre>
|
||||
*
|
||||
* This macro MUST always be called at the end of a co-routine function.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine to be created.
|
||||
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
static int32_t ulAVariable;
|
||||
|
||||
// Must start every co-routine with a call to crSTART();
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Co-routine functionality goes here.
|
||||
}
|
||||
|
||||
// Must end every co-routine with a call to crEND();
|
||||
crEND();
|
||||
}</pre>
|
||||
* <pre>
|
||||
* // Co-routine to be created.
|
||||
* void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
* static int32_t ulAVariable;
|
||||
*
|
||||
* // Must start every co-routine with a call to crSTART();
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Co-routine functionality goes here.
|
||||
* }
|
||||
*
|
||||
* // Must end every co-routine with a call to crEND();
|
||||
* crEND();
|
||||
* }</pre>
|
||||
* \defgroup crSTART crSTART
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
@@ -237,13 +242,17 @@ void vCoRoutineSchedule( void );
|
||||
* These macros are intended for internal use by the co-routine implementation
|
||||
* only. The macros should not be used directly by application writers.
|
||||
*/
|
||||
#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
|
||||
#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
|
||||
#define crSET_STATE0( xHandle ) \
|
||||
( ( CRCB_t * ) ( xHandle ) )->uxState = ( __LINE__ * 2 ); return; \
|
||||
case ( __LINE__ * 2 ):
|
||||
#define crSET_STATE1( xHandle ) \
|
||||
( ( CRCB_t * ) ( xHandle ) )->uxState = ( ( __LINE__ * 2 ) + 1 ); return; \
|
||||
case ( ( __LINE__ * 2 ) + 1 ):
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
*<pre>
|
||||
crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre>
|
||||
* crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre>
|
||||
*
|
||||
* Delay a co-routine for a fixed period of time.
|
||||
*
|
||||
@@ -260,29 +269,29 @@ void vCoRoutineSchedule( void );
|
||||
* can be used to convert ticks to milliseconds.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine to be created.
|
||||
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
// This may not be necessary for const variables.
|
||||
// We are to delay for 200ms.
|
||||
static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
|
||||
|
||||
// Must start every co-routine with a call to crSTART();
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Delay for 200ms.
|
||||
crDELAY( xHandle, xDelayTime );
|
||||
|
||||
// Do something here.
|
||||
}
|
||||
|
||||
// Must end every co-routine with a call to crEND();
|
||||
crEND();
|
||||
}</pre>
|
||||
* <pre>
|
||||
* // Co-routine to be created.
|
||||
* void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
* // This may not be necessary for const variables.
|
||||
* // We are to delay for 200ms.
|
||||
* static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
|
||||
*
|
||||
* // Must start every co-routine with a call to crSTART();
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Delay for 200ms.
|
||||
* crDELAY( xHandle, xDelayTime );
|
||||
*
|
||||
* // Do something here.
|
||||
* }
|
||||
*
|
||||
* // Must end every co-routine with a call to crEND();
|
||||
* crEND();
|
||||
* }</pre>
|
||||
* \defgroup crDELAY crDELAY
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
@@ -295,13 +304,13 @@ void vCoRoutineSchedule( void );
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
crQUEUE_SEND(
|
||||
CoRoutineHandle_t xHandle,
|
||||
QueueHandle_t pxQueue,
|
||||
void *pvItemToQueue,
|
||||
TickType_t xTicksToWait,
|
||||
BaseType_t *pxResult
|
||||
)</pre>
|
||||
* crQUEUE_SEND(
|
||||
* CoRoutineHandle_t xHandle,
|
||||
* QueueHandle_t pxQueue,
|
||||
* void *pvItemToQueue,
|
||||
* TickType_t xTicksToWait,
|
||||
* BaseType_t *pxResult
|
||||
* )</pre>
|
||||
*
|
||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||
@@ -341,38 +350,38 @@ void vCoRoutineSchedule( void );
|
||||
* error defined within ProjDefs.h.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine function that blocks for a fixed period then posts a number onto
|
||||
// a queue.
|
||||
static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
static BaseType_t xNumberToPost = 0;
|
||||
static BaseType_t xResult;
|
||||
|
||||
// Co-routines must begin with a call to crSTART().
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// This assumes the queue has already been created.
|
||||
crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
|
||||
|
||||
if( xResult != pdPASS )
|
||||
{
|
||||
// The message was not posted!
|
||||
}
|
||||
|
||||
// Increment the number to be posted onto the queue.
|
||||
xNumberToPost++;
|
||||
|
||||
// Delay for 100 ticks.
|
||||
crDELAY( xHandle, 100 );
|
||||
}
|
||||
|
||||
// Co-routines must end with a call to crEND().
|
||||
crEND();
|
||||
}</pre>
|
||||
* <pre>
|
||||
* // Co-routine function that blocks for a fixed period then posts a number onto
|
||||
* // a queue.
|
||||
* static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
* static BaseType_t xNumberToPost = 0;
|
||||
* static BaseType_t xResult;
|
||||
*
|
||||
* // Co-routines must begin with a call to crSTART().
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // This assumes the queue has already been created.
|
||||
* crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
|
||||
*
|
||||
* if( xResult != pdPASS )
|
||||
* {
|
||||
* // The message was not posted!
|
||||
* }
|
||||
*
|
||||
* // Increment the number to be posted onto the queue.
|
||||
* xNumberToPost++;
|
||||
*
|
||||
* // Delay for 100 ticks.
|
||||
* crDELAY( xHandle, 100 );
|
||||
* }
|
||||
*
|
||||
* // Co-routines must end with a call to crEND().
|
||||
* crEND();
|
||||
* }</pre>
|
||||
* \defgroup crQUEUE_SEND crQUEUE_SEND
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
@@ -394,13 +403,13 @@ void vCoRoutineSchedule( void );
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crQUEUE_RECEIVE(
|
||||
CoRoutineHandle_t xHandle,
|
||||
QueueHandle_t pxQueue,
|
||||
void *pvBuffer,
|
||||
TickType_t xTicksToWait,
|
||||
BaseType_t *pxResult
|
||||
)</pre>
|
||||
* crQUEUE_RECEIVE(
|
||||
* CoRoutineHandle_t xHandle,
|
||||
* QueueHandle_t pxQueue,
|
||||
* void *pvBuffer,
|
||||
* TickType_t xTicksToWait,
|
||||
* BaseType_t *pxResult
|
||||
* )</pre>
|
||||
*
|
||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||
@@ -439,32 +448,32 @@ void vCoRoutineSchedule( void );
|
||||
* an error code as defined within ProjDefs.h.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// A co-routine receives the number of an LED to flash from a queue. It
|
||||
// blocks on the queue until the number is received.
|
||||
static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
static BaseType_t xResult;
|
||||
static UBaseType_t uxLEDToFlash;
|
||||
|
||||
// All co-routines must start with a call to crSTART().
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Wait for data to become available on the queue.
|
||||
crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
// We received the LED to flash - flash it!
|
||||
vParTestToggleLED( uxLEDToFlash );
|
||||
}
|
||||
}
|
||||
|
||||
crEND();
|
||||
}</pre>
|
||||
* <pre>
|
||||
* // A co-routine receives the number of an LED to flash from a queue. It
|
||||
* // blocks on the queue until the number is received.
|
||||
* static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
* static BaseType_t xResult;
|
||||
* static UBaseType_t uxLEDToFlash;
|
||||
*
|
||||
* // All co-routines must start with a call to crSTART().
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Wait for data to become available on the queue.
|
||||
* crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||
*
|
||||
* if( xResult == pdPASS )
|
||||
* {
|
||||
* // We received the LED to flash - flash it!
|
||||
* vParTestToggleLED( uxLEDToFlash );
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* crEND();
|
||||
* }</pre>
|
||||
* \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
@@ -486,11 +495,11 @@ void vCoRoutineSchedule( void );
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crQUEUE_SEND_FROM_ISR(
|
||||
QueueHandle_t pxQueue,
|
||||
void *pvItemToQueue,
|
||||
BaseType_t xCoRoutinePreviouslyWoken
|
||||
)</pre>
|
||||
* crQUEUE_SEND_FROM_ISR(
|
||||
* QueueHandle_t pxQueue,
|
||||
* void *pvItemToQueue,
|
||||
* BaseType_t xCoRoutinePreviouslyWoken
|
||||
* )</pre>
|
||||
*
|
||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||
@@ -525,55 +534,55 @@ void vCoRoutineSchedule( void );
|
||||
* the ISR.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// A co-routine that blocks on a queue waiting for characters to be received.
|
||||
static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
char cRxedChar;
|
||||
BaseType_t xResult;
|
||||
|
||||
// All co-routines must start with a call to crSTART().
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Wait for data to become available on the queue. This assumes the
|
||||
// queue xCommsRxQueue has already been created!
|
||||
crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||
|
||||
// Was a character received?
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
// Process the character here.
|
||||
}
|
||||
}
|
||||
|
||||
// All co-routines must end with a call to crEND().
|
||||
crEND();
|
||||
}
|
||||
|
||||
// An ISR that uses a queue to send characters received on a serial port to
|
||||
// a co-routine.
|
||||
void vUART_ISR( void )
|
||||
{
|
||||
char cRxedChar;
|
||||
BaseType_t xCRWokenByPost = pdFALSE;
|
||||
|
||||
// We loop around reading characters until there are none left in the UART.
|
||||
while( UART_RX_REG_NOT_EMPTY() )
|
||||
{
|
||||
// Obtain the character from the UART.
|
||||
cRxedChar = UART_RX_REG;
|
||||
|
||||
// Post the character onto a queue. xCRWokenByPost will be pdFALSE
|
||||
// the first time around the loop. If the post causes a co-routine
|
||||
// to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
|
||||
// In this manner we can ensure that if more than one co-routine is
|
||||
// blocked on the queue only one is woken by this ISR no matter how
|
||||
// many characters are posted to the queue.
|
||||
xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
|
||||
}
|
||||
}</pre>
|
||||
* <pre>
|
||||
* // A co-routine that blocks on a queue waiting for characters to be received.
|
||||
* static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* char cRxedChar;
|
||||
* BaseType_t xResult;
|
||||
*
|
||||
* // All co-routines must start with a call to crSTART().
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Wait for data to become available on the queue. This assumes the
|
||||
* // queue xCommsRxQueue has already been created!
|
||||
* crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||
*
|
||||
* // Was a character received?
|
||||
* if( xResult == pdPASS )
|
||||
* {
|
||||
* // Process the character here.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // All co-routines must end with a call to crEND().
|
||||
* crEND();
|
||||
* }
|
||||
*
|
||||
* // An ISR that uses a queue to send characters received on a serial port to
|
||||
* // a co-routine.
|
||||
* void vUART_ISR( void )
|
||||
* {
|
||||
* char cRxedChar;
|
||||
* BaseType_t xCRWokenByPost = pdFALSE;
|
||||
*
|
||||
* // We loop around reading characters until there are none left in the UART.
|
||||
* while( UART_RX_REG_NOT_EMPTY() )
|
||||
* {
|
||||
* // Obtain the character from the UART.
|
||||
* cRxedChar = UART_RX_REG;
|
||||
*
|
||||
* // Post the character onto a queue. xCRWokenByPost will be pdFALSE
|
||||
* // the first time around the loop. If the post causes a co-routine
|
||||
* // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
|
||||
* // In this manner we can ensure that if more than one co-routine is
|
||||
* // blocked on the queue only one is woken by this ISR no matter how
|
||||
* // many characters are posted to the queue.
|
||||
* xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
|
||||
* }
|
||||
* }</pre>
|
||||
* \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
@@ -583,11 +592,11 @@ void vCoRoutineSchedule( void );
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crQUEUE_SEND_FROM_ISR(
|
||||
QueueHandle_t pxQueue,
|
||||
void *pvBuffer,
|
||||
BaseType_t * pxCoRoutineWoken
|
||||
)</pre>
|
||||
* crQUEUE_SEND_FROM_ISR(
|
||||
* QueueHandle_t pxQueue,
|
||||
* void *pvBuffer,
|
||||
* BaseType_t * pxCoRoutineWoken
|
||||
* )</pre>
|
||||
*
|
||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||
@@ -622,71 +631,71 @@ void vCoRoutineSchedule( void );
|
||||
* pdFALSE.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// A co-routine that posts a character to a queue then blocks for a fixed
|
||||
// period. The character is incremented each time.
|
||||
static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// cChar holds its value while this co-routine is blocked and must therefore
|
||||
// be declared static.
|
||||
static char cCharToTx = 'a';
|
||||
BaseType_t xResult;
|
||||
|
||||
// All co-routines must start with a call to crSTART().
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Send the next character to the queue.
|
||||
crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
|
||||
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
// The character was successfully posted to the queue.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Could not post the character to the queue.
|
||||
}
|
||||
|
||||
// Enable the UART Tx interrupt to cause an interrupt in this
|
||||
// hypothetical UART. The interrupt will obtain the character
|
||||
// from the queue and send it.
|
||||
ENABLE_RX_INTERRUPT();
|
||||
|
||||
// Increment to the next character then block for a fixed period.
|
||||
// cCharToTx will maintain its value across the delay as it is
|
||||
// declared static.
|
||||
cCharToTx++;
|
||||
if( cCharToTx > 'x' )
|
||||
{
|
||||
cCharToTx = 'a';
|
||||
}
|
||||
crDELAY( 100 );
|
||||
}
|
||||
|
||||
// All co-routines must end with a call to crEND().
|
||||
crEND();
|
||||
}
|
||||
|
||||
// An ISR that uses a queue to receive characters to send on a UART.
|
||||
void vUART_ISR( void )
|
||||
{
|
||||
char cCharToTx;
|
||||
BaseType_t xCRWokenByPost = pdFALSE;
|
||||
|
||||
while( UART_TX_REG_EMPTY() )
|
||||
{
|
||||
// Are there any characters in the queue waiting to be sent?
|
||||
// xCRWokenByPost will automatically be set to pdTRUE if a co-routine
|
||||
// is woken by the post - ensuring that only a single co-routine is
|
||||
// woken no matter how many times we go around this loop.
|
||||
if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
|
||||
{
|
||||
SEND_CHARACTER( cCharToTx );
|
||||
}
|
||||
}
|
||||
}</pre>
|
||||
* <pre>
|
||||
* // A co-routine that posts a character to a queue then blocks for a fixed
|
||||
* // period. The character is incremented each time.
|
||||
* static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // cChar holds its value while this co-routine is blocked and must therefore
|
||||
* // be declared static.
|
||||
* static char cCharToTx = 'a';
|
||||
* BaseType_t xResult;
|
||||
*
|
||||
* // All co-routines must start with a call to crSTART().
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Send the next character to the queue.
|
||||
* crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
|
||||
*
|
||||
* if( xResult == pdPASS )
|
||||
* {
|
||||
* // The character was successfully posted to the queue.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // Could not post the character to the queue.
|
||||
* }
|
||||
*
|
||||
* // Enable the UART Tx interrupt to cause an interrupt in this
|
||||
* // hypothetical UART. The interrupt will obtain the character
|
||||
* // from the queue and send it.
|
||||
* ENABLE_RX_INTERRUPT();
|
||||
*
|
||||
* // Increment to the next character then block for a fixed period.
|
||||
* // cCharToTx will maintain its value across the delay as it is
|
||||
* // declared static.
|
||||
* cCharToTx++;
|
||||
* if( cCharToTx > 'x' )
|
||||
* {
|
||||
* cCharToTx = 'a';
|
||||
* }
|
||||
* crDELAY( 100 );
|
||||
* }
|
||||
*
|
||||
* // All co-routines must end with a call to crEND().
|
||||
* crEND();
|
||||
* }
|
||||
*
|
||||
* // An ISR that uses a queue to receive characters to send on a UART.
|
||||
* void vUART_ISR( void )
|
||||
* {
|
||||
* char cCharToTx;
|
||||
* BaseType_t xCRWokenByPost = pdFALSE;
|
||||
*
|
||||
* while( UART_TX_REG_EMPTY() )
|
||||
* {
|
||||
* // Are there any characters in the queue waiting to be sent?
|
||||
* // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
|
||||
* // is woken by the post - ensuring that only a single co-routine is
|
||||
* // woken no matter how many times we go around this loop.
|
||||
* if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
|
||||
* {
|
||||
* SEND_CHARACTER( cCharToTx );
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
* \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
@@ -701,7 +710,8 @@ void vCoRoutineSchedule( void );
|
||||
* Removes the current co-routine from its ready list and places it in the
|
||||
* appropriate delayed list.
|
||||
*/
|
||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList );
|
||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
|
||||
List_t * pxEventList );
|
||||
|
||||
/*
|
||||
* This function is intended for internal use by the queue implementation only.
|
||||
|
||||
@@ -29,13 +29,13 @@
|
||||
|
||||
|
||||
/* 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. */
|
||||
* 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"
|
||||
@@ -208,16 +208,18 @@ projects should not use them. */
|
||||
#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. */
|
||||
* 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. */
|
||||
* FreeRTOSConfig.h when using the Borland compiler. */
|
||||
#include "frconfig.h"
|
||||
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
||||
typedef void ( __interrupt __far * pxISR )();
|
||||
@@ -275,4 +277,3 @@ projects should not use them. */
|
||||
#endif
|
||||
|
||||
#endif /* DEPRECATED_DEFINITIONS_H */
|
||||
|
||||
|
||||
@@ -93,8 +93,8 @@ typedef TickType_t EventBits_t;
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventGroupHandle_t xEventGroupCreate( void );
|
||||
</pre>
|
||||
* EventGroupHandle_t xEventGroupCreate( void );
|
||||
* </pre>
|
||||
*
|
||||
* Create a new event group.
|
||||
*
|
||||
@@ -121,24 +121,24 @@ typedef TickType_t EventBits_t;
|
||||
* 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>
|
||||
* <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
|
||||
*/
|
||||
@@ -149,8 +149,8 @@ typedef TickType_t EventBits_t;
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
|
||||
</pre>
|
||||
* EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
|
||||
* </pre>
|
||||
*
|
||||
* Create a new event group.
|
||||
*
|
||||
@@ -180,20 +180,20 @@ typedef TickType_t EventBits_t;
|
||||
* 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>
|
||||
* <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;
|
||||
@@ -202,12 +202,12 @@ typedef TickType_t EventBits_t;
|
||||
/**
|
||||
* 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>
|
||||
* 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.
|
||||
@@ -251,53 +251,57 @@ typedef TickType_t EventBits_t;
|
||||
* pdTRUE.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
* <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>
|
||||
*
|
||||
* 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;
|
||||
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>
|
||||
* 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.
|
||||
@@ -311,50 +315,51 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits
|
||||
* @return The value of the event group before the specified bits were cleared.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
* <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>
|
||||
*
|
||||
* 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;
|
||||
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>
|
||||
* BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||
* </pre>
|
||||
*
|
||||
* A version of xEventGroupClearBits() that can be called from an interrupt.
|
||||
*
|
||||
@@ -379,32 +384,33 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
|
||||
* if the timer service queue was full.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
* <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>
|
||||
*
|
||||
* // 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;
|
||||
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
|
||||
@@ -412,8 +418,8 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||
</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()
|
||||
@@ -439,55 +445,56 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
|
||||
* event group value before the call to xEventGroupSetBits() returns.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
* <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>
|
||||
*
|
||||
* 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;
|
||||
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>
|
||||
* 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.
|
||||
*
|
||||
@@ -520,43 +527,45 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
|
||||
* if the timer service queue was full.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
* <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>
|
||||
*
|
||||
* // 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;
|
||||
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
|
||||
@@ -564,11 +573,11 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
TickType_t xTicksToWait );
|
||||
</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
|
||||
@@ -607,92 +616,95 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
|
||||
* automatically cleared.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Bits used by the three tasks.
|
||||
* <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>
|
||||
*
|
||||
* // 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;
|
||||
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>
|
||||
* 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.
|
||||
@@ -709,8 +721,8 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t u
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
|
||||
</pre>
|
||||
* EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
|
||||
* </pre>
|
||||
*
|
||||
* A version of xEventGroupGetBits() that can be called from an ISR.
|
||||
*
|
||||
@@ -726,8 +738,8 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
void xEventGroupDelete( EventGroupHandle_t xEventGroup );
|
||||
</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
|
||||
@@ -738,13 +750,16 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG
|
||||
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;
|
||||
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;
|
||||
void vEventGroupSetNumber( void * xEventGroup,
|
||||
UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -752,5 +767,3 @@ void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToCl
|
||||
#endif
|
||||
|
||||
#endif /* EVENT_GROUPS_H */
|
||||
|
||||
|
||||
|
||||
@@ -96,10 +96,10 @@ 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.*/
|
||||
* 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
|
||||
@@ -112,7 +112,7 @@ use of FreeRTOS.*/
|
||||
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
|
||||
#define listTEST_LIST_ITEM_INTEGRITY( pxItem )
|
||||
#define listTEST_LIST_INTEGRITY( pxList )
|
||||
#else
|
||||
#else /* if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) */
|
||||
/* Define macros that add new members into the list structures. */
|
||||
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
|
||||
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
|
||||
@@ -126,7 +126,7 @@ use of FreeRTOS.*/
|
||||
#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. */
|
||||
* 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 */
|
||||
@@ -365,7 +365,8 @@ void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
|
||||
* \page vListInsert vListInsert
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||
void vListInsert( List_t * const pxList,
|
||||
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Insert a list item into a list. The item will be inserted in a position
|
||||
@@ -386,7 +387,8 @@ void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIV
|
||||
* \page vListInsertEnd vListInsertEnd
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||
void vListInsertEnd( List_t * const pxList,
|
||||
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Remove an item from a list. The list item has a pointer to the list that
|
||||
@@ -407,5 +409,4 @@ UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTIO
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ifndef LIST_H */
|
||||
|
||||
@@ -85,9 +85,9 @@ typedef void * MessageBufferHandle_t;
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
|
||||
</pre>
|
||||
* <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
|
||||
@@ -111,30 +111,30 @@ MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
|
||||
* 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>
|
||||
* <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
|
||||
*/
|
||||
@@ -143,11 +143,11 @@ const size_t xMessageBufferSizeBytes = 100;
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
|
||||
uint8_t *pucMessageBufferStorageArea,
|
||||
StaticMessageBuffer_t *pxStaticMessageBuffer );
|
||||
</pre>
|
||||
* <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.
|
||||
*
|
||||
@@ -172,35 +172,35 @@ MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
|
||||
* 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.
|
||||
* <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>
|
||||
*
|
||||
* // 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
|
||||
*/
|
||||
@@ -209,12 +209,12 @@ MessageBufferHandle_t xMessageBuffer;
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
TickType_t xTicksToWait );
|
||||
<pre>
|
||||
* <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
|
||||
@@ -271,35 +271,35 @@ size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
|
||||
* 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>
|
||||
* <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
|
||||
*/
|
||||
@@ -308,12 +308,12 @@ const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
BaseType_t *pxHigherPriorityTaskWoken );
|
||||
<pre>
|
||||
* <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
|
||||
@@ -371,39 +371,39 @@ size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||
* 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 portYIELD_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.
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
</pre>
|
||||
* <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 portYIELD_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.
|
||||
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
@@ -412,12 +412,12 @@ BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
TickType_t xTicksToWait );
|
||||
</pre>
|
||||
* <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.
|
||||
@@ -470,28 +470,28 @@ size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
|
||||
* 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>
|
||||
* <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
|
||||
*/
|
||||
@@ -501,12 +501,12 @@ const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
* <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
|
||||
@@ -560,39 +560,39 @@ size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||
* 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 portYIELD_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.
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
</pre>
|
||||
* <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 portYIELD_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.
|
||||
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
@@ -601,9 +601,9 @@ BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
|
||||
</pre>
|
||||
* <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
|
||||
@@ -620,9 +620,9 @@ void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
|
||||
</pre>
|
||||
* <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
|
||||
@@ -637,9 +637,9 @@ BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
|
||||
</pre>
|
||||
* <pre>
|
||||
* BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
|
||||
* </pre>
|
||||
*
|
||||
* Tests to see if a message buffer is empty (does not contain any messages).
|
||||
*
|
||||
@@ -653,9 +653,9 @@ BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
|
||||
</pre>
|
||||
* <pre>
|
||||
* BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
|
||||
* </pre>
|
||||
*
|
||||
* Resets a message buffer to its initial empty state, discarding any message it
|
||||
* contained.
|
||||
@@ -677,9 +677,9 @@ BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
|
||||
</pre>
|
||||
* <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.
|
||||
@@ -699,9 +699,9 @@ size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
<pre>
|
||||
size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) );
|
||||
</pre>
|
||||
* <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.
|
||||
@@ -719,9 +719,9 @@ size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
* <pre>
|
||||
* BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
* </pre>
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
@@ -758,9 +758,9 @@ BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuff
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
* <pre>
|
||||
* BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
* </pre>
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
|
||||
@@ -37,19 +37,38 @@
|
||||
#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;
|
||||
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;
|
||||
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_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;
|
||||
@@ -61,87 +80,166 @@ 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;
|
||||
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;
|
||||
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;
|
||||
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
|
||||
const UBaseType_t uxArraySize,
|
||||
uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL;
|
||||
uint32_t MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskGetRunTimeStats( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL;
|
||||
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify,
|
||||
UBaseType_t uxIndexToNotify,
|
||||
uint32_t ulValue,
|
||||
eNotifyAction eAction,
|
||||
uint32_t * pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn,
|
||||
uint32_t ulBitsToClearOnEntry,
|
||||
uint32_t ulBitsToClearOnExit,
|
||||
uint32_t * pulNotificationValue,
|
||||
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn,
|
||||
BaseType_t xClearCountOnExit,
|
||||
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask,
|
||||
UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL;
|
||||
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask,
|
||||
UBaseType_t uxIndexToClear,
|
||||
uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL;
|
||||
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;
|
||||
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;
|
||||
BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of queue.h API functions. */
|
||||
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL;
|
||||
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;
|
||||
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;
|
||||
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_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_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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer,
|
||||
const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
TickType_t MPU_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;
|
||||
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;
|
||||
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_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;
|
||||
@@ -149,11 +247,17 @@ BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERT
|
||||
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;
|
||||
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 */
|
||||
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
#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. */
|
||||
* 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. */
|
||||
* included from queue.c or task.c to prevent it from having an effect within
|
||||
* those files. */
|
||||
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/*
|
||||
@@ -143,7 +143,7 @@ only for ports that are using the MPU. */
|
||||
#define vEventGroupDelete MPU_vEventGroupDelete
|
||||
|
||||
/* Map standard message/stream_buffer.h API functions to the MPU
|
||||
equivalents. */
|
||||
* equivalents. */
|
||||
#define xStreamBufferSend MPU_xStreamBufferSend
|
||||
#define xStreamBufferReceive MPU_xStreamBufferReceive
|
||||
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
|
||||
@@ -159,8 +159,8 @@ only for ports that are using the MPU. */
|
||||
|
||||
|
||||
/* 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). */
|
||||
* 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
|
||||
@@ -185,4 +185,3 @@ only for ports that are using the MPU. */
|
||||
|
||||
|
||||
#endif /* MPU_WRAPPERS_H */
|
||||
|
||||
|
||||
@@ -32,21 +32,21 @@
|
||||
#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. */
|
||||
* 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. */
|
||||
* 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
|
||||
@@ -105,20 +105,32 @@ extern "C" {
|
||||
*/
|
||||
#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;
|
||||
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;
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters,
|
||||
BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
#else
|
||||
#else /* 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 ) PRIVILEGED_FUNCTION;
|
||||
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
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
#endif /* if ( portUSING_MPU_WRAPPERS == 1 ) */
|
||||
|
||||
/* Used by heap_5.c to define the start address and size of each memory region
|
||||
that together comprise the total FreeRTOS heap space. */
|
||||
* that together comprise the total FreeRTOS heap space. */
|
||||
typedef struct HeapRegion
|
||||
{
|
||||
uint8_t * pucStartAddress;
|
||||
@@ -187,7 +199,10 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
||||
*/
|
||||
#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;
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||
const struct xMEMORY_REGION * const xRegions,
|
||||
StackType_t * pxBottomOfStack,
|
||||
uint32_t ulStackDepth ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -195,4 +210,3 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
#endif /* PORTABLE_H */
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
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. */
|
||||
* 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
|
||||
@@ -65,7 +65,7 @@ definition here is not suitable for your application. */
|
||||
#endif
|
||||
|
||||
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
|
||||
itself. */
|
||||
* 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 */
|
||||
@@ -108,7 +108,7 @@ itself. */
|
||||
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
|
||||
|
||||
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS
|
||||
itself. */
|
||||
* itself. */
|
||||
#define pdFREERTOS_LITTLE_ENDIAN 0
|
||||
#define pdFREERTOS_BIG_ENDIAN 1
|
||||
|
||||
@@ -118,6 +118,3 @@ itself. */
|
||||
|
||||
|
||||
#endif /* PROJDEFS_H */
|
||||
|
||||
|
||||
|
||||
|
||||
1449
include/queue.h
1449
include/queue.h
File diff suppressed because it is too large
Load Diff
790
include/semphr.h
790
include/semphr.h
@@ -70,22 +70,22 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
SemaphoreHandle_t xSemaphore = NULL;
|
||||
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
|
||||
// This is a macro so pass the variable in directly.
|
||||
vSemaphoreCreateBinary( xSemaphore );
|
||||
|
||||
if( xSemaphore != NULL )
|
||||
{
|
||||
// The semaphore was created successfully.
|
||||
// The semaphore can now be used.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* SemaphoreHandle_t xSemaphore = NULL;
|
||||
*
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
|
||||
* // This is a macro so pass the variable in directly.
|
||||
* vSemaphoreCreateBinary( xSemaphore );
|
||||
*
|
||||
* if( xSemaphore != NULL )
|
||||
* {
|
||||
* // The semaphore was created successfully.
|
||||
* // The semaphore can now be used.
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -138,22 +138,22 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* hold the semaphore's data structures could not be allocated.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
SemaphoreHandle_t xSemaphore = NULL;
|
||||
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// Semaphore cannot be used before a call to xSemaphoreCreateBinary().
|
||||
// This is a macro so pass the variable in directly.
|
||||
xSemaphore = xSemaphoreCreateBinary();
|
||||
|
||||
if( xSemaphore != NULL )
|
||||
{
|
||||
// The semaphore was created successfully.
|
||||
// The semaphore can now be used.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* SemaphoreHandle_t xSemaphore = NULL;
|
||||
*
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
|
||||
* // This is a macro so pass the variable in directly.
|
||||
* xSemaphore = xSemaphoreCreateBinary();
|
||||
*
|
||||
* if( xSemaphore != NULL )
|
||||
* {
|
||||
* // The semaphore was created successfully.
|
||||
* // The semaphore can now be used.
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -196,23 +196,23 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* returned. If pxSemaphoreBuffer is NULL then NULL is returned.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
SemaphoreHandle_t xSemaphore = NULL;
|
||||
StaticSemaphore_t xSemaphoreBuffer;
|
||||
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// Semaphore cannot be used before a call to xSemaphoreCreateBinary().
|
||||
// The semaphore's data structures will be placed in the xSemaphoreBuffer
|
||||
// variable, the address of which is passed into the function. The
|
||||
// function's parameter is not NULL, so the function will not attempt any
|
||||
// dynamic memory allocation, and therefore the function will not return
|
||||
// return NULL.
|
||||
xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
|
||||
|
||||
// Rest of task code goes here.
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* SemaphoreHandle_t xSemaphore = NULL;
|
||||
* StaticSemaphore_t xSemaphoreBuffer;
|
||||
*
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
|
||||
* // The semaphore's data structures will be placed in the xSemaphoreBuffer
|
||||
* // variable, the address of which is passed into the function. The
|
||||
* // function's parameter is not NULL, so the function will not attempt any
|
||||
* // dynamic memory allocation, and therefore the function will not return
|
||||
* // return NULL.
|
||||
* xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
|
||||
*
|
||||
* // Rest of task code goes here.
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -244,44 +244,44 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* if xBlockTime expired without the semaphore becoming available.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
SemaphoreHandle_t xSemaphore = NULL;
|
||||
|
||||
// A task that creates a semaphore.
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// Create the semaphore to guard a shared resource.
|
||||
xSemaphore = xSemaphoreCreateBinary();
|
||||
}
|
||||
|
||||
// A task that uses the semaphore.
|
||||
void vAnotherTask( void * pvParameters )
|
||||
{
|
||||
// ... Do other things.
|
||||
|
||||
if( xSemaphore != NULL )
|
||||
{
|
||||
// See if we can obtain the semaphore. If the semaphore is not available
|
||||
// wait 10 ticks to see if it becomes free.
|
||||
if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
|
||||
{
|
||||
// We were able to obtain the semaphore and can now access the
|
||||
// shared resource.
|
||||
|
||||
// ...
|
||||
|
||||
// We have finished accessing the shared resource. Release the
|
||||
// semaphore.
|
||||
xSemaphoreGive( xSemaphore );
|
||||
}
|
||||
else
|
||||
{
|
||||
// We could not obtain the semaphore and can therefore not access
|
||||
// the shared resource safely.
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* SemaphoreHandle_t xSemaphore = NULL;
|
||||
*
|
||||
* // A task that creates a semaphore.
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* // Create the semaphore to guard a shared resource.
|
||||
* xSemaphore = xSemaphoreCreateBinary();
|
||||
* }
|
||||
*
|
||||
* // A task that uses the semaphore.
|
||||
* void vAnotherTask( void * pvParameters )
|
||||
* {
|
||||
* // ... Do other things.
|
||||
*
|
||||
* if( xSemaphore != NULL )
|
||||
* {
|
||||
* // See if we can obtain the semaphore. If the semaphore is not available
|
||||
* // wait 10 ticks to see if it becomes free.
|
||||
* if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
|
||||
* {
|
||||
* // We were able to obtain the semaphore and can now access the
|
||||
* // shared resource.
|
||||
*
|
||||
* // ...
|
||||
*
|
||||
* // We have finished accessing the shared resource. Release the
|
||||
* // semaphore.
|
||||
* xSemaphoreGive( xSemaphore );
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // We could not obtain the semaphore and can therefore not access
|
||||
* // the shared resource safely.
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xSemaphoreTake xSemaphoreTake
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -323,58 +323,58 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* expired without the semaphore becoming available.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
SemaphoreHandle_t xMutex = NULL;
|
||||
|
||||
// A task that creates a mutex.
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// Create the mutex to guard a shared resource.
|
||||
xMutex = xSemaphoreCreateRecursiveMutex();
|
||||
}
|
||||
|
||||
// A task that uses the mutex.
|
||||
void vAnotherTask( void * pvParameters )
|
||||
{
|
||||
// ... Do other things.
|
||||
|
||||
if( xMutex != NULL )
|
||||
{
|
||||
// See if we can obtain the mutex. If the mutex is not available
|
||||
// wait 10 ticks to see if it becomes free.
|
||||
if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
|
||||
{
|
||||
// We were able to obtain the mutex and can now access the
|
||||
// shared resource.
|
||||
|
||||
// ...
|
||||
// For some reason due to the nature of the code further calls to
|
||||
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||
// code these would not be just sequential calls as this would make
|
||||
// no sense. Instead the calls are likely to be buried inside
|
||||
// a more complex call structure.
|
||||
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||
|
||||
// The mutex has now been 'taken' three times, so will not be
|
||||
// available to another task until it has also been given back
|
||||
// three times. Again it is unlikely that real code would have
|
||||
// these calls sequentially, but instead buried in a more complex
|
||||
// call structure. This is just for illustrative purposes.
|
||||
xSemaphoreGiveRecursive( xMutex );
|
||||
xSemaphoreGiveRecursive( xMutex );
|
||||
xSemaphoreGiveRecursive( xMutex );
|
||||
|
||||
// Now the mutex can be taken by other tasks.
|
||||
}
|
||||
else
|
||||
{
|
||||
// We could not obtain the mutex and can therefore not access
|
||||
// the shared resource safely.
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* SemaphoreHandle_t xMutex = NULL;
|
||||
*
|
||||
* // A task that creates a mutex.
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* // Create the mutex to guard a shared resource.
|
||||
* xMutex = xSemaphoreCreateRecursiveMutex();
|
||||
* }
|
||||
*
|
||||
* // A task that uses the mutex.
|
||||
* void vAnotherTask( void * pvParameters )
|
||||
* {
|
||||
* // ... Do other things.
|
||||
*
|
||||
* if( xMutex != NULL )
|
||||
* {
|
||||
* // See if we can obtain the mutex. If the mutex is not available
|
||||
* // wait 10 ticks to see if it becomes free.
|
||||
* if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
|
||||
* {
|
||||
* // We were able to obtain the mutex and can now access the
|
||||
* // shared resource.
|
||||
*
|
||||
* // ...
|
||||
* // For some reason due to the nature of the code further calls to
|
||||
* // xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||
* // code these would not be just sequential calls as this would make
|
||||
* // no sense. Instead the calls are likely to be buried inside
|
||||
* // a more complex call structure.
|
||||
* xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||
* xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||
*
|
||||
* // The mutex has now been 'taken' three times, so will not be
|
||||
* // available to another task until it has also been given back
|
||||
* // three times. Again it is unlikely that real code would have
|
||||
* // these calls sequentially, but instead buried in a more complex
|
||||
* // call structure. This is just for illustrative purposes.
|
||||
* xSemaphoreGiveRecursive( xMutex );
|
||||
* xSemaphoreGiveRecursive( xMutex );
|
||||
* xSemaphoreGiveRecursive( xMutex );
|
||||
*
|
||||
* // Now the mutex can be taken by other tasks.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // We could not obtain the mutex and can therefore not access
|
||||
* // the shared resource safely.
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -405,41 +405,41 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* semaphore was not first obtained correctly.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
SemaphoreHandle_t xSemaphore = NULL;
|
||||
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// Create the semaphore to guard a shared resource.
|
||||
xSemaphore = vSemaphoreCreateBinary();
|
||||
|
||||
if( xSemaphore != NULL )
|
||||
{
|
||||
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
||||
{
|
||||
// We would expect this call to fail because we cannot give
|
||||
// a semaphore without first "taking" it!
|
||||
}
|
||||
|
||||
// Obtain the semaphore - don't block if the semaphore is not
|
||||
// immediately available.
|
||||
if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
|
||||
{
|
||||
// We now have the semaphore and can access the shared resource.
|
||||
|
||||
// ...
|
||||
|
||||
// We have finished accessing the shared resource so can free the
|
||||
// semaphore.
|
||||
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
||||
{
|
||||
// We would not expect this call to fail because we must have
|
||||
// obtained the semaphore to get here.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* SemaphoreHandle_t xSemaphore = NULL;
|
||||
*
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* // Create the semaphore to guard a shared resource.
|
||||
* xSemaphore = vSemaphoreCreateBinary();
|
||||
*
|
||||
* if( xSemaphore != NULL )
|
||||
* {
|
||||
* if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
||||
* {
|
||||
* // We would expect this call to fail because we cannot give
|
||||
* // a semaphore without first "taking" it!
|
||||
* }
|
||||
*
|
||||
* // Obtain the semaphore - don't block if the semaphore is not
|
||||
* // immediately available.
|
||||
* if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
|
||||
* {
|
||||
* // We now have the semaphore and can access the shared resource.
|
||||
*
|
||||
* // ...
|
||||
*
|
||||
* // We have finished accessing the shared resource so can free the
|
||||
* // semaphore.
|
||||
* if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
||||
* {
|
||||
* // We would not expect this call to fail because we must have
|
||||
* // obtained the semaphore to get here.
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xSemaphoreGive xSemaphoreGive
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -471,59 +471,59 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* @return pdTRUE if the semaphore was given.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
SemaphoreHandle_t xMutex = NULL;
|
||||
|
||||
// A task that creates a mutex.
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// Create the mutex to guard a shared resource.
|
||||
xMutex = xSemaphoreCreateRecursiveMutex();
|
||||
}
|
||||
|
||||
// A task that uses the mutex.
|
||||
void vAnotherTask( void * pvParameters )
|
||||
{
|
||||
// ... Do other things.
|
||||
|
||||
if( xMutex != NULL )
|
||||
{
|
||||
// See if we can obtain the mutex. If the mutex is not available
|
||||
// wait 10 ticks to see if it becomes free.
|
||||
if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
|
||||
{
|
||||
// We were able to obtain the mutex and can now access the
|
||||
// shared resource.
|
||||
|
||||
// ...
|
||||
// For some reason due to the nature of the code further calls to
|
||||
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||
// code these would not be just sequential calls as this would make
|
||||
// no sense. Instead the calls are likely to be buried inside
|
||||
// a more complex call structure.
|
||||
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||
|
||||
// The mutex has now been 'taken' three times, so will not be
|
||||
// available to another task until it has also been given back
|
||||
// three times. Again it is unlikely that real code would have
|
||||
// these calls sequentially, it would be more likely that the calls
|
||||
// to xSemaphoreGiveRecursive() would be called as a call stack
|
||||
// unwound. This is just for demonstrative purposes.
|
||||
xSemaphoreGiveRecursive( xMutex );
|
||||
xSemaphoreGiveRecursive( xMutex );
|
||||
xSemaphoreGiveRecursive( xMutex );
|
||||
|
||||
// Now the mutex can be taken by other tasks.
|
||||
}
|
||||
else
|
||||
{
|
||||
// We could not obtain the mutex and can therefore not access
|
||||
// the shared resource safely.
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* SemaphoreHandle_t xMutex = NULL;
|
||||
*
|
||||
* // A task that creates a mutex.
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* // Create the mutex to guard a shared resource.
|
||||
* xMutex = xSemaphoreCreateRecursiveMutex();
|
||||
* }
|
||||
*
|
||||
* // A task that uses the mutex.
|
||||
* void vAnotherTask( void * pvParameters )
|
||||
* {
|
||||
* // ... Do other things.
|
||||
*
|
||||
* if( xMutex != NULL )
|
||||
* {
|
||||
* // See if we can obtain the mutex. If the mutex is not available
|
||||
* // wait 10 ticks to see if it becomes free.
|
||||
* if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
|
||||
* {
|
||||
* // We were able to obtain the mutex and can now access the
|
||||
* // shared resource.
|
||||
*
|
||||
* // ...
|
||||
* // For some reason due to the nature of the code further calls to
|
||||
* // xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||
* // code these would not be just sequential calls as this would make
|
||||
* // no sense. Instead the calls are likely to be buried inside
|
||||
* // a more complex call structure.
|
||||
* xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||
* xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||
*
|
||||
* // The mutex has now been 'taken' three times, so will not be
|
||||
* // available to another task until it has also been given back
|
||||
* // three times. Again it is unlikely that real code would have
|
||||
* // these calls sequentially, it would be more likely that the calls
|
||||
* // to xSemaphoreGiveRecursive() would be called as a call stack
|
||||
* // unwound. This is just for demonstrative purposes.
|
||||
* xSemaphoreGiveRecursive( xMutex );
|
||||
* xSemaphoreGiveRecursive( xMutex );
|
||||
* xSemaphoreGiveRecursive( xMutex );
|
||||
*
|
||||
* // Now the mutex can be taken by other tasks.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // We could not obtain the mutex and can therefore not access
|
||||
* // the shared resource safely.
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -534,10 +534,10 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
/**
|
||||
* semphr. h
|
||||
* <pre>
|
||||
xSemaphoreGiveFromISR(
|
||||
SemaphoreHandle_t xSemaphore,
|
||||
BaseType_t *pxHigherPriorityTaskWoken
|
||||
)</pre>
|
||||
* xSemaphoreGiveFromISR(
|
||||
* SemaphoreHandle_t xSemaphore,
|
||||
* BaseType_t *pxHigherPriorityTaskWoken
|
||||
* )</pre>
|
||||
*
|
||||
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
|
||||
* created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting().
|
||||
@@ -559,64 +559,64 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
* <pre>
|
||||
\#define LONG_TIME 0xffff
|
||||
\#define TICKS_TO_WAIT 10
|
||||
SemaphoreHandle_t xSemaphore = NULL;
|
||||
|
||||
// Repetitive task.
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
// We want this task to run every 10 ticks of a timer. The semaphore
|
||||
// was created before this task was started.
|
||||
|
||||
// Block waiting for the semaphore to become available.
|
||||
if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
|
||||
{
|
||||
// It is time to execute.
|
||||
|
||||
// ...
|
||||
|
||||
// We have finished our task. Return to the top of the loop where
|
||||
// we will block on the semaphore until it is time to execute
|
||||
// again. Note when using the semaphore for synchronisation with an
|
||||
// ISR in this manner there is no need to 'give' the semaphore back.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Timer ISR
|
||||
void vTimerISR( void * pvParameters )
|
||||
{
|
||||
static uint8_t ucLocalTickCount = 0;
|
||||
static BaseType_t xHigherPriorityTaskWoken;
|
||||
|
||||
// A timer tick has occurred.
|
||||
|
||||
// ... Do other time functions.
|
||||
|
||||
// Is it time for vATask () to run?
|
||||
xHigherPriorityTaskWoken = pdFALSE;
|
||||
ucLocalTickCount++;
|
||||
if( ucLocalTickCount >= TICKS_TO_WAIT )
|
||||
{
|
||||
// Unblock the task by releasing the semaphore.
|
||||
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
|
||||
|
||||
// Reset the count so we release the semaphore again in 10 ticks time.
|
||||
ucLocalTickCount = 0;
|
||||
}
|
||||
|
||||
if( xHigherPriorityTaskWoken != pdFALSE )
|
||||
{
|
||||
// We can force a context switch here. Context switching from an
|
||||
// ISR uses port specific syntax. Check the demo task for your port
|
||||
// to find the syntax required.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* SemaphoreHandle_t xSemaphore = NULL;
|
||||
*
|
||||
* // Repetitive task.
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* for( ;; )
|
||||
* {
|
||||
* // We want this task to run every 10 ticks of a timer. The semaphore
|
||||
* // was created before this task was started.
|
||||
*
|
||||
* // Block waiting for the semaphore to become available.
|
||||
* if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
|
||||
* {
|
||||
* // It is time to execute.
|
||||
*
|
||||
* // ...
|
||||
*
|
||||
* // We have finished our task. Return to the top of the loop where
|
||||
* // we will block on the semaphore until it is time to execute
|
||||
* // again. Note when using the semaphore for synchronisation with an
|
||||
* // ISR in this manner there is no need to 'give' the semaphore back.
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Timer ISR
|
||||
* void vTimerISR( void * pvParameters )
|
||||
* {
|
||||
* static uint8_t ucLocalTickCount = 0;
|
||||
* static BaseType_t xHigherPriorityTaskWoken;
|
||||
*
|
||||
* // A timer tick has occurred.
|
||||
*
|
||||
* // ... Do other time functions.
|
||||
*
|
||||
* // Is it time for vATask () to run?
|
||||
* xHigherPriorityTaskWoken = pdFALSE;
|
||||
* ucLocalTickCount++;
|
||||
* if( ucLocalTickCount >= TICKS_TO_WAIT )
|
||||
* {
|
||||
* // Unblock the task by releasing the semaphore.
|
||||
* xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
|
||||
*
|
||||
* // Reset the count so we release the semaphore again in 10 ticks time.
|
||||
* ucLocalTickCount = 0;
|
||||
* }
|
||||
*
|
||||
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||
* {
|
||||
* // We can force a context switch here. Context switching from an
|
||||
* // ISR uses port specific syntax. Check the demo task for your port
|
||||
* // to find the syntax required.
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -625,10 +625,10 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
/**
|
||||
* semphr. h
|
||||
* <pre>
|
||||
xSemaphoreTakeFromISR(
|
||||
SemaphoreHandle_t xSemaphore,
|
||||
BaseType_t *pxHigherPriorityTaskWoken
|
||||
)</pre>
|
||||
* xSemaphoreTakeFromISR(
|
||||
* SemaphoreHandle_t xSemaphore,
|
||||
* BaseType_t *pxHigherPriorityTaskWoken
|
||||
* )</pre>
|
||||
*
|
||||
* <i>Macro</i> to take a semaphore from an ISR. The semaphore must have
|
||||
* previously been created with a call to xSemaphoreCreateBinary() or
|
||||
@@ -692,22 +692,22 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* data structures then NULL is returned.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
SemaphoreHandle_t xSemaphore;
|
||||
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
|
||||
// This is a macro so pass the variable in directly.
|
||||
xSemaphore = xSemaphoreCreateMutex();
|
||||
|
||||
if( xSemaphore != NULL )
|
||||
{
|
||||
// The semaphore was created successfully.
|
||||
// The semaphore can now be used.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* SemaphoreHandle_t xSemaphore;
|
||||
*
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
|
||||
* // This is a macro so pass the variable in directly.
|
||||
* xSemaphore = xSemaphoreCreateMutex();
|
||||
*
|
||||
* if( xSemaphore != NULL )
|
||||
* {
|
||||
* // The semaphore was created successfully.
|
||||
* // The semaphore can now be used.
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -754,21 +754,21 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* mutex is returned. If pxMutexBuffer was NULL then NULL is returned.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
SemaphoreHandle_t xSemaphore;
|
||||
StaticSemaphore_t xMutexBuffer;
|
||||
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// A mutex cannot be used before it has been created. xMutexBuffer is
|
||||
// into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
|
||||
// attempted.
|
||||
xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
|
||||
|
||||
// As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
|
||||
// so there is no need to check it.
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* SemaphoreHandle_t xSemaphore;
|
||||
* StaticSemaphore_t xMutexBuffer;
|
||||
*
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* // A mutex cannot be used before it has been created. xMutexBuffer is
|
||||
* // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
|
||||
* // attempted.
|
||||
* xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
|
||||
*
|
||||
* // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
|
||||
* // so there is no need to check it.
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -821,22 +821,22 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* SemaphoreHandle_t.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
SemaphoreHandle_t xSemaphore;
|
||||
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
|
||||
// This is a macro so pass the variable in directly.
|
||||
xSemaphore = xSemaphoreCreateRecursiveMutex();
|
||||
|
||||
if( xSemaphore != NULL )
|
||||
{
|
||||
// The semaphore was created successfully.
|
||||
// The semaphore can now be used.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* SemaphoreHandle_t xSemaphore;
|
||||
*
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
|
||||
* // This is a macro so pass the variable in directly.
|
||||
* xSemaphore = xSemaphoreCreateRecursiveMutex();
|
||||
*
|
||||
* if( xSemaphore != NULL )
|
||||
* {
|
||||
* // The semaphore was created successfully.
|
||||
* // The semaphore can now be used.
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -893,23 +893,23 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* returned.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
SemaphoreHandle_t xSemaphore;
|
||||
StaticSemaphore_t xMutexBuffer;
|
||||
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
// A recursive semaphore cannot be used before it is created. Here a
|
||||
// recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
|
||||
// The address of xMutexBuffer is passed into the function, and will hold
|
||||
// the mutexes data structures - so no dynamic memory allocation will be
|
||||
// attempted.
|
||||
xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
|
||||
|
||||
// As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
|
||||
// so there is no need to check it.
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* SemaphoreHandle_t xSemaphore;
|
||||
* StaticSemaphore_t xMutexBuffer;
|
||||
*
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* // A recursive semaphore cannot be used before it is created. Here a
|
||||
* // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
|
||||
* // The address of xMutexBuffer is passed into the function, and will hold
|
||||
* // the mutexes data structures - so no dynamic memory allocation will be
|
||||
* // attempted.
|
||||
* xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
|
||||
*
|
||||
* // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
|
||||
* // so there is no need to check it.
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -971,25 +971,25 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* created.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
SemaphoreHandle_t xSemaphore;
|
||||
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
SemaphoreHandle_t xSemaphore = NULL;
|
||||
|
||||
// Semaphore cannot be used before a call to xSemaphoreCreateCounting().
|
||||
// The max value to which the semaphore can count should be 10, and the
|
||||
// initial value assigned to the count should be 0.
|
||||
xSemaphore = xSemaphoreCreateCounting( 10, 0 );
|
||||
|
||||
if( xSemaphore != NULL )
|
||||
{
|
||||
// The semaphore was created successfully.
|
||||
// The semaphore can now be used.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* SemaphoreHandle_t xSemaphore;
|
||||
*
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* SemaphoreHandle_t xSemaphore = NULL;
|
||||
*
|
||||
* // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
|
||||
* // The max value to which the semaphore can count should be 10, and the
|
||||
* // initial value assigned to the count should be 0.
|
||||
* xSemaphore = xSemaphoreCreateCounting( 10, 0 );
|
||||
*
|
||||
* if( xSemaphore != NULL )
|
||||
* {
|
||||
* // The semaphore was created successfully.
|
||||
* // The semaphore can now be used.
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -1055,26 +1055,26 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
* then NULL is returned.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
SemaphoreHandle_t xSemaphore;
|
||||
StaticSemaphore_t xSemaphoreBuffer;
|
||||
|
||||
void vATask( void * pvParameters )
|
||||
{
|
||||
SemaphoreHandle_t xSemaphore = NULL;
|
||||
|
||||
// Counting semaphore cannot be used before they have been created. Create
|
||||
// a counting semaphore using xSemaphoreCreateCountingStatic(). The max
|
||||
// value to which the semaphore can count is 10, and the initial value
|
||||
// assigned to the count will be 0. The address of xSemaphoreBuffer is
|
||||
// passed in and will be used to hold the semaphore structure, so no dynamic
|
||||
// memory allocation will be used.
|
||||
xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
|
||||
|
||||
// No memory allocation was attempted so xSemaphore cannot be NULL, so there
|
||||
// is no need to check its value.
|
||||
}
|
||||
</pre>
|
||||
* <pre>
|
||||
* SemaphoreHandle_t xSemaphore;
|
||||
* StaticSemaphore_t xSemaphoreBuffer;
|
||||
*
|
||||
* void vATask( void * pvParameters )
|
||||
* {
|
||||
* SemaphoreHandle_t xSemaphore = NULL;
|
||||
*
|
||||
* // Counting semaphore cannot be used before they have been created. Create
|
||||
* // a counting semaphore using xSemaphoreCreateCountingStatic(). The max
|
||||
* // value to which the semaphore can count is 10, and the initial value
|
||||
* // assigned to the count will be 0. The address of xSemaphoreBuffer is
|
||||
* // passed in and will be used to hold the semaphore structure, so no dynamic
|
||||
* // memory allocation will be used.
|
||||
* xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
|
||||
*
|
||||
* // No memory allocation was attempted so xSemaphore cannot be NULL, so there
|
||||
* // is no need to check its value.
|
||||
* }
|
||||
* </pre>
|
||||
* \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic
|
||||
* \ingroup Semaphores
|
||||
*/
|
||||
@@ -1135,5 +1135,3 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||
#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
|
||||
|
||||
#endif /* SEMAPHORE_H */
|
||||
|
||||
|
||||
|
||||
@@ -125,4 +125,3 @@
|
||||
|
||||
|
||||
#endif /* STACK_MACROS_H */
|
||||
|
||||
|
||||
@@ -71,9 +71,9 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t;
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
<pre>
|
||||
StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
|
||||
</pre>
|
||||
* <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
|
||||
@@ -107,29 +107,29 @@ StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTrigg
|
||||
* 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>
|
||||
* <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
|
||||
*/
|
||||
@@ -138,12 +138,12 @@ const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
uint8_t *pucStreamBufferStorageArea,
|
||||
StaticStreamBuffer_t *pxStaticStreamBuffer );
|
||||
</pre>
|
||||
* <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.
|
||||
*
|
||||
@@ -180,37 +180,37 @@ StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
|
||||
* 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.
|
||||
* <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>
|
||||
*
|
||||
* // 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
|
||||
*/
|
||||
@@ -219,12 +219,12 @@ const size_t xTriggerLevel = 1;
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
TickType_t xTicksToWait );
|
||||
</pre>
|
||||
* <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.
|
||||
*
|
||||
@@ -274,37 +274,37 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
* 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>
|
||||
* <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
|
||||
*/
|
||||
@@ -316,12 +316,12 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
const void *pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
* <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.
|
||||
@@ -373,39 +373,39 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
* 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>
|
||||
* <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
|
||||
*/
|
||||
@@ -417,12 +417,12 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
TickType_t xTicksToWait );
|
||||
</pre>
|
||||
* <pre>
|
||||
* size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
* void *pvRxData,
|
||||
* size_t xBufferLengthBytes,
|
||||
* TickType_t xTicksToWait );
|
||||
* </pre>
|
||||
*
|
||||
* Receives bytes from a stream buffer.
|
||||
*
|
||||
@@ -472,29 +472,29 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
* 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>
|
||||
* <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
|
||||
*/
|
||||
@@ -506,12 +506,12 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
void *pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
* <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.
|
||||
@@ -548,39 +548,39 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
* @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>
|
||||
* <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
|
||||
*/
|
||||
@@ -592,9 +592,9 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
* <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
|
||||
@@ -614,9 +614,9 @@ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTI
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
* <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.
|
||||
@@ -634,9 +634,9 @@ BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
* <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.
|
||||
@@ -654,9 +654,9 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
* <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
|
||||
@@ -677,9 +677,9 @@ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_F
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
* <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
|
||||
@@ -698,9 +698,9 @@ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVIL
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||
</pre>
|
||||
* <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
|
||||
@@ -719,9 +719,9 @@ size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILE
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
|
||||
</pre>
|
||||
* <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
|
||||
@@ -751,14 +751,15 @@ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, siz
|
||||
* \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
|
||||
size_t xTriggerLevel ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
* <pre>
|
||||
* BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
* </pre>
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
@@ -790,14 +791,15 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer
|
||||
* \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
<pre>
|
||||
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
* <pre>
|
||||
* BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
* </pre>
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
@@ -830,7 +832,8 @@ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuf
|
||||
* \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/* Functions below here are not part of the public API. */
|
||||
StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
||||
@@ -846,7 +849,8 @@ StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
|
||||
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer,
|
||||
UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
|
||||
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
1317
include/task.h
1317
include/task.h
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,7 @@
|
||||
#endif
|
||||
|
||||
/*lint -save -e537 This headers are only multiply included if the application code
|
||||
happens to also be including task.h. */
|
||||
* happens to also be including task.h. */
|
||||
#include "task.h"
|
||||
/*lint -restore */
|
||||
|
||||
@@ -46,10 +46,10 @@ extern "C" {
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* IDs for commands that can be sent/received on the timer queue. These are to
|
||||
be used solely through the macros that make up the public software timer API,
|
||||
as defined below. The commands that are sent from interrupts must use the
|
||||
highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task
|
||||
or interrupt version of the queue send function should be used. */
|
||||
* be used solely through the macros that make up the public software timer API,
|
||||
* as defined below. The commands that are sent from interrupts must use the
|
||||
* highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task
|
||||
* or interrupt version of the queue send function should be used. */
|
||||
#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 )
|
||||
#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 )
|
||||
#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 )
|
||||
@@ -84,7 +84,8 @@ typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer );
|
||||
* Defines the prototype to which functions used with the
|
||||
* xTimerPendFunctionCallFromISR() function must conform.
|
||||
*/
|
||||
typedef void (*PendedFunction_t)( void *, uint32_t );
|
||||
typedef void (* PendedFunction_t)( void *,
|
||||
uint32_t );
|
||||
|
||||
/**
|
||||
* TimerHandle_t xTimerCreate( const char * const pcTimerName,
|
||||
@@ -403,7 +404,8 @@ void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||
*
|
||||
* See the xTimerCreate() API function example usage scenario.
|
||||
*/
|
||||
void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION;
|
||||
void vTimerSetTimerID( TimerHandle_t xTimer,
|
||||
void * pvNewID ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );
|
||||
@@ -1183,7 +1185,10 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||
* }
|
||||
* @endverbatim
|
||||
*/
|
||||
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend,
|
||||
void * pvParameter1,
|
||||
uint32_t ulParameter2,
|
||||
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
||||
@@ -1217,7 +1222,10 @@ BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void
|
||||
* timer daemon task, otherwise pdFALSE is returned.
|
||||
*
|
||||
*/
|
||||
BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
||||
void * pvParameter1,
|
||||
uint32_t ulParameter2,
|
||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* const char * const pcTimerGetName( TimerHandle_t xTimer );
|
||||
@@ -1245,7 +1253,8 @@ const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint
|
||||
* uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
|
||||
* enter the dormant state after it expires.
|
||||
*/
|
||||
void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION;
|
||||
void vTimerSetReloadMode( TimerHandle_t xTimer,
|
||||
const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer );
|
||||
@@ -1292,10 +1301,15 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||
* for use by the kernel only.
|
||||
*/
|
||||
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer,
|
||||
const BaseType_t xCommandID,
|
||||
const TickType_t xOptionalValue,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION;
|
||||
void vTimerSetTimerNumber( TimerHandle_t xTimer,
|
||||
UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION;
|
||||
UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
@@ -1303,6 +1317,3 @@ BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommand
|
||||
}
|
||||
#endif
|
||||
#endif /* TIMERS_H */
|
||||
|
||||
|
||||
|
||||
|
||||
89
list.c
89
list.c
@@ -36,23 +36,23 @@
|
||||
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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
|
||||
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
|
||||
}
|
||||
@@ -64,25 +64,26 @@ void vListInitialiseItem( ListItem_t * const pxItem )
|
||||
pxItem->pxContainer = NULL;
|
||||
|
||||
/* Write known values into the list item if
|
||||
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
||||
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
|
||||
void vListInsertEnd( List_t * const pxList,
|
||||
ListItem_t * const pxNewListItem )
|
||||
{
|
||||
ListItem_t * const pxIndex = pxList->pxIndex;
|
||||
|
||||
/* 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. */
|
||||
* 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(). */
|
||||
* 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;
|
||||
|
||||
@@ -99,25 +100,26 @@ ListItem_t * const pxIndex = pxList->pxIndex;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
|
||||
void vListInsert( List_t * const pxList,
|
||||
ListItem_t * const pxNewListItem )
|
||||
{
|
||||
ListItem_t * pxIterator;
|
||||
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. */
|
||||
* 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 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;
|
||||
@@ -125,31 +127,31 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||
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?).
|
||||
* 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. */
|
||||
* insertion position. */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +161,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||
pxIterator->pxNext = pxNewListItem;
|
||||
|
||||
/* Remember which list the item is in. This allows fast removal of the
|
||||
item later. */
|
||||
* item later. */
|
||||
pxNewListItem->pxContainer = pxList;
|
||||
|
||||
( pxList->uxNumberOfItems )++;
|
||||
@@ -169,7 +171,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
||||
{
|
||||
/* The list item knows which list it is in. Obtain the list from the list
|
||||
item. */
|
||||
* item. */
|
||||
List_t * const pxList = pxItemToRemove->pxContainer;
|
||||
|
||||
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
||||
@@ -194,4 +196,3 @@ List_t * const pxList = pxItemToRemove->pxContainer;
|
||||
return pxList->uxNumberOfItems;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
/* 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 a the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||
@@ -205,6 +206,7 @@
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
|
||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||
|
||||
/**
|
||||
* @brief Initial EXC_RETURN value.
|
||||
*
|
||||
@@ -221,6 +223,7 @@
|
||||
*/
|
||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||
#else
|
||||
|
||||
/**
|
||||
* @brief Initial EXC_RETURN value.
|
||||
*
|
||||
@@ -285,6 +288,7 @@
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Setup the Memory Protection Unit (MPU).
|
||||
*/
|
||||
@@ -292,6 +296,7 @@ static void prvTaskExitError( void );
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_FPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Setup the Floating Point Unit (FPU).
|
||||
*/
|
||||
@@ -347,6 +352,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVI
|
||||
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.
|
||||
@@ -355,6 +361,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||
|
||||
/**
|
||||
* @brief The number of SysTick increments that make up one tick period.
|
||||
*/
|
||||
@@ -396,6 +403,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
* 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;
|
||||
@@ -446,12 +454,14 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
* so a copy is taken. */
|
||||
xModifiableIdleTime = xExpectedIdleTime;
|
||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||
|
||||
if( xModifiableIdleTime > 0 )
|
||||
{
|
||||
__asm volatile ( "dsb" ::: "memory" );
|
||||
__asm volatile ( "wfi" );
|
||||
__asm volatile ( "isb" );
|
||||
}
|
||||
|
||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||
|
||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||
@@ -590,6 +600,7 @@ volatile uint32_t ulDummy = 0UL;
|
||||
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__;
|
||||
@@ -600,7 +611,7 @@ volatile uint32_t ulDummy = 0UL;
|
||||
extern uint32_t * __unprivileged_flash_end__;
|
||||
extern uint32_t * __privileged_sram_start__;
|
||||
extern uint32_t * __privileged_sram_end__;
|
||||
#else
|
||||
#else /* if defined( __ARMCC_VERSION ) */
|
||||
/* Declaration when these variable are exported from linker scripts. */
|
||||
extern uint32_t __privileged_functions_start__[];
|
||||
extern uint32_t __privileged_functions_end__[];
|
||||
@@ -753,6 +764,7 @@ void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION
|
||||
{
|
||||
#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__;
|
||||
@@ -783,7 +795,7 @@ uint8_t 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 ];
|
||||
@@ -800,7 +812,7 @@ uint8_t ucSVCNumber;
|
||||
/* Allocate and load a context for the secure task. */
|
||||
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
|
||||
}
|
||||
#else
|
||||
#else /* if ( configENABLE_MPU == 1 ) */
|
||||
{
|
||||
/* Allocate and load a context for the secure task. */
|
||||
xSecureContext = SecureContext_AllocateContext( ulR0 );
|
||||
@@ -809,22 +821,18 @@ uint8_t ucSVCNumber;
|
||||
|
||||
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
|
||||
@@ -846,36 +854,39 @@ uint8_t ucSVCNumber;
|
||||
/* 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__ )
|
||||
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 */
|
||||
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 */
|
||||
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
|
||||
@@ -896,6 +907,7 @@ uint8_t ucSVCNumber;
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
|
||||
if( xRunPrivileged == pdTRUE )
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
@@ -957,6 +969,7 @@ uint8_t ucSVCNumber;
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
|
||||
if( xRunPrivileged == pdTRUE )
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
@@ -1030,7 +1043,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||
const struct xMEMORY_REGION * const xRegions,
|
||||
StackType_t * pxBottomOfStack,
|
||||
uint32_t ulStackDepth )
|
||||
{
|
||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||
int32_t lIndex = 0;
|
||||
|
||||
@@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
@@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
|
||||
@@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
@@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
|
||||
@@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
@@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
|
||||
@@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
@@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
|
||||
@@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
@@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
|
||||
@@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
@@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
|
||||
@@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
@@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
|
||||
@@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
@@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
|
||||
@@ -95,7 +95,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged )
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||
uint32_t ulIsTaskPrivileged )
|
||||
#else /* configENABLE_MPU */
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
|
||||
#endif /* configENABLE_MPU */
|
||||
@@ -103,6 +104,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
uint8_t * pucStackMemory = NULL;
|
||||
uint32_t ulIPSR;
|
||||
SecureContextHandle_t xSecureContextHandle = NULL;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
uint32_t * pulCurrentStackPointer = NULL;
|
||||
#endif /* configENABLE_MPU */
|
||||
@@ -143,6 +145,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
@@ -161,7 +164,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
|
||||
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
}
|
||||
|
||||
@@ -69,7 +69,8 @@ void SecureContext_Init( void );
|
||||
* otherwise.
|
||||
*/
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged );
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||
uint32_t ulIsTaskPrivileged );
|
||||
#else /* configENABLE_MPU */
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
|
||||
/* 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 ];
|
||||
@@ -190,6 +191,7 @@ uint8_t *puc;
|
||||
/* 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;
|
||||
@@ -203,6 +205,7 @@ uint8_t *puc;
|
||||
/* 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 )
|
||||
@@ -288,6 +291,7 @@ void *pvReturn = NULL;
|
||||
* one of adequate size is found. */
|
||||
pxPreviousBlock = &xStart;
|
||||
pxBlock = xStart.pxNextFreeBlock;
|
||||
|
||||
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
|
||||
{
|
||||
pxPreviousBlock = pxBlock;
|
||||
@@ -375,7 +379,7 @@ void *pvReturn = NULL;
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||
|
||||
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
return pvReturn;
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
{ \
|
||||
secureportDISABLE_SECURE_INTERRUPTS(); \
|
||||
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
|
||||
for( ;; ); \
|
||||
for( ; ; ) {; } \
|
||||
}
|
||||
|
||||
#endif /* __SECURE_PORT_MACROS_H__ */
|
||||
|
||||
@@ -25,16 +25,16 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V1.00:
|
||||
|
||||
* Changes from V1.00:
|
||||
*
|
||||
+ Call to taskYIELD() from within tick ISR has been replaced by the more
|
||||
efficient portSWITCH_CONTEXT().
|
||||
+ efficient portSWITCH_CONTEXT().
|
||||
+ ISR function definitions renamed to include the prv prefix.
|
||||
|
||||
Changes from V2.6.1
|
||||
|
||||
+
|
||||
+ Changes from V2.6.1
|
||||
+
|
||||
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
|
||||
macro to be consistent with the later ports.
|
||||
+ macro to be consistent with the later ports.
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
@@ -67,14 +67,16 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz );
|
||||
static void prvExitFunction( void );
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||
is being used. */
|
||||
* is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
being used. */
|
||||
* being used. */
|
||||
static void __interrupt __far prvPreemptiveTick( void );
|
||||
#else
|
||||
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
being used. */
|
||||
* being used. */
|
||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||
#endif
|
||||
|
||||
@@ -87,8 +89,8 @@ static void __interrupt __far prvYieldProcessor( void );
|
||||
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(). */
|
||||
* 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. */
|
||||
@@ -102,11 +104,11 @@ 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. */
|
||||
* 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. */
|
||||
* vector. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
@@ -142,7 +144,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative scheduler
|
||||
is being used. */
|
||||
* is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
static void __interrupt __far prvPreemptiveTick( void )
|
||||
{
|
||||
@@ -156,15 +158,15 @@ is being used. */
|
||||
/* Reset the PIC ready for the next time. */
|
||||
portRESET_PIC();
|
||||
}
|
||||
#else
|
||||
#else /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
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. */
|
||||
* so we don't have to switch in the context of the next task. */
|
||||
xTaskIncrementTick();
|
||||
portRESET_PIC();
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void __interrupt __far prvYieldProcessor( void )
|
||||
@@ -177,8 +179,8 @@ static void __interrupt __far prvYieldProcessor( void )
|
||||
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. */
|
||||
* scheduler. This means we are not going to be using a
|
||||
* task stack frame so the task can be deleted. */
|
||||
longjmp( xJumpBuf, 1 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -189,18 +191,19 @@ const uint16_t usTimerDisable = 0x0000;
|
||||
uint16_t usTimer0Control;
|
||||
|
||||
/* Interrupts should be disabled here anyway - but no
|
||||
harm in making sure. */
|
||||
* harm in making sure. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
if( xSchedulerRunning == pdTRUE )
|
||||
{
|
||||
/* Put back the switch interrupt routines that was in place
|
||||
before the scheduler started. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
@@ -240,4 +243,3 @@ uint32_t ulTimerCount = ulClockFrequency / ulTickRateHz;
|
||||
|
||||
|
||||
/*lint +e950 */
|
||||
|
||||
|
||||
@@ -60,7 +60,8 @@ typedef unsigned short UBaseType_t;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section handling. */
|
||||
#define portENTER_CRITICAL() __asm{ pushf } \
|
||||
#define portENTER_CRITICAL() \
|
||||
__asm{ pushf } \
|
||||
__asm{ cli } \
|
||||
|
||||
#define portEXIT_CRITICAL() __asm{ popf }
|
||||
@@ -93,4 +94,3 @@ typedef unsigned short UBaseType_t;
|
||||
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -25,15 +25,15 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V2.6.1
|
||||
|
||||
* 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
|
||||
|
||||
+ 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.
|
||||
+ its proper value when the scheduler exits.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -60,19 +60,21 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz );
|
||||
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. */
|
||||
* 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. */
|
||||
* scheduler is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
|
||||
/* Tick service routine used by the scheduler when preemptive scheduling is
|
||||
being used. */
|
||||
* being used. */
|
||||
static void __interrupt __far prvPreemptiveTick( void );
|
||||
#else
|
||||
|
||||
/* Tick service routine used by the scheduler when cooperative scheduling is
|
||||
being used. */
|
||||
* being used. */
|
||||
static void __interrupt __far prvNonPreemptiveTick( void );
|
||||
#endif
|
||||
|
||||
@@ -80,7 +82,7 @@ scheduler is being used. */
|
||||
static void __interrupt __far prvYieldProcessor( void );
|
||||
|
||||
/* Set the tick frequency back so the floppy drive works correctly when the
|
||||
scheduler exits. */
|
||||
* scheduler exits. */
|
||||
static void prvSetTickFrequencyDefault( void );
|
||||
|
||||
/*lint -e956 File scopes necessary here. */
|
||||
@@ -110,7 +112,7 @@ 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. */
|
||||
* 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 );
|
||||
@@ -118,15 +120,15 @@ pxISR pxOriginalTickISR;
|
||||
prvSetTickFrequency( configTICK_RATE_HZ );
|
||||
|
||||
/* Put our manual switch (yield) function on a known
|
||||
vector. */
|
||||
* vector. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
|
||||
|
||||
/* Put the old tick on a different interrupt number so we can
|
||||
call it when we want. */
|
||||
* call it when we want. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOriginalTickISR );
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
* scheduler is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
{
|
||||
/* Put our tick switch function on the timer interrupt. */
|
||||
@@ -140,8 +142,8 @@ pxISR pxOriginalTickISR;
|
||||
#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. */
|
||||
* 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. */
|
||||
@@ -163,7 +165,7 @@ pxISR pxOriginalTickISR;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The ISR used depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
* scheduler is being used. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
static void __interrupt __far prvPreemptiveTick( void )
|
||||
{
|
||||
@@ -177,15 +179,15 @@ scheduler is being used. */
|
||||
/* Reset the PIC ready for the next time. */
|
||||
prvPortResetPIC();
|
||||
}
|
||||
#else
|
||||
#else /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
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. */
|
||||
* so we don't have to switch in the context of the next task. */
|
||||
xTaskIncrementTick();
|
||||
prvPortResetPIC();
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void __interrupt __far prvYieldProcessor( void )
|
||||
@@ -198,19 +200,22 @@ static void __interrupt __far prvYieldProcessor( void )
|
||||
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. */
|
||||
* 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 };
|
||||
__asm {
|
||||
int portSWITCH_INT_NUMBER + 1
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset the PIC as the DOS tick is not being called to
|
||||
do it. */
|
||||
* do it. */
|
||||
__asm
|
||||
{
|
||||
mov al, 20H
|
||||
@@ -223,8 +228,8 @@ static void prvPortResetPIC( void )
|
||||
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. */
|
||||
* scheduler. This means we are not going to be using a
|
||||
* task stack frame so the task can be deleted. */
|
||||
longjmp( xJumpBuf, 1 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -234,8 +239,9 @@ static void prvExitFunction( void )
|
||||
void( __interrupt __far * pxOriginalTickISR )();
|
||||
|
||||
/* Interrupts should be disabled here anyway - but no
|
||||
harm in making sure. */
|
||||
* harm in making sure. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
if( xSchedulerRunning == pdTRUE )
|
||||
{
|
||||
/* Set the DOS tick back onto the timer ticker. */
|
||||
@@ -244,12 +250,13 @@ void ( __interrupt __far *pxOriginalTickISR )();
|
||||
prvSetTickFrequencyDefault();
|
||||
|
||||
/* Put back the switch interrupt routines that was in place
|
||||
before the scheduler started. */
|
||||
* before the scheduler started. */
|
||||
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
|
||||
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOldSwitchISRPlus1 );
|
||||
}
|
||||
|
||||
/* The tick timer is back how DOS wants it. We can re-enable
|
||||
interrupts without the scheduler being called. */
|
||||
* interrupts without the scheduler being called. */
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -284,4 +291,3 @@ const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
|
||||
|
||||
|
||||
/*lint +e950 */
|
||||
|
||||
|
||||
@@ -60,7 +60,8 @@ typedef unsigned short UBaseType_t;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
#define portENTER_CRITICAL() __asm{ pushf } \
|
||||
#define portENTER_CRITICAL() \
|
||||
__asm{ pushf } \
|
||||
__asm{ cli } \
|
||||
|
||||
#define portEXIT_CRITICAL() __asm{ popf }
|
||||
@@ -93,4 +94,3 @@ typedef unsigned short UBaseType_t;
|
||||
#define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void * pvParameters )
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -46,10 +46,10 @@ void portSWITCH_CONTEXT( void );
|
||||
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. */
|
||||
* 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 } \
|
||||
@@ -82,5 +82,4 @@ debugger). The true stack pointer is then stored in the bp register. We add
|
||||
__asm { iret }
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ifndef PORT_ASM_H */
|
||||
|
||||
@@ -25,14 +25,14 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V1.00:
|
||||
|
||||
* 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
|
||||
|
||||
+ 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.
|
||||
*/
|
||||
|
||||
@@ -44,12 +44,14 @@ Changes from V2.6.1
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* See header file for description. */
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
StackType_t DS_Reg = 0;
|
||||
|
||||
/* Place a few bytes of known values on the bottom of the stack.
|
||||
This is just useful for debugging. */
|
||||
* This is just useful for debugging. */
|
||||
|
||||
*pxTopOfStack = 0x1111;
|
||||
pxTopOfStack--;
|
||||
@@ -66,8 +68,8 @@ StackType_t DS_Reg = 0;
|
||||
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
||||
|
||||
/* 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. */
|
||||
* instruction to load the program counter, so first there would be the
|
||||
* function call with parameters preamble. */
|
||||
|
||||
*pxTopOfStack = FP_SEG( pvParameters );
|
||||
pxTopOfStack--;
|
||||
@@ -87,8 +89,8 @@ StackType_t DS_Reg = 0;
|
||||
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. */
|
||||
* switch function. These are loaded with values simply to make debugging
|
||||
* easier. */
|
||||
*pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */
|
||||
@@ -101,7 +103,9 @@ StackType_t DS_Reg = 0;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* We need the true data segment. */
|
||||
__asm{ MOV DS_Reg, DS };
|
||||
__asm {
|
||||
MOV DS_Reg, DS
|
||||
};
|
||||
|
||||
*pxTopOfStack = DS_Reg; /* DS */
|
||||
pxTopOfStack--;
|
||||
@@ -116,4 +120,3 @@ StackType_t DS_Reg = 0;
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#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
|
||||
#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
|
||||
@@ -41,8 +41,9 @@
|
||||
/* 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. */
|
||||
* as the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||
#endif
|
||||
|
||||
@@ -81,12 +82,12 @@
|
||||
#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. */
|
||||
* 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. */
|
||||
* have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||
|
||||
/*
|
||||
@@ -114,11 +115,11 @@ static void prvTaskExitError( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
setting. */
|
||||
* setting. */
|
||||
const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. */
|
||||
* variable. */
|
||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
|
||||
/*
|
||||
@@ -165,10 +166,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
void * pvParameters )
|
||||
{
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
interrupt. */
|
||||
* interrupt. */
|
||||
|
||||
/* Offset added to account for the way the MCU uses the stack on entry/exit
|
||||
of interrupts, and to ensure alignment. */
|
||||
* of interrupts, and to ensure alignment. */
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||
@@ -190,14 +191,17 @@ StackType_t * pxPortInitialiseStack( StackType_t * 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. */
|
||||
* 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( ;; );
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -213,15 +217,15 @@ BaseType_t xPortStartScheduler( void )
|
||||
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. */
|
||||
* 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. */
|
||||
* possible bits. */
|
||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
@@ -231,8 +235,9 @@ BaseType_t xPortStartScheduler( void )
|
||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
of bits read back. */
|
||||
* of bits read back. */
|
||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulMaxPRIGROUPValue--;
|
||||
@@ -242,8 +247,8 @@ BaseType_t xPortStartScheduler( void )
|
||||
#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. */
|
||||
* priority bits matches the number of priority bits actually queried
|
||||
* from the hardware. */
|
||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
||||
}
|
||||
#endif
|
||||
@@ -251,19 +256,19 @@ BaseType_t xPortStartScheduler( void )
|
||||
#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. */
|
||||
* 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. */
|
||||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
value. */
|
||||
* value. */
|
||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||
}
|
||||
#endif /* conifgASSERT_DEFINED */
|
||||
@@ -273,7 +278,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
vPortSetupTimerInterrupt();
|
||||
|
||||
/* Initialise the critical nesting count ready for the first task. */
|
||||
@@ -290,7 +295,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
* Artificially force an assert. */
|
||||
configASSERT( uxCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -301,10 +306,10 @@ void vPortEnterCritical( void )
|
||||
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. */
|
||||
* 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 );
|
||||
@@ -316,6 +321,7 @@ void vPortExitCritical( void )
|
||||
{
|
||||
configASSERT( uxCriticalNesting );
|
||||
uxCriticalNesting--;
|
||||
|
||||
if( uxCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
@@ -326,16 +332,16 @@ void vPortExitCritical( void )
|
||||
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. */
|
||||
* 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. */
|
||||
* the PendSV interrupt. Pend the PendSV interrupt. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
}
|
||||
}
|
||||
@@ -358,44 +364,44 @@ void xPortSysTickHandler( void )
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* periods. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||
|
||||
/* Re-enable interrupts - see comments above __disable_interrupt()
|
||||
call above. */
|
||||
* call above. */
|
||||
__asm( " cpsie i");
|
||||
}
|
||||
else
|
||||
@@ -404,69 +410,71 @@ void xPortSysTickHandler( void )
|
||||
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
||||
|
||||
/* Clear the SysTick count flag and set the count value back to
|
||||
zero. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* 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 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). */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* underflowed because the post sleep hook did something
|
||||
* that took too long. */
|
||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
||||
{
|
||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
||||
@@ -475,30 +483,30 @@ void xPortSysTickHandler( void )
|
||||
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. */
|
||||
* 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). */
|
||||
* 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? */
|
||||
* was waiting? */
|
||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
||||
|
||||
/* The reload value is set to whatever fraction of a single tick
|
||||
period remains. */
|
||||
* 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. */
|
||||
* 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 );
|
||||
@@ -555,66 +563,45 @@ void vPortSetupTimerInterrupt( void )
|
||||
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 */
|
||||
* 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. */
|
||||
* 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 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ typedef unsigned long UBaseType_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. */
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -146,8 +146,8 @@ extern void vPortExitCritical( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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. */
|
||||
* 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 )
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -167,4 +167,3 @@ not necessary for to use this port. They are defined so the common demo files
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#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
|
||||
#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
|
||||
@@ -45,8 +45,9 @@
|
||||
/* 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. */
|
||||
* as the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||
#endif
|
||||
|
||||
@@ -90,12 +91,12 @@
|
||||
#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. */
|
||||
* 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. */
|
||||
* have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||
|
||||
/*
|
||||
@@ -128,11 +129,11 @@ static void prvTaskExitError( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
setting. */
|
||||
* setting. */
|
||||
const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. */
|
||||
* variable. */
|
||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
|
||||
/*
|
||||
@@ -174,13 +175,15 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
interrupt. */
|
||||
* interrupt. */
|
||||
|
||||
/* Offset added to account for the way the MCU uses the stack on entry/exit
|
||||
of interrupts, and to ensure alignment. */
|
||||
* of interrupts, and to ensure alignment. */
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||
@@ -194,7 +197,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
|
||||
/* A save method is being used that requires each task to maintain its
|
||||
own exec return value. */
|
||||
* own exec return value. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
||||
|
||||
@@ -207,14 +210,17 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
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. */
|
||||
* 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( ;; );
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -230,15 +236,15 @@ BaseType_t xPortStartScheduler( void )
|
||||
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. */
|
||||
* 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. */
|
||||
* possible bits. */
|
||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
@@ -248,8 +254,9 @@ BaseType_t xPortStartScheduler( void )
|
||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
of bits read back. */
|
||||
* of bits read back. */
|
||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulMaxPRIGROUPValue--;
|
||||
@@ -259,8 +266,8 @@ BaseType_t xPortStartScheduler( void )
|
||||
#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. */
|
||||
* priority bits matches the number of priority bits actually queried
|
||||
* from the hardware. */
|
||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
||||
}
|
||||
#endif
|
||||
@@ -268,19 +275,19 @@ BaseType_t xPortStartScheduler( void )
|
||||
#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. */
|
||||
* 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. */
|
||||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
value. */
|
||||
* value. */
|
||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||
}
|
||||
#endif /* conifgASSERT_DEFINED */
|
||||
@@ -290,7 +297,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
vPortSetupTimerInterrupt();
|
||||
|
||||
/* Initialise the critical nesting count ready for the first task. */
|
||||
@@ -313,7 +320,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
* Artificially force an assert. */
|
||||
configASSERT( uxCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -324,10 +331,10 @@ void vPortEnterCritical( void )
|
||||
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. */
|
||||
* 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 );
|
||||
@@ -339,6 +346,7 @@ void vPortExitCritical( void )
|
||||
{
|
||||
configASSERT( uxCriticalNesting );
|
||||
uxCriticalNesting--;
|
||||
|
||||
if( uxCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
@@ -349,16 +357,16 @@ void vPortExitCritical( void )
|
||||
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. */
|
||||
* 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. */
|
||||
* the PendSV interrupt. Pend the PendSV interrupt. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
}
|
||||
}
|
||||
@@ -381,44 +389,44 @@ void xPortSysTickHandler( void )
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* periods. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||
|
||||
/* Re-enable interrupts - see comments above __disable_interrupt()
|
||||
call above. */
|
||||
* call above. */
|
||||
__asm( " cpsie i");
|
||||
}
|
||||
else
|
||||
@@ -427,69 +435,71 @@ void xPortSysTickHandler( void )
|
||||
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
||||
|
||||
/* Clear the SysTick count flag and set the count value back to
|
||||
zero. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* 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 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). */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* underflowed because the post sleep hook did something
|
||||
* that took too long. */
|
||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
||||
{
|
||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
||||
@@ -498,30 +508,30 @@ void xPortSysTickHandler( void )
|
||||
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. */
|
||||
* 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). */
|
||||
* 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? */
|
||||
* was waiting? */
|
||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
||||
|
||||
/* The reload value is set to whatever fraction of a single tick
|
||||
period remains. */
|
||||
* 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. */
|
||||
* 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 );
|
||||
@@ -578,66 +588,45 @@ void vPortSetupTimerInterrupt( void )
|
||||
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 */
|
||||
* 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. */
|
||||
* 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 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ typedef unsigned long UBaseType_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. */
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -140,8 +140,8 @@ extern void vPortExitCritical( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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. */
|
||||
* 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 )
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -161,4 +161,3 @@ not necessary for to use this port. They are defined so the common demo files
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ uint32_t ulCriticalNesting = 9999;
|
||||
#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. */
|
||||
* R0 (in which the parameters are passed. */
|
||||
#define portSPACE_BETWEEN_TOS_AND_PARAMETERS ( 12 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -67,7 +67,7 @@ extern void vPortStartFirstTask( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Saved as part of the task context. Set to pdFALSE if the task does not
|
||||
require an FPU context. */
|
||||
* require an FPU context. */
|
||||
uint32_t ulTaskHasFPUContext = 0;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -76,7 +76,9 @@ uint32_t ulTaskHasFPUContext = 0;
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
StackType_t * pxOriginalTOS;
|
||||
|
||||
@@ -90,11 +92,11 @@ StackType_t *pxOriginalTOS;
|
||||
#endif
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
* expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which is the start of the as
|
||||
the task has not executed yet. The offset is added to make the return
|
||||
address appear as it would within an IRQ ISR. */
|
||||
* 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--;
|
||||
|
||||
@@ -130,11 +132,11 @@ StackType_t *pxOriginalTOS;
|
||||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
}
|
||||
#else
|
||||
#else /* ifdef portPRELOAD_TASK_REGISTERS */
|
||||
{
|
||||
pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS;
|
||||
}
|
||||
#endif
|
||||
#endif /* ifdef portPRELOAD_TASK_REGISTERS */
|
||||
|
||||
/* Function parameters are passed in R0. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
@@ -154,8 +156,8 @@ StackType_t *pxOriginalTOS;
|
||||
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. */
|
||||
* default is set to indicate that the stack frame does not include FPU
|
||||
* registers. */
|
||||
*pxTopOfStack = pdFALSE;
|
||||
}
|
||||
#endif
|
||||
@@ -206,7 +208,7 @@ BaseType_t xPortStartScheduler(void)
|
||||
ulCriticalNesting = 0;
|
||||
|
||||
/* Start the first task. This is done from portASM.asm as ARM mode must be
|
||||
used. */
|
||||
* used. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* Should not get here! */
|
||||
@@ -220,7 +222,7 @@ BaseType_t xPortStartScheduler(void)
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
* Artificially force an assert. */
|
||||
configASSERT( ulCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -235,11 +237,11 @@ void vPortEndScheduler(void)
|
||||
portRTI_INTFLAG_REG = 0x00000001;
|
||||
|
||||
/* Increment the tick count - this may make a delaying task ready
|
||||
to run - but a context switch is not performed. */
|
||||
* to run - but a context switch is not performed. */
|
||||
xTaskIncrementTick();
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* if configUSE_PREEMPTION == 0 */
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
@@ -250,7 +252,7 @@ void vPortEndScheduler(void)
|
||||
*/
|
||||
void vPortPreemptiveTick( void );
|
||||
|
||||
#endif
|
||||
#endif /* if configUSE_PREEMPTION == 0 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -263,8 +265,8 @@ void vPortEnterCritical( void )
|
||||
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. */
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -281,7 +283,7 @@ void vPortExitCritical( void )
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
* re-enabled. */
|
||||
if( ulCriticalNesting == 0 )
|
||||
{
|
||||
/* Enable interrupts as per portENABLE_INTERRUPTS(). */
|
||||
@@ -298,7 +300,7 @@ void vPortExitCritical( 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. */
|
||||
* FPU flag (saved as part of the task context. */
|
||||
ulTaskHasFPUContext = pdTRUE;
|
||||
|
||||
/* Initialise the floating point status register. */
|
||||
@@ -308,4 +310,3 @@ void vPortExitCritical( void )
|
||||
#endif /* __TI_VFP_SUPPORT__ */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ typedef unsigned long UBaseType_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. */
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
|
||||
@@ -113,4 +113,3 @@ extern void vPortYield( void );
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
#endif /* __PORTMACRO_H__ */
|
||||
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
; /*
|
||||
; * FreeRTOS Kernel V10.3.1
|
||||
; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
; *
|
||||
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
; * this software and associated documentation files (the "Software"), to deal in
|
||||
; * the Software without restriction, including without limitation the rights to
|
||||
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
; * subject to the following conditions:
|
||||
; *
|
||||
; * The above copyright notice and this permission notice shall be included in all
|
||||
; * copies or substantial portions of the Software.
|
||||
; *
|
||||
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
; *
|
||||
; * http://www.FreeRTOS.org
|
||||
; * http://aws.amazon.com/freertos
|
||||
; *
|
||||
; */
|
||||
* ; * FreeRTOS Kernel V10.3.1
|
||||
* ; * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* ; *
|
||||
* ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* ; * this software and associated documentation files (the "Software"), to deal in
|
||||
* ; * the Software without restriction, including without limitation the rights to
|
||||
* ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* ; * the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* ; * subject to the following conditions:
|
||||
* ; *
|
||||
* ; * The above copyright notice and this permission notice shall be included in all
|
||||
* ; * copies or substantial portions of the Software.
|
||||
* ; *
|
||||
* ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* ; *
|
||||
* ; * http://www.FreeRTOS.org
|
||||
* ; * http://aws.amazon.com/freertos
|
||||
* ; *
|
||||
* ; */
|
||||
|
||||
.if $DEFINED( __LARGE_DATA_MODEL__ )
|
||||
.define "pushm.a", pushm_x
|
||||
@@ -45,8 +45,3 @@
|
||||
.define "call", call_x
|
||||
.define "ret", ret_x
|
||||
.endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -33,24 +33,24 @@
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Constants required for hardware setup. The tick ISR runs off the ACLK,
|
||||
not the MCLK. */
|
||||
* not the MCLK. */
|
||||
#define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 )
|
||||
#define 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. */
|
||||
* 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. */
|
||||
* 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;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -68,25 +68,27 @@ void vPortSetupTimerInterrupt( void );
|
||||
*
|
||||
* See the header file portable.h.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
uint16_t * pusTopOfStack;
|
||||
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.
|
||||
|
||||
* 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--;
|
||||
* pxTopOfStack = ( StackType_t ) 0x2222;
|
||||
pxTopOfStack--;
|
||||
* pxTopOfStack--;
|
||||
* pxTopOfStack = ( StackType_t ) 0x3333;
|
||||
pxTopOfStack--;
|
||||
* pxTopOfStack--;
|
||||
*/
|
||||
|
||||
/* Data types are need either 16 bits or 32 bits depending on the data
|
||||
and code model used. */
|
||||
* and code model used. */
|
||||
if( sizeof( pxCode ) == sizeof( uint16_t ) )
|
||||
{
|
||||
pusTopOfStack = ( uint16_t * ) pxTopOfStack;
|
||||
@@ -135,19 +137,19 @@ uint32_t *pulTopOfStack, ulTemp;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x4444;
|
||||
pxTopOfStack--;
|
||||
#else
|
||||
#else /* ifdef PRELOAD_REGISTER_VALUES */
|
||||
pxTopOfStack -= 3;
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||
pxTopOfStack -= 9;
|
||||
#endif
|
||||
#endif /* ifdef PRELOAD_REGISTER_VALUES */
|
||||
|
||||
/* 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. */
|
||||
* 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. */
|
||||
* be stored in the task control block for the task. */
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -155,7 +157,7 @@ uint32_t *pulTopOfStack, ulTemp;
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the MSP430 port will get stopped. If required simply
|
||||
disable the tick interrupt here. */
|
||||
* disable the tick interrupt here. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -182,5 +184,3 @@ extern void vPortTickISR( void );
|
||||
vPortCooperativeTickISR();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -135,8 +135,7 @@ extern void vTaskSwitchContext( void );
|
||||
void vApplicationSetupTimerInterrupt( void );
|
||||
|
||||
/* sizeof( int ) != sizeof( long ) so a full printf() library is required if
|
||||
run time stats information is to be displayed. */
|
||||
* run time stats information is to be displayed. */
|
||||
#define portLU_PRINTF_SPECIFIER_REQUIRED
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -44,17 +44,20 @@ 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. */
|
||||
* 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 )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
|
||||
uint32_t ulOriginalA5;
|
||||
|
||||
__asm{ MOVE.L A5, ulOriginalA5 };
|
||||
__asm {
|
||||
MOVE.L A5, ulOriginalA5
|
||||
};
|
||||
|
||||
|
||||
*pxTopOfStack = ( StackType_t ) 0xDEADBEEF;
|
||||
@@ -105,7 +108,7 @@ static void prvSetupTimerInterrupt( void )
|
||||
RTCMOD = portRTC_CLOCK_HZ / configTICK_RATE_HZ;
|
||||
|
||||
/* Enable the RTC to generate interrupts - interrupts are already disabled
|
||||
when this code executes. */
|
||||
* when this code executes. */
|
||||
RTCSC_RTIE = 1;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -121,19 +124,20 @@ void vPortEnterCritical( void )
|
||||
if( ulCriticalNesting == 0UL )
|
||||
{
|
||||
/* Guard against context switches being pended simultaneously with a
|
||||
critical section being entered. */
|
||||
* critical section being entered. */
|
||||
do
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
if( INTC_FRC == 0UL )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
} while( 1 );
|
||||
}
|
||||
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -141,6 +145,7 @@ void vPortEnterCritical( void )
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
ulCriticalNesting--;
|
||||
|
||||
if( ulCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
@@ -179,4 +184,3 @@ uint32_t ulSavedInterruptMask;
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,8 @@ extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
portYIELD(); \
|
||||
}
|
||||
@@ -111,4 +112,3 @@ extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#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. */
|
||||
* will be set to 0 prior to the first task being started. */
|
||||
static uint32_t ulCriticalNesting = 0x9999UL;
|
||||
|
||||
|
||||
@@ -56,7 +56,9 @@ static uint32_t ulCriticalNesting = 0x9999UL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters;
|
||||
pxTopOfStack--;
|
||||
@@ -105,19 +107,20 @@ void vPortEnterCritical( void )
|
||||
if( ulCriticalNesting == 0UL )
|
||||
{
|
||||
/* Guard against context switches being pended simultaneously with a
|
||||
critical section being entered. */
|
||||
* critical section being entered. */
|
||||
do
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
if( MCF_INTC0_INTFRCH == 0UL )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
} while( 1 );
|
||||
}
|
||||
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -125,6 +128,7 @@ void vPortEnterCritical( void )
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
ulCriticalNesting--;
|
||||
|
||||
if( ulCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
@@ -143,4 +147,3 @@ uint32_t ulSavedInterruptMask;
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -99,7 +99,8 @@ extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
portYIELD(); \
|
||||
}
|
||||
@@ -110,4 +111,3 @@ extern void vPortClearInterruptMaskFromISR( UBaseType_t );
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/* Interrupt service routines have to be in non-banked memory - as does the
|
||||
scheduler startup function. */
|
||||
* scheduler startup function. */
|
||||
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
||||
|
||||
/* Manual context switch function. This is the SWI ISR. */
|
||||
@@ -51,19 +51,19 @@ scheduler startup function. */
|
||||
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. */
|
||||
* 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. */
|
||||
* 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;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -71,25 +71,27 @@ volatile UBaseType_t uxCriticalNesting = 0xff;
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
/*
|
||||
Place a few bytes of known values on the bottom of the stack.
|
||||
This can be uncommented to provide useful stack markers when debugging.
|
||||
|
||||
* 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--;
|
||||
* pxTopOfStack = ( StackType_t ) 0x22;
|
||||
pxTopOfStack--;
|
||||
* pxTopOfStack--;
|
||||
* pxTopOfStack = ( StackType_t ) 0x33;
|
||||
pxTopOfStack--;
|
||||
* 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. */
|
||||
* 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. */
|
||||
@@ -121,7 +123,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
pxTopOfStack--;
|
||||
|
||||
/* CCR: Note that when the task starts interrupts will be enabled since
|
||||
"I" bit of CCR is cleared */
|
||||
* "I" bit of CCR is cleared */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||
pxTopOfStack--;
|
||||
|
||||
@@ -132,7 +134,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
#endif
|
||||
|
||||
/* Finally the critical nesting depth is initialised with 0 (not within
|
||||
a critical section). */
|
||||
* a critical section). */
|
||||
*pxTopOfStack = ( StackType_t ) 0x00;
|
||||
|
||||
return pxTopOfStack;
|
||||
@@ -155,10 +157,10 @@ static void prvSetupTimerInterrupt( void )
|
||||
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. */
|
||||
* 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();
|
||||
}
|
||||
@@ -169,7 +171,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
static BaseType_t xBankedStartScheduler( void )
|
||||
{
|
||||
/* Configure the timer that will generate the RTOS tick. Interrupts are
|
||||
disabled when this function is called. */
|
||||
* disabled when this function is called. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Restore the context of the first task. */
|
||||
@@ -220,17 +222,15 @@ void interrupt vPortTickInterrupt( void )
|
||||
TFLG1 = 1;
|
||||
|
||||
/* Restore the context of a task - which may be a different task
|
||||
to that interrupted. */
|
||||
* to that interrupted. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
#else
|
||||
#else /* if configUSE_PREEMPTION == 1 */
|
||||
{
|
||||
xTaskIncrementTick();
|
||||
TFLG1 = 1;
|
||||
}
|
||||
#endif
|
||||
#endif /* if configUSE_PREEMPTION == 1 */
|
||||
}
|
||||
|
||||
#pragma CODE_SEG DEFAULT
|
||||
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ typedef unsigned char UBaseType_t;
|
||||
*/
|
||||
|
||||
#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
|
||||
@@ -151,7 +152,7 @@ typedef unsigned char UBaseType_t;
|
||||
__asm( "ldx pxCurrentTCB" ); \
|
||||
__asm( "sts 0, x" ); \
|
||||
}
|
||||
#else
|
||||
#else /* ifdef BANKED_MODEL */
|
||||
|
||||
/*
|
||||
* These macros are as per the BANKED versions above, but without saving
|
||||
@@ -179,7 +180,7 @@ typedef unsigned char UBaseType_t;
|
||||
__asm( "ldx pxCurrentTCB" ); \
|
||||
__asm( "sts 0, x" ); \
|
||||
}
|
||||
#endif
|
||||
#endif /* ifdef BANKED_MODEL */
|
||||
|
||||
/*
|
||||
* Utility macro to call macros above in correct order in order to perform a
|
||||
@@ -198,4 +199,3 @@ typedef unsigned char UBaseType_t;
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
*/
|
||||
|
||||
/* 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. */
|
||||
* 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. */
|
||||
@@ -86,7 +86,8 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition,
|
||||
TaskHandle_t * pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -99,7 +100,8 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition,
|
||||
TaskHandle_t * pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -112,7 +114,12 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode,
|
||||
const char * const pcName,
|
||||
uint16_t usStackDepth,
|
||||
void * pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -125,7 +132,13 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) /* FREERTOS_SYSTEM_CALL */
|
||||
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
StackType_t * const puxStackBuffer,
|
||||
StaticTask_t * const pxTaskBuffer ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
TaskHandle_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -137,7 +150,8 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const xRegions ) /* FREERTOS_SYSTEM_CALL */
|
||||
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask,
|
||||
const MemoryRegion_t * const xRegions ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
@@ -158,7 +172,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( INCLUDE_vTaskDelayUntil == 1 )
|
||||
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, TickType_t xTimeIncrement ) /* FREERTOS_SYSTEM_CALL */
|
||||
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
|
||||
TickType_t xTimeIncrement ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
@@ -206,7 +221,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( INCLUDE_vTaskPrioritySet == 1 )
|
||||
void MPU_vTaskPrioritySet( TaskHandle_t pxTask, UBaseType_t uxNewPriority ) /* FREERTOS_SYSTEM_CALL */
|
||||
void MPU_vTaskPrioritySet( TaskHandle_t pxTask,
|
||||
UBaseType_t uxNewPriority ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
@@ -230,14 +246,17 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) /* FREERTOS_SYSTEM_CALL */
|
||||
void MPU_vTaskGetInfo( TaskHandle_t xTask,
|
||||
TaskStatus_t * pxTaskStatus,
|
||||
BaseType_t xGetFreeStackSpace,
|
||||
eTaskState eState ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState );
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
|
||||
@@ -377,7 +396,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
|
||||
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxTagValue ) /* FREERTOS_SYSTEM_CALL */
|
||||
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask,
|
||||
TaskHookFunction_t pxTagValue ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
@@ -401,7 +421,9 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
|
||||
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) /* FREERTOS_SYSTEM_CALL */
|
||||
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
|
||||
BaseType_t xIndex,
|
||||
void * pvValue ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
@@ -412,7 +434,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
|
||||
void *MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) /* FREERTOS_SYSTEM_CALL */
|
||||
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
|
||||
BaseType_t xIndex ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
void * pvReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -421,11 +444,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return pvReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
|
||||
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask,
|
||||
void * pvParameter ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -434,11 +458,13 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t *pxTaskStatusArray, UBaseType_t uxArraySize, uint32_t *pulTotalRunTime ) /* FREERTOS_SYSTEM_CALL */
|
||||
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * pxTaskStatusArray,
|
||||
UBaseType_t uxArraySize,
|
||||
uint32_t * pulTotalRunTime ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
UBaseType_t uxReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -447,7 +473,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return uxReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) /* FREERTOS_SYSTEM_CALL */
|
||||
@@ -522,7 +548,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
|
||||
TickType_t * const pxTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -534,7 +561,11 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify,
|
||||
UBaseType_t uxIndexToNotify,
|
||||
uint32_t ulValue,
|
||||
eNotifyAction eAction,
|
||||
uint32_t * pulPreviousNotificationValue ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -543,11 +574,15 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn,
|
||||
uint32_t ulBitsToClearOnEntry,
|
||||
uint32_t ulBitsToClearOnExit,
|
||||
uint32_t * pulNotificationValue,
|
||||
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -556,11 +591,13 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn,
|
||||
BaseType_t xClearCountOnExit,
|
||||
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -569,11 +606,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return ulReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask,
|
||||
UBaseType_t uxIndexToClear ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -582,11 +620,13 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ) /* FREERTOS_SYSTEM_CALL */
|
||||
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask,
|
||||
UBaseType_t uxIndexToClear,
|
||||
uint32_t ulBitsToClear ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
uint32_t ulReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -595,11 +635,13 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return ulReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize, uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */
|
||||
QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength,
|
||||
UBaseType_t uxItemSize,
|
||||
uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
QueueHandle_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -608,11 +650,15 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */
|
||||
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength,
|
||||
const UBaseType_t uxItemSize,
|
||||
uint8_t * pucQueueStorage,
|
||||
StaticQueue_t * pxStaticQueue,
|
||||
const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
QueueHandle_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -621,10 +667,11 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t MPU_xQueueGenericReset( QueueHandle_t pxQueue, BaseType_t xNewQueue ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xQueueGenericReset( QueueHandle_t pxQueue,
|
||||
BaseType_t xNewQueue ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -635,7 +682,10 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
TickType_t xTicksToWait,
|
||||
BaseType_t xCopyPosition ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -668,7 +718,9 @@ UBaseType_t uxReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t MPU_xQueueReceive( QueueHandle_t pxQueue, void * const pvBuffer, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xQueueReceive( QueueHandle_t pxQueue,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
BaseType_t xReturn;
|
||||
@@ -679,7 +731,9 @@ BaseType_t xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t MPU_xQueuePeek( 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 xRunningPrivileged = xPortRaisePrivilege();
|
||||
BaseType_t xReturn;
|
||||
@@ -690,7 +744,8 @@ BaseType_t xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue,
|
||||
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
BaseType_t xReturn;
|
||||
@@ -728,7 +783,8 @@ BaseType_t xReturn;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */
|
||||
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType,
|
||||
StaticQueue_t * pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
QueueHandle_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -737,11 +793,12 @@ BaseType_t xReturn;
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue, UBaseType_t uxInitialCount ) /* FREERTOS_SYSTEM_CALL */
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue,
|
||||
UBaseType_t uxInitialCount ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
QueueHandle_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -750,12 +807,14 @@ BaseType_t xReturn;
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount,
|
||||
const UBaseType_t uxInitialCount,
|
||||
StaticQueue_t * pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
QueueHandle_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -764,11 +823,12 @@ BaseType_t xReturn;
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_RECURSIVE_MUTEXES == 1 )
|
||||
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xBlockTime ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex,
|
||||
TickType_t xBlockTime ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -777,7 +837,7 @@ BaseType_t xReturn;
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_RECURSIVE_MUTEXES == 1 )
|
||||
@@ -807,7 +867,8 @@ BaseType_t xReturn;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */
|
||||
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
|
||||
TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
QueueSetMemberHandle_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -816,11 +877,12 @@ BaseType_t xReturn;
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_QUEUE_SETS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||
QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -829,11 +891,12 @@ BaseType_t xReturn;
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_QUEUE_SETS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||
QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -842,11 +905,12 @@ BaseType_t xReturn;
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_QUEUE_SETS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if configQUEUE_REGISTRY_SIZE > 0
|
||||
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) /* FREERTOS_SYSTEM_CALL */
|
||||
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue,
|
||||
const char * pcName ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
@@ -880,7 +944,7 @@ BaseType_t xReturn;
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
return pcReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if configQUEUE_REGISTRY_SIZE > 0 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void MPU_vQueueDelete( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */
|
||||
@@ -948,7 +1012,11 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) /* FREERTOS_SYSTEM_CALL */
|
||||
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
TimerHandle_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -958,11 +1026,16 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) /* FREERTOS_SYSTEM_CALL */
|
||||
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction,
|
||||
StaticTimer_t * pxTimerBuffer ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
TimerHandle_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -972,7 +1045,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TIMERS == 1 )
|
||||
@@ -986,11 +1059,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
return pvReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TIMERS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TIMERS == 1 )
|
||||
void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) /* FREERTOS_SYSTEM_CALL */
|
||||
void MPU_vTimerSetTimerID( TimerHandle_t xTimer,
|
||||
void * pvNewID ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
@@ -1011,7 +1085,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TIMERS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TIMERS == 1 )
|
||||
@@ -1025,11 +1099,14 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TIMERS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
||||
void * pvParameter1,
|
||||
uint32_t ulParameter2,
|
||||
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -1039,11 +1116,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TIMERS == 1 )
|
||||
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */
|
||||
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer,
|
||||
const UBaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
@@ -1077,7 +1155,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
return pcReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TIMERS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TIMERS == 1 )
|
||||
@@ -1091,7 +1169,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TIMERS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TIMERS == 1 )
|
||||
@@ -1105,11 +1183,15 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TIMERS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TIMERS == 1 )
|
||||
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer,
|
||||
const BaseType_t xCommandID,
|
||||
const TickType_t xOptionalValue,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
const TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -1119,7 +1201,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TIMERS == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
@@ -1133,7 +1215,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
@@ -1147,10 +1229,14 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xClearOnExit,
|
||||
const BaseType_t xWaitForAllBits,
|
||||
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
EventBits_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -1162,7 +1248,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) /* FREERTOS_SYSTEM_CALL */
|
||||
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
EventBits_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -1174,7 +1261,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) /* FREERTOS_SYSTEM_CALL */
|
||||
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
EventBits_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -1186,7 +1274,10 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
EventBits_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -1207,7 +1298,10 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
const void * pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
size_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -1231,7 +1325,10 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, 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 xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -1312,7 +1409,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) /* FREERTOS_SYSTEM_CALL */
|
||||
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
|
||||
size_t xTriggerLevel ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -1325,7 +1423,9 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) /* FREERTOS_SYSTEM_CALL */
|
||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xIsMessageBuffer ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
StreamBufferHandle_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -1339,7 +1439,11 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) /* FREERTOS_SYSTEM_CALL */
|
||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xIsMessageBuffer,
|
||||
uint8_t * const pucStreamBufferStorageArea,
|
||||
StaticStreamBuffer_t * const pxStaticStreamBuffer ) /* FREERTOS_SYSTEM_CALL */
|
||||
{
|
||||
StreamBufferHandle_t xReturn;
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
@@ -1354,18 +1458,18 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
|
||||
/* Functions that the application writer wants to execute in privileged mode
|
||||
can be defined in application_defined_privileged_functions.h. The functions
|
||||
must take the same format as those above whereby the privilege state on exit
|
||||
equals the privilege state on entry. For example:
|
||||
|
||||
void MPU_FunctionName( [parameters ] )
|
||||
{
|
||||
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
FunctionName( [parameters ] );
|
||||
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
}
|
||||
* can be defined in application_defined_privileged_functions.h. The functions
|
||||
* must take the same format as those above whereby the privilege state on exit
|
||||
* equals the privilege state on entry. For example:
|
||||
*
|
||||
* void MPU_FunctionName( [parameters ] )
|
||||
* {
|
||||
* BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
*
|
||||
* FunctionName( [parameters ] );
|
||||
*
|
||||
* vPortResetPrivilege( xRunningPrivileged );
|
||||
* }
|
||||
*/
|
||||
|
||||
#if configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS == 1
|
||||
|
||||
@@ -72,22 +72,24 @@ extern void vPortISRStartFirstTask( void );
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
StackType_t * pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||
is not really required. */
|
||||
* is not really required. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
* expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which in this case is the
|
||||
start of the task. The offset is added to make the return address appear
|
||||
as it would within an IRQ ISR. */
|
||||
* 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--;
|
||||
|
||||
@@ -121,12 +123,12 @@ StackType_t *pxOriginalTOS;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
* 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. */
|
||||
* system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||
|
||||
#ifdef THUMB_INTERWORK
|
||||
@@ -139,9 +141,9 @@ StackType_t *pxOriginalTOS;
|
||||
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. */
|
||||
* 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;
|
||||
@@ -151,7 +153,7 @@ StackType_t *pxOriginalTOS;
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
@@ -165,7 +167,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
* is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -189,8 +191,8 @@ volatile uint32_t ulDummy;
|
||||
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. */
|
||||
* The ISR installed depends on whether the preemptive or cooperative
|
||||
* scheduler is being used. */
|
||||
#if configUSE_PREEMPTION == 1
|
||||
{
|
||||
extern void( vPreemptiveTick )( void );
|
||||
@@ -207,8 +209,8 @@ volatile uint32_t ulDummy;
|
||||
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 */
|
||||
*
|
||||
* First at timer level */
|
||||
portTIMER_REG_BASE_PTR->TC_IER = TC_CPCS;
|
||||
|
||||
/* Then at the AIC level. */
|
||||
@@ -218,14 +220,14 @@ volatile uint32_t ulDummy;
|
||||
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). */
|
||||
* 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. */
|
||||
* 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 );
|
||||
}
|
||||
@@ -234,4 +236,3 @@ volatile uint32_t ulDummy;
|
||||
portTIMER_REG_BASE_PTR->TC_CCR = TC_SWTRG | TC_CLKEN;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -32,10 +32,10 @@
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.4
|
||||
|
||||
* 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.
|
||||
+ than each line having its own asm block.
|
||||
*/
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ void vPortISRStartFirstTask( void );
|
||||
void vPortISRStartFirstTask( void )
|
||||
{
|
||||
/* Simply start the scheduler. This is included here as it can only be
|
||||
called from ARM mode. */
|
||||
* called from ARM mode. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -81,8 +81,8 @@ void vPortISRStartFirstTask( void )
|
||||
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. */
|
||||
* 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. */
|
||||
@@ -104,7 +104,7 @@ void vPortYieldProcessor( void )
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
simply increment the system tick. */
|
||||
* simply increment the system tick. */
|
||||
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
||||
void vNonPreemptiveTick( void )
|
||||
{
|
||||
@@ -122,7 +122,7 @@ void vPortYieldProcessor( void )
|
||||
#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. */
|
||||
* saved on entry as part of the context switch. */
|
||||
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
||||
void vPreemptiveTick( void )
|
||||
{
|
||||
@@ -130,14 +130,14 @@ void vPortYieldProcessor( void )
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* WARNING - Do not use local (stack) variables here. Use globals
|
||||
if you must! */
|
||||
* 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. */
|
||||
* task that is ready to run. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
vTaskSwitchContext();
|
||||
@@ -150,7 +150,7 @@ void vPortYieldProcessor( void )
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* if configUSE_PREEMPTION == 0 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
@@ -189,9 +189,9 @@ void vPortYieldProcessor( void )
|
||||
#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. */
|
||||
* 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(); */
|
||||
@@ -203,8 +203,8 @@ void vPortEnterCritical( void )
|
||||
"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. */
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ void vPortExitCritical( void )
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
* re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||
@@ -229,4 +229,3 @@ void vPortExitCritical( void )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,26 +25,26 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.3
|
||||
|
||||
* Changes from V3.2.3
|
||||
*
|
||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||
|
||||
Changes from V3.2.4
|
||||
|
||||
+
|
||||
+ Changes from V3.2.4
|
||||
+
|
||||
+ Removed the use of the %0 parameter within the assembler macros and
|
||||
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.
|
||||
|
||||
+ 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
|
||||
|
||||
+ 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.
|
||||
+ 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
|
||||
@@ -251,4 +251,3 @@ extern void vPortExitCritical( void );
|
||||
#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 +1,50 @@
|
||||
//* ----------------------------------------------------------------------------
|
||||
//* 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//
|
||||
//* ----------------------------------------------------------------------------
|
||||
/** ---------------------------------------------------------------------------- */
|
||||
/** 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
|
||||
//*----------------------------------------------------------------------------
|
||||
|
||||
/**---------------------------------------------------------------------------- */
|
||||
/** \fn AT91F_AIC_ConfigureIt */
|
||||
/** \brief Interrupt Handler Initialization */
|
||||
/**---------------------------------------------------------------------------- */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -81,22 +81,24 @@ extern void vPortISRStartFirstTask( void );
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
StackType_t * pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||
is not really required. */
|
||||
* is not really required. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
* expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which in this case is the
|
||||
start of the task. The offset is added to make the return address appear
|
||||
as it would within an IRQ ISR. */
|
||||
* 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--;
|
||||
|
||||
@@ -130,12 +132,12 @@ StackType_t *pxOriginalTOS;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
* 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. */
|
||||
* system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||
|
||||
#ifdef THUMB_INTERWORK
|
||||
@@ -148,9 +150,9 @@ StackType_t *pxOriginalTOS;
|
||||
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. */
|
||||
* 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;
|
||||
@@ -160,7 +162,7 @@ StackType_t *pxOriginalTOS;
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
@@ -174,7 +176,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
* is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -186,27 +188,20 @@ 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. */
|
||||
* 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. */
|
||||
* this is safe. */
|
||||
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -32,10 +32,10 @@
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.4
|
||||
|
||||
* 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.
|
||||
+ than each line having its own asm block.
|
||||
*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
@@ -67,7 +67,7 @@ void vPortISRStartFirstTask( void );
|
||||
void vPortISRStartFirstTask( void )
|
||||
{
|
||||
/* Simply start the scheduler. This is included here as it can only be
|
||||
called from ARM mode. */
|
||||
* called from ARM mode. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -83,8 +83,8 @@ void vPortISRStartFirstTask( void )
|
||||
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. */
|
||||
* 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. */
|
||||
@@ -106,15 +106,15 @@ void vPortYieldProcessor( void )
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
simply increment the system tick. */
|
||||
* simply increment the system tick. */
|
||||
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
||||
void vNonPreemptiveTick( void )
|
||||
{
|
||||
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. */
|
||||
* preemptive scheduler is not being used any woken task is not given
|
||||
* processor time no matter what its priority. */
|
||||
xTaskIncrementTick();
|
||||
|
||||
/* Clear the PIT interrupt. */
|
||||
@@ -124,10 +124,10 @@ void vPortYieldProcessor( void )
|
||||
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* if configUSE_PREEMPTION == 0 */
|
||||
|
||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||
saved on entry as part of the context switch. */
|
||||
* saved on entry as part of the context switch. */
|
||||
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
||||
void vPreemptiveTick( void )
|
||||
{
|
||||
@@ -147,7 +147,7 @@ void vPortYieldProcessor( void )
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* if configUSE_PREEMPTION == 0 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
@@ -183,9 +183,9 @@ void vPortEnableInterruptsFromThumb( void )
|
||||
|
||||
|
||||
/* 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. */
|
||||
* 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(); */
|
||||
@@ -197,8 +197,8 @@ void vPortEnterCritical( void )
|
||||
"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. */
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ void vPortExitCritical( void )
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
* re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||
@@ -223,4 +223,3 @@ void vPortExitCritical( void )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,26 +25,26 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.3
|
||||
|
||||
* Changes from V3.2.3
|
||||
*
|
||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||
|
||||
Changes from V3.2.4
|
||||
|
||||
+
|
||||
+ Changes from V3.2.4
|
||||
+
|
||||
+ Removed the use of the %0 parameter within the assembler macros and
|
||||
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.
|
||||
|
||||
+ 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
|
||||
|
||||
+ 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.
|
||||
+ 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
|
||||
@@ -245,4 +245,3 @@ extern void vPortExitCritical( void );
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -77,22 +77,24 @@ extern void vPortISRStartFirstTask( void );
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
StackType_t * pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||
is not really required. */
|
||||
* is not really required. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
* expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which in this case is the
|
||||
start of the task. The offset is added to make the return address appear
|
||||
as it would within an IRQ ISR. */
|
||||
* 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--;
|
||||
|
||||
@@ -126,12 +128,12 @@ StackType_t *pxOriginalTOS;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
* 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. */
|
||||
* system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||
|
||||
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
||||
@@ -143,9 +145,9 @@ StackType_t *pxOriginalTOS;
|
||||
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. */
|
||||
* 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;
|
||||
@@ -155,7 +157,7 @@ StackType_t *pxOriginalTOS;
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
@@ -169,7 +171,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
* is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -179,17 +181,18 @@ void vPortEndScheduler( void )
|
||||
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. */
|
||||
* 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. */
|
||||
* in a warning - hence the #if. */
|
||||
#if portPRESCALE_VALUE != 0
|
||||
{
|
||||
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||
@@ -205,16 +208,13 @@ extern void ( vTickISR )( void );
|
||||
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
|
||||
|
||||
/* The ISR installed depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
* 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. */
|
||||
* so it is okay to do this here. */
|
||||
T0_TCR = portENABLE_TIMER;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -32,21 +32,21 @@
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Changes from V2.5.2
|
||||
|
||||
* 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
|
||||
|
||||
+ 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
|
||||
|
||||
+ 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.
|
||||
+ than each line having its own asm block.
|
||||
*/
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ void vPortISRStartFirstTask( void );
|
||||
void vPortISRStartFirstTask( void )
|
||||
{
|
||||
/* Simply start the scheduler. This is included here as it can only be
|
||||
called from ARM mode. */
|
||||
* called from ARM mode. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -92,8 +92,8 @@ void vPortISRStartFirstTask( void )
|
||||
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. */
|
||||
* 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. */
|
||||
@@ -117,7 +117,7 @@ void vTickISR( void )
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Increment the RTOS tick count, then look for the highest priority
|
||||
task that is ready to run. */
|
||||
* task that is ready to run. */
|
||||
__asm volatile
|
||||
(
|
||||
" bl xTaskIncrementTick \t\n"\
|
||||
@@ -172,9 +172,9 @@ void vTickISR( void )
|
||||
#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. */
|
||||
* 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(); */
|
||||
@@ -186,8 +186,8 @@ void vPortEnterCritical( void )
|
||||
"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. */
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ void vPortExitCritical( void )
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
* re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||
|
||||
@@ -222,4 +222,3 @@ extern void vPortExitCritical( void );
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -77,22 +77,24 @@ extern void vPortISRStartFirstTask( void );
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
StackType_t * pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* To ensure asserts in tasks.c don't fail, although in this case the assert
|
||||
is not really required. */
|
||||
* is not really required. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
* expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which in this case is the
|
||||
start of the task. The offset is added to make the return address appear
|
||||
as it would within an IRQ ISR. */
|
||||
* 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--;
|
||||
|
||||
@@ -126,12 +128,12 @@ StackType_t *pxOriginalTOS;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
* 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. */
|
||||
* system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
|
||||
|
||||
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
|
||||
@@ -143,9 +145,9 @@ StackType_t *pxOriginalTOS;
|
||||
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. */
|
||||
* 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;
|
||||
@@ -155,7 +157,7 @@ StackType_t *pxOriginalTOS;
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
@@ -169,7 +171,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
* is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -185,14 +187,14 @@ uint32_t ulCompareMatch;
|
||||
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. */
|
||||
* 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. */
|
||||
* in a warning - hence the #if. */
|
||||
#if portPRESCALE_VALUE != 0
|
||||
{
|
||||
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||
@@ -207,7 +209,7 @@ uint32_t ulCompareMatch;
|
||||
VICIntEnable = 0x00000010;
|
||||
|
||||
/* The ISR installed depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
* scheduler is being used. */
|
||||
#if configUSE_PREEMPTION == 1
|
||||
{
|
||||
extern void( vPreemptiveTick )( void );
|
||||
@@ -223,10 +225,7 @@ uint32_t ulCompareMatch;
|
||||
VICVectCntl4 = 1;
|
||||
|
||||
/* Start the timer - interrupts are disabled when this function is called
|
||||
so it is okay to do this here. */
|
||||
* so it is okay to do this here. */
|
||||
T0TCR = portENABLE_TIMER;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ void vPortISRStartFirstTask( void );
|
||||
void vPortISRStartFirstTask( void )
|
||||
{
|
||||
/* Simply start the scheduler. This is included here as it can only be
|
||||
called from ARM mode. */
|
||||
* called from ARM mode. */
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -74,8 +74,8 @@ void vPortISRStartFirstTask( void )
|
||||
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. */
|
||||
* 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. */
|
||||
@@ -98,7 +98,7 @@ void vPortYieldProcessor( void )
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
simply increment the system tick. */
|
||||
* simply increment the system tick. */
|
||||
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
|
||||
void vNonPreemptiveTick( void )
|
||||
{
|
||||
@@ -107,10 +107,10 @@ void vPortYieldProcessor( void )
|
||||
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* if configUSE_PREEMPTION == 0 */
|
||||
|
||||
/* The preemptive scheduler is defined as "naked" as the full context is
|
||||
saved on entry as part of the context switch. */
|
||||
* saved on entry as part of the context switch. */
|
||||
void vPreemptiveTick( void ) __attribute__( ( naked ) );
|
||||
void vPreemptiveTick( void )
|
||||
{
|
||||
@@ -118,7 +118,7 @@ void vPortYieldProcessor( void )
|
||||
portSAVE_CONTEXT();
|
||||
|
||||
/* Increment the RTOS tick count, then look for the highest priority
|
||||
task that is ready to run. */
|
||||
* task that is ready to run. */
|
||||
__asm volatile
|
||||
(
|
||||
" bl xTaskIncrementTick \t\n"\
|
||||
@@ -136,7 +136,7 @@ void vPortYieldProcessor( void )
|
||||
portRESTORE_CONTEXT();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* if configUSE_PREEMPTION == 0 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
@@ -175,9 +175,9 @@ void vPortYieldProcessor( void )
|
||||
#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. */
|
||||
* 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(); */
|
||||
@@ -189,8 +189,8 @@ void vPortEnterCritical( void )
|
||||
"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. */
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ void vPortExitCritical( void )
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
* re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Enable interrupts as per portEXIT_CRITICAL(). */
|
||||
|
||||
@@ -25,26 +25,26 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.3
|
||||
|
||||
* Changes from V3.2.3
|
||||
*
|
||||
+ Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
|
||||
|
||||
Changes from V3.2.4
|
||||
|
||||
+
|
||||
+ Changes from V3.2.4
|
||||
+
|
||||
+ Removed the use of the %0 parameter within the assembler macros and
|
||||
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.
|
||||
|
||||
+ 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
|
||||
|
||||
+ 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.
|
||||
+ 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
|
||||
@@ -245,4 +245,3 @@ extern void vPortExitCritical( void );
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -32,23 +32,23 @@
|
||||
#include "task.h"
|
||||
|
||||
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
||||
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||
#endif
|
||||
|
||||
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
||||
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||
#endif
|
||||
|
||||
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||
#endif
|
||||
|
||||
#ifndef configSETUP_TICK_INTERRUPT
|
||||
#error configSETUP_TICK_INTERRUPT() must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error configSETUP_TICK_INTERRUPT() must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||
#endif /* configSETUP_TICK_INTERRUPT */
|
||||
|
||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||
#endif
|
||||
|
||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
||||
@@ -72,24 +72,24 @@
|
||||
#endif
|
||||
|
||||
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||
portmacro.h. */
|
||||
* portmacro.h. */
|
||||
#ifndef configCLEAR_TICK_INTERRUPT
|
||||
#define configCLEAR_TICK_INTERRUPT()
|
||||
#endif
|
||||
|
||||
/* A critical section is exited when the critical section nesting count reaches
|
||||
this value. */
|
||||
* this value. */
|
||||
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
|
||||
|
||||
/* In all GICs 255 can be written to the priority mask register to unmask all
|
||||
(but the lowest) interrupt priority. */
|
||||
* (but the lowest) interrupt priority. */
|
||||
#define portUNMASK_VALUE ( 0xFFUL )
|
||||
|
||||
/* Tasks are not created with a floating point context, but can be given a
|
||||
floating point context after they have been created. A variable is stored as
|
||||
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||
does not have an FPU context, or any other value if the task does have an FPU
|
||||
context. */
|
||||
* floating point context after they have been created. A variable is stored as
|
||||
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||
* does not have an FPU context, or any other value if the task does have an FPU
|
||||
* context. */
|
||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||
|
||||
/* Constants required to setup the initial task context. */
|
||||
@@ -107,7 +107,7 @@ context. */
|
||||
|
||||
|
||||
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
||||
point is zero. */
|
||||
* point is zero. */
|
||||
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
||||
|
||||
/* Masks all bits in the APSR other than the mode bits. */
|
||||
@@ -142,21 +142,21 @@ extern void vPortRestoreTaskContext( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* A variable is used to keep track of the critical section nesting. This
|
||||
variable has to be stored as part of the task context and must be initialised to
|
||||
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||
the scheduler starts. As it is stored as part of the task context it will
|
||||
automatically be set to 0 when the first task is started. */
|
||||
* variable has to be stored as part of the task context and must be initialised to
|
||||
* a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||
* the scheduler starts. As it is stored as part of the task context it will
|
||||
* automatically be set to 0 when the first task is started. */
|
||||
volatile uint64_t ullCriticalNesting = 9999ULL;
|
||||
|
||||
/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
|
||||
then floating point context must be saved and restored for the task. */
|
||||
* then floating point context must be saved and restored for the task. */
|
||||
uint64_t ullPortTaskHasFPUContext = pdFALSE;
|
||||
|
||||
/* Set to 1 to pend a context switch from an ISR. */
|
||||
uint64_t ullPortYieldRequired = pdFALSE;
|
||||
|
||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||
if the nesting depth is 0. */
|
||||
* if the nesting depth is 0. */
|
||||
uint64_t ullPortInterruptNesting = 0;
|
||||
|
||||
/* Used in the ASM code. */
|
||||
@@ -170,10 +170,12 @@ __attribute__(( used )) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_C
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
* expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First all the general purpose registers. */
|
||||
pxTopOfStack--;
|
||||
@@ -249,13 +251,13 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||
enabled. */
|
||||
* enabled. */
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The task will start without a floating point context. A task that uses
|
||||
the floating point hardware must call vPortTaskUsesFPU() before executing
|
||||
any floating point instructions. */
|
||||
* the floating point hardware must call vPortTaskUsesFPU() before executing
|
||||
* any floating point instructions. */
|
||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||
|
||||
return pxTopOfStack;
|
||||
@@ -273,12 +275,12 @@ uint32_t ulAPSR;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
/* Determine how many priority bits are implemented in the GIC.
|
||||
|
||||
Save the interrupt priority value that is about to be clobbered. */
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||
|
||||
/* Determine the number of priority bits available. First write to
|
||||
all possible bits. */
|
||||
* all possible bits. */
|
||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
@@ -291,13 +293,13 @@ uint32_t ulAPSR;
|
||||
}
|
||||
|
||||
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
||||
value. */
|
||||
* value. */
|
||||
|
||||
configASSERT( ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY );
|
||||
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
value. */
|
||||
* value. */
|
||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||
}
|
||||
#endif /* conifgASSERT_DEFINED */
|
||||
@@ -310,23 +312,25 @@ uint32_t ulAPSR;
|
||||
#if defined( GUEST )
|
||||
#warning Building for execution as a guest under XEN. THIS IS NOT A FULLY TESTED PATH.
|
||||
configASSERT( ulAPSR == portEL1 );
|
||||
|
||||
if( ulAPSR == portEL1 )
|
||||
#else
|
||||
configASSERT( ulAPSR == portEL3 );
|
||||
|
||||
if( ulAPSR == portEL3 )
|
||||
#endif
|
||||
{
|
||||
/* Only continue if the binary point value is set to its lowest possible
|
||||
setting. See the comments in vPortValidateInterruptPriority() below for
|
||||
more information. */
|
||||
* setting. See the comments in vPortValidateInterruptPriority() below for
|
||||
* more information. */
|
||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||
|
||||
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
||||
{
|
||||
/* Interrupts are turned off in the CPU itself to ensure a tick does
|
||||
not execute while the scheduler is being started. Interrupts are
|
||||
automatically turned back on in the CPU when the first task starts
|
||||
executing. */
|
||||
* not execute while the scheduler is being started. Interrupts are
|
||||
* automatically turned back on in the CPU when the first task starts
|
||||
* executing. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
/* Start the timer that generates the tick ISR. */
|
||||
@@ -344,7 +348,7 @@ uint32_t ulAPSR;
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
* Artificially force an assert. */
|
||||
configASSERT( ullCriticalNesting == 1000ULL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -355,15 +359,15 @@ void vPortEnterCritical( void )
|
||||
uxPortSetInterruptMask();
|
||||
|
||||
/* Now interrupts are disabled ullCriticalNesting can be accessed
|
||||
directly. Increment ullCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
* directly. Increment ullCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ullCriticalNesting++;
|
||||
|
||||
/* 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. */
|
||||
* 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( ullCriticalNesting == 1ULL )
|
||||
{
|
||||
configASSERT( ullPortInterruptNesting == 0 );
|
||||
@@ -376,15 +380,15 @@ void vPortExitCritical( void )
|
||||
if( ullCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as the critical section is being
|
||||
exited. */
|
||||
* exited. */
|
||||
ullCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then all interrupt
|
||||
priorities must be re-enabled. */
|
||||
* priorities must be re-enabled. */
|
||||
if( ullCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Critical nesting has reached zero so all interrupt priorities
|
||||
should be unmasked. */
|
||||
* should be unmasked. */
|
||||
portCLEAR_INTERRUPT_MASK();
|
||||
}
|
||||
}
|
||||
@@ -411,10 +415,10 @@ void FreeRTOS_Tick_Handler( void )
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Set interrupt mask before altering scheduler structures. The tick
|
||||
handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||
so there is no need to save and restore the current mask value. It is
|
||||
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||
updated. */
|
||||
* handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||
* so there is no need to save and restore the current mask value. It is
|
||||
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||
* updated. */
|
||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||
__asm volatile ( "dsb sy \n"
|
||||
"isb sy \n"::: "memory" );
|
||||
@@ -437,11 +441,11 @@ void FreeRTOS_Tick_Handler( void )
|
||||
void vPortTaskUsesFPU( void )
|
||||
{
|
||||
/* A task is registering the fact that it needs an FPU context. Set the
|
||||
FPU flag (which is saved as part of the task context). */
|
||||
* FPU flag (which is saved as part of the task context). */
|
||||
ullPortTaskHasFPUContext = pdTRUE;
|
||||
|
||||
/* Consider initialising the FPSR here - but probably not necessary in
|
||||
AArch64. */
|
||||
* AArch64. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -459,8 +463,9 @@ UBaseType_t uxPortSetInterruptMask( void )
|
||||
uint32_t ulReturn;
|
||||
|
||||
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
||||
updated. */
|
||||
* updated. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
||||
{
|
||||
/* Interrupts were already masked. */
|
||||
@@ -473,6 +478,7 @@ uint32_t ulReturn;
|
||||
__asm volatile ( "dsb sy \n"
|
||||
"isb sy \n"::: "memory" );
|
||||
}
|
||||
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
return ulReturn;
|
||||
@@ -484,34 +490,33 @@ uint32_t ulReturn;
|
||||
void vPortValidateInterruptPriority( void )
|
||||
{
|
||||
/* 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.
|
||||
|
||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
interrupt entry is as fast and simple as possible. */
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
* interrupt entry is as fast and simple as possible. */
|
||||
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
||||
|
||||
/* Priority grouping: The interrupt controller (GIC) 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).
|
||||
|
||||
The priority grouping is configured by the GIC's binary point register
|
||||
(ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||
possible value (which may be above 0). */
|
||||
* 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).
|
||||
*
|
||||
* The priority grouping is configured by the GIC's binary point register
|
||||
* (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||
* possible value (which may be above 0). */
|
||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||
}
|
||||
|
||||
#endif /* configASSERT_DEFINED */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ typedef uint64_t TickType_t;
|
||||
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
not need to be guarded with a critical section. */
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -90,6 +90,7 @@ extern uint64_t ullPortYieldRequired; \
|
||||
#else
|
||||
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Critical section control
|
||||
*----------------------------------------------------------*/
|
||||
@@ -112,7 +113,7 @@ extern void vPortInstallFreeRTOSVectorTable( void );
|
||||
|
||||
|
||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask()
|
||||
@@ -121,17 +122,17 @@ interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||
not required for this port but included in case common demo code that uses these
|
||||
macros is used. */
|
||||
* not required for this port but included in case common demo code that uses these
|
||||
* macros is used. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||
handler for whichever peripheral is used to generate the RTOS tick. */
|
||||
* handler for whichever peripheral is used to generate the RTOS tick. */
|
||||
void FreeRTOS_Tick_Handler( void );
|
||||
|
||||
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
|
||||
before any floating point instructions are executed. */
|
||||
* before any floating point instructions are executed. */
|
||||
void vPortTaskUsesFPU( void );
|
||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||
|
||||
@@ -169,7 +170,7 @@ void vPortTaskUsesFPU( void );
|
||||
|
||||
|
||||
/* The number of bits to shift for an interrupt priority is dependent on the
|
||||
number of bits implemented by the interrupt controller. */
|
||||
* number of bits implemented by the interrupt controller. */
|
||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||
#define portPRIORITY_SHIFT 4
|
||||
#define portMAX_BINARY_POINT_VALUE 3
|
||||
@@ -185,9 +186,9 @@ number of bits implemented by the interrupt controller. */
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||
#define portPRIORITY_SHIFT 0
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#else
|
||||
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
||||
#endif
|
||||
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
|
||||
/* Interrupt controller access addresses. */
|
||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||
@@ -207,4 +208,3 @@ number of bits implemented by the interrupt controller. */
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -32,23 +32,23 @@
|
||||
#include "task.h"
|
||||
|
||||
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
|
||||
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||
#endif
|
||||
|
||||
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
|
||||
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||
#endif
|
||||
|
||||
#ifndef configUNIQUE_INTERRUPT_PRIORITIES
|
||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||
#endif
|
||||
|
||||
#ifndef configSETUP_TICK_INTERRUPT
|
||||
#error configSETUP_TICK_INTERRUPT() must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error configSETUP_TICK_INTERRUPT() must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||
#endif /* configSETUP_TICK_INTERRUPT */
|
||||
|
||||
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html
|
||||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
|
||||
#endif
|
||||
|
||||
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
|
||||
@@ -72,24 +72,24 @@
|
||||
#endif
|
||||
|
||||
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||
portmacro.h. */
|
||||
* portmacro.h. */
|
||||
#ifndef configCLEAR_TICK_INTERRUPT
|
||||
#define configCLEAR_TICK_INTERRUPT()
|
||||
#endif
|
||||
|
||||
/* A critical section is exited when the critical section nesting count reaches
|
||||
this value. */
|
||||
* this value. */
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
|
||||
/* In all GICs 255 can be written to the priority mask register to unmask all
|
||||
(but the lowest) interrupt priority. */
|
||||
* (but the lowest) interrupt priority. */
|
||||
#define portUNMASK_VALUE ( 0xFFUL )
|
||||
|
||||
/* Tasks are not created with a floating point context, but can be given a
|
||||
floating point context after they have been created. A variable is stored as
|
||||
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||
does not have an FPU context, or any other value if the task does have an FPU
|
||||
context. */
|
||||
* floating point context after they have been created. A variable is stored as
|
||||
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||
* does not have an FPU context, or any other value if the task does have an FPU
|
||||
* context. */
|
||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||
|
||||
/* Constants required to setup the initial task context. */
|
||||
@@ -99,19 +99,19 @@ context. */
|
||||
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
|
||||
|
||||
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
||||
point is zero. */
|
||||
* point is zero. */
|
||||
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
||||
|
||||
/* Masks all bits in the APSR other than the mode bits. */
|
||||
#define portAPSR_MODE_BITS_MASK ( 0x1F )
|
||||
|
||||
/* The value of the mode bits in the APSR when the CPU is executing in user
|
||||
mode. */
|
||||
* mode. */
|
||||
#define portAPSR_USER_MODE ( 0x10 )
|
||||
|
||||
/* The critical section macros only mask interrupts up to an application
|
||||
determined priority level. Sometimes it is necessary to turn interrupt off in
|
||||
the CPU itself before modifying certain hardware registers. */
|
||||
* determined priority level. Sometimes it is necessary to turn interrupt off in
|
||||
* the CPU itself before modifying certain hardware registers. */
|
||||
#define portCPU_IRQ_DISABLE() \
|
||||
__asm volatile ( "CPSID i" ::: "memory" ); \
|
||||
__asm volatile ( "DSB" ); \
|
||||
@@ -138,8 +138,8 @@ the CPU itself before modifying certain hardware registers. */
|
||||
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
||||
|
||||
/* 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. */
|
||||
* 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
|
||||
@@ -147,7 +147,7 @@ debugger. */
|
||||
#endif
|
||||
|
||||
/* The space on the stack required to hold the FPU registers. This is 32 64-bit
|
||||
registers, plus a 32-bit status register. */
|
||||
* registers, plus a 32-bit status register. */
|
||||
#define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -187,21 +187,21 @@ void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* A variable is used to keep track of the critical section nesting. This
|
||||
variable has to be stored as part of the task context and must be initialised to
|
||||
a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||
the scheduler starts. As it is stored as part of the task context it will
|
||||
automatically be set to 0 when the first task is started. */
|
||||
* variable has to be stored as part of the task context and must be initialised to
|
||||
* a non zero value to ensure interrupts don't inadvertently become unmasked before
|
||||
* the scheduler starts. As it is stored as part of the task context it will
|
||||
* automatically be set to 0 when the first task is started. */
|
||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||
|
||||
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
|
||||
a floating point context must be saved and restored for the task. */
|
||||
* a floating point context must be saved and restored for the task. */
|
||||
volatile uint32_t ulPortTaskHasFPUContext = pdFALSE;
|
||||
|
||||
/* Set to 1 to pend a context switch from an ISR. */
|
||||
volatile uint32_t ulPortYieldRequired = pdFALSE;
|
||||
|
||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||
if the nesting depth is 0. */
|
||||
* if the nesting depth is 0. */
|
||||
volatile uint32_t ulPortInterruptNesting = 0UL;
|
||||
|
||||
/* Used in the asm file. */
|
||||
@@ -215,14 +215,16 @@ __attribute__(( used )) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CA
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro.
|
||||
|
||||
The fist real value on the stack is the status register, which is set for
|
||||
system mode, with interrupts enabled. A few NULLs are added first to ensure
|
||||
GDB does not try decoding a non-existent return address. */
|
||||
* expected by the portRESTORE_CONTEXT() macro.
|
||||
*
|
||||
* The fist real value on the stack is the status register, which is set for
|
||||
* system mode, with interrupts enabled. A few NULLs are added first to ensure
|
||||
* GDB does not try decoding a non-existent return address. */
|
||||
*pxTopOfStack = ( StackType_t ) NULL;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) NULL;
|
||||
@@ -274,21 +276,21 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||
enabled. */
|
||||
* enabled. */
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
|
||||
#if ( configUSE_TASK_FPU_SUPPORT == 1 )
|
||||
{
|
||||
/* The task will start without a floating point context. A task that
|
||||
uses the floating point hardware must call vPortTaskUsesFPU() before
|
||||
executing any floating point instructions. */
|
||||
* uses the floating point hardware must call vPortTaskUsesFPU() before
|
||||
* executing any floating point instructions. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||
}
|
||||
#elif ( configUSE_TASK_FPU_SUPPORT == 2 )
|
||||
{
|
||||
/* The task will start with a floating point context. Leave enough
|
||||
space for the registers - and ensure they are initialised to 0. */
|
||||
* space for the registers - and ensure they are initialised to 0. */
|
||||
pxTopOfStack -= portFPU_REGISTER_WORDS;
|
||||
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
|
||||
|
||||
@@ -296,11 +298,11 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
*pxTopOfStack = pdTRUE;
|
||||
ulPortTaskHasFPUContext = pdTRUE;
|
||||
}
|
||||
#else
|
||||
#else /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
|
||||
{
|
||||
#error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined.
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
@@ -309,14 +311,17 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
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. */
|
||||
* 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( ulPortInterruptNesting == ~0UL );
|
||||
portDISABLE_INTERRUPTS();
|
||||
for( ;; );
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -331,12 +336,12 @@ uint32_t ulAPSR;
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
/* Determine how many priority bits are implemented in the GIC.
|
||||
|
||||
Save the interrupt priority value that is about to be clobbered. */
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||
|
||||
/* Determine the number of priority bits available. First write to
|
||||
all possible bits. */
|
||||
* all possible bits. */
|
||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
@@ -349,18 +354,18 @@ uint32_t ulAPSR;
|
||||
}
|
||||
|
||||
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
||||
value. */
|
||||
* value. */
|
||||
configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY );
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
value. */
|
||||
* value. */
|
||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||
}
|
||||
#endif /* conifgASSERT_DEFINED */
|
||||
|
||||
|
||||
/* Only continue if the CPU is not in User mode. The CPU must be in a
|
||||
Privileged mode for the scheduler to start. */
|
||||
* Privileged mode for the scheduler to start. */
|
||||
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR )::"memory" );
|
||||
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
||||
configASSERT( ulAPSR != portAPSR_USER_MODE );
|
||||
@@ -368,16 +373,16 @@ uint32_t ulAPSR;
|
||||
if( ulAPSR != portAPSR_USER_MODE )
|
||||
{
|
||||
/* Only continue if the binary point value is set to its lowest possible
|
||||
setting. See the comments in vPortValidateInterruptPriority() below for
|
||||
more information. */
|
||||
* setting. See the comments in vPortValidateInterruptPriority() below for
|
||||
* more information. */
|
||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||
|
||||
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
||||
{
|
||||
/* Interrupts are turned off in the CPU itself to ensure tick does
|
||||
not execute while the scheduler is being started. Interrupts are
|
||||
automatically turned back on in the CPU when the first task starts
|
||||
executing. */
|
||||
* not execute while the scheduler is being started. Interrupts are
|
||||
* automatically turned back on in the CPU when the first task starts
|
||||
* executing. */
|
||||
portCPU_IRQ_DISABLE();
|
||||
|
||||
/* Start the timer that generates the tick ISR. */
|
||||
@@ -389,10 +394,10 @@ uint32_t ulAPSR;
|
||||
}
|
||||
|
||||
/* Will only get here if vTaskStartScheduler() was called with the CPU in
|
||||
a non-privileged mode or the binary point register was not set to its lowest
|
||||
possible value. prvTaskExitError() is referenced to prevent a compiler
|
||||
warning about it being defined but not referenced in the case that the user
|
||||
defines their own exit address. */
|
||||
* a non-privileged mode or the binary point register was not set to its lowest
|
||||
* possible value. prvTaskExitError() is referenced to prevent a compiler
|
||||
* warning about it being defined but not referenced in the case that the user
|
||||
* defines their own exit address. */
|
||||
( void ) prvTaskExitError;
|
||||
return 0;
|
||||
}
|
||||
@@ -401,7 +406,7 @@ uint32_t ulAPSR;
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
* Artificially force an assert. */
|
||||
configASSERT( ulCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -412,15 +417,15 @@ void vPortEnterCritical( void )
|
||||
ulPortSetInterruptMask();
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
|
||||
/* 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. */
|
||||
* 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( ulCriticalNesting == 1 )
|
||||
{
|
||||
configASSERT( ulPortInterruptNesting == 0 );
|
||||
@@ -433,15 +438,15 @@ void vPortExitCritical( void )
|
||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as the critical section is being
|
||||
exited. */
|
||||
* exited. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then all interrupt
|
||||
priorities must be re-enabled. */
|
||||
* priorities must be re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Critical nesting has reached zero so all interrupt priorities
|
||||
should be unmasked. */
|
||||
* should be unmasked. */
|
||||
portCLEAR_INTERRUPT_MASK();
|
||||
}
|
||||
}
|
||||
@@ -451,10 +456,10 @@ void vPortExitCritical( void )
|
||||
void FreeRTOS_Tick_Handler( void )
|
||||
{
|
||||
/* Set interrupt mask before altering scheduler structures. The tick
|
||||
handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||
so there is no need to save and restore the current mask value. It is
|
||||
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||
updated. */
|
||||
* handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||
* so there is no need to save and restore the current mask value. It is
|
||||
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||
* updated. */
|
||||
portCPU_IRQ_DISABLE();
|
||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||
__asm volatile ( "dsb \n"
|
||||
@@ -480,7 +485,7 @@ void FreeRTOS_Tick_Handler( void )
|
||||
uint32_t ulInitialFPSCR = 0;
|
||||
|
||||
/* A task is registering the fact that it needs an FPU context. Set the
|
||||
FPU flag (which is saved as part of the task context). */
|
||||
* FPU flag (which is saved as part of the task context). */
|
||||
ulPortTaskHasFPUContext = pdTRUE;
|
||||
|
||||
/* Initialise the floating point status register. */
|
||||
@@ -504,8 +509,9 @@ uint32_t ulPortSetInterruptMask( void )
|
||||
uint32_t ulReturn;
|
||||
|
||||
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
||||
updated. */
|
||||
* updated. */
|
||||
portCPU_IRQ_DISABLE();
|
||||
|
||||
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
||||
{
|
||||
/* Interrupts were already masked. */
|
||||
@@ -518,6 +524,7 @@ uint32_t ulReturn;
|
||||
__asm volatile ( "dsb \n"
|
||||
"isb \n"::: "memory" );
|
||||
}
|
||||
|
||||
portCPU_IRQ_ENABLE();
|
||||
|
||||
return ulReturn;
|
||||
@@ -529,31 +536,31 @@ uint32_t ulReturn;
|
||||
void vPortValidateInterruptPriority( void )
|
||||
{
|
||||
/* 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.
|
||||
|
||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
interrupt entry is as fast and simple as possible. */
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
* interrupt entry is as fast and simple as possible. */
|
||||
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
||||
|
||||
/* Priority grouping: The interrupt controller (GIC) 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).
|
||||
|
||||
The priority grouping is configured by the GIC's binary point register
|
||||
(ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||
possible value (which may be above 0). */
|
||||
* 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).
|
||||
*
|
||||
* The priority grouping is configured by the GIC's binary point register
|
||||
* (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
|
||||
* possible value (which may be above 0). */
|
||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ 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. */
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -98,7 +98,7 @@ extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||
|
||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||
@@ -109,25 +109,26 @@ interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||
not required for this port but included in case common demo code that uses these
|
||||
macros is used. */
|
||||
* not required for this port but included in case common demo code that uses these
|
||||
* macros is used. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||
handler for whichever peripheral is used to generate the RTOS tick. */
|
||||
* handler for whichever peripheral is used to generate the RTOS tick. */
|
||||
void FreeRTOS_Tick_Handler( void );
|
||||
|
||||
/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
|
||||
created without an FPU context and must call vPortTaskUsesFPU() to give
|
||||
themselves an FPU context before using any FPU instructions. If
|
||||
configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
|
||||
by default. */
|
||||
* created without an FPU context and must call vPortTaskUsesFPU() to give
|
||||
* themselves an FPU context before using any FPU instructions. If
|
||||
* configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
|
||||
* by default. */
|
||||
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
|
||||
void vPortTaskUsesFPU( void );
|
||||
#else
|
||||
|
||||
/* Each task has an FPU context already, so define this function away to
|
||||
nothing to prevent it being called accidentally. */
|
||||
* nothing to prevent it being called accidentally. */
|
||||
#define vPortTaskUsesFPU()
|
||||
#endif
|
||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||
@@ -166,7 +167,7 @@ by default. */
|
||||
|
||||
|
||||
/* The number of bits to shift for an interrupt priority is dependent on the
|
||||
number of bits implemented by the interrupt controller. */
|
||||
* number of bits implemented by the interrupt controller. */
|
||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||
#define portPRIORITY_SHIFT 4
|
||||
#define portMAX_BINARY_POINT_VALUE 3
|
||||
@@ -182,9 +183,9 @@ number of bits implemented by the interrupt controller. */
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||
#define portPRIORITY_SHIFT 0
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#else
|
||||
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
||||
#endif
|
||||
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
|
||||
/* Interrupt controller access addresses. */
|
||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||
@@ -204,4 +205,3 @@ number of bits implemented by the interrupt controller. */
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -54,15 +54,15 @@
|
||||
#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. */
|
||||
* occurred while the SysTick counter is stopped during tickless idle
|
||||
* calculations. */
|
||||
#ifndef portMISSED_COUNTS_FACTOR
|
||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
||||
#endif
|
||||
|
||||
/* 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. */
|
||||
* 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
|
||||
@@ -96,7 +96,7 @@ static void prvTaskExitError( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. */
|
||||
* variable. */
|
||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -129,10 +129,12 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
interrupt. */
|
||||
* interrupt. */
|
||||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||
pxTopOfStack--;
|
||||
@@ -152,22 +154,23 @@ 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. */
|
||||
* 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();
|
||||
|
||||
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. */
|
||||
* 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. */
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -175,15 +178,15 @@ volatile uint32_t ulDummy = 0UL;
|
||||
void vPortSVCHandler( void )
|
||||
{
|
||||
/* This function is no longer used, but retained for backward
|
||||
compatibility. */
|
||||
* compatibility. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortStartFirstTask( void )
|
||||
{
|
||||
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
|
||||
table offset register that can be used to locate the initial stack value.
|
||||
Not all M0 parts have the application vector table at address 0. */
|
||||
* table offset register that can be used to locate the initial stack value.
|
||||
* Not all M0 parts have the application vector table at address 0. */
|
||||
__asm volatile (
|
||||
" .syntax unified \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n"/* Obtain location of pxCurrentTCB. */
|
||||
@@ -217,7 +220,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
vPortSetupTimerInterrupt();
|
||||
|
||||
/* Initialise the critical nesting count ready for the first task. */
|
||||
@@ -227,11 +230,11 @@ BaseType_t xPortStartScheduler( void )
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* 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 optimisation does not remove the
|
||||
symbol. */
|
||||
* 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 optimisation does not remove the
|
||||
* symbol. */
|
||||
vTaskSwitchContext();
|
||||
prvTaskExitError();
|
||||
|
||||
@@ -243,7 +246,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
* Artificially force an assert. */
|
||||
configASSERT( uxCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -254,7 +257,7 @@ void vPortYield( void )
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
|
||||
/* Barriers are normally not required but do ensure the code is completely
|
||||
within the specified behaviour for the architecture. */
|
||||
* within the specified behaviour for the architecture. */
|
||||
__asm volatile ( "dsb" ::: "memory" );
|
||||
__asm volatile ( "isb" );
|
||||
}
|
||||
@@ -273,6 +276,7 @@ void vPortExitCritical( void )
|
||||
{
|
||||
configASSERT( uxCriticalNesting );
|
||||
uxCriticalNesting--;
|
||||
|
||||
if( uxCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
@@ -406,43 +410,44 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* method as that will mask interrupts that should exit sleep mode. */
|
||||
__asm volatile ( "cpsid i" ::: "memory" );
|
||||
__asm volatile ( "dsb" );
|
||||
__asm volatile ( "isb" );
|
||||
|
||||
/* If a context switch is pending or a task is waiting for the scheduler
|
||||
to be unsuspended then abandon the low power entry. */
|
||||
* to be unsuspended then abandon the low power entry. */
|
||||
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
||||
{
|
||||
/* Restart from whatever is left in the count register to complete
|
||||
this tick period. */
|
||||
* this tick period. */
|
||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||
|
||||
/* Restart SysTick. */
|
||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||
|
||||
/* Reset the reload register to the value required for normal tick
|
||||
periods. */
|
||||
* periods. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||
|
||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||
above. */
|
||||
* above. */
|
||||
__asm volatile ( "cpsie i" ::: "memory" );
|
||||
}
|
||||
else
|
||||
@@ -451,69 +456,71 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
||||
|
||||
/* Clear the SysTick count flag and set the count value back to
|
||||
zero. */
|
||||
* 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. */
|
||||
* 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 volatile ( "dsb" ::: "memory" );
|
||||
__asm volatile ( "wfi" );
|
||||
__asm volatile ( "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. */
|
||||
* out of sleep mode to execute immediately. see comments above
|
||||
* __disable_interrupt() call above. */
|
||||
__asm volatile ( "cpsie i" ::: "memory" );
|
||||
__asm volatile ( "dsb" );
|
||||
__asm volatile ( "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. */
|
||||
* and interrupts that execute while the clock is stopped will increase
|
||||
* any slippage between the time maintained by the RTOS and calendar
|
||||
* time. */
|
||||
__asm volatile ( "cpsid i" ::: "memory" );
|
||||
__asm volatile ( "dsb" );
|
||||
__asm volatile ( "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 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). */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* underflowed because the post sleep hook did something
|
||||
* that took too long. */
|
||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
||||
{
|
||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
||||
@@ -522,30 +529,30 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||
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. */
|
||||
* 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). */
|
||||
* 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? */
|
||||
* was waiting? */
|
||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
||||
|
||||
/* The reload value is set to whatever fraction of a single tick
|
||||
period remains. */
|
||||
* 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. */
|
||||
* 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 );
|
||||
|
||||
@@ -63,7 +63,7 @@ typedef unsigned long UBaseType_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. */
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -121,4 +121,3 @@ extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__((naked)
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
/* 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 a the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||
@@ -205,6 +206,7 @@
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
|
||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||
|
||||
/**
|
||||
* @brief Initial EXC_RETURN value.
|
||||
*
|
||||
@@ -221,6 +223,7 @@
|
||||
*/
|
||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||
#else
|
||||
|
||||
/**
|
||||
* @brief Initial EXC_RETURN value.
|
||||
*
|
||||
@@ -285,6 +288,7 @@
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Setup the Memory Protection Unit (MPU).
|
||||
*/
|
||||
@@ -292,6 +296,7 @@ static void prvTaskExitError( void );
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_FPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Setup the Floating Point Unit (FPU).
|
||||
*/
|
||||
@@ -347,6 +352,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVI
|
||||
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.
|
||||
@@ -355,6 +361,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||
|
||||
/**
|
||||
* @brief The number of SysTick increments that make up one tick period.
|
||||
*/
|
||||
@@ -396,6 +403,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
* 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;
|
||||
@@ -446,12 +454,14 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
* so a copy is taken. */
|
||||
xModifiableIdleTime = xExpectedIdleTime;
|
||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||
|
||||
if( xModifiableIdleTime > 0 )
|
||||
{
|
||||
__asm volatile ( "dsb" ::: "memory" );
|
||||
__asm volatile ( "wfi" );
|
||||
__asm volatile ( "isb" );
|
||||
}
|
||||
|
||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||
|
||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||
@@ -590,6 +600,7 @@ volatile uint32_t ulDummy = 0UL;
|
||||
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__;
|
||||
@@ -600,7 +611,7 @@ volatile uint32_t ulDummy = 0UL;
|
||||
extern uint32_t * __unprivileged_flash_end__;
|
||||
extern uint32_t * __privileged_sram_start__;
|
||||
extern uint32_t * __privileged_sram_end__;
|
||||
#else
|
||||
#else /* if defined( __ARMCC_VERSION ) */
|
||||
/* Declaration when these variable are exported from linker scripts. */
|
||||
extern uint32_t __privileged_functions_start__[];
|
||||
extern uint32_t __privileged_functions_end__[];
|
||||
@@ -753,6 +764,7 @@ void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION
|
||||
{
|
||||
#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__;
|
||||
@@ -783,7 +795,7 @@ uint8_t 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 ];
|
||||
@@ -800,7 +812,7 @@ uint8_t ucSVCNumber;
|
||||
/* Allocate and load a context for the secure task. */
|
||||
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
|
||||
}
|
||||
#else
|
||||
#else /* if ( configENABLE_MPU == 1 ) */
|
||||
{
|
||||
/* Allocate and load a context for the secure task. */
|
||||
xSecureContext = SecureContext_AllocateContext( ulR0 );
|
||||
@@ -809,22 +821,18 @@ uint8_t ucSVCNumber;
|
||||
|
||||
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
|
||||
@@ -846,36 +854,39 @@ uint8_t ucSVCNumber;
|
||||
/* 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__ )
|
||||
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 */
|
||||
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 */
|
||||
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
|
||||
@@ -896,6 +907,7 @@ uint8_t ucSVCNumber;
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
|
||||
if( xRunPrivileged == pdTRUE )
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
@@ -957,6 +969,7 @@ uint8_t ucSVCNumber;
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
|
||||
if( xRunPrivileged == pdTRUE )
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
@@ -1030,7 +1043,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||
const struct xMEMORY_REGION * const xRegions,
|
||||
StackType_t * pxBottomOfStack,
|
||||
uint32_t ulStackDepth )
|
||||
{
|
||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||
int32_t lIndex = 0;
|
||||
|
||||
@@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
@@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
|
||||
@@ -95,7 +95,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged )
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||
uint32_t ulIsTaskPrivileged )
|
||||
#else /* configENABLE_MPU */
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
|
||||
#endif /* configENABLE_MPU */
|
||||
@@ -103,6 +104,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
uint8_t * pucStackMemory = NULL;
|
||||
uint32_t ulIPSR;
|
||||
SecureContextHandle_t xSecureContextHandle = NULL;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
uint32_t * pulCurrentStackPointer = NULL;
|
||||
#endif /* configENABLE_MPU */
|
||||
@@ -143,6 +145,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
@@ -161,7 +164,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
|
||||
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
}
|
||||
|
||||
@@ -69,7 +69,8 @@ void SecureContext_Init( void );
|
||||
* otherwise.
|
||||
*/
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged );
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||
uint32_t ulIsTaskPrivileged );
|
||||
#else /* configENABLE_MPU */
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
|
||||
/* 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 ];
|
||||
@@ -190,6 +191,7 @@ uint8_t *puc;
|
||||
/* 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;
|
||||
@@ -203,6 +205,7 @@ uint8_t *puc;
|
||||
/* 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 )
|
||||
@@ -288,6 +291,7 @@ void *pvReturn = NULL;
|
||||
* one of adequate size is found. */
|
||||
pxPreviousBlock = &xStart;
|
||||
pxBlock = xStart.pxNextFreeBlock;
|
||||
|
||||
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
|
||||
{
|
||||
pxPreviousBlock = pxBlock;
|
||||
@@ -375,7 +379,7 @@ void *pvReturn = NULL;
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||
|
||||
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
return pvReturn;
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
{ \
|
||||
secureportDISABLE_SECURE_INTERRUPTS(); \
|
||||
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
|
||||
for( ;; ); \
|
||||
for( ; ; ) {; } \
|
||||
}
|
||||
|
||||
#endif /* __SECURE_PORT_MACROS_H__ */
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
/* 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 a the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||
@@ -205,6 +206,7 @@
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
|
||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||
|
||||
/**
|
||||
* @brief Initial EXC_RETURN value.
|
||||
*
|
||||
@@ -221,6 +223,7 @@
|
||||
*/
|
||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||
#else
|
||||
|
||||
/**
|
||||
* @brief Initial EXC_RETURN value.
|
||||
*
|
||||
@@ -285,6 +288,7 @@
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Setup the Memory Protection Unit (MPU).
|
||||
*/
|
||||
@@ -292,6 +296,7 @@ static void prvTaskExitError( void );
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_FPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Setup the Floating Point Unit (FPU).
|
||||
*/
|
||||
@@ -347,6 +352,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVI
|
||||
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.
|
||||
@@ -355,6 +361,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||
|
||||
/**
|
||||
* @brief The number of SysTick increments that make up one tick period.
|
||||
*/
|
||||
@@ -396,6 +403,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
* 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;
|
||||
@@ -446,12 +454,14 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
* so a copy is taken. */
|
||||
xModifiableIdleTime = xExpectedIdleTime;
|
||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||
|
||||
if( xModifiableIdleTime > 0 )
|
||||
{
|
||||
__asm volatile ( "dsb" ::: "memory" );
|
||||
__asm volatile ( "wfi" );
|
||||
__asm volatile ( "isb" );
|
||||
}
|
||||
|
||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||
|
||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||
@@ -590,6 +600,7 @@ volatile uint32_t ulDummy = 0UL;
|
||||
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__;
|
||||
@@ -600,7 +611,7 @@ volatile uint32_t ulDummy = 0UL;
|
||||
extern uint32_t * __unprivileged_flash_end__;
|
||||
extern uint32_t * __privileged_sram_start__;
|
||||
extern uint32_t * __privileged_sram_end__;
|
||||
#else
|
||||
#else /* if defined( __ARMCC_VERSION ) */
|
||||
/* Declaration when these variable are exported from linker scripts. */
|
||||
extern uint32_t __privileged_functions_start__[];
|
||||
extern uint32_t __privileged_functions_end__[];
|
||||
@@ -753,6 +764,7 @@ void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION
|
||||
{
|
||||
#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__;
|
||||
@@ -783,7 +795,7 @@ uint8_t 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 ];
|
||||
@@ -800,7 +812,7 @@ uint8_t ucSVCNumber;
|
||||
/* Allocate and load a context for the secure task. */
|
||||
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
|
||||
}
|
||||
#else
|
||||
#else /* if ( configENABLE_MPU == 1 ) */
|
||||
{
|
||||
/* Allocate and load a context for the secure task. */
|
||||
xSecureContext = SecureContext_AllocateContext( ulR0 );
|
||||
@@ -809,22 +821,18 @@ uint8_t ucSVCNumber;
|
||||
|
||||
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
|
||||
@@ -846,36 +854,39 @@ uint8_t ucSVCNumber;
|
||||
/* 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__ )
|
||||
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 */
|
||||
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 */
|
||||
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
|
||||
@@ -896,6 +907,7 @@ uint8_t ucSVCNumber;
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
|
||||
if( xRunPrivileged == pdTRUE )
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
@@ -957,6 +969,7 @@ uint8_t ucSVCNumber;
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
|
||||
if( xRunPrivileged == pdTRUE )
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
@@ -1030,7 +1043,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||
const struct xMEMORY_REGION * const xRegions,
|
||||
StackType_t * pxBottomOfStack,
|
||||
uint32_t ulStackDepth )
|
||||
{
|
||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||
int32_t lIndex = 0;
|
||||
|
||||
@@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
@@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
#include "task.h"
|
||||
|
||||
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
|
||||
defined. The value should also ensure backward compatibility.
|
||||
FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
|
||||
* defined. The value should also ensure backward compatibility.
|
||||
* FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
|
||||
#ifndef configKERNEL_INTERRUPT_PRIORITY
|
||||
#define configKERNEL_INTERRUPT_PRIORITY 255
|
||||
#endif
|
||||
@@ -44,8 +44,9 @@ FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
|
||||
/* 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. */
|
||||
* as the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||
#endif
|
||||
|
||||
@@ -84,17 +85,17 @@ FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
|
||||
#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. */
|
||||
* 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. */
|
||||
* have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||
|
||||
/* 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. */
|
||||
* 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
|
||||
@@ -128,7 +129,7 @@ static void prvTaskExitError( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. */
|
||||
* variable. */
|
||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
|
||||
/*
|
||||
@@ -170,10 +171,12 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
interrupt. */
|
||||
* interrupt. */
|
||||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||
pxTopOfStack--;
|
||||
@@ -193,22 +196,23 @@ 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. */
|
||||
* 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();
|
||||
|
||||
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. */
|
||||
* 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. */
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -257,7 +261,7 @@ static void prvPortStartFirstTask( void )
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
|
||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||
* See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
@@ -267,15 +271,15 @@ BaseType_t xPortStartScheduler( void )
|
||||
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. */
|
||||
* 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. */
|
||||
* possible bits. */
|
||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
@@ -285,8 +289,9 @@ BaseType_t xPortStartScheduler( void )
|
||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
of bits read back. */
|
||||
* of bits read back. */
|
||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulMaxPRIGROUPValue--;
|
||||
@@ -296,8 +301,8 @@ BaseType_t xPortStartScheduler( void )
|
||||
#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. */
|
||||
* priority bits matches the number of priority bits actually queried
|
||||
* from the hardware. */
|
||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
||||
}
|
||||
#endif
|
||||
@@ -305,19 +310,19 @@ BaseType_t xPortStartScheduler( void )
|
||||
#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. */
|
||||
* 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. */
|
||||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
value. */
|
||||
* value. */
|
||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||
}
|
||||
#endif /* conifgASSERT_DEFINED */
|
||||
@@ -327,7 +332,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
vPortSetupTimerInterrupt();
|
||||
|
||||
/* Initialise the critical nesting count ready for the first task. */
|
||||
@@ -337,11 +342,11 @@ BaseType_t xPortStartScheduler( void )
|
||||
prvPortStartFirstTask();
|
||||
|
||||
/* 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 optimisation does not remove the
|
||||
symbol. */
|
||||
* 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 optimisation does not remove the
|
||||
* symbol. */
|
||||
vTaskSwitchContext();
|
||||
prvTaskExitError();
|
||||
|
||||
@@ -353,7 +358,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
* Artificially force an assert. */
|
||||
configASSERT( uxCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -364,10 +369,10 @@ void vPortEnterCritical( void )
|
||||
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. */
|
||||
* 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 );
|
||||
@@ -379,6 +384,7 @@ void vPortExitCritical( void )
|
||||
{
|
||||
configASSERT( uxCriticalNesting );
|
||||
uxCriticalNesting--;
|
||||
|
||||
if( uxCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
@@ -426,16 +432,16 @@ void xPortPendSVHandler( void )
|
||||
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. */
|
||||
* 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. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
{
|
||||
/* Increment the RTOS tick. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
/* A context switch is required. Context switching is performed in
|
||||
the PendSV interrupt. Pend the PendSV interrupt. */
|
||||
* the PendSV interrupt. Pend the PendSV interrupt. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
}
|
||||
}
|
||||
@@ -457,43 +463,44 @@ void xPortSysTickHandler( void )
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* method as that will mask interrupts that should exit sleep mode. */
|
||||
__asm volatile ( "cpsid i" ::: "memory" );
|
||||
__asm volatile ( "dsb" );
|
||||
__asm volatile ( "isb" );
|
||||
|
||||
/* If a context switch is pending or a task is waiting for the scheduler
|
||||
to be unsuspended then abandon the low power entry. */
|
||||
* to be unsuspended then abandon the low power entry. */
|
||||
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
||||
{
|
||||
/* Restart from whatever is left in the count register to complete
|
||||
this tick period. */
|
||||
* this tick period. */
|
||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||
|
||||
/* Restart SysTick. */
|
||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||
|
||||
/* Reset the reload register to the value required for normal tick
|
||||
periods. */
|
||||
* periods. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||
|
||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||
above. */
|
||||
* above. */
|
||||
__asm volatile ( "cpsie i" ::: "memory" );
|
||||
}
|
||||
else
|
||||
@@ -502,69 +509,71 @@ void xPortSysTickHandler( void )
|
||||
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
||||
|
||||
/* Clear the SysTick count flag and set the count value back to
|
||||
zero. */
|
||||
* 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. */
|
||||
* 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 volatile ( "dsb" ::: "memory" );
|
||||
__asm volatile ( "wfi" );
|
||||
__asm volatile ( "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. */
|
||||
* out of sleep mode to execute immediately. see comments above
|
||||
* __disable_interrupt() call above. */
|
||||
__asm volatile ( "cpsie i" ::: "memory" );
|
||||
__asm volatile ( "dsb" );
|
||||
__asm volatile ( "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. */
|
||||
* and interrupts that execute while the clock is stopped will increase
|
||||
* any slippage between the time maintained by the RTOS and calendar
|
||||
* time. */
|
||||
__asm volatile ( "cpsid i" ::: "memory" );
|
||||
__asm volatile ( "dsb" );
|
||||
__asm volatile ( "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 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). */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* underflowed because the post sleep hook did something
|
||||
* that took too long. */
|
||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
||||
{
|
||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
||||
@@ -573,30 +582,30 @@ void xPortSysTickHandler( void )
|
||||
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. */
|
||||
* 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). */
|
||||
* 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? */
|
||||
* was waiting? */
|
||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
||||
|
||||
/* The reload value is set to whatever fraction of a single tick
|
||||
period remains. */
|
||||
* 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. */
|
||||
* 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 );
|
||||
@@ -652,66 +661,45 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||
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 */
|
||||
* 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. */
|
||||
* 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 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ typedef unsigned long UBaseType_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. */
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -82,7 +82,7 @@ typedef unsigned long UBaseType_t;
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||
\
|
||||
/* Barriers are normally not required but do ensure the code is completely \
|
||||
within the specified behaviour for the architecture. */ \
|
||||
* within the specified behaviour for the architecture. */\
|
||||
__asm volatile ( "dsb" ::: "memory" ); \
|
||||
__asm volatile ( "isb" ); \
|
||||
}
|
||||
@@ -106,8 +106,8 @@ extern void vPortExitCritical( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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. */
|
||||
* 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 )
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -132,6 +132,7 @@ not necessary for to use this port. They are defined so the common demo files
|
||||
uint8_t ucReturn;
|
||||
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||
|
||||
return ucReturn;
|
||||
}
|
||||
|
||||
@@ -221,7 +222,7 @@ uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||
);
|
||||
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
warnings. */
|
||||
* warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -242,4 +243,3 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
/* 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 a the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||
@@ -205,6 +206,7 @@
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
|
||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||
|
||||
/**
|
||||
* @brief Initial EXC_RETURN value.
|
||||
*
|
||||
@@ -221,6 +223,7 @@
|
||||
*/
|
||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||
#else
|
||||
|
||||
/**
|
||||
* @brief Initial EXC_RETURN value.
|
||||
*
|
||||
@@ -285,6 +288,7 @@
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Setup the Memory Protection Unit (MPU).
|
||||
*/
|
||||
@@ -292,6 +296,7 @@ static void prvTaskExitError( void );
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_FPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Setup the Floating Point Unit (FPU).
|
||||
*/
|
||||
@@ -347,6 +352,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVI
|
||||
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.
|
||||
@@ -355,6 +361,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||
|
||||
/**
|
||||
* @brief The number of SysTick increments that make up one tick period.
|
||||
*/
|
||||
@@ -396,6 +403,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
* 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;
|
||||
@@ -446,12 +454,14 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
* so a copy is taken. */
|
||||
xModifiableIdleTime = xExpectedIdleTime;
|
||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||
|
||||
if( xModifiableIdleTime > 0 )
|
||||
{
|
||||
__asm volatile ( "dsb" ::: "memory" );
|
||||
__asm volatile ( "wfi" );
|
||||
__asm volatile ( "isb" );
|
||||
}
|
||||
|
||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||
|
||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||
@@ -590,6 +600,7 @@ volatile uint32_t ulDummy = 0UL;
|
||||
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__;
|
||||
@@ -600,7 +611,7 @@ volatile uint32_t ulDummy = 0UL;
|
||||
extern uint32_t * __unprivileged_flash_end__;
|
||||
extern uint32_t * __privileged_sram_start__;
|
||||
extern uint32_t * __privileged_sram_end__;
|
||||
#else
|
||||
#else /* if defined( __ARMCC_VERSION ) */
|
||||
/* Declaration when these variable are exported from linker scripts. */
|
||||
extern uint32_t __privileged_functions_start__[];
|
||||
extern uint32_t __privileged_functions_end__[];
|
||||
@@ -753,6 +764,7 @@ void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION
|
||||
{
|
||||
#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__;
|
||||
@@ -783,7 +795,7 @@ uint8_t 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 ];
|
||||
@@ -800,7 +812,7 @@ uint8_t ucSVCNumber;
|
||||
/* Allocate and load a context for the secure task. */
|
||||
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
|
||||
}
|
||||
#else
|
||||
#else /* if ( configENABLE_MPU == 1 ) */
|
||||
{
|
||||
/* Allocate and load a context for the secure task. */
|
||||
xSecureContext = SecureContext_AllocateContext( ulR0 );
|
||||
@@ -809,22 +821,18 @@ uint8_t ucSVCNumber;
|
||||
|
||||
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
|
||||
@@ -846,36 +854,39 @@ uint8_t ucSVCNumber;
|
||||
/* 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__ )
|
||||
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 */
|
||||
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 */
|
||||
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
|
||||
@@ -896,6 +907,7 @@ uint8_t ucSVCNumber;
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
|
||||
if( xRunPrivileged == pdTRUE )
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
@@ -957,6 +969,7 @@ uint8_t ucSVCNumber;
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
|
||||
if( xRunPrivileged == pdTRUE )
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
@@ -1030,7 +1043,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||
const struct xMEMORY_REGION * const xRegions,
|
||||
StackType_t * pxBottomOfStack,
|
||||
uint32_t ulStackDepth )
|
||||
{
|
||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||
int32_t lIndex = 0;
|
||||
|
||||
@@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
@@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
|
||||
@@ -95,7 +95,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged )
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||
uint32_t ulIsTaskPrivileged )
|
||||
#else /* configENABLE_MPU */
|
||||
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
|
||||
#endif /* configENABLE_MPU */
|
||||
@@ -103,6 +104,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
uint8_t * pucStackMemory = NULL;
|
||||
uint32_t ulIPSR;
|
||||
SecureContextHandle_t xSecureContextHandle = NULL;
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
uint32_t * pulCurrentStackPointer = NULL;
|
||||
#endif /* configENABLE_MPU */
|
||||
@@ -143,6 +145,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
* context switch. */
|
||||
pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
|
||||
pulCurrentStackPointer--;
|
||||
|
||||
if( ulIsTaskPrivileged )
|
||||
{
|
||||
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||
@@ -161,7 +164,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||
/* Current SP is set to the starting of the stack. This
|
||||
* value programmed in the PSP register on context switch. */
|
||||
xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
|
||||
|
||||
}
|
||||
#endif /* configENABLE_MPU */
|
||||
}
|
||||
|
||||
@@ -69,7 +69,8 @@ void SecureContext_Init( void );
|
||||
* otherwise.
|
||||
*/
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged );
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||
uint32_t ulIsTaskPrivileged );
|
||||
#else /* configENABLE_MPU */
|
||||
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
|
||||
/* 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 ];
|
||||
@@ -190,6 +191,7 @@ uint8_t *puc;
|
||||
/* 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;
|
||||
@@ -203,6 +205,7 @@ uint8_t *puc;
|
||||
/* 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 )
|
||||
@@ -288,6 +291,7 @@ void *pvReturn = NULL;
|
||||
* one of adequate size is found. */
|
||||
pxPreviousBlock = &xStart;
|
||||
pxBlock = xStart.pxNextFreeBlock;
|
||||
|
||||
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
|
||||
{
|
||||
pxPreviousBlock = pxBlock;
|
||||
@@ -375,7 +379,7 @@ void *pvReturn = NULL;
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||
|
||||
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||
return pvReturn;
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
{ \
|
||||
secureportDISABLE_SECURE_INTERRUPTS(); \
|
||||
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
|
||||
for( ;; ); \
|
||||
for( ; ; ) {; } \
|
||||
}
|
||||
|
||||
#endif /* __SECURE_PORT_MACROS_H__ */
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
/* 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 a the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||
@@ -205,6 +206,7 @@
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
|
||||
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
|
||||
|
||||
/**
|
||||
* @brief Initial EXC_RETURN value.
|
||||
*
|
||||
@@ -221,6 +223,7 @@
|
||||
*/
|
||||
#define portINITIAL_EXC_RETURN ( 0xfffffffd )
|
||||
#else
|
||||
|
||||
/**
|
||||
* @brief Initial EXC_RETURN value.
|
||||
*
|
||||
@@ -285,6 +288,7 @@
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Setup the Memory Protection Unit (MPU).
|
||||
*/
|
||||
@@ -292,6 +296,7 @@ static void prvTaskExitError( void );
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#if ( configENABLE_FPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Setup the Floating Point Unit (FPU).
|
||||
*/
|
||||
@@ -347,6 +352,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVI
|
||||
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.
|
||||
@@ -355,6 +361,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
#endif /* configENABLE_TRUSTZONE */
|
||||
|
||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||
|
||||
/**
|
||||
* @brief The number of SysTick increments that make up one tick period.
|
||||
*/
|
||||
@@ -396,6 +403,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
* 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;
|
||||
@@ -446,12 +454,14 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
|
||||
* so a copy is taken. */
|
||||
xModifiableIdleTime = xExpectedIdleTime;
|
||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||
|
||||
if( xModifiableIdleTime > 0 )
|
||||
{
|
||||
__asm volatile ( "dsb" ::: "memory" );
|
||||
__asm volatile ( "wfi" );
|
||||
__asm volatile ( "isb" );
|
||||
}
|
||||
|
||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||
|
||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||
@@ -590,6 +600,7 @@ volatile uint32_t ulDummy = 0UL;
|
||||
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__;
|
||||
@@ -600,7 +611,7 @@ volatile uint32_t ulDummy = 0UL;
|
||||
extern uint32_t * __unprivileged_flash_end__;
|
||||
extern uint32_t * __privileged_sram_start__;
|
||||
extern uint32_t * __privileged_sram_end__;
|
||||
#else
|
||||
#else /* if defined( __ARMCC_VERSION ) */
|
||||
/* Declaration when these variable are exported from linker scripts. */
|
||||
extern uint32_t __privileged_functions_start__[];
|
||||
extern uint32_t __privileged_functions_end__[];
|
||||
@@ -753,6 +764,7 @@ void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION
|
||||
{
|
||||
#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__;
|
||||
@@ -783,7 +795,7 @@ uint8_t 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 ];
|
||||
@@ -800,7 +812,7 @@ uint8_t ucSVCNumber;
|
||||
/* Allocate and load a context for the secure task. */
|
||||
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
|
||||
}
|
||||
#else
|
||||
#else /* if ( configENABLE_MPU == 1 ) */
|
||||
{
|
||||
/* Allocate and load a context for the secure task. */
|
||||
xSecureContext = SecureContext_AllocateContext( ulR0 );
|
||||
@@ -809,22 +821,18 @@ uint8_t ucSVCNumber;
|
||||
|
||||
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
|
||||
@@ -846,36 +854,39 @@ uint8_t ucSVCNumber;
|
||||
/* 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__ )
|
||||
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 */
|
||||
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 */
|
||||
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
|
||||
@@ -896,6 +907,7 @@ uint8_t ucSVCNumber;
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
|
||||
if( xRunPrivileged == pdTRUE )
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
@@ -957,6 +969,7 @@ uint8_t ucSVCNumber;
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
{
|
||||
pxTopOfStack--;
|
||||
|
||||
if( xRunPrivileged == pdTRUE )
|
||||
{
|
||||
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
|
||||
@@ -1030,7 +1043,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||
const struct xMEMORY_REGION * const xRegions,
|
||||
StackType_t * pxBottomOfStack,
|
||||
uint32_t ulStackDepth )
|
||||
{
|
||||
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
|
||||
int32_t lIndex = 0;
|
||||
|
||||
@@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_TRUSTZONE == 1 )
|
||||
|
||||
/**
|
||||
* @brief Allocate a secure context for the task.
|
||||
*
|
||||
@@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configENABLE_MPU == 1 )
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the processor is privileged.
|
||||
*
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||
#define portNVIC_SYSTICK_CLK ( 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 ( 0 )
|
||||
@@ -190,7 +191,10 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters,
|
||||
BaseType_t xRunPrivileged )
|
||||
{
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
* interrupt. */
|
||||
@@ -240,8 +244,10 @@ static void prvSVCHandler( uint32_t *pulParam )
|
||||
{
|
||||
uint8_t ucSVCNumber;
|
||||
uint32_t ulPC;
|
||||
|
||||
#if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 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__;
|
||||
@@ -260,11 +266,14 @@ uint32_t ulPC;
|
||||
|
||||
switch( ucSVCNumber )
|
||||
{
|
||||
case portSVC_START_SCHEDULER : portNVIC_SYSPRI1_REG |= portNVIC_SVC_PRI;
|
||||
case portSVC_START_SCHEDULER:
|
||||
portNVIC_SYSPRI1_REG |= portNVIC_SVC_PRI;
|
||||
prvRestoreContextOfFirstTask();
|
||||
break;
|
||||
|
||||
case portSVC_YIELD : portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
case portSVC_YIELD:
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
|
||||
/* Barriers are normally not required
|
||||
* but do ensure the code is completely
|
||||
* within the specified behaviour for the
|
||||
@@ -279,8 +288,9 @@ uint32_t ulPC;
|
||||
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__ )
|
||||
|
||||
if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) &&
|
||||
( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) )
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
@@ -290,9 +300,11 @@ uint32_t ulPC;
|
||||
::: "r1", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
#else
|
||||
case portSVC_RAISE_PRIVILEGE : __asm volatile
|
||||
#else /* if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */
|
||||
case portSVC_RAISE_PRIVILEGE:
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r1, control \n" /* Obtain current control value. */
|
||||
" bic r1, #1 \n" /* Set privilege bit. */
|
||||
@@ -370,7 +382,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
* 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;
|
||||
|
||||
@@ -387,6 +399,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
/* 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--;
|
||||
@@ -483,10 +496,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
configASSERT( uxCriticalNesting );
|
||||
uxCriticalNesting--;
|
||||
|
||||
if( uxCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -699,7 +714,10 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||
const struct xMEMORY_REGION * const xRegions,
|
||||
StackType_t * pxBottomOfStack,
|
||||
uint32_t ulStackDepth )
|
||||
{
|
||||
extern uint32_t __SRAM_segment_start__[];
|
||||
extern uint32_t __SRAM_segment_end__[];
|
||||
@@ -817,20 +835,20 @@ uint32_t ul;
|
||||
* 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 */
|
||||
@@ -843,7 +861,7 @@ uint32_t ul;
|
||||
* 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
|
||||
|
||||
@@ -63,7 +63,7 @@ typedef unsigned long UBaseType_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. */
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -125,7 +125,7 @@ typedef struct MPU_SETTINGS
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||
\
|
||||
/* Barriers are normally not required but do ensure the code is completely \
|
||||
within the specified behaviour for the architecture. */ \
|
||||
* within the specified behaviour for the architecture. */\
|
||||
__asm volatile ( "dsb" ::: "memory" ); \
|
||||
__asm volatile ( "isb" ); \
|
||||
}
|
||||
@@ -149,8 +149,8 @@ extern void vPortExitCritical( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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. */
|
||||
* 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 )
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -168,6 +168,7 @@ not necessary for to use this port. They are defined so the common demo files
|
||||
uint8_t ucReturn;
|
||||
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||
|
||||
return ucReturn;
|
||||
}
|
||||
|
||||
@@ -278,7 +279,7 @@ uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||
);
|
||||
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
warnings. */
|
||||
* warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -295,7 +296,7 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
|
||||
#ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY
|
||||
#warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. https://www.freertos.org/FreeRTOS-V10.3.x.html"
|
||||
#warning "configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY is not defined. We recommend defining it to 1 in FreeRTOSConfig.h for better security. https: /*www.freertos.org/FreeRTOS-V10.3.x.html" */
|
||||
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -304,4 +305,3 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -41,8 +41,9 @@
|
||||
/* 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. */
|
||||
* as the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 0 )
|
||||
#endif
|
||||
|
||||
@@ -59,7 +60,7 @@
|
||||
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
||||
|
||||
/* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7
|
||||
r0p1 port. */
|
||||
* r0p1 port. */
|
||||
#define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) )
|
||||
#define portCORTEX_M7_r0p1_ID ( 0x410FC271UL )
|
||||
#define portCORTEX_M7_r0p0_ID ( 0x410FC270UL )
|
||||
@@ -92,17 +93,17 @@ r0p1 port. */
|
||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
||||
|
||||
/* For strict compliance with the Cortex-M spec the task start address should
|
||||
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||
* have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||
|
||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
||||
occurred while the SysTick counter is stopped during tickless idle
|
||||
calculations. */
|
||||
* occurred while the SysTick counter is stopped during tickless idle
|
||||
* calculations. */
|
||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
||||
|
||||
/* 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. */
|
||||
* 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
|
||||
@@ -141,7 +142,7 @@ static void prvTaskExitError( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. */
|
||||
* variable. */
|
||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
|
||||
/*
|
||||
@@ -183,13 +184,15 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
interrupt. */
|
||||
* interrupt. */
|
||||
|
||||
/* Offset added to account for the way the MCU uses the stack on entry/exit
|
||||
of interrupts, and to ensure alignment. */
|
||||
* of interrupts, and to ensure alignment. */
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||
@@ -203,7 +206,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
|
||||
/* A save method is being used that requires each task to maintain its
|
||||
own exec return value. */
|
||||
* own exec return value. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
||||
|
||||
@@ -218,22 +221,23 @@ static void prvTaskExitError( void )
|
||||
volatile uint32_t ulDummy = 0;
|
||||
|
||||
/* 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. */
|
||||
* 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();
|
||||
|
||||
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. */
|
||||
* 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. */
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -260,9 +264,9 @@ void vPortSVCHandler( void )
|
||||
static void prvPortStartFirstTask( void )
|
||||
{
|
||||
/* Start the first task. This also clears 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. */
|
||||
* 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. */
|
||||
__asm volatile (
|
||||
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n"
|
||||
@@ -287,12 +291,12 @@ static void prvPortStartFirstTask( void )
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
|
||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||
* See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||
|
||||
/* This port can be used on all revisions of the Cortex-M7 core other than
|
||||
the r0p1 parts. r0p1 parts should use the port from the
|
||||
/source/portable/GCC/ARM_CM7/r0p1 directory. */
|
||||
* the r0p1 parts. r0p1 parts should use the port from the
|
||||
* /source/portable/GCC/ARM_CM7/r0p1 directory. */
|
||||
configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
|
||||
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
|
||||
|
||||
@@ -303,15 +307,15 @@ BaseType_t xPortStartScheduler( void )
|
||||
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. */
|
||||
* 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. */
|
||||
* possible bits. */
|
||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
@@ -321,8 +325,9 @@ BaseType_t xPortStartScheduler( void )
|
||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
of bits read back. */
|
||||
* of bits read back. */
|
||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulMaxPRIGROUPValue--;
|
||||
@@ -332,8 +337,8 @@ BaseType_t xPortStartScheduler( void )
|
||||
#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. */
|
||||
* priority bits matches the number of priority bits actually queried
|
||||
* from the hardware. */
|
||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
||||
}
|
||||
#endif
|
||||
@@ -341,19 +346,19 @@ BaseType_t xPortStartScheduler( void )
|
||||
#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. */
|
||||
* 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. */
|
||||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
value. */
|
||||
* value. */
|
||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||
}
|
||||
#endif /* conifgASSERT_DEFINED */
|
||||
@@ -363,7 +368,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
vPortSetupTimerInterrupt();
|
||||
|
||||
/* Initialise the critical nesting count ready for the first task. */
|
||||
@@ -379,11 +384,11 @@ BaseType_t xPortStartScheduler( void )
|
||||
prvPortStartFirstTask();
|
||||
|
||||
/* 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 optimisation does not remove the
|
||||
symbol. */
|
||||
* 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 optimisation does not remove the
|
||||
* symbol. */
|
||||
vTaskSwitchContext();
|
||||
prvTaskExitError();
|
||||
|
||||
@@ -395,7 +400,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
* Artificially force an assert. */
|
||||
configASSERT( uxCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -406,10 +411,10 @@ void vPortEnterCritical( void )
|
||||
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. */
|
||||
* 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 );
|
||||
@@ -421,6 +426,7 @@ void vPortExitCritical( void )
|
||||
{
|
||||
configASSERT( uxCriticalNesting );
|
||||
uxCriticalNesting--;
|
||||
|
||||
if( uxCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
@@ -488,16 +494,16 @@ void xPortPendSVHandler( void )
|
||||
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. */
|
||||
* 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. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
{
|
||||
/* Increment the RTOS tick. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
/* A context switch is required. Context switching is performed in
|
||||
the PendSV interrupt. Pend the PendSV interrupt. */
|
||||
* the PendSV interrupt. Pend the PendSV interrupt. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
}
|
||||
}
|
||||
@@ -519,43 +525,44 @@ void xPortSysTickHandler( void )
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* method as that will mask interrupts that should exit sleep mode. */
|
||||
__asm volatile ( "cpsid i" ::: "memory" );
|
||||
__asm volatile ( "dsb" );
|
||||
__asm volatile ( "isb" );
|
||||
|
||||
/* If a context switch is pending or a task is waiting for the scheduler
|
||||
to be unsuspended then abandon the low power entry. */
|
||||
* to be unsuspended then abandon the low power entry. */
|
||||
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
||||
{
|
||||
/* Restart from whatever is left in the count register to complete
|
||||
this tick period. */
|
||||
* this tick period. */
|
||||
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||
|
||||
/* Restart SysTick. */
|
||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||
|
||||
/* Reset the reload register to the value required for normal tick
|
||||
periods. */
|
||||
* periods. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||
|
||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||
above. */
|
||||
* above. */
|
||||
__asm volatile ( "cpsie i" ::: "memory" );
|
||||
}
|
||||
else
|
||||
@@ -564,69 +571,71 @@ void xPortSysTickHandler( void )
|
||||
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
||||
|
||||
/* Clear the SysTick count flag and set the count value back to
|
||||
zero. */
|
||||
* 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. */
|
||||
* 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 volatile ( "dsb" ::: "memory" );
|
||||
__asm volatile ( "wfi" );
|
||||
__asm volatile ( "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. */
|
||||
* out of sleep mode to execute immediately. see comments above
|
||||
* __disable_interrupt() call above. */
|
||||
__asm volatile ( "cpsie i" ::: "memory" );
|
||||
__asm volatile ( "dsb" );
|
||||
__asm volatile ( "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. */
|
||||
* and interrupts that execute while the clock is stopped will increase
|
||||
* any slippage between the time maintained by the RTOS and calendar
|
||||
* time. */
|
||||
__asm volatile ( "cpsid i" ::: "memory" );
|
||||
__asm volatile ( "dsb" );
|
||||
__asm volatile ( "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 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). */
|
||||
* 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. */
|
||||
* 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. */
|
||||
* underflowed because the post sleep hook did something
|
||||
* that took too long. */
|
||||
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
||||
{
|
||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
||||
@@ -635,30 +644,30 @@ void xPortSysTickHandler( void )
|
||||
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. */
|
||||
* 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). */
|
||||
* 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? */
|
||||
* was waiting? */
|
||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
||||
|
||||
/* The reload value is set to whatever fraction of a single tick
|
||||
period remains. */
|
||||
* 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. */
|
||||
* 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 );
|
||||
@@ -730,47 +739,45 @@ static void vPortEnableVFP( void )
|
||||
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 */
|
||||
* 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. */
|
||||
* 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 */
|
||||
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ typedef unsigned long UBaseType_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. */
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -82,7 +82,7 @@ typedef unsigned long UBaseType_t;
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||
\
|
||||
/* Barriers are normally not required but do ensure the code is completely \
|
||||
within the specified behaviour for the architecture. */ \
|
||||
* within the specified behaviour for the architecture. */\
|
||||
__asm volatile ( "dsb" ::: "memory" ); \
|
||||
__asm volatile ( "isb" ); \
|
||||
}
|
||||
@@ -106,8 +106,8 @@ extern void vPortExitCritical( void );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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. */
|
||||
* 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 )
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -132,6 +132,7 @@ not necessary for to use this port. They are defined so the common demo files
|
||||
uint8_t ucReturn;
|
||||
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||
|
||||
return ucReturn;
|
||||
}
|
||||
|
||||
@@ -219,7 +220,7 @@ uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||
);
|
||||
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
warnings. */
|
||||
* warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -240,4 +241,3 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* 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. */
|
||||
* 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. */
|
||||
@@ -48,8 +48,9 @@ task.h is included from an application file. */
|
||||
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||
#define portNVIC_SYSTICK_CLK ( 1UL << 2UL )
|
||||
#else
|
||||
|
||||
/* The way the SysTick is clocked is not modified in case it is not the same
|
||||
as the core. */
|
||||
* as the core. */
|
||||
#define portNVIC_SYSTICK_CLK ( 0 )
|
||||
#endif
|
||||
|
||||
@@ -107,7 +108,7 @@ task.h is included from an application file. */
|
||||
#define portOFFSET_TO_PC ( 6 )
|
||||
|
||||
/* For strict compliance with the Cortex-M spec the task start address should
|
||||
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||
* have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||
|
||||
/*
|
||||
@@ -184,8 +185,8 @@ extern void vPortResetPrivilege( BaseType_t xRunningPrivileged );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. Note this is not saved as part of the task context as context
|
||||
switches can only occur when uxCriticalNesting is zero. */
|
||||
* variable. Note this is not saved as part of the task context as context
|
||||
* switches can only occur when uxCriticalNesting is zero. */
|
||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
|
||||
/*
|
||||
@@ -204,10 +205,13 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters,
|
||||
BaseType_t xRunPrivileged )
|
||||
{
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
interrupt. */
|
||||
* interrupt. */
|
||||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||
pxTopOfStack--;
|
||||
@@ -218,7 +222,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
|
||||
/* A save method is being used that requires each task to maintain its
|
||||
own exec return value. */
|
||||
* own exec return value. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portINITIAL_EXC_RETURN;
|
||||
|
||||
@@ -260,8 +264,10 @@ static void prvSVCHandler( uint32_t *pulParam )
|
||||
{
|
||||
uint8_t ucSVCNumber;
|
||||
uint32_t ulPC;
|
||||
|
||||
#if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 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__;
|
||||
@@ -274,21 +280,24 @@ uint32_t ulPC;
|
||||
#endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */
|
||||
|
||||
/* The stack contains: r0, r1, r2, r3, r12, LR, PC and xPSR. The first
|
||||
argument (r0) is pulParam[ 0 ]. */
|
||||
* argument (r0) is pulParam[ 0 ]. */
|
||||
ulPC = pulParam[ portOFFSET_TO_PC ];
|
||||
ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ];
|
||||
|
||||
switch( ucSVCNumber )
|
||||
{
|
||||
case portSVC_START_SCHEDULER : portNVIC_SYSPRI1_REG |= portNVIC_SVC_PRI;
|
||||
case portSVC_START_SCHEDULER:
|
||||
portNVIC_SYSPRI1_REG |= portNVIC_SVC_PRI;
|
||||
prvRestoreContextOfFirstTask();
|
||||
break;
|
||||
|
||||
case portSVC_YIELD : portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
case portSVC_YIELD:
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
|
||||
/* Barriers are normally not required
|
||||
but do ensure the code is completely
|
||||
within the specified behaviour for the
|
||||
architecture. */
|
||||
* but do ensure the code is completely
|
||||
* within the specified behaviour for the
|
||||
* architecture. */
|
||||
__asm volatile ( "dsb" ::: "memory" );
|
||||
__asm volatile ( "isb" );
|
||||
|
||||
@@ -298,8 +307,9 @@ uint32_t ulPC;
|
||||
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__ )
|
||||
|
||||
if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) &&
|
||||
( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) )
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
@@ -309,9 +319,11 @@ uint32_t ulPC;
|
||||
::: "r1", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
#else
|
||||
case portSVC_RAISE_PRIVILEGE : __asm volatile
|
||||
#else /* if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */
|
||||
case portSVC_RAISE_PRIVILEGE:
|
||||
__asm volatile
|
||||
(
|
||||
" mrs r1, control \n" /* Obtain current control value. */
|
||||
" bic r1, #1 \n" /* Set privilege bit. */
|
||||
@@ -375,7 +387,7 @@ static void prvRestoreContextOfFirstTask( void )
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See
|
||||
http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||
* http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||
configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) );
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
@@ -385,15 +397,15 @@ BaseType_t xPortStartScheduler( void )
|
||||
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. */
|
||||
* 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. */
|
||||
* possible bits. */
|
||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
@@ -403,8 +415,9 @@ BaseType_t xPortStartScheduler( void )
|
||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
||||
|
||||
/* Calculate the maximum acceptable priority group value for the number
|
||||
of bits read back. */
|
||||
* of bits read back. */
|
||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||
|
||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
||||
{
|
||||
ulMaxPRIGROUPValue--;
|
||||
@@ -414,8 +427,8 @@ BaseType_t xPortStartScheduler( void )
|
||||
#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. */
|
||||
* priority bits matches the number of priority bits actually queried
|
||||
* from the hardware. */
|
||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
||||
}
|
||||
#endif
|
||||
@@ -423,26 +436,26 @@ BaseType_t xPortStartScheduler( void )
|
||||
#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. */
|
||||
* 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. */
|
||||
* register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
value. */
|
||||
* value. */
|
||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||
}
|
||||
#endif /* conifgASSERT_DEFINED */
|
||||
|
||||
/* Make PendSV and SysTick the same priority as the kernel, and the SVC
|
||||
handler higher priority so it can be used to exit a critical section (where
|
||||
lower priorities are masked). */
|
||||
* handler higher priority so it can be used to exit a critical section (where
|
||||
* lower priorities are masked). */
|
||||
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||
|
||||
@@ -450,7 +463,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
prvSetupMPU();
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
* here already. */
|
||||
vPortSetupTimerInterrupt();
|
||||
|
||||
/* Initialise the critical nesting count ready for the first task. */
|
||||
@@ -463,9 +476,9 @@ BaseType_t xPortStartScheduler( void )
|
||||
*( portFPCCR ) |= portASPEN_AND_LSPEN_BITS;
|
||||
|
||||
/* Start the first task. This also clears 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. */
|
||||
* 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. */
|
||||
__asm volatile (
|
||||
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
|
||||
" ldr r0, [r0] \n"
|
||||
@@ -490,7 +503,7 @@ BaseType_t xPortStartScheduler( void )
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
* Artificially force an assert. */
|
||||
configASSERT( uxCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -512,10 +525,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
|
||||
|
||||
configASSERT( uxCriticalNesting );
|
||||
uxCriticalNesting--;
|
||||
|
||||
if( uxCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
|
||||
vPortResetPrivilege( xRunningPrivileged );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -639,6 +654,7 @@ static void vPortEnableVFP( void )
|
||||
static void prvSetupMPU( void )
|
||||
{
|
||||
#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__;
|
||||
@@ -655,7 +671,8 @@ static void prvSetupMPU( void )
|
||||
extern uint32_t __FLASH_segment_end__[];
|
||||
extern uint32_t __privileged_data_start__[];
|
||||
extern uint32_t __privileged_data_end__[];
|
||||
#endif
|
||||
#endif /* if defined( __ARMCC_VERSION ) */
|
||||
|
||||
/* Check the expected MPU is present. */
|
||||
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
|
||||
{
|
||||
@@ -670,7 +687,7 @@ static void prvSetupMPU( void )
|
||||
( portMPU_REGION_ENABLE );
|
||||
|
||||
/* Setup the privileged flash for privileged only access. This is where
|
||||
the kernel code is placed. */
|
||||
* the kernel code is placed. */
|
||||
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_functions_start__ ) | /* Base address. */
|
||||
( portMPU_REGION_VALID ) |
|
||||
( portPRIVILEGED_FLASH_REGION );
|
||||
@@ -681,7 +698,7 @@ static void prvSetupMPU( void )
|
||||
( portMPU_REGION_ENABLE );
|
||||
|
||||
/* Setup the privileged data RAM region. This is where the kernel data
|
||||
is placed. */
|
||||
* is placed. */
|
||||
portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */
|
||||
( portMPU_REGION_VALID ) |
|
||||
( portPRIVILEGED_RAM_REGION );
|
||||
@@ -692,7 +709,7 @@ static void prvSetupMPU( void )
|
||||
( portMPU_REGION_ENABLE );
|
||||
|
||||
/* By default allow everything to access the general peripherals. The
|
||||
system peripherals and registers are protected. */
|
||||
* system peripherals and registers are protected. */
|
||||
portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS ) |
|
||||
( portMPU_REGION_VALID ) |
|
||||
( portGENERAL_PERIPHERALS_REGION );
|
||||
@@ -715,7 +732,7 @@ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes )
|
||||
uint32_t ulRegionSize, ulReturnValue = 4;
|
||||
|
||||
/* 32 is the smallest region size, 31 is the largest valid value for
|
||||
ulReturnValue. */
|
||||
* ulReturnValue. */
|
||||
for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) )
|
||||
{
|
||||
if( ulActualSizeInBytes <= ulRegionSize )
|
||||
@@ -729,7 +746,7 @@ uint32_t ulRegionSize, ulReturnValue = 4;
|
||||
}
|
||||
|
||||
/* Shift the code by one before returning so it can be written directly
|
||||
into the the correct bit position of the attribute register. */
|
||||
* into the the correct bit position of the attribute register. */
|
||||
return( ulReturnValue << 1UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -764,9 +781,13 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||
const struct xMEMORY_REGION * const xRegions,
|
||||
StackType_t * pxBottomOfStack,
|
||||
uint32_t ulStackDepth )
|
||||
{
|
||||
#if defined( __ARMCC_VERSION )
|
||||
|
||||
/* Declaration when these variable are defined in code instead of being
|
||||
* exported from linker scripts. */
|
||||
extern uint32_t * __SRAM_segment_start__;
|
||||
@@ -779,7 +800,7 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMOR
|
||||
extern uint32_t __SRAM_segment_end__[];
|
||||
extern uint32_t __privileged_data_start__[];
|
||||
extern uint32_t __privileged_data_end__[];
|
||||
#endif
|
||||
#endif /* if defined( __ARMCC_VERSION ) */
|
||||
|
||||
int32_t lIndex;
|
||||
uint32_t ul;
|
||||
@@ -799,7 +820,7 @@ uint32_t ul;
|
||||
( portMPU_REGION_ENABLE );
|
||||
|
||||
/* Re-instate the privileged only RAM region as xRegion[ 0 ] will have
|
||||
just removed the privileged only parameters. */
|
||||
* just removed the privileged only parameters. */
|
||||
xMPUSettings->xRegion[ 1 ].ulRegionBaseAddress =
|
||||
( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */
|
||||
( portMPU_REGION_VALID ) |
|
||||
@@ -821,9 +842,9 @@ uint32_t ul;
|
||||
else
|
||||
{
|
||||
/* 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. */
|
||||
* 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. */
|
||||
@@ -846,8 +867,8 @@ uint32_t ul;
|
||||
if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL )
|
||||
{
|
||||
/* Translate the generic region definition contained in
|
||||
xRegions into the CM3 specific MPU settings that are then
|
||||
stored in xMPUSettings. */
|
||||
* xRegions into the CM3 specific MPU settings that are then
|
||||
* stored in xMPUSettings. */
|
||||
xMPUSettings->xRegion[ ul ].ulRegionBaseAddress =
|
||||
( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) |
|
||||
( portMPU_REGION_VALID ) |
|
||||
@@ -888,48 +909,46 @@ uint32_t ul;
|
||||
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 */
|
||||
* 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 unpredicable behaviour. */
|
||||
* 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 unpredicable behaviour. */
|
||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
||||
}
|
||||
|
||||
#endif /* configASSERT_DEFINED */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user