Style: uncrusitfy

This commit is contained in:
Alfred Gedeon 2020-07-01 22:27:40 -07:00 committed by alfred gedeon
parent a5dbc2b1de
commit 718178c68a
406 changed files with 108795 additions and 106323 deletions

View file

@ -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; BaseType_t xReturn;
CRCB_t * pxCoRoutine; CRCB_t * pxCoRoutine;
/* Allocate the memory that will store the co-routine control block. */ /* Allocate the memory that will store the co-routine control block. */
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
if( pxCoRoutine ) if( pxCoRoutine )
{ {
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to /* If pxCurrentCoRoutine is NULL then this is the first co-routine to
be created and the co-routine data structures need initialising. */ * be created and the co-routine data structures need initialising. */
if( pxCurrentCoRoutine == NULL ) if( pxCurrentCoRoutine == NULL )
{ {
pxCurrentCoRoutine = pxCoRoutine; pxCurrentCoRoutine = pxCoRoutine;
@ -132,8 +135,8 @@ CRCB_t *pxCoRoutine;
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
/* Set the co-routine control block as a link back from the ListItem_t. /* Set the co-routine control block as a link back from the ListItem_t.
This is so we can get back to the containing CRCB from a generic item * This is so we can get back to the containing CRCB from a generic item
in a list. */ * in a list. */
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
@ -141,7 +144,7 @@ CRCB_t *pxCoRoutine;
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
/* Now the co-routine has been initialised it can be added to the ready /* Now the co-routine has been initialised it can be added to the ready
list at the correct priority. */ * list at the correct priority. */
prvAddCoRoutineToReadyQueue( pxCoRoutine ); prvAddCoRoutineToReadyQueue( pxCoRoutine );
xReturn = pdPASS; xReturn = pdPASS;
@ -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; TickType_t xTimeToWake;
/* Calculate the time to wake - this may overflow but this is /* Calculate the time to wake - this may overflow but this is
not a problem. */ * not a problem. */
xTimeToWake = xCoRoutineTickCount + xTicksToDelay; xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
/* We must remove ourselves from the ready list before adding /* We must remove ourselves from the ready list before adding
ourselves to the blocked list as the same list item is used for * ourselves to the blocked list as the same list item is used for
both lists. */ * both lists. */
( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
/* The list item will be inserted in wake time order. */ /* The list item will be inserted in wake time order. */
@ -174,20 +178,20 @@ TickType_t xTimeToWake;
if( xTimeToWake < xCoRoutineTickCount ) if( xTimeToWake < xCoRoutineTickCount )
{ {
/* Wake time has overflowed. Place this item in the /* Wake time has overflowed. Place this item in the
overflow list. */ * overflow list. */
vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
} }
else else
{ {
/* The wake time has not overflowed, so we can use the /* The wake time has not overflowed, so we can use the
current block list. */ * current block list. */
vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
} }
if( pxEventList ) if( pxEventList )
{ {
/* Also add the co-routine to an event list. If this is done then the /* Also add the co-routine to an event list. If this is done then the
function must be called with interrupts disabled. */ * function must be called with interrupts disabled. */
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
} }
} }
@ -196,8 +200,8 @@ TickType_t xTimeToWake;
static void prvCheckPendingReadyList( void ) static void prvCheckPendingReadyList( void )
{ {
/* Are there any co-routines waiting to get moved to the ready list? These /* Are there any co-routines waiting to get moved to the ready list? These
are co-routines that have been readied by an ISR. The ISR cannot access * are co-routines that have been readied by an ISR. The ISR cannot access
the ready lists itself. */ * the ready lists itself. */
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
{ {
CRCB_t * pxUnblockedCRCB; CRCB_t * pxUnblockedCRCB;
@ -221,6 +225,7 @@ static void prvCheckDelayedList( void )
CRCB_t * pxCRCB; CRCB_t * pxCRCB;
xPassedTicks = xTaskGetTickCount() - xLastTickCount; xPassedTicks = xTaskGetTickCount() - xLastTickCount;
while( xPassedTicks ) while( xPassedTicks )
{ {
xCoRoutineTickCount++; xCoRoutineTickCount++;
@ -232,7 +237,7 @@ CRCB_t *pxCRCB;
List_t * pxTemp; List_t * pxTemp;
/* Tick count has overflowed so we need to swap the delay lists. If there are /* Tick count has overflowed so we need to swap the delay lists. If there are
any items in pxDelayedCoRoutineList here then there is an error! */ * any items in pxDelayedCoRoutineList here then there is an error! */
pxTemp = pxDelayedCoRoutineList; pxTemp = pxDelayedCoRoutineList;
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
pxOverflowDelayedCoRoutineList = pxTemp; pxOverflowDelayedCoRoutineList = pxTemp;
@ -252,10 +257,10 @@ CRCB_t *pxCRCB;
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
{ {
/* The event could have occurred just before this critical /* The event could have occurred just before this critical
section. If this is the case then the generic list item will * section. If this is the case then the generic list item will
have been moved to the pending ready list and the following * have been moved to the pending ready list and the following
line is still valid. Also the pvContainer parameter will have * line is still valid. Also the pvContainer parameter will have
been set to NULL so the following lines are also valid. */ * been set to NULL so the following lines are also valid. */
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
/* Is the co-routine waiting on an event also? */ /* Is the co-routine waiting on an event also? */
@ -277,8 +282,8 @@ CRCB_t *pxCRCB;
void vCoRoutineSchedule( void ) void vCoRoutineSchedule( void )
{ {
/* Only run a co-routine after prvInitialiseCoRoutineLists() has been /* Only run a co-routine after prvInitialiseCoRoutineLists() has been
called. prvInitialiseCoRoutineLists() is called automatically when a * called. prvInitialiseCoRoutineLists() is called automatically when a
co-routine is created. */ * co-routine is created. */
if( pxDelayedCoRoutineList != NULL ) if( pxDelayedCoRoutineList != NULL )
{ {
/* See if any co-routines readied by events need moving to the ready lists. */ /* See if any co-routines readied by events need moving to the ready lists. */
@ -295,18 +300,17 @@ void vCoRoutineSchedule( void )
/* No more co-routines to check. */ /* No more co-routines to check. */
return; return;
} }
--uxTopCoRoutineReadyPriority; --uxTopCoRoutineReadyPriority;
} }
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
of the same priority get an equal share of the processor time. */ * of the same priority get an equal share of the processor time. */
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
/* Call the co-routine. */ /* Call the co-routine. */
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
} }
return;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -324,7 +328,7 @@ UBaseType_t uxPriority;
vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
/* Start with pxDelayedCoRoutineList using list1 and the /* Start with pxDelayedCoRoutineList using list1 and the
pxOverflowDelayedCoRoutineList using list2. */ * pxOverflowDelayedCoRoutineList using list2. */
pxDelayedCoRoutineList = &xDelayedCoRoutineList1; pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
} }
@ -336,8 +340,8 @@ CRCB_t *pxUnblockedCRCB;
BaseType_t xReturn; BaseType_t xReturn;
/* This function is called from within an interrupt. It can only access /* This function is called from within an interrupt. It can only access
event lists and the pending ready list. This function assumes that a * event lists and the pending ready list. This function assumes that a
check has already been made to ensure pxEventList is not empty. */ * check has already been made to ensure pxEventList is not empty. */
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
@ -355,4 +359,3 @@ BaseType_t xReturn;
} }
#endif /* configUSE_CO_ROUTINES == 0 */ #endif /* configUSE_CO_ROUTINES == 0 */

View file

@ -28,8 +28,8 @@
#include <stdlib.h> #include <stdlib.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when * all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */ * task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* FreeRTOS includes. */ /* FreeRTOS includes. */
@ -39,14 +39,14 @@ task.h is included from an application file. */
#include "event_groups.h" #include "event_groups.h"
/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified /* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified
because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
for the header files above, but not in this file, in order to generate the * for the header files above, but not in this file, in order to generate the
correct privileged Vs unprivileged linkage and placement. */ * correct privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */
/* The following bit fields convey control information in a task's event list /* The following bit fields convey control information in a task's event list
item value. It is important they don't clash with the * item value. It is important they don't clash with the
taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */ * taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
#if configUSE_16_BIT_TICKS == 1 #if configUSE_16_BIT_TICKS == 1
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
@ -83,7 +83,9 @@ typedef struct EventGroupDef_t
* wait condition is met if any of the bits set in uxBitsToWait for are also set * wait condition is met if any of the bits set in uxBitsToWait for are also set
* in uxCurrentEventBits. * in uxCurrentEventBits.
*/ */
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION; static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -99,8 +101,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
#if ( configASSERT_DEFINED == 1 ) #if ( configASSERT_DEFINED == 1 )
{ {
/* Sanity check that the size of the structure used to declare a /* Sanity check that the size of the structure used to declare a
variable of type StaticEventGroup_t equals the size of the real * variable of type StaticEventGroup_t equals the size of the real
event group structure. */ * event group structure. */
volatile size_t xSize = sizeof( StaticEventGroup_t ); volatile size_t xSize = sizeof( StaticEventGroup_t );
configASSERT( xSize == sizeof( EventGroup_t ) ); configASSERT( xSize == sizeof( EventGroup_t ) );
} /*lint !e529 xSize is referenced if configASSERT() is defined. */ } /*lint !e529 xSize is referenced if configASSERT() is defined. */
@ -117,8 +119,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{ {
/* Both static and dynamic allocation can be used, so note that /* Both static and dynamic allocation can be used, so note that
this event group was created statically in case the event group * this event group was created statically in case the event group
is later deleted. */ * is later deleted. */
pxEventBits->ucStaticallyAllocated = pdTRUE; pxEventBits->ucStaticallyAllocated = pdTRUE;
} }
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
@ -128,8 +130,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
else else
{ {
/* xEventGroupCreateStatic should only ever be called with /* xEventGroupCreateStatic should only ever be called with
pxEventGroupBuffer pointing to a pre-allocated (compile time * pxEventGroupBuffer pointing to a pre-allocated (compile time
allocated) StaticEventGroup_t variable. */ * allocated) StaticEventGroup_t variable. */
traceEVENT_GROUP_CREATE_FAILED(); traceEVENT_GROUP_CREATE_FAILED();
} }
@ -146,18 +148,18 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
EventGroup_t * pxEventBits; EventGroup_t * pxEventBits;
/* Allocate the event group. Justification for MISRA deviation as /* Allocate the event group. Justification for MISRA deviation as
follows: pvPortMalloc() always ensures returned memory blocks are * follows: pvPortMalloc() always ensures returned memory blocks are
aligned per the requirements of the MCU stack. In this case * aligned per the requirements of the MCU stack. In this case
pvPortMalloc() must return a pointer that is guaranteed to meet the * pvPortMalloc() must return a pointer that is guaranteed to meet the
alignment requirements of the EventGroup_t structure - which (if you * alignment requirements of the EventGroup_t structure - which (if you
follow it through) is the alignment requirements of the TickType_t type * follow it through) is the alignment requirements of the TickType_t type
(EventBits_t being of TickType_t itself). Therefore, whenever the * (EventBits_t being of TickType_t itself). Therefore, whenever the
stack alignment requirements are greater than or equal to the * stack alignment requirements are greater than or equal to the
TickType_t alignment requirements the cast is safe. In other cases, * TickType_t alignment requirements the cast is safe. In other cases,
where the natural word size of the architecture is less than * where the natural word size of the architecture is less than
sizeof( TickType_t ), the TickType_t variables will be accessed in two * sizeof( TickType_t ), the TickType_t variables will be accessed in two
or more reads operations, and the alignment requirements is only that * or more reads operations, and the alignment requirements is only that
of each individual read. */ * of each individual read. */
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */ pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */
if( pxEventBits != NULL ) if( pxEventBits != NULL )
@ -168,8 +170,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
{ {
/* Both static and dynamic allocation can be used, so note this /* Both static and dynamic allocation can be used, so note this
event group was allocated statically in case the event group is * event group was allocated statically in case the event group is
later deleted. */ * later deleted. */
pxEventBits->ucStaticallyAllocated = pdFALSE; pxEventBits->ucStaticallyAllocated = pdFALSE;
} }
#endif /* configSUPPORT_STATIC_ALLOCATION */ #endif /* configSUPPORT_STATIC_ALLOCATION */
@ -187,7 +189,10 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait )
{ {
EventBits_t uxOriginalBitValue, uxReturn; EventBits_t uxOriginalBitValue, uxReturn;
EventGroup_t * pxEventBits = xEventGroup; EventGroup_t * pxEventBits = xEventGroup;
@ -214,7 +219,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
uxReturn = ( uxOriginalBitValue | uxBitsToSet ); uxReturn = ( uxOriginalBitValue | uxBitsToSet );
/* Rendezvous always clear the bits. They will have been cleared /* Rendezvous always clear the bits. They will have been cleared
already unless this is the only task in the rendezvous. */ * already unless this is the only task in the rendezvous. */
pxEventBits->uxEventBits &= ~uxBitsToWaitFor; pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
xTicksToWait = 0; xTicksToWait = 0;
@ -226,20 +231,20 @@ BaseType_t xTimeoutOccurred = pdFALSE;
traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
/* Store the bits that the calling task is waiting for in the /* Store the bits that the calling task is waiting for in the
task's event list item so the kernel knows when a match is * task's event list item so the kernel knows when a match is
found. Then enter the blocked state. */ * found. Then enter the blocked state. */
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
/* This assignment is obsolete as uxReturn will get set after /* This assignment is obsolete as uxReturn will get set after
the task unblocks, but some compilers mistakenly generate a * the task unblocks, but some compilers mistakenly generate a
warning about uxReturn being returned without being set if the * warning about uxReturn being returned without being set if the
assignment is omitted. */ * assignment is omitted. */
uxReturn = 0; uxReturn = 0;
} }
else else
{ {
/* The rendezvous bits were not set, but no block time was /* The rendezvous bits were not set, but no block time was
specified - just return the current event bit value. */ * specified - just return the current event bit value. */
uxReturn = pxEventBits->uxEventBits; uxReturn = pxEventBits->uxEventBits;
xTimeoutOccurred = pdTRUE; xTimeoutOccurred = pdTRUE;
} }
@ -259,9 +264,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
} }
/* The task blocked to wait for its required bits to be set - at this /* The task blocked to wait for its required bits to be set - at this
point either the required bits were set or the block time expired. If * point either the required bits were set or the block time expired. If
the required bits were set they will have been stored in the task's * the required bits were set they will have been stored in the task's
event list item, and they should now be retrieved then cleared. */ * event list item, and they should now be retrieved then cleared. */
uxReturn = uxTaskResetEventItemValue(); uxReturn = uxTaskResetEventItemValue();
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
@ -272,9 +277,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
uxReturn = pxEventBits->uxEventBits; uxReturn = pxEventBits->uxEventBits;
/* Although the task got here because it timed out before the /* Although the task got here because it timed out before the
bits it was waiting for were set, it is possible that since it * bits it was waiting for were set, it is possible that since it
unblocked another task has set the bits. If this is the case * unblocked another task has set the bits. If this is the case
then it needs to clear the bits before exiting. */ * then it needs to clear the bits before exiting. */
if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
{ {
pxEventBits->uxEventBits &= ~uxBitsToWaitFor; pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
@ -294,7 +299,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
} }
/* Control bits might be set as the task had blocked should not be /* Control bits might be set as the task had blocked should not be
returned. */ * returned. */
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
} }
@ -307,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; EventGroup_t * pxEventBits = xEventGroup;
EventBits_t uxReturn, uxControlBits = 0; EventBits_t uxReturn, uxControlBits = 0;
@ -315,7 +324,7 @@ BaseType_t xWaitConditionMet, xAlreadyYielded;
BaseType_t xTimeoutOccurred = pdFALSE; BaseType_t xTimeoutOccurred = pdFALSE;
/* Check the user is not attempting to wait on the bits used by the kernel /* Check the user is not attempting to wait on the bits used by the kernel
itself, and that at least one bit is being requested. */ * itself, and that at least one bit is being requested. */
configASSERT( xEventGroup ); configASSERT( xEventGroup );
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
configASSERT( uxBitsToWaitFor != 0 ); configASSERT( uxBitsToWaitFor != 0 );
@ -335,7 +344,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
if( xWaitConditionMet != pdFALSE ) if( xWaitConditionMet != pdFALSE )
{ {
/* The wait condition has already been met so there is no need to /* The wait condition has already been met so there is no need to
block. */ * block. */
uxReturn = uxCurrentEventBits; uxReturn = uxCurrentEventBits;
xTicksToWait = ( TickType_t ) 0; xTicksToWait = ( TickType_t ) 0;
@ -352,16 +361,16 @@ BaseType_t xTimeoutOccurred = pdFALSE;
else if( xTicksToWait == ( TickType_t ) 0 ) else if( xTicksToWait == ( TickType_t ) 0 )
{ {
/* The wait condition has not been met, but no block time was /* The wait condition has not been met, but no block time was
specified, so just return the current value. */ * specified, so just return the current value. */
uxReturn = uxCurrentEventBits; uxReturn = uxCurrentEventBits;
xTimeoutOccurred = pdTRUE; xTimeoutOccurred = pdTRUE;
} }
else else
{ {
/* The task is going to block to wait for its required bits to be /* The task is going to block to wait for its required bits to be
set. uxControlBits are used to remember the specified behaviour of * set. uxControlBits are used to remember the specified behaviour of
this call to xEventGroupWaitBits() - for use when the event bits * this call to xEventGroupWaitBits() - for use when the event bits
unblock the task. */ * unblock the task. */
if( xClearOnExit != pdFALSE ) if( xClearOnExit != pdFALSE )
{ {
uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
@ -381,13 +390,13 @@ BaseType_t xTimeoutOccurred = pdFALSE;
} }
/* Store the bits that the calling task is waiting for in the /* Store the bits that the calling task is waiting for in the
task's event list item so the kernel knows when a match is * task's event list item so the kernel knows when a match is
found. Then enter the blocked state. */ * found. Then enter the blocked state. */
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
/* This is obsolete as it will get set after the task unblocks, but /* This is obsolete as it will get set after the task unblocks, but
some compilers mistakenly generate a warning about the variable * some compilers mistakenly generate a warning about the variable
being returned without being set if it is not done. */ * being returned without being set if it is not done. */
uxReturn = 0; uxReturn = 0;
traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
@ -407,9 +416,9 @@ BaseType_t xTimeoutOccurred = pdFALSE;
} }
/* The task blocked to wait for its required bits to be set - at this /* The task blocked to wait for its required bits to be set - at this
point either the required bits were set or the block time expired. If * point either the required bits were set or the block time expired. If
the required bits were set they will have been stored in the task's * the required bits were set they will have been stored in the task's
event list item, and they should now be retrieved then cleared. */ * event list item, and they should now be retrieved then cleared. */
uxReturn = uxTaskResetEventItemValue(); uxReturn = uxTaskResetEventItemValue();
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
@ -420,7 +429,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
uxReturn = pxEventBits->uxEventBits; uxReturn = pxEventBits->uxEventBits;
/* It is possible that the event bits were updated between this /* It is possible that the event bits were updated between this
task leaving the Blocked state and running again. */ * task leaving the Blocked state and running again. */
if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
{ {
if( xClearOnExit != pdFALSE ) if( xClearOnExit != pdFALSE )
@ -436,6 +445,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
{ {
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
xTimeoutOccurred = pdTRUE; xTimeoutOccurred = pdTRUE;
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
@ -448,6 +458,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
/* The task blocked so control bits may have been set. */ /* The task blocked so control bits may have been set. */
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
} }
traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
/* Prevent compiler warnings when trace macros are not used. */ /* Prevent compiler warnings when trace macros are not used. */
@ -457,13 +468,14 @@ BaseType_t xTimeoutOccurred = pdFALSE;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear )
{ {
EventGroup_t * pxEventBits = xEventGroup; EventGroup_t * pxEventBits = xEventGroup;
EventBits_t uxReturn; EventBits_t uxReturn;
/* Check the user is not attempting to clear the bits used by the kernel /* Check the user is not attempting to clear the bits used by the kernel
itself. */ * itself. */
configASSERT( xEventGroup ); configASSERT( xEventGroup );
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
@ -472,7 +484,7 @@ EventBits_t uxReturn;
traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
/* The value returned is the event group value prior to the bits being /* The value returned is the event group value prior to the bits being
cleared. */ * cleared. */
uxReturn = pxEventBits->uxEventBits; uxReturn = pxEventBits->uxEventBits;
/* Clear the bits. */ /* Clear the bits. */
@ -486,7 +498,8 @@ EventBits_t uxReturn;
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear )
{ {
BaseType_t xReturn; BaseType_t xReturn;
@ -496,7 +509,7 @@ EventBits_t uxReturn;
return xReturn; return xReturn;
} }
#endif #endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
@ -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. */ } /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet )
{ {
ListItem_t * pxListItem, * pxNext; ListItem_t * pxListItem, * pxNext;
ListItem_t const * pxListEnd; ListItem_t const * pxListEnd;
@ -525,7 +539,7 @@ EventGroup_t *pxEventBits = xEventGroup;
BaseType_t xMatchFound = pdFALSE; BaseType_t xMatchFound = pdFALSE;
/* Check the user is not attempting to set the bits used by the kernel /* Check the user is not attempting to set the bits used by the kernel
itself. */ * itself. */
configASSERT( xEventGroup ); configASSERT( xEventGroup );
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
@ -586,21 +600,21 @@ BaseType_t xMatchFound = pdFALSE;
} }
/* Store the actual event flag value in the task's event list /* Store the actual event flag value in the task's event list
item before removing the task from the event list. The * item before removing the task from the event list. The
eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows * eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
that is was unblocked due to its required bits matching, rather * that is was unblocked due to its required bits matching, rather
than because it timed out. */ * than because it timed out. */
vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
} }
/* Move onto the next list item. Note pxListItem->pxNext is not /* Move onto the next list item. Note pxListItem->pxNext is not
used here as the list item may have been removed from the event list * used here as the list item may have been removed from the event list
and inserted into the ready/pending reading list. */ * and inserted into the ready/pending reading list. */
pxListItem = pxNext; pxListItem = pxNext;
} }
/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
bit was set in the control word. */ * bit was set in the control word. */
pxEventBits->uxEventBits &= ~uxBitsToClear; pxEventBits->uxEventBits &= ~uxBitsToClear;
} }
( void ) xTaskResumeAll(); ( void ) xTaskResumeAll();
@ -621,7 +635,7 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
{ {
/* Unblock the task, returning 0 as the event list is being deleted /* Unblock the task, returning 0 as the event list is being deleted
and cannot therefore have any bits set. */ * and cannot therefore have any bits set. */
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
} }
@ -629,13 +643,13 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
{ {
/* The event group can only have been allocated dynamically - free /* The event group can only have been allocated dynamically - free
it again. */ * it again. */
vPortFree( pxEventBits ); vPortFree( pxEventBits );
} }
#elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) #elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
{ {
/* The event group could have been allocated statically or /* The event group could have been allocated statically or
dynamically, so check before attempting to free the memory. */ * dynamically, so check before attempting to free the memory. */
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
{ {
vPortFree( pxEventBits ); vPortFree( pxEventBits );
@ -652,29 +666,33 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* For internal use only - execute a 'set bits' command that was pended from /* For internal use only - execute a 'set bits' command that was pended from
an interrupt. */ * an interrupt. */
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) void vEventGroupSetBitsCallback( void * pvEventGroup,
const uint32_t ulBitsToSet )
{ {
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* For internal use only - execute a 'clear bits' command that was pended from /* For internal use only - execute a 'clear bits' command that was pended from
an interrupt. */ * an interrupt. */
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) void vEventGroupClearBitsCallback( void * pvEventGroup,
const uint32_t ulBitsToClear )
{ {
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xWaitForAllBits )
{ {
BaseType_t xWaitConditionMet = pdFALSE; BaseType_t xWaitConditionMet = pdFALSE;
if( xWaitForAllBits == pdFALSE ) if( xWaitForAllBits == pdFALSE )
{ {
/* Task only has to wait for one bit within uxBitsToWaitFor to be /* Task only has to wait for one bit within uxBitsToWaitFor to be
set. Is one already set? */ * set. Is one already set? */
if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
{ {
xWaitConditionMet = pdTRUE; xWaitConditionMet = pdTRUE;
@ -687,7 +705,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
else else
{ {
/* Task has to wait for all the bits in uxBitsToWaitFor to be set. /* Task has to wait for all the bits in uxBitsToWaitFor to be set.
Are they set already? */ * Are they set already? */
if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
{ {
xWaitConditionMet = pdTRUE; xWaitConditionMet = pdTRUE;
@ -704,7 +722,9 @@ BaseType_t xWaitConditionMet = pdFALSE;
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
BaseType_t * pxHigherPriorityTaskWoken )
{ {
BaseType_t xReturn; BaseType_t xReturn;
@ -714,7 +734,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
return xReturn; return xReturn;
} }
#endif #endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
@ -741,12 +761,11 @@ BaseType_t xWaitConditionMet = pdFALSE;
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) void vEventGroupSetNumber( void * xEventGroup,
UBaseType_t uxEventGroupNumber )
{ {
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
} }
#endif /* configUSE_TRACE_FACILITY */ #endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -69,6 +69,7 @@ extern "C" {
#if ( configUSE_NEWLIB_REENTRANT == 1 ) #if ( configUSE_NEWLIB_REENTRANT == 1 )
#include <reent.h> #include <reent.h>
#endif #endif
/* /*
* Check all the required application specific macros have been defined. * Check all the required application specific macros have been defined.
* These macros are application specific and (as downloaded) are defined * These macros are application specific and (as downloaded) are defined
@ -241,10 +242,10 @@ extern "C" {
#endif #endif
/* configPRECONDITION should be defined as configASSERT. /* configPRECONDITION should be defined as configASSERT.
The CBMC proofs need a way to track assumptions and assertions. * The CBMC proofs need a way to track assumptions and assertions.
A configPRECONDITION statement should express an implicit invariant or * A configPRECONDITION statement should express an implicit invariant or
assumption made. A configASSERT statement should express an invariant that must * assumption made. A configASSERT statement should express an invariant that must
hold explicit before calling the code. */ * hold explicit before calling the code. */
#ifndef configPRECONDITION #ifndef configPRECONDITION
#define configPRECONDITION( X ) configASSERT( X ) #define configPRECONDITION( X ) configASSERT( X )
#define configPRECONDITION_DEFINED 0 #define configPRECONDITION_DEFINED 0
@ -313,26 +314,30 @@ hold explicit before calling the code. */
/* Remove any unused trace macros. */ /* Remove any unused trace macros. */
#ifndef traceSTART #ifndef traceSTART
/* Used to perform any necessary initialisation - for example, open a file /* 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() #define traceSTART()
#endif #endif
#ifndef traceEND #ifndef traceEND
/* Use to close a trace, for example close a file into which trace has been /* Use to close a trace, for example close a file into which trace has been
written. */ * written. */
#define traceEND() #define traceEND()
#endif #endif
#ifndef traceTASK_SWITCHED_IN #ifndef traceTASK_SWITCHED_IN
/* Called after a task has been selected to run. pxCurrentTCB holds a pointer /* 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() #define traceTASK_SWITCHED_IN()
#endif #endif
#ifndef traceINCREASE_TICK_COUNT #ifndef traceINCREASE_TICK_COUNT
/* Called before stepping the tick count after waking from tickless idle /* Called before stepping the tick count after waking from tickless idle
sleep. */ * sleep. */
#define traceINCREASE_TICK_COUNT( x ) #define traceINCREASE_TICK_COUNT( x )
#endif #endif
@ -347,49 +352,55 @@ hold explicit before calling the code. */
#endif #endif
#ifndef traceTASK_SWITCHED_OUT #ifndef traceTASK_SWITCHED_OUT
/* Called before a task has been selected to run. pxCurrentTCB holds a pointer /* 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() #define traceTASK_SWITCHED_OUT()
#endif #endif
#ifndef traceTASK_PRIORITY_INHERIT #ifndef traceTASK_PRIORITY_INHERIT
/* Called when a task attempts to take a mutex that is already held by a /* 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 * lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task
that holds the mutex. uxInheritedPriority is the priority the mutex holder * that holds the mutex. uxInheritedPriority is the priority the mutex holder
will inherit (the priority of the task that is attempting to obtain the * will inherit (the priority of the task that is attempting to obtain the
muted. */ * muted. */
#define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority )
#endif #endif
#ifndef traceTASK_PRIORITY_DISINHERIT #ifndef traceTASK_PRIORITY_DISINHERIT
/* Called when a task releases a mutex, the holding of which had resulted in /* Called when a task releases a mutex, the holding of which had resulted in
the task inheriting the priority of a higher priority task. * the task inheriting the priority of a higher priority task.
pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the * pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the
mutex. uxOriginalPriority is the task's configured (base) priority. */ * mutex. uxOriginalPriority is the task's configured (base) priority. */
#define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority )
#endif #endif
#ifndef traceBLOCKING_ON_QUEUE_RECEIVE #ifndef traceBLOCKING_ON_QUEUE_RECEIVE
/* Task is about to block because it cannot read from a /* Task is about to block because it cannot read from a
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore * 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 * upon which the read was attempted. pxCurrentTCB points to the TCB of the
task that attempted the read. */ * task that attempted the read. */
#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
#endif #endif
#ifndef traceBLOCKING_ON_QUEUE_PEEK #ifndef traceBLOCKING_ON_QUEUE_PEEK
/* Task is about to block because it cannot read from a /* Task is about to block because it cannot read from a
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore * 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 * upon which the read was attempted. pxCurrentTCB points to the TCB of the
task that attempted the read. */ * task that attempted the read. */
#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) #define traceBLOCKING_ON_QUEUE_PEEK( pxQueue )
#endif #endif
#ifndef traceBLOCKING_ON_QUEUE_SEND #ifndef traceBLOCKING_ON_QUEUE_SEND
/* Task is about to block because it cannot write to a /* Task is about to block because it cannot write to a
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore * 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 * upon which the write was attempted. pxCurrentTCB points to the TCB of the
task that attempted the write. */ * task that attempted the write. */
#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) #define traceBLOCKING_ON_QUEUE_SEND( pxQueue )
#endif #endif
@ -864,15 +875,17 @@ hold explicit before calling the code. */
#endif #endif
#ifndef configSTACK_DEPTH_TYPE #ifndef configSTACK_DEPTH_TYPE
/* Defaults to uint16_t for backward compatibility, but can be overridden /* 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 #define configSTACK_DEPTH_TYPE uint16_t
#endif #endif
#ifndef configMESSAGE_BUFFER_LENGTH_TYPE #ifndef configMESSAGE_BUFFER_LENGTH_TYPE
/* Defaults to size_t for backward compatibility, but can be overridden /* 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 FreeRTOSConfig.h if lengths will always be less than the number of bytes
in a size_t. */ * in a size_t. */
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t #define configMESSAGE_BUFFER_LENGTH_TYPE size_t
#endif #endif
@ -896,51 +909,56 @@ hold explicit before calling the code. */
#endif #endif
#if ( portTICK_TYPE_IS_ATOMIC == 0 ) #if ( portTICK_TYPE_IS_ATOMIC == 0 )
/* Either variables of tick type cannot be read atomically, or /* Either variables of tick type cannot be read atomically, or
portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when * portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when
the tick count is returned to the standard critical section macros. */ * the tick count is returned to the standard critical section macros. */
#define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL() #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL()
#define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL() #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL()
#define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() #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 ) ) #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) )
#else #else
/* The tick type can be read atomically, so critical sections used when the /* 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_ENTER_CRITICAL()
#define portTICK_TYPE_EXIT_CRITICAL() #define portTICK_TYPE_EXIT_CRITICAL()
#define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0 #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0
#define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) x #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 /* Definitions to allow backward compatibility with FreeRTOS versions prior to
V8 if desired. */ * V8 if desired. */
#ifndef configENABLE_BACKWARD_COMPATIBILITY #ifndef configENABLE_BACKWARD_COMPATIBILITY
#define configENABLE_BACKWARD_COMPATIBILITY 1 #define configENABLE_BACKWARD_COMPATIBILITY 1
#endif #endif
#ifndef configPRINTF #ifndef configPRINTF
/* configPRINTF() was not defined, so define it away to nothing. To use /* configPRINTF() was not defined, so define it away to nothing. To use
configPRINTF() then define it as follows (where MyPrintFunction() is * configPRINTF() then define it as follows (where MyPrintFunction() is
provided by the application writer): * provided by the application writer):
*
void MyPrintFunction(const char *pcFormat, ... ); * void MyPrintFunction(const char *pcFormat, ... );
#define configPRINTF( X ) MyPrintFunction X #define configPRINTF( X ) MyPrintFunction X
*
Then call like a standard printf() function, but placing brackets around * Then call like a standard printf() function, but placing brackets around
all parameters so they are passed as a single parameter. For example: * all parameters so they are passed as a single parameter. For example:
configPRINTF( ("Value = %d", MyVariable) ); */ * configPRINTF( ("Value = %d", MyVariable) ); */
#define configPRINTF( X ) #define configPRINTF( X )
#endif #endif
#ifndef configMAX #ifndef configMAX
/* The application writer has not provided their own MAX macro, so define /* 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 ) ) #define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
#endif #endif
#ifndef configMIN #ifndef configMIN
/* The application writer has not provided their own MAX macro, so define /* 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 ) ) #define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
#endif #endif
@ -967,14 +985,14 @@ V8 if desired. */
#define xTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter #define xTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter
/* Backward compatibility within the scheduler code only - these definitions /* 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 tmrTIMER_CALLBACK TimerCallbackFunction_t
#define pdTASK_CODE TaskFunction_t #define pdTASK_CODE TaskFunction_t
#define xListItem ListItem_t #define xListItem ListItem_t
#define xList List_t #define xList List_t
/* For libraries that break the list data hiding, and access list structure /* 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 #define pxContainer pvContainer
#endif /* configENABLE_BACKWARD_COMPATIBILITY */ #endif /* configENABLE_BACKWARD_COMPATIBILITY */
@ -983,33 +1001,33 @@ V8 if desired. */
#endif #endif
/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even /* 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. * 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 * This constant is not supported by all FreeRTOS ports that include floating
point support. */ * point support. */
#ifndef configUSE_TASK_FPU_SUPPORT #ifndef configUSE_TASK_FPU_SUPPORT
#define configUSE_TASK_FPU_SUPPORT 1 #define configUSE_TASK_FPU_SUPPORT 1
#endif #endif
/* Set configENABLE_MPU to 1 to enable MPU support and 0 to disable it. This is /* 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 #ifndef configENABLE_MPU
#define configENABLE_MPU 0 #define configENABLE_MPU 0
#endif #endif
/* Set configENABLE_FPU to 1 to enable FPU support and 0 to disable it. This is /* 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 #ifndef configENABLE_FPU
#define configENABLE_FPU 1 #define configENABLE_FPU 1
#endif #endif
/* Set configENABLE_TRUSTZONE to 1 enable TrustZone support and 0 to disable it. /* 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 #ifndef configENABLE_TRUSTZONE
#define configENABLE_TRUSTZONE 1 #define configENABLE_TRUSTZONE 1
#endif #endif
/* Set configRUN_FREERTOS_SECURE_ONLY to 1 to run the FreeRTOS ARMv8M port on /* 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 #ifndef configRUN_FREERTOS_SECURE_ONLY
#define configRUN_FREERTOS_SECURE_ONLY 0 #define configRUN_FREERTOS_SECURE_ONLY 0
#endif #endif
@ -1056,7 +1074,8 @@ the Secure Side only. */
* | | | | xTaskCreateRestrictedStatic | | | | * | | | | 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 ) ) ) ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) )
/* /*
@ -1210,7 +1229,6 @@ typedef struct xSTATIC_QUEUE
UBaseType_t uxDummy8; UBaseType_t uxDummy8;
uint8_t ucDummy9; uint8_t ucDummy9;
#endif #endif
} StaticQueue_t; } StaticQueue_t;
typedef StaticQueue_t StaticSemaphore_t; typedef StaticQueue_t StaticSemaphore_t;
@ -1240,7 +1258,6 @@ typedef struct xSTATIC_EVENT_GROUP
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
uint8_t ucDummy4; uint8_t ucDummy4;
#endif #endif
} StaticEventGroup_t; } StaticEventGroup_t;
/* /*
@ -1268,7 +1285,6 @@ typedef struct xSTATIC_TIMER
UBaseType_t uxDummy7; UBaseType_t uxDummy7;
#endif #endif
uint8_t ucDummy8; uint8_t ucDummy8;
} StaticTimer_t; } StaticTimer_t;
/* /*
@ -1303,4 +1319,3 @@ typedef StaticStreamBuffer_t StaticMessageBuffer_t;
#endif #endif
#endif /* INC_FREERTOS_H */ #endif /* INC_FREERTOS_H */

View file

@ -129,4 +129,3 @@
#endif /* STACK_MACROS_H */ #endif /* STACK_MACROS_H */

View file

@ -38,12 +38,13 @@ extern "C" {
#endif #endif
/* Used to hide the implementation of the co-routine control block. The /* Used to hide the implementation of the co-routine control block. The
control block structure however has to be included in the header due to * control block structure however has to be included in the header due to
the macro implementation of the co-routine functionality. */ * the macro implementation of the co-routine functionality. */
typedef void * CoRoutineHandle_t; typedef void * CoRoutineHandle_t;
/* Defines the prototype to which co-routine functions must conform. */ /* Defines the prototype to which co-routine functions must conform. */
typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t ); typedef void (* crCOROUTINE_CODE)( CoRoutineHandle_t,
UBaseType_t );
typedef struct corCoRoutineControlBlock typedef struct corCoRoutineControlBlock
{ {
@ -58,11 +59,11 @@ typedef struct corCoRoutineControlBlock
/** /**
* croutine. h * croutine. h
*<pre> *<pre>
BaseType_t xCoRoutineCreate( * BaseType_t xCoRoutineCreate(
crCOROUTINE_CODE pxCoRoutineCode, * crCOROUTINE_CODE pxCoRoutineCode,
UBaseType_t uxPriority, * UBaseType_t uxPriority,
UBaseType_t uxIndex * UBaseType_t uxIndex
);</pre> * );</pre>
* *
* Create a new co-routine and add it to the list of co-routines that are * Create a new co-routine and add it to the list of co-routines that are
* ready to run. * ready to run.
@ -82,58 +83,60 @@ typedef struct corCoRoutineControlBlock
* list, otherwise an error code defined with ProjDefs.h. * list, otherwise an error code defined with ProjDefs.h.
* *
* Example usage: * Example usage:
<pre> * <pre>
// Co-routine to be created. * // Co-routine to be created.
void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// Variables in co-routines must be declared static if they must maintain value across a blocking call. * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
// This may not be necessary for const variables. * // This may not be necessary for const variables.
static const char cLedToFlash[ 2 ] = { 5, 6 }; * static const char cLedToFlash[ 2 ] = { 5, 6 };
static const TickType_t uxFlashRates[ 2 ] = { 200, 400 }; * static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
*
// Must start every co-routine with a call to crSTART(); * // Must start every co-routine with a call to crSTART();
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// This co-routine just delays for a fixed period, then toggles * // This co-routine just delays for a fixed period, then toggles
// an LED. Two co-routines are created using this function, so * // an LED. Two co-routines are created using this function, so
// the uxIndex parameter is used to tell the co-routine which * // the uxIndex parameter is used to tell the co-routine which
// LED to flash and how int32_t to delay. This assumes xQueue has * // LED to flash and how int32_t to delay. This assumes xQueue has
// already been created. * // already been created.
vParTestToggleLED( cLedToFlash[ uxIndex ] ); * vParTestToggleLED( cLedToFlash[ uxIndex ] );
crDELAY( xHandle, uxFlashRates[ uxIndex ] ); * crDELAY( xHandle, uxFlashRates[ uxIndex ] );
} * }
*
// Must end every co-routine with a call to crEND(); * // Must end every co-routine with a call to crEND();
crEND(); * crEND();
} * }
*
// Function that creates two co-routines. * // Function that creates two co-routines.
void vOtherFunction( void ) * void vOtherFunction( void )
{ * {
uint8_t ucParameterToPass; * uint8_t ucParameterToPass;
TaskHandle_t xHandle; * TaskHandle_t xHandle;
*
// Create two co-routines at priority 0. The first is given index 0 * // Create two co-routines at priority 0. The first is given index 0
// so (from the code above) toggles LED 5 every 200 ticks. The second * // so (from the code above) toggles LED 5 every 200 ticks. The second
// is given index 1 so toggles LED 6 every 400 ticks. * // is given index 1 so toggles LED 6 every 400 ticks.
for( uxIndex = 0; uxIndex < 2; uxIndex++ ) * for( uxIndex = 0; uxIndex < 2; uxIndex++ )
{ * {
xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex ); * xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
} * }
} * }
</pre> * </pre>
* \defgroup xCoRoutineCreate xCoRoutineCreate * \defgroup xCoRoutineCreate xCoRoutineCreate
* \ingroup Tasks * \ingroup Tasks
*/ */
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ); BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode,
UBaseType_t uxPriority,
UBaseType_t uxIndex );
/** /**
* croutine. h * croutine. h
*<pre> *<pre>
void vCoRoutineSchedule( void );</pre> * void vCoRoutineSchedule( void );</pre>
* *
* Run a co-routine. * Run a co-routine.
* *
@ -147,25 +150,25 @@ BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPri
* hook). * hook).
* *
* Example usage: * Example usage:
<pre> * <pre>
// This idle task hook will schedule a co-routine each time it is called. * // This idle task hook will schedule a co-routine each time it is called.
// The rest of the idle task will execute between co-routine calls. * // The rest of the idle task will execute between co-routine calls.
void vApplicationIdleHook( void ) * void vApplicationIdleHook( void )
{ * {
vCoRoutineSchedule(); * vCoRoutineSchedule();
} * }
*
// Alternatively, if you do not require any other part of the idle task to * // Alternatively, if you do not require any other part of the idle task to
// execute, the idle task hook can call vCoRoutineSchedule() within an * // execute, the idle task hook can call vCoRoutineSchedule() within an
// infinite loop. * // infinite loop.
void vApplicationIdleHook( void ) * void vApplicationIdleHook( void )
{ * {
for( ;; ) * for( ;; )
{ * {
vCoRoutineSchedule(); * vCoRoutineSchedule();
} * }
} * }
</pre> * </pre>
* \defgroup vCoRoutineSchedule vCoRoutineSchedule * \defgroup vCoRoutineSchedule vCoRoutineSchedule
* \ingroup Tasks * \ingroup Tasks
*/ */
@ -174,60 +177,62 @@ void vCoRoutineSchedule( void );
/** /**
* croutine. h * croutine. h
* <pre> * <pre>
crSTART( CoRoutineHandle_t xHandle );</pre> * crSTART( CoRoutineHandle_t xHandle );</pre>
* *
* This macro MUST always be called at the start of a co-routine function. * This macro MUST always be called at the start of a co-routine function.
* *
* Example usage: * Example usage:
<pre> * <pre>
// Co-routine to be created. * // Co-routine to be created.
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// Variables in co-routines must be declared static if they must maintain value across a blocking call. * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
static int32_t ulAVariable; * static int32_t ulAVariable;
*
// Must start every co-routine with a call to crSTART(); * // Must start every co-routine with a call to crSTART();
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// Co-routine functionality goes here. * // Co-routine functionality goes here.
} * }
*
// Must end every co-routine with a call to crEND(); * // Must end every co-routine with a call to crEND();
crEND(); * crEND();
}</pre> * }</pre>
* \defgroup crSTART crSTART * \defgroup crSTART crSTART
* \ingroup Tasks * \ingroup Tasks
*/ */
#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0: #define crSTART( pxCRCB ) \
switch( ( ( CRCB_t * ) ( pxCRCB ) )->uxState ) { \
case 0:
/** /**
* croutine. h * croutine. h
* <pre> * <pre>
crEND();</pre> * crEND();</pre>
* *
* This macro MUST always be called at the end of a co-routine function. * This macro MUST always be called at the end of a co-routine function.
* *
* Example usage: * Example usage:
<pre> * <pre>
// Co-routine to be created. * // Co-routine to be created.
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// Variables in co-routines must be declared static if they must maintain value across a blocking call. * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
static int32_t ulAVariable; * static int32_t ulAVariable;
*
// Must start every co-routine with a call to crSTART(); * // Must start every co-routine with a call to crSTART();
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// Co-routine functionality goes here. * // Co-routine functionality goes here.
} * }
*
// Must end every co-routine with a call to crEND(); * // Must end every co-routine with a call to crEND();
crEND(); * crEND();
}</pre> * }</pre>
* \defgroup crSTART crSTART * \defgroup crSTART crSTART
* \ingroup Tasks * \ingroup Tasks
*/ */
@ -237,13 +242,17 @@ void vCoRoutineSchedule( void );
* These macros are intended for internal use by the co-routine implementation * These macros are intended for internal use by the co-routine implementation
* only. The macros should not be used directly by application writers. * only. The macros should not be used directly by application writers.
*/ */
#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): #define crSET_STATE0( xHandle ) \
#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): ( ( CRCB_t * ) ( xHandle ) )->uxState = ( __LINE__ * 2 ); return; \
case ( __LINE__ * 2 ):
#define crSET_STATE1( xHandle ) \
( ( CRCB_t * ) ( xHandle ) )->uxState = ( ( __LINE__ * 2 ) + 1 ); return; \
case ( ( __LINE__ * 2 ) + 1 ):
/** /**
* croutine. h * croutine. h
*<pre> *<pre>
crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre> * crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre>
* *
* Delay a co-routine for a fixed period of time. * Delay a co-routine for a fixed period of time.
* *
@ -260,29 +269,29 @@ void vCoRoutineSchedule( void );
* can be used to convert ticks to milliseconds. * can be used to convert ticks to milliseconds.
* *
* Example usage: * Example usage:
<pre> * <pre>
// Co-routine to be created. * // Co-routine to be created.
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// Variables in co-routines must be declared static if they must maintain value across a blocking call. * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
// This may not be necessary for const variables. * // This may not be necessary for const variables.
// We are to delay for 200ms. * // We are to delay for 200ms.
static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS; * static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
*
// Must start every co-routine with a call to crSTART(); * // Must start every co-routine with a call to crSTART();
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// Delay for 200ms. * // Delay for 200ms.
crDELAY( xHandle, xDelayTime ); * crDELAY( xHandle, xDelayTime );
*
// Do something here. * // Do something here.
} * }
*
// Must end every co-routine with a call to crEND(); * // Must end every co-routine with a call to crEND();
crEND(); * crEND();
}</pre> * }</pre>
* \defgroup crDELAY crDELAY * \defgroup crDELAY crDELAY
* \ingroup Tasks * \ingroup Tasks
*/ */
@ -295,13 +304,13 @@ void vCoRoutineSchedule( void );
/** /**
* <pre> * <pre>
crQUEUE_SEND( * crQUEUE_SEND(
CoRoutineHandle_t xHandle, * CoRoutineHandle_t xHandle,
QueueHandle_t pxQueue, * QueueHandle_t pxQueue,
void *pvItemToQueue, * void *pvItemToQueue,
TickType_t xTicksToWait, * TickType_t xTicksToWait,
BaseType_t *pxResult * BaseType_t *pxResult
)</pre> * )</pre>
* *
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
@ -341,38 +350,38 @@ void vCoRoutineSchedule( void );
* error defined within ProjDefs.h. * error defined within ProjDefs.h.
* *
* Example usage: * Example usage:
<pre> * <pre>
// Co-routine function that blocks for a fixed period then posts a number onto * // Co-routine function that blocks for a fixed period then posts a number onto
// a queue. * // a queue.
static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// Variables in co-routines must be declared static if they must maintain value across a blocking call. * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
static BaseType_t xNumberToPost = 0; * static BaseType_t xNumberToPost = 0;
static BaseType_t xResult; * static BaseType_t xResult;
*
// Co-routines must begin with a call to crSTART(). * // Co-routines must begin with a call to crSTART().
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// This assumes the queue has already been created. * // This assumes the queue has already been created.
crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult ); * crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
*
if( xResult != pdPASS ) * if( xResult != pdPASS )
{ * {
// The message was not posted! * // The message was not posted!
} * }
*
// Increment the number to be posted onto the queue. * // Increment the number to be posted onto the queue.
xNumberToPost++; * xNumberToPost++;
*
// Delay for 100 ticks. * // Delay for 100 ticks.
crDELAY( xHandle, 100 ); * crDELAY( xHandle, 100 );
} * }
*
// Co-routines must end with a call to crEND(). * // Co-routines must end with a call to crEND().
crEND(); * crEND();
}</pre> * }</pre>
* \defgroup crQUEUE_SEND crQUEUE_SEND * \defgroup crQUEUE_SEND crQUEUE_SEND
* \ingroup Tasks * \ingroup Tasks
*/ */
@ -394,13 +403,13 @@ void vCoRoutineSchedule( void );
/** /**
* croutine. h * croutine. h
* <pre> * <pre>
crQUEUE_RECEIVE( * crQUEUE_RECEIVE(
CoRoutineHandle_t xHandle, * CoRoutineHandle_t xHandle,
QueueHandle_t pxQueue, * QueueHandle_t pxQueue,
void *pvBuffer, * void *pvBuffer,
TickType_t xTicksToWait, * TickType_t xTicksToWait,
BaseType_t *pxResult * BaseType_t *pxResult
)</pre> * )</pre>
* *
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
@ -439,32 +448,32 @@ void vCoRoutineSchedule( void );
* an error code as defined within ProjDefs.h. * an error code as defined within ProjDefs.h.
* *
* Example usage: * Example usage:
<pre> * <pre>
// A co-routine receives the number of an LED to flash from a queue. It * // A co-routine receives the number of an LED to flash from a queue. It
// blocks on the queue until the number is received. * // blocks on the queue until the number is received.
static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// Variables in co-routines must be declared static if they must maintain value across a blocking call. * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
static BaseType_t xResult; * static BaseType_t xResult;
static UBaseType_t uxLEDToFlash; * static UBaseType_t uxLEDToFlash;
*
// All co-routines must start with a call to crSTART(). * // All co-routines must start with a call to crSTART().
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// Wait for data to become available on the queue. * // Wait for data to become available on the queue.
crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); * crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
*
if( xResult == pdPASS ) * if( xResult == pdPASS )
{ * {
// We received the LED to flash - flash it! * // We received the LED to flash - flash it!
vParTestToggleLED( uxLEDToFlash ); * vParTestToggleLED( uxLEDToFlash );
} * }
} * }
*
crEND(); * crEND();
}</pre> * }</pre>
* \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
* \ingroup Tasks * \ingroup Tasks
*/ */
@ -486,11 +495,11 @@ void vCoRoutineSchedule( void );
/** /**
* croutine. h * croutine. h
* <pre> * <pre>
crQUEUE_SEND_FROM_ISR( * crQUEUE_SEND_FROM_ISR(
QueueHandle_t pxQueue, * QueueHandle_t pxQueue,
void *pvItemToQueue, * void *pvItemToQueue,
BaseType_t xCoRoutinePreviouslyWoken * BaseType_t xCoRoutinePreviouslyWoken
)</pre> * )</pre>
* *
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
@ -525,55 +534,55 @@ void vCoRoutineSchedule( void );
* the ISR. * the ISR.
* *
* Example usage: * Example usage:
<pre> * <pre>
// A co-routine that blocks on a queue waiting for characters to be received. * // A co-routine that blocks on a queue waiting for characters to be received.
static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
char cRxedChar; * char cRxedChar;
BaseType_t xResult; * BaseType_t xResult;
*
// All co-routines must start with a call to crSTART(). * // All co-routines must start with a call to crSTART().
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// Wait for data to become available on the queue. This assumes the * // Wait for data to become available on the queue. This assumes the
// queue xCommsRxQueue has already been created! * // queue xCommsRxQueue has already been created!
crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); * crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
*
// Was a character received? * // Was a character received?
if( xResult == pdPASS ) * if( xResult == pdPASS )
{ * {
// Process the character here. * // Process the character here.
} * }
} * }
*
// All co-routines must end with a call to crEND(). * // All co-routines must end with a call to crEND().
crEND(); * crEND();
} * }
*
// An ISR that uses a queue to send characters received on a serial port to * // An ISR that uses a queue to send characters received on a serial port to
// a co-routine. * // a co-routine.
void vUART_ISR( void ) * void vUART_ISR( void )
{ * {
char cRxedChar; * char cRxedChar;
BaseType_t xCRWokenByPost = pdFALSE; * BaseType_t xCRWokenByPost = pdFALSE;
*
// We loop around reading characters until there are none left in the UART. * // We loop around reading characters until there are none left in the UART.
while( UART_RX_REG_NOT_EMPTY() ) * while( UART_RX_REG_NOT_EMPTY() )
{ * {
// Obtain the character from the UART. * // Obtain the character from the UART.
cRxedChar = UART_RX_REG; * cRxedChar = UART_RX_REG;
*
// Post the character onto a queue. xCRWokenByPost will be pdFALSE * // Post the character onto a queue. xCRWokenByPost will be pdFALSE
// the first time around the loop. If the post causes a co-routine * // the first time around the loop. If the post causes a co-routine
// to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE. * // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
// In this manner we can ensure that if more than one co-routine is * // In this manner we can ensure that if more than one co-routine is
// blocked on the queue only one is woken by this ISR no matter how * // blocked on the queue only one is woken by this ISR no matter how
// many characters are posted to the queue. * // many characters are posted to the queue.
xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost ); * xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
} * }
}</pre> * }</pre>
* \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
* \ingroup Tasks * \ingroup Tasks
*/ */
@ -583,11 +592,11 @@ void vCoRoutineSchedule( void );
/** /**
* croutine. h * croutine. h
* <pre> * <pre>
crQUEUE_SEND_FROM_ISR( * crQUEUE_SEND_FROM_ISR(
QueueHandle_t pxQueue, * QueueHandle_t pxQueue,
void *pvBuffer, * void *pvBuffer,
BaseType_t * pxCoRoutineWoken * BaseType_t * pxCoRoutineWoken
)</pre> * )</pre>
* *
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
@ -622,71 +631,71 @@ void vCoRoutineSchedule( void );
* pdFALSE. * pdFALSE.
* *
* Example usage: * Example usage:
<pre> * <pre>
// A co-routine that posts a character to a queue then blocks for a fixed * // A co-routine that posts a character to a queue then blocks for a fixed
// period. The character is incremented each time. * // period. The character is incremented each time.
static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) * static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
{ * {
// cChar holds its value while this co-routine is blocked and must therefore * // cChar holds its value while this co-routine is blocked and must therefore
// be declared static. * // be declared static.
static char cCharToTx = 'a'; * static char cCharToTx = 'a';
BaseType_t xResult; * BaseType_t xResult;
*
// All co-routines must start with a call to crSTART(). * // All co-routines must start with a call to crSTART().
crSTART( xHandle ); * crSTART( xHandle );
*
for( ;; ) * for( ;; )
{ * {
// Send the next character to the queue. * // Send the next character to the queue.
crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult ); * crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
*
if( xResult == pdPASS ) * if( xResult == pdPASS )
{ * {
// The character was successfully posted to the queue. * // The character was successfully posted to the queue.
} * }
else * else
{ * {
// Could not post the character to the queue. * // Could not post the character to the queue.
} * }
*
// Enable the UART Tx interrupt to cause an interrupt in this * // Enable the UART Tx interrupt to cause an interrupt in this
// hypothetical UART. The interrupt will obtain the character * // hypothetical UART. The interrupt will obtain the character
// from the queue and send it. * // from the queue and send it.
ENABLE_RX_INTERRUPT(); * ENABLE_RX_INTERRUPT();
*
// Increment to the next character then block for a fixed period. * // Increment to the next character then block for a fixed period.
// cCharToTx will maintain its value across the delay as it is * // cCharToTx will maintain its value across the delay as it is
// declared static. * // declared static.
cCharToTx++; * cCharToTx++;
if( cCharToTx > 'x' ) * if( cCharToTx > 'x' )
{ * {
cCharToTx = 'a'; * cCharToTx = 'a';
} * }
crDELAY( 100 ); * crDELAY( 100 );
} * }
*
// All co-routines must end with a call to crEND(). * // All co-routines must end with a call to crEND().
crEND(); * crEND();
} * }
*
// An ISR that uses a queue to receive characters to send on a UART. * // An ISR that uses a queue to receive characters to send on a UART.
void vUART_ISR( void ) * void vUART_ISR( void )
{ * {
char cCharToTx; * char cCharToTx;
BaseType_t xCRWokenByPost = pdFALSE; * BaseType_t xCRWokenByPost = pdFALSE;
*
while( UART_TX_REG_EMPTY() ) * while( UART_TX_REG_EMPTY() )
{ * {
// Are there any characters in the queue waiting to be sent? * // Are there any characters in the queue waiting to be sent?
// xCRWokenByPost will automatically be set to pdTRUE if a co-routine * // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
// is woken by the post - ensuring that only a single co-routine is * // is woken by the post - ensuring that only a single co-routine is
// woken no matter how many times we go around this loop. * // woken no matter how many times we go around this loop.
if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) ) * if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
{ * {
SEND_CHARACTER( cCharToTx ); * SEND_CHARACTER( cCharToTx );
} * }
} * }
}</pre> * }</pre>
* \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
* \ingroup Tasks * \ingroup Tasks
*/ */
@ -701,7 +710,8 @@ void vCoRoutineSchedule( void );
* Removes the current co-routine from its ready list and places it in the * Removes the current co-routine from its ready list and places it in the
* appropriate delayed list. * appropriate delayed list.
*/ */
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ); void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
List_t * pxEventList );
/* /*
* This function is intended for internal use by the queue implementation only. * This function is intended for internal use by the queue implementation only.

View file

@ -29,13 +29,13 @@
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a /* Each FreeRTOS port has a unique portmacro.h header file. Originally a
pre-processor definition was used to ensure the pre-processor found the correct * pre-processor definition was used to ensure the pre-processor found the correct
portmacro.h file for the port being used. That scheme was deprecated in favour * portmacro.h file for the port being used. That scheme was deprecated in favour
of setting the compiler's include path such that it found the correct * of setting the compiler's include path such that it found the correct
portmacro.h file - removing the need for the constant and allowing the * portmacro.h file - removing the need for the constant and allowing the
portmacro.h file to be located anywhere in relation to the port being used. The * portmacro.h file to be located anywhere in relation to the port being used. The
definitions below remain in the code for backward compatibility only. New * definitions below remain in the code for backward compatibility only. New
projects should not use them. */ * projects should not use them. */
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT #ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
@ -208,16 +208,18 @@ projects should not use them. */
#endif #endif
#ifdef BCC_INDUSTRIAL_PC_PORT #ifdef BCC_INDUSTRIAL_PC_PORT
/* A short file name has to be used in place of the normal /* A short file name has to be used in place of the normal
FreeRTOSConfig.h when using the Borland compiler. */ * FreeRTOSConfig.h when using the Borland compiler. */
#include "frconfig.h" #include "frconfig.h"
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h" #include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
typedef void ( __interrupt __far * pxISR )(); typedef void ( __interrupt __far * pxISR )();
#endif #endif
#ifdef BCC_FLASH_LITE_186_PORT #ifdef BCC_FLASH_LITE_186_PORT
/* A short file name has to be used in place of the normal /* A short file name has to be used in place of the normal
FreeRTOSConfig.h when using the Borland compiler. */ * FreeRTOSConfig.h when using the Borland compiler. */
#include "frconfig.h" #include "frconfig.h"
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
typedef void ( __interrupt __far * pxISR )(); typedef void ( __interrupt __far * pxISR )();
@ -275,4 +277,3 @@ projects should not use them. */
#endif #endif
#endif /* DEPRECATED_DEFINITIONS_H */ #endif /* DEPRECATED_DEFINITIONS_H */

View file

@ -93,8 +93,8 @@ typedef TickType_t EventBits_t;
/** /**
* event_groups.h * event_groups.h
*<pre> *<pre>
EventGroupHandle_t xEventGroupCreate( void ); * EventGroupHandle_t xEventGroupCreate( void );
</pre> * </pre>
* *
* Create a new event group. * Create a new event group.
* *
@ -121,24 +121,24 @@ typedef TickType_t EventBits_t;
* event group then NULL is returned. See http://www.freertos.org/a00111.html * event group then NULL is returned. See http://www.freertos.org/a00111.html
* *
* Example usage: * Example usage:
<pre> * <pre>
// Declare a variable to hold the created event group. * // Declare a variable to hold the created event group.
EventGroupHandle_t xCreatedEventGroup; * EventGroupHandle_t xCreatedEventGroup;
*
// Attempt to create the event group. * // Attempt to create the event group.
xCreatedEventGroup = xEventGroupCreate(); * xCreatedEventGroup = xEventGroupCreate();
*
// Was the event group created successfully? * // Was the event group created successfully?
if( xCreatedEventGroup == NULL ) * if( xCreatedEventGroup == NULL )
{ * {
// The event group was not created because there was insufficient * // The event group was not created because there was insufficient
// FreeRTOS heap available. * // FreeRTOS heap available.
} * }
else * else
{ * {
// The event group was created. * // The event group was created.
} * }
</pre> * </pre>
* \defgroup xEventGroupCreate xEventGroupCreate * \defgroup xEventGroupCreate xEventGroupCreate
* \ingroup EventGroup * \ingroup EventGroup
*/ */
@ -149,8 +149,8 @@ typedef TickType_t EventBits_t;
/** /**
* event_groups.h * event_groups.h
*<pre> *<pre>
EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer ); * EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
</pre> * </pre>
* *
* Create a new event group. * Create a new event group.
* *
@ -180,20 +180,20 @@ typedef TickType_t EventBits_t;
* returned. If pxEventGroupBuffer was NULL then NULL is returned. * returned. If pxEventGroupBuffer was NULL then NULL is returned.
* *
* Example usage: * Example usage:
<pre> * <pre>
// StaticEventGroup_t is a publicly accessible structure that has the same * // StaticEventGroup_t is a publicly accessible structure that has the same
// size and alignment requirements as the real event group structure. It is * // size and alignment requirements as the real event group structure. It is
// provided as a mechanism for applications to know the size of the event * // provided as a mechanism for applications to know the size of the event
// group (which is dependent on the architecture and configuration file * // group (which is dependent on the architecture and configuration file
// settings) without breaking the strict data hiding policy by exposing the * // settings) without breaking the strict data hiding policy by exposing the
// real event group internals. This StaticEventGroup_t variable is passed * // real event group internals. This StaticEventGroup_t variable is passed
// into the xSemaphoreCreateEventGroupStatic() function and is used to store * // into the xSemaphoreCreateEventGroupStatic() function and is used to store
// the event group's data structures * // the event group's data structures
StaticEventGroup_t xEventGroupBuffer; * StaticEventGroup_t xEventGroupBuffer;
*
// Create the event group without dynamically allocating any memory. * // Create the event group without dynamically allocating any memory.
xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer ); * xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
</pre> * </pre>
*/ */
#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION; EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
@ -202,12 +202,12 @@ typedef TickType_t EventBits_t;
/** /**
* event_groups.h * event_groups.h
*<pre> *<pre>
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, * EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor, * const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit, * const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits, * const BaseType_t xWaitForAllBits,
const TickType_t xTicksToWait ); * const TickType_t xTicksToWait );
</pre> * </pre>
* *
* [Potentially] block to wait for one or more bits to be set within a * [Potentially] block to wait for one or more bits to be set within a
* previously created event group. * previously created event group.
@ -251,53 +251,57 @@ typedef TickType_t EventBits_t;
* pdTRUE. * pdTRUE.
* *
* Example usage: * Example usage:
<pre> * <pre>
#define BIT_0 ( 1 << 0 ) #define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 ) #define BIT_4 ( 1 << 4 )
*
void aFunction( EventGroupHandle_t xEventGroup ) * void aFunction( EventGroupHandle_t xEventGroup )
{ * {
EventBits_t uxBits; * EventBits_t uxBits;
const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; * const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
*
// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within * // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
// the event group. Clear the bits before exiting. * // the event group. Clear the bits before exiting.
uxBits = xEventGroupWaitBits( * uxBits = xEventGroupWaitBits(
xEventGroup, // The event group being tested. * xEventGroup, // The event group being tested.
BIT_0 | BIT_4, // The bits within the event group to wait for. * BIT_0 | BIT_4, // The bits within the event group to wait for.
pdTRUE, // BIT_0 and BIT_4 should be cleared before returning. * pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
pdFALSE, // Don't wait for both bits, either bit will do. * pdFALSE, // Don't wait for both bits, either bit will do.
xTicksToWait ); // Wait a maximum of 100ms for either bit to be set. * xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
*
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
{ * {
// xEventGroupWaitBits() returned because both bits were set. * // xEventGroupWaitBits() returned because both bits were set.
} * }
else if( ( uxBits & BIT_0 ) != 0 ) * else if( ( uxBits & BIT_0 ) != 0 )
{ * {
// xEventGroupWaitBits() returned because just BIT_0 was set. * // xEventGroupWaitBits() returned because just BIT_0 was set.
} * }
else if( ( uxBits & BIT_4 ) != 0 ) * else if( ( uxBits & BIT_4 ) != 0 )
{ * {
// xEventGroupWaitBits() returned because just BIT_4 was set. * // xEventGroupWaitBits() returned because just BIT_4 was set.
} * }
else * else
{ * {
// xEventGroupWaitBits() returned because xTicksToWait ticks passed * // xEventGroupWaitBits() returned because xTicksToWait ticks passed
// without either BIT_0 or BIT_4 becoming set. * // without either BIT_0 or BIT_4 becoming set.
} * }
} * }
</pre> * </pre>
* \defgroup xEventGroupWaitBits xEventGroupWaitBits * \defgroup xEventGroupWaitBits xEventGroupWaitBits
* \ingroup EventGroup * \ingroup EventGroup
*/ */
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/** /**
* event_groups.h * event_groups.h
*<pre> *<pre>
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ); * EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
</pre> * </pre>
* *
* Clear bits within an event group. This function cannot be called from an * Clear bits within an event group. This function cannot be called from an
* interrupt. * interrupt.
@ -311,50 +315,51 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits
* @return The value of the event group before the specified bits were cleared. * @return The value of the event group before the specified bits were cleared.
* *
* Example usage: * Example usage:
<pre> * <pre>
#define BIT_0 ( 1 << 0 ) #define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 ) #define BIT_4 ( 1 << 4 )
*
void aFunction( EventGroupHandle_t xEventGroup ) * void aFunction( EventGroupHandle_t xEventGroup )
{ * {
EventBits_t uxBits; * EventBits_t uxBits;
*
// Clear bit 0 and bit 4 in xEventGroup. * // Clear bit 0 and bit 4 in xEventGroup.
uxBits = xEventGroupClearBits( * uxBits = xEventGroupClearBits(
xEventGroup, // The event group being updated. * xEventGroup, // The event group being updated.
BIT_0 | BIT_4 );// The bits being cleared. * BIT_0 | BIT_4 );// The bits being cleared.
*
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
{ * {
// Both bit 0 and bit 4 were set before xEventGroupClearBits() was * // Both bit 0 and bit 4 were set before xEventGroupClearBits() was
// called. Both will now be clear (not set). * // called. Both will now be clear (not set).
} * }
else if( ( uxBits & BIT_0 ) != 0 ) * else if( ( uxBits & BIT_0 ) != 0 )
{ * {
// Bit 0 was set before xEventGroupClearBits() was called. It will * // Bit 0 was set before xEventGroupClearBits() was called. It will
// now be clear. * // now be clear.
} * }
else if( ( uxBits & BIT_4 ) != 0 ) * else if( ( uxBits & BIT_4 ) != 0 )
{ * {
// Bit 4 was set before xEventGroupClearBits() was called. It will * // Bit 4 was set before xEventGroupClearBits() was called. It will
// now be clear. * // now be clear.
} * }
else * else
{ * {
// Neither bit 0 nor bit 4 were set in the first place. * // Neither bit 0 nor bit 4 were set in the first place.
} * }
} * }
</pre> * </pre>
* \defgroup xEventGroupClearBits xEventGroupClearBits * \defgroup xEventGroupClearBits xEventGroupClearBits
* \ingroup EventGroup * \ingroup EventGroup
*/ */
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
/** /**
* event_groups.h * event_groups.h
*<pre> *<pre>
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); * BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
</pre> * </pre>
* *
* A version of xEventGroupClearBits() that can be called from an interrupt. * A version of xEventGroupClearBits() that can be called from an interrupt.
* *
@ -379,32 +384,33 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
* if the timer service queue was full. * if the timer service queue was full.
* *
* Example usage: * Example usage:
<pre> * <pre>
#define BIT_0 ( 1 << 0 ) #define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 ) #define BIT_4 ( 1 << 4 )
*
// An event group which it is assumed has already been created by a call to * // An event group which it is assumed has already been created by a call to
// xEventGroupCreate(). * // xEventGroupCreate().
EventGroupHandle_t xEventGroup; * EventGroupHandle_t xEventGroup;
*
void anInterruptHandler( void ) * void anInterruptHandler( void )
{ * {
// Clear bit 0 and bit 4 in xEventGroup. * // Clear bit 0 and bit 4 in xEventGroup.
xResult = xEventGroupClearBitsFromISR( * xResult = xEventGroupClearBitsFromISR(
xEventGroup, // The event group being updated. * xEventGroup, // The event group being updated.
BIT_0 | BIT_4 ); // The bits being set. * BIT_0 | BIT_4 ); // The bits being set.
*
if( xResult == pdPASS ) * if( xResult == pdPASS )
{ * {
// The message was posted successfully. * // The message was posted successfully.
} * }
} * }
</pre> * </pre>
* \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
* \ingroup EventGroup * \ingroup EventGroup
*/ */
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
#else #else
#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ) #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
#endif #endif
@ -412,8 +418,8 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
/** /**
* event_groups.h * event_groups.h
*<pre> *<pre>
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); * EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
</pre> * </pre>
* *
* Set bits within an event group. * Set bits within an event group.
* This function cannot be called from an interrupt. xEventGroupSetBitsFromISR() * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR()
@ -439,55 +445,56 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBit
* event group value before the call to xEventGroupSetBits() returns. * event group value before the call to xEventGroupSetBits() returns.
* *
* Example usage: * Example usage:
<pre> * <pre>
#define BIT_0 ( 1 << 0 ) #define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 ) #define BIT_4 ( 1 << 4 )
*
void aFunction( EventGroupHandle_t xEventGroup ) * void aFunction( EventGroupHandle_t xEventGroup )
{ * {
EventBits_t uxBits; * EventBits_t uxBits;
*
// Set bit 0 and bit 4 in xEventGroup. * // Set bit 0 and bit 4 in xEventGroup.
uxBits = xEventGroupSetBits( * uxBits = xEventGroupSetBits(
xEventGroup, // The event group being updated. * xEventGroup, // The event group being updated.
BIT_0 | BIT_4 );// The bits being set. * BIT_0 | BIT_4 );// The bits being set.
*
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
{ * {
// Both bit 0 and bit 4 remained set when the function returned. * // Both bit 0 and bit 4 remained set when the function returned.
} * }
else if( ( uxBits & BIT_0 ) != 0 ) * else if( ( uxBits & BIT_0 ) != 0 )
{ * {
// Bit 0 remained set when the function returned, but bit 4 was * // Bit 0 remained set when the function returned, but bit 4 was
// cleared. It might be that bit 4 was cleared automatically as a * // cleared. It might be that bit 4 was cleared automatically as a
// task that was waiting for bit 4 was removed from the Blocked * // task that was waiting for bit 4 was removed from the Blocked
// state. * // state.
} * }
else if( ( uxBits & BIT_4 ) != 0 ) * else if( ( uxBits & BIT_4 ) != 0 )
{ * {
// Bit 4 remained set when the function returned, but bit 0 was * // Bit 4 remained set when the function returned, but bit 0 was
// cleared. It might be that bit 0 was cleared automatically as a * // cleared. It might be that bit 0 was cleared automatically as a
// task that was waiting for bit 0 was removed from the Blocked * // task that was waiting for bit 0 was removed from the Blocked
// state. * // state.
} * }
else * else
{ * {
// Neither bit 0 nor bit 4 remained set. It might be that a task * // Neither bit 0 nor bit 4 remained set. It might be that a task
// was waiting for both of the bits to be set, and the bits were * // was waiting for both of the bits to be set, and the bits were
// cleared as the task left the Blocked state. * // cleared as the task left the Blocked state.
} * }
} * }
</pre> * </pre>
* \defgroup xEventGroupSetBits xEventGroupSetBits * \defgroup xEventGroupSetBits xEventGroupSetBits
* \ingroup EventGroup * \ingroup EventGroup
*/ */
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
/** /**
* event_groups.h * event_groups.h
*<pre> *<pre>
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
</pre> * </pre>
* *
* A version of xEventGroupSetBits() that can be called from an interrupt. * A version of xEventGroupSetBits() that can be called from an interrupt.
* *
@ -520,43 +527,45 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
* if the timer service queue was full. * if the timer service queue was full.
* *
* Example usage: * Example usage:
<pre> * <pre>
#define BIT_0 ( 1 << 0 ) #define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 ) #define BIT_4 ( 1 << 4 )
*
// An event group which it is assumed has already been created by a call to * // An event group which it is assumed has already been created by a call to
// xEventGroupCreate(). * // xEventGroupCreate().
EventGroupHandle_t xEventGroup; * EventGroupHandle_t xEventGroup;
*
void anInterruptHandler( void ) * void anInterruptHandler( void )
{ * {
BaseType_t xHigherPriorityTaskWoken, xResult; * BaseType_t xHigherPriorityTaskWoken, xResult;
*
// xHigherPriorityTaskWoken must be initialised to pdFALSE. * // xHigherPriorityTaskWoken must be initialised to pdFALSE.
xHigherPriorityTaskWoken = pdFALSE; * xHigherPriorityTaskWoken = pdFALSE;
*
// Set bit 0 and bit 4 in xEventGroup. * // Set bit 0 and bit 4 in xEventGroup.
xResult = xEventGroupSetBitsFromISR( * xResult = xEventGroupSetBitsFromISR(
xEventGroup, // The event group being updated. * xEventGroup, // The event group being updated.
BIT_0 | BIT_4 // The bits being set. * BIT_0 | BIT_4 // The bits being set.
&xHigherPriorityTaskWoken ); * &xHigherPriorityTaskWoken );
*
// Was the message posted successfully? * // Was the message posted successfully?
if( xResult == pdPASS ) * if( xResult == pdPASS )
{ * {
// If xHigherPriorityTaskWoken is now set to pdTRUE then a context * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context
// switch should be requested. The macro used is port specific and * // switch should be requested. The macro used is port specific and
// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - * // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
// refer to the documentation page for the port being used. * // refer to the documentation page for the port being used.
portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} * }
} * }
</pre> * </pre>
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
* \ingroup EventGroup * \ingroup EventGroup
*/ */
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
#else #else
#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ) #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
#endif #endif
@ -564,11 +573,11 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
/** /**
* event_groups.h * event_groups.h
*<pre> *<pre>
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, * EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet, * const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor, * const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait ); * TickType_t xTicksToWait );
</pre> * </pre>
* *
* Atomically set bits within an event group, then wait for a combination of * Atomically set bits within an event group, then wait for a combination of
* bits to be set within the same event group. This functionality is typically * bits to be set within the same event group. This functionality is typically
@ -607,92 +616,95 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_
* automatically cleared. * automatically cleared.
* *
* Example usage: * Example usage:
<pre> * <pre>
// Bits used by the three tasks. * // Bits used by the three tasks.
#define TASK_0_BIT ( 1 << 0 ) #define TASK_0_BIT ( 1 << 0 )
#define TASK_1_BIT ( 1 << 1 ) #define TASK_1_BIT ( 1 << 1 )
#define TASK_2_BIT ( 1 << 2 ) #define TASK_2_BIT ( 1 << 2 )
*
#define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT ) #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
*
// Use an event group to synchronise three tasks. It is assumed this event * // Use an event group to synchronise three tasks. It is assumed this event
// group has already been created elsewhere. * // group has already been created elsewhere.
EventGroupHandle_t xEventBits; * EventGroupHandle_t xEventBits;
*
void vTask0( void *pvParameters ) * void vTask0( void *pvParameters )
{ * {
EventBits_t uxReturn; * EventBits_t uxReturn;
TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; * TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
*
for( ;; ) * for( ;; )
{ * {
// Perform task functionality here. * // Perform task functionality here.
*
// Set bit 0 in the event flag to note this task has reached the * // Set bit 0 in the event flag to note this task has reached the
// sync point. The other two tasks will set the other two bits defined * // sync point. The other two tasks will set the other two bits defined
// by ALL_SYNC_BITS. All three tasks have reached the synchronisation * // by ALL_SYNC_BITS. All three tasks have reached the synchronisation
// point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms * // point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms
// for this to happen. * // for this to happen.
uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait ); * uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
*
if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS ) * if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
{ * {
// All three tasks reached the synchronisation point before the call * // All three tasks reached the synchronisation point before the call
// to xEventGroupSync() timed out. * // to xEventGroupSync() timed out.
} * }
} * }
} * }
*
void vTask1( void *pvParameters ) * void vTask1( void *pvParameters )
{ * {
for( ;; ) * for( ;; )
{ * {
// Perform task functionality here. * // Perform task functionality here.
*
// Set bit 1 in the event flag to note this task has reached the * // Set bit 1 in the event flag to note this task has reached the
// synchronisation point. The other two tasks will set the other two * // synchronisation point. The other two tasks will set the other two
// bits defined by ALL_SYNC_BITS. All three tasks have reached the * // bits defined by ALL_SYNC_BITS. All three tasks have reached the
// synchronisation point when all the ALL_SYNC_BITS are set. Wait * // synchronisation point when all the ALL_SYNC_BITS are set. Wait
// indefinitely for this to happen. * // indefinitely for this to happen.
xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY ); * xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
*
// xEventGroupSync() was called with an indefinite block time, so * // xEventGroupSync() was called with an indefinite block time, so
// this task will only reach here if the syncrhonisation was made by all * // this task will only reach here if the syncrhonisation was made by all
// three tasks, so there is no need to test the return value. * // three tasks, so there is no need to test the return value.
} * }
} * }
*
void vTask2( void *pvParameters ) * void vTask2( void *pvParameters )
{ * {
for( ;; ) * for( ;; )
{ * {
// Perform task functionality here. * // Perform task functionality here.
*
// Set bit 2 in the event flag to note this task has reached the * // Set bit 2 in the event flag to note this task has reached the
// synchronisation point. The other two tasks will set the other two * // synchronisation point. The other two tasks will set the other two
// bits defined by ALL_SYNC_BITS. All three tasks have reached the * // bits defined by ALL_SYNC_BITS. All three tasks have reached the
// synchronisation point when all the ALL_SYNC_BITS are set. Wait * // synchronisation point when all the ALL_SYNC_BITS are set. Wait
// indefinitely for this to happen. * // indefinitely for this to happen.
xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY ); * xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
*
// xEventGroupSync() was called with an indefinite block time, so * // xEventGroupSync() was called with an indefinite block time, so
// this task will only reach here if the syncrhonisation was made by all * // this task will only reach here if the syncrhonisation was made by all
// three tasks, so there is no need to test the return value. * // three tasks, so there is no need to test the return value.
} * }
} * }
*
</pre> * </pre>
* \defgroup xEventGroupSync xEventGroupSync * \defgroup xEventGroupSync xEventGroupSync
* \ingroup EventGroup * \ingroup EventGroup
*/ */
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/** /**
* event_groups.h * event_groups.h
*<pre> *<pre>
EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup ); * EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
</pre> * </pre>
* *
* Returns the current value of the bits in an event group. This function * Returns the current value of the bits in an event group. This function
* cannot be used from an interrupt. * cannot be used from an interrupt.
@ -709,8 +721,8 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t u
/** /**
* event_groups.h * event_groups.h
*<pre> *<pre>
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ); * EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
</pre> * </pre>
* *
* A version of xEventGroupGetBits() that can be called from an ISR. * A version of xEventGroupGetBits() that can be called from an ISR.
* *
@ -726,8 +738,8 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG
/** /**
* event_groups.h * event_groups.h
*<pre> *<pre>
void xEventGroupDelete( EventGroupHandle_t xEventGroup ); * void xEventGroupDelete( EventGroupHandle_t xEventGroup );
</pre> * </pre>
* *
* Delete an event group that was previously created by a call to * Delete an event group that was previously created by a call to
* xEventGroupCreate(). Tasks that are blocked on the event group will be * xEventGroupCreate(). Tasks that are blocked on the event group will be
@ -738,13 +750,16 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
/* For internal use only. */ /* For internal use only. */
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; void vEventGroupSetBitsCallback( void * pvEventGroup,
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
void vEventGroupClearBitsCallback( void * pvEventGroup,
const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) PRIVILEGED_FUNCTION; UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) PRIVILEGED_FUNCTION;
void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; void vEventGroupSetNumber( void * xEventGroup,
UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -752,5 +767,3 @@ void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToCl
#endif #endif
#endif /* EVENT_GROUPS_H */ #endif /* EVENT_GROUPS_H */

View file

@ -96,10 +96,10 @@ extern "C" {
#endif #endif
/* Macros that can be used to place known values within the list structures, /* Macros that can be used to place known values within the list structures,
then check that the known values do not get corrupted during the execution of * then check that the known values do not get corrupted during the execution of
the application. These may catch the list data structures being overwritten in * the application. These may catch the list data structures being overwritten in
memory. They will not catch data errors caused by incorrect configuration or * memory. They will not catch data errors caused by incorrect configuration or
use of FreeRTOS.*/ * use of FreeRTOS.*/
#if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
/* Define the macros to do nothing. */ /* Define the macros to do nothing. */
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
@ -112,7 +112,7 @@ use of FreeRTOS.*/
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) #define listTEST_LIST_ITEM_INTEGRITY( pxItem )
#define listTEST_LIST_INTEGRITY( pxList ) #define listTEST_LIST_INTEGRITY( pxList )
#else #else /* if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) */
/* Define macros that add new members into the list structures. */ /* Define macros that add new members into the list structures. */
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
@ -126,7 +126,7 @@ use of FreeRTOS.*/
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
/* Define macros that will assert if one of the structure members does not /* Define macros that will assert if one of the structure members does not
contain its expected value. */ * contain its expected value. */
#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
#define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ #endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
@ -365,7 +365,8 @@ void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
* \page vListInsert vListInsert * \page vListInsert vListInsert
* \ingroup LinkedList * \ingroup LinkedList
*/ */
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; void vListInsert( List_t * const pxList,
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
/* /*
* Insert a list item into a list. The item will be inserted in a position * Insert a list item into a list. The item will be inserted in a position
@ -386,7 +387,8 @@ void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIV
* \page vListInsertEnd vListInsertEnd * \page vListInsertEnd vListInsertEnd
* \ingroup LinkedList * \ingroup LinkedList
*/ */
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; void vListInsertEnd( List_t * const pxList,
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
/* /*
* Remove an item from a list. The list item has a pointer to the list that * Remove an item from a list. The list item has a pointer to the list that
@ -407,5 +409,4 @@ UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTIO
} }
#endif #endif
#endif #endif /* ifndef LIST_H */

View file

@ -85,9 +85,9 @@ typedef void * MessageBufferHandle_t;
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * <pre>
MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes ); * MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
</pre> * </pre>
* *
* Creates a new message buffer using dynamically allocated memory. See * Creates a new message buffer using dynamically allocated memory. See
* xMessageBufferCreateStatic() for a version that uses statically allocated * xMessageBufferCreateStatic() for a version that uses statically allocated
@ -111,30 +111,30 @@ MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
* buffer. * buffer.
* *
* Example use: * Example use:
<pre> * <pre>
*
void vAFunction( void ) * void vAFunction( void )
{ * {
MessageBufferHandle_t xMessageBuffer; * MessageBufferHandle_t xMessageBuffer;
const size_t xMessageBufferSizeBytes = 100; * const size_t xMessageBufferSizeBytes = 100;
*
// Create a message buffer that can hold 100 bytes. The memory used to hold * // Create a message buffer that can hold 100 bytes. The memory used to hold
// both the message buffer structure and the messages themselves is allocated * // both the message buffer structure and the messages themselves is allocated
// dynamically. Each message added to the buffer consumes an additional 4 * // dynamically. Each message added to the buffer consumes an additional 4
// bytes which are used to hold the lengh of the message. * // bytes which are used to hold the lengh of the message.
xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes ); * xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
*
if( xMessageBuffer == NULL ) * if( xMessageBuffer == NULL )
{ * {
// There was not enough heap memory space available to create the * // There was not enough heap memory space available to create the
// message buffer. * // message buffer.
} * }
else * else
{ * {
// The message buffer was created successfully and can now be used. * // The message buffer was created successfully and can now be used.
} * }
*
</pre> * </pre>
* \defgroup xMessageBufferCreate xMessageBufferCreate * \defgroup xMessageBufferCreate xMessageBufferCreate
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
@ -143,11 +143,11 @@ const size_t xMessageBufferSizeBytes = 100;
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * <pre>
MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes, * MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
uint8_t *pucMessageBufferStorageArea, * uint8_t *pucMessageBufferStorageArea,
StaticMessageBuffer_t *pxStaticMessageBuffer ); * StaticMessageBuffer_t *pxStaticMessageBuffer );
</pre> * </pre>
* Creates a new message buffer using statically allocated memory. See * Creates a new message buffer using statically allocated memory. See
* xMessageBufferCreate() for a version that uses dynamically allocated memory. * xMessageBufferCreate() for a version that uses dynamically allocated memory.
* *
@ -172,35 +172,35 @@ MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
* pxStaticmessageBuffer are NULL then NULL is returned. * pxStaticmessageBuffer are NULL then NULL is returned.
* *
* Example use: * Example use:
<pre> * <pre>
*
// Used to dimension the array used to hold the messages. The available space * // Used to dimension the array used to hold the messages. The available space
// will actually be one less than this, so 999. * // will actually be one less than this, so 999.
#define STORAGE_SIZE_BYTES 1000 #define STORAGE_SIZE_BYTES 1000
*
// Defines the memory that will actually hold the messages within the message * // Defines the memory that will actually hold the messages within the message
// buffer. * // buffer.
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; * static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
*
// The variable used to hold the message buffer structure. * // The variable used to hold the message buffer structure.
StaticMessageBuffer_t xMessageBufferStruct; * StaticMessageBuffer_t xMessageBufferStruct;
*
void MyFunction( void ) * void MyFunction( void )
{ * {
MessageBufferHandle_t xMessageBuffer; * MessageBufferHandle_t xMessageBuffer;
*
xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ), * xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ),
ucBufferStorage, * ucBufferStorage,
&xMessageBufferStruct ); * &xMessageBufferStruct );
*
// As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer * // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
// parameters were NULL, xMessageBuffer will not be NULL, and can be used to * // parameters were NULL, xMessageBuffer will not be NULL, and can be used to
// reference the created message buffer in other message buffer API calls. * // reference the created message buffer in other message buffer API calls.
*
// Other code that uses the message buffer can go here. * // Other code that uses the message buffer can go here.
} * }
*
</pre> * </pre>
* \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
@ -209,12 +209,12 @@ MessageBufferHandle_t xMessageBuffer;
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * <pre>
size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer, * size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
const void *pvTxData, * const void *pvTxData,
size_t xDataLengthBytes, * size_t xDataLengthBytes,
TickType_t xTicksToWait ); * TickType_t xTicksToWait );
<pre> * <pre>
* *
* Sends a discrete message to the message buffer. The message can be any * Sends a discrete message to the message buffer. The message can be any
* length that fits within the buffer's free space, and is copied into the * length that fits within the buffer's free space, and is copied into the
@ -271,35 +271,35 @@ size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
* time out then xDataLengthBytes is returned. * time out then xDataLengthBytes is returned.
* *
* Example use: * Example use:
<pre> * <pre>
void vAFunction( MessageBufferHandle_t xMessageBuffer ) * void vAFunction( MessageBufferHandle_t xMessageBuffer )
{ * {
size_t xBytesSent; * size_t xBytesSent;
uint8_t ucArrayToSend[] = { 0, 1, 2, 3 }; * uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
char *pcStringToSend = "String to send"; * char *pcStringToSend = "String to send";
const TickType_t x100ms = pdMS_TO_TICKS( 100 ); * const TickType_t x100ms = pdMS_TO_TICKS( 100 );
*
// Send an array to the message buffer, blocking for a maximum of 100ms to * // Send an array to the message buffer, blocking for a maximum of 100ms to
// wait for enough space to be available in the message buffer. * // wait for enough space to be available in the message buffer.
xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms ); * xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
*
if( xBytesSent != sizeof( ucArrayToSend ) ) * if( xBytesSent != sizeof( ucArrayToSend ) )
{ * {
// The call to xMessageBufferSend() times out before there was enough * // The call to xMessageBufferSend() times out before there was enough
// space in the buffer for the data to be written. * // space in the buffer for the data to be written.
} * }
*
// Send the string to the message buffer. Return immediately if there is * // Send the string to the message buffer. Return immediately if there is
// not enough space in the buffer. * // not enough space in the buffer.
xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 ); * xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
*
if( xBytesSent != strlen( pcStringToSend ) ) * if( xBytesSent != strlen( pcStringToSend ) )
{ * {
// The string could not be added to the message buffer because there was * // The string could not be added to the message buffer because there was
// not enough free space in the buffer. * // not enough free space in the buffer.
} * }
} * }
</pre> * </pre>
* \defgroup xMessageBufferSend xMessageBufferSend * \defgroup xMessageBufferSend xMessageBufferSend
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
@ -308,12 +308,12 @@ const TickType_t x100ms = pdMS_TO_TICKS( 100 );
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * <pre>
size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer, * size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
const void *pvTxData, * const void *pvTxData,
size_t xDataLengthBytes, * size_t xDataLengthBytes,
BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t *pxHigherPriorityTaskWoken );
<pre> * <pre>
* *
* Interrupt safe version of the API function that sends a discrete message to * Interrupt safe version of the API function that sends a discrete message to
* the message buffer. The message can be any length that fits within the * the message buffer. The message can be any length that fits within the
@ -371,39 +371,39 @@ size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
* then 0 is returned, otherwise xDataLengthBytes is returned. * then 0 is returned, otherwise xDataLengthBytes is returned.
* *
* Example use: * Example use:
<pre> * <pre>
// A message buffer that has already been created. * // A message buffer that has already been created.
MessageBufferHandle_t xMessageBuffer; * MessageBufferHandle_t xMessageBuffer;
*
void vAnInterruptServiceRoutine( void ) * void vAnInterruptServiceRoutine( void )
{ * {
size_t xBytesSent; * size_t xBytesSent;
char *pcStringToSend = "String to send"; * char *pcStringToSend = "String to send";
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
*
// Attempt to send the string to the message buffer. * // Attempt to send the string to the message buffer.
xBytesSent = xMessageBufferSendFromISR( xMessageBuffer, * xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
( void * ) pcStringToSend, * ( void * ) pcStringToSend,
strlen( pcStringToSend ), * strlen( pcStringToSend ),
&xHigherPriorityTaskWoken ); * &xHigherPriorityTaskWoken );
*
if( xBytesSent != strlen( pcStringToSend ) ) * if( xBytesSent != strlen( pcStringToSend ) )
{ * {
// The string could not be added to the message buffer because there was * // The string could not be added to the message buffer because there was
// not enough free space in the buffer. * // not enough free space in the buffer.
} * }
*
// If xHigherPriorityTaskWoken was set to pdTRUE inside * // If xHigherPriorityTaskWoken was set to pdTRUE inside
// xMessageBufferSendFromISR() then a task that has a priority above the * // xMessageBufferSendFromISR() then a task that has a priority above the
// priority of the currently executing task was unblocked and a context * // priority of the currently executing task was unblocked and a context
// switch should be performed to ensure the ISR returns to the unblocked * // switch should be performed to ensure the ISR returns to the unblocked
// task. In most FreeRTOS ports this is done by simply passing * // task. In most FreeRTOS ports this is done by simply passing
// xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
// variables value, and perform the context switch if necessary. Check the * // variables value, and perform the context switch if necessary. Check the
// documentation for the port in use for port specific instructions. * // documentation for the port in use for port specific instructions.
portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} * }
</pre> * </pre>
* \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
@ -412,12 +412,12 @@ BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * <pre>
size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer, * size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
void *pvRxData, * void *pvRxData,
size_t xBufferLengthBytes, * size_t xBufferLengthBytes,
TickType_t xTicksToWait ); * TickType_t xTicksToWait );
</pre> * </pre>
* *
* Receives a discrete message from a message buffer. Messages can be of * Receives a discrete message from a message buffer. Messages can be of
* variable length and are copied out of the buffer. * variable length and are copied out of the buffer.
@ -470,28 +470,28 @@ size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
* zero is returned. * zero is returned.
* *
* Example use: * Example use:
<pre> * <pre>
void vAFunction( MessageBuffer_t xMessageBuffer ) * void vAFunction( MessageBuffer_t xMessageBuffer )
{ * {
uint8_t ucRxData[ 20 ]; * uint8_t ucRxData[ 20 ];
size_t xReceivedBytes; * size_t xReceivedBytes;
const TickType_t xBlockTime = pdMS_TO_TICKS( 20 ); * const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
*
// Receive the next message from the message buffer. Wait in the Blocked * // Receive the next message from the message buffer. Wait in the Blocked
// state (so not using any CPU processing time) for a maximum of 100ms for * // state (so not using any CPU processing time) for a maximum of 100ms for
// a message to become available. * // a message to become available.
xReceivedBytes = xMessageBufferReceive( xMessageBuffer, * xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
( void * ) ucRxData, * ( void * ) ucRxData,
sizeof( ucRxData ), * sizeof( ucRxData ),
xBlockTime ); * xBlockTime );
*
if( xReceivedBytes > 0 ) * if( xReceivedBytes > 0 )
{ * {
// A ucRxData contains a message that is xReceivedBytes long. Process * // A ucRxData contains a message that is xReceivedBytes long. Process
// the message here.... * // the message here....
} * }
} * }
</pre> * </pre>
* \defgroup xMessageBufferReceive xMessageBufferReceive * \defgroup xMessageBufferReceive xMessageBufferReceive
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
@ -501,12 +501,12 @@ const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * <pre>
size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer, * size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
void *pvRxData, * void *pvRxData,
size_t xBufferLengthBytes, * size_t xBufferLengthBytes,
BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t *pxHigherPriorityTaskWoken );
</pre> * </pre>
* *
* An interrupt safe version of the API function that receives a discrete * An interrupt safe version of the API function that receives a discrete
* message from a message buffer. Messages can be of variable length and are * message from a message buffer. Messages can be of variable length and are
@ -560,39 +560,39 @@ size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
* any. * any.
* *
* Example use: * Example use:
<pre> * <pre>
// A message buffer that has already been created. * // A message buffer that has already been created.
MessageBuffer_t xMessageBuffer; * MessageBuffer_t xMessageBuffer;
*
void vAnInterruptServiceRoutine( void ) * void vAnInterruptServiceRoutine( void )
{ * {
uint8_t ucRxData[ 20 ]; * uint8_t ucRxData[ 20 ];
size_t xReceivedBytes; * size_t xReceivedBytes;
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
*
// Receive the next message from the message buffer. * // Receive the next message from the message buffer.
xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer, * xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
( void * ) ucRxData, * ( void * ) ucRxData,
sizeof( ucRxData ), * sizeof( ucRxData ),
&xHigherPriorityTaskWoken ); * &xHigherPriorityTaskWoken );
*
if( xReceivedBytes > 0 ) * if( xReceivedBytes > 0 )
{ * {
// A ucRxData contains a message that is xReceivedBytes long. Process * // A ucRxData contains a message that is xReceivedBytes long. Process
// the message here.... * // the message here....
} * }
*
// If xHigherPriorityTaskWoken was set to pdTRUE inside * // If xHigherPriorityTaskWoken was set to pdTRUE inside
// xMessageBufferReceiveFromISR() then a task that has a priority above the * // xMessageBufferReceiveFromISR() then a task that has a priority above the
// priority of the currently executing task was unblocked and a context * // priority of the currently executing task was unblocked and a context
// switch should be performed to ensure the ISR returns to the unblocked * // switch should be performed to ensure the ISR returns to the unblocked
// task. In most FreeRTOS ports this is done by simply passing * // task. In most FreeRTOS ports this is done by simply passing
// xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
// variables value, and perform the context switch if necessary. Check the * // variables value, and perform the context switch if necessary. Check the
// documentation for the port in use for port specific instructions. * // documentation for the port in use for port specific instructions.
portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} * }
</pre> * </pre>
* \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR
* \ingroup MessageBufferManagement * \ingroup MessageBufferManagement
*/ */
@ -601,9 +601,9 @@ BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * <pre>
void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer ); * void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
</pre> * </pre>
* *
* Deletes a message buffer that was previously created using a call to * Deletes a message buffer that was previously created using a call to
* xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message * xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message
@ -620,9 +620,9 @@ void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
/** /**
* message_buffer.h * message_buffer.h
<pre> * <pre>
BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) ); * BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
</pre> * </pre>
* *
* Tests to see if a message buffer is full. A message buffer is full if it * Tests to see if a message buffer is full. A message buffer is full if it
* cannot accept any more messages, of any size, until space is made available * cannot accept any more messages, of any size, until space is made available
@ -637,9 +637,9 @@ BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
/** /**
* message_buffer.h * message_buffer.h
<pre> * <pre>
BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) ); * BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
</pre> * </pre>
* *
* Tests to see if a message buffer is empty (does not contain any messages). * Tests to see if a message buffer is empty (does not contain any messages).
* *
@ -653,9 +653,9 @@ BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
/** /**
* message_buffer.h * message_buffer.h
<pre> * <pre>
BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer ); * BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
</pre> * </pre>
* *
* Resets a message buffer to its initial empty state, discarding any message it * Resets a message buffer to its initial empty state, discarding any message it
* contained. * contained.
@ -677,9 +677,9 @@ BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
/** /**
* message_buffer.h * message_buffer.h
<pre> * <pre>
size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) ); * size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
</pre> * </pre>
* Returns the number of bytes of free space in the message buffer. * Returns the number of bytes of free space in the message buffer.
* *
* @param xMessageBuffer The handle of the message buffer being queried. * @param xMessageBuffer The handle of the message buffer being queried.
@ -699,9 +699,9 @@ size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
/** /**
* message_buffer.h * message_buffer.h
<pre> * <pre>
size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) ); * size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) );
</pre> * </pre>
* Returns the length (in bytes) of the next message in a message buffer. * Returns the length (in bytes) of the next message in a message buffer.
* Useful if xMessageBufferReceive() returned 0 because the size of the buffer * Useful if xMessageBufferReceive() returned 0 because the size of the buffer
* passed into xMessageBufferReceive() was too small to hold the next message. * passed into xMessageBufferReceive() was too small to hold the next message.
@ -719,9 +719,9 @@ size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * <pre>
BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
</pre> * </pre>
* *
* For advanced users only. * For advanced users only.
* *
@ -758,9 +758,9 @@ BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuff
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * <pre>
BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
</pre> * </pre>
* *
* For advanced users only. * For advanced users only.
* *

View file

@ -37,19 +37,38 @@
#define MPU_PROTOTYPES_H #define MPU_PROTOTYPES_H
/* MPU versions of tasks.h API functions. */ /* MPU versions of tasks.h API functions. */
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode,
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL; const char * const pcName,
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; const uint16_t usStackDepth,
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; void * const pvParameters,
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) FREERTOS_SYSTEM_CALL; UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint32_t ulStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
StackType_t * const puxStackBuffer,
StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition,
TaskHandle_t * pxCreatedTask ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition,
TaskHandle_t * pxCreatedTask ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask,
const MemoryRegion_t * const pxRegions ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL; void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL; void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL; void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) FREERTOS_SYSTEM_CALL; void MPU_vTaskGetInfo( TaskHandle_t xTask,
void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL; TaskStatus_t * pxTaskStatus,
BaseType_t xGetFreeStackSpace,
eTaskState eState ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskPrioritySet( TaskHandle_t xTask,
UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL; void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL; void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL;
@ -61,87 +80,166 @@ char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask,
TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL;
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) FREERTOS_SYSTEM_CALL; BaseType_t xIndex,
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) FREERTOS_SYSTEM_CALL; void * pvValue ) FREERTOS_SYSTEM_CALL;
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
BaseType_t xIndex ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask,
void * pvParameter ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
const UBaseType_t uxArraySize,
uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL;
uint32_t MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL; uint32_t MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskGetRunTimeStats( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; void MPU_vTaskGetRunTimeStats( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify,
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; UBaseType_t uxIndexToNotify,
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; uint32_t ulValue,
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL; eNotifyAction eAction,
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL; uint32_t * pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn,
uint32_t ulBitsToClearOnEntry,
uint32_t ulBitsToClearOnExit,
uint32_t * pulNotificationValue,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn,
BaseType_t xClearCountOnExit,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask,
UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL;
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask,
UBaseType_t uxIndexToClear,
uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL; void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL;
void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL; void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL;
/* MPU versions of queue.h API functions. */ /* MPU versions of queue.h API functions. */
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue,
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; const void * const pvItemToQueue,
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; TickType_t xTicksToWait,
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue,
void * const pvBuffer,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue,
void * const pvBuffer,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType,
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL; StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount,
const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount,
const UBaseType_t uxInitialCount,
StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) FREERTOS_SYSTEM_CALL; void MPU_vQueueAddToRegistry( QueueHandle_t xQueue,
const char * pcName ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength,
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; const UBaseType_t uxItemSize,
const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength,
const UBaseType_t uxItemSize,
uint8_t * pucQueueStorage,
StaticQueue_t * pxStaticQueue,
const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL; QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL; QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL; QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,
BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL;
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue,
UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
/* MPU versions of timers.h API functions. */ /* MPU versions of timers.h API functions. */
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL; TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName,
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) FREERTOS_SYSTEM_CALL; const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL;
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction,
StaticTimer_t * pxTimerBuffer ) FREERTOS_SYSTEM_CALL;
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetTimerID( TimerHandle_t xTimer,
void * pvNewID ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL; TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
void * pvParameter1,
uint32_t ulParameter2,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer,
const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer,
const BaseType_t xCommandID,
const TickType_t xOptionalValue,
BaseType_t * const pxHigherPriorityTaskWoken,
const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
/* MPU versions of event_group.h API functions. */ /* MPU versions of event_group.h API functions. */
EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL; EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL;
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; const EventBits_t uxBitsToWaitFor,
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL; const BaseType_t xClearOnExit,
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL;
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL;
UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL;
/* MPU versions of message/stream_buffer.h API functions. */ /* MPU versions of message/stream_buffer.h API functions. */
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; const void * pvTxData,
size_t xDataLengthBytes,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
void * pvRxData,
size_t xBufferLengthBytes,
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
@ -149,11 +247,17 @@ BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERT
BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL; size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL;
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL; StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes,
BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL;
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes,
BaseType_t xIsMessageBuffer,
uint8_t * const pucStreamBufferStorageArea,
StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL;
#endif /* MPU_PROTOTYPES_H */ #endif /* MPU_PROTOTYPES_H */

View file

@ -28,12 +28,12 @@
#define MPU_WRAPPERS_H #define MPU_WRAPPERS_H
/* This file redefines API functions to be called through a wrapper macro, but /* This file redefines API functions to be called through a wrapper macro, but
only for ports that are using the MPU. */ * only for ports that are using the MPU. */
#ifdef portUSING_MPU_WRAPPERS #ifdef portUSING_MPU_WRAPPERS
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
included from queue.c or task.c to prevent it from having an effect within * included from queue.c or task.c to prevent it from having an effect within
those files. */ * those files. */
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* /*
@ -143,7 +143,7 @@ only for ports that are using the MPU. */
#define vEventGroupDelete MPU_vEventGroupDelete #define vEventGroupDelete MPU_vEventGroupDelete
/* Map standard message/stream_buffer.h API functions to the MPU /* Map standard message/stream_buffer.h API functions to the MPU
equivalents. */ * equivalents. */
#define xStreamBufferSend MPU_xStreamBufferSend #define xStreamBufferSend MPU_xStreamBufferSend
#define xStreamBufferReceive MPU_xStreamBufferReceive #define xStreamBufferReceive MPU_xStreamBufferReceive
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes #define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
@ -159,8 +159,8 @@ only for ports that are using the MPU. */
/* Remove the privileged function macro, but keep the PRIVILEGED_DATA /* Remove the privileged function macro, but keep the PRIVILEGED_DATA
macro so applications can place data in privileged access sections * macro so applications can place data in privileged access sections
(useful when using statically allocated objects). */ * (useful when using statically allocated objects). */
#define PRIVILEGED_FUNCTION #define PRIVILEGED_FUNCTION
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) ) #define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
#define FREERTOS_SYSTEM_CALL #define FREERTOS_SYSTEM_CALL
@ -185,4 +185,3 @@ only for ports that are using the MPU. */
#endif /* MPU_WRAPPERS_H */ #endif /* MPU_WRAPPERS_H */

View file

@ -32,21 +32,21 @@
#define PORTABLE_H #define PORTABLE_H
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a /* Each FreeRTOS port has a unique portmacro.h header file. Originally a
pre-processor definition was used to ensure the pre-processor found the correct * pre-processor definition was used to ensure the pre-processor found the correct
portmacro.h file for the port being used. That scheme was deprecated in favour * portmacro.h file for the port being used. That scheme was deprecated in favour
of setting the compiler's include path such that it found the correct * of setting the compiler's include path such that it found the correct
portmacro.h file - removing the need for the constant and allowing the * portmacro.h file - removing the need for the constant and allowing the
portmacro.h file to be located anywhere in relation to the port being used. * portmacro.h file to be located anywhere in relation to the port being used.
Purely for reasons of backward compatibility the old method is still valid, but * Purely for reasons of backward compatibility the old method is still valid, but
to make it clear that new projects should not use it, support for the port * to make it clear that new projects should not use it, support for the port
specific constants has been moved into the deprecated_definitions.h header * specific constants has been moved into the deprecated_definitions.h header
file. */ * file. */
#include "deprecated_definitions.h" #include "deprecated_definitions.h"
/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h /* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
did not result in a portmacro.h header file being included - and it should be * did not result in a portmacro.h header file being included - and it should be
included here. In this case the path to the correct portmacro.h header file * included here. In this case the path to the correct portmacro.h header file
must be set in the compiler's include path. */ * must be set in the compiler's include path. */
#ifndef portENTER_CRITICAL #ifndef portENTER_CRITICAL
#include "portmacro.h" #include "portmacro.h"
#endif #endif
@ -105,20 +105,32 @@ extern "C" {
*/ */
#if ( portUSING_MPU_WRAPPERS == 1 ) #if ( portUSING_MPU_WRAPPERS == 1 )
#if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack,
TaskFunction_t pxCode,
void * pvParameters,
BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
#else #else
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters,
BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
#endif #endif
#else #else /* if ( portUSING_MPU_WRAPPERS == 1 ) */
#if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack,
TaskFunction_t pxCode,
void * pvParameters ) PRIVILEGED_FUNCTION;
#else #else
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
#endif TaskFunction_t pxCode,
void * pvParameters ) PRIVILEGED_FUNCTION;
#endif #endif
#endif /* if ( portUSING_MPU_WRAPPERS == 1 ) */
/* Used by heap_5.c to define the start address and size of each memory region /* Used by heap_5.c to define the start address and size of each memory region
that together comprise the total FreeRTOS heap space. */ * that together comprise the total FreeRTOS heap space. */
typedef struct HeapRegion typedef struct HeapRegion
{ {
uint8_t * pucStartAddress; uint8_t * pucStartAddress;
@ -187,7 +199,10 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
*/ */
#if ( portUSING_MPU_WRAPPERS == 1 ) #if ( portUSING_MPU_WRAPPERS == 1 )
struct xMEMORY_REGION; struct xMEMORY_REGION;
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
const struct xMEMORY_REGION * const xRegions,
StackType_t * pxBottomOfStack,
uint32_t ulStackDepth ) PRIVILEGED_FUNCTION;
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -195,4 +210,3 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
#endif #endif
#endif /* PORTABLE_H */ #endif /* PORTABLE_H */

View file

@ -34,8 +34,8 @@
typedef void (* TaskFunction_t)( void * ); typedef void (* TaskFunction_t)( void * );
/* Converts a time in milliseconds to a time in ticks. This macro can be /* Converts a time in milliseconds to a time in ticks. This macro can be
overridden by a macro of the same name defined in FreeRTOSConfig.h in case the * overridden by a macro of the same name defined in FreeRTOSConfig.h in case the
definition here is not suitable for your application. */ * definition here is not suitable for your application. */
#ifndef pdMS_TO_TICKS #ifndef pdMS_TO_TICKS
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )
#endif #endif
@ -65,7 +65,7 @@ definition here is not suitable for your application. */
#endif #endif
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS /* The following errno values are used by FreeRTOS+ components, not FreeRTOS
itself. */ * itself. */
#define pdFREERTOS_ERRNO_NONE 0 /* No errors */ #define pdFREERTOS_ERRNO_NONE 0 /* No errors */
#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ #define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ #define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */
@ -108,7 +108,7 @@ itself. */
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ #define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS /* The following endian values are used by FreeRTOS+ components, not FreeRTOS
itself. */ * itself. */
#define pdFREERTOS_LITTLE_ENDIAN 0 #define pdFREERTOS_LITTLE_ENDIAN 0
#define pdFREERTOS_BIG_ENDIAN 1 #define pdFREERTOS_BIG_ENDIAN 1
@ -118,6 +118,3 @@ itself. */
#endif /* PROJDEFS_H */ #endif /* PROJDEFS_H */

File diff suppressed because it is too large Load diff

View file

@ -70,22 +70,22 @@ typedef QueueHandle_t SemaphoreHandle_t;
* @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t. * @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t.
* *
* Example usage: * Example usage:
<pre> * <pre>
SemaphoreHandle_t xSemaphore = NULL; * SemaphoreHandle_t xSemaphore = NULL;
*
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
// Semaphore cannot be used before a call to vSemaphoreCreateBinary (). * // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
// This is a macro so pass the variable in directly. * // This is a macro so pass the variable in directly.
vSemaphoreCreateBinary( xSemaphore ); * vSemaphoreCreateBinary( xSemaphore );
*
if( xSemaphore != NULL ) * if( xSemaphore != NULL )
{ * {
// The semaphore was created successfully. * // The semaphore was created successfully.
// The semaphore can now be used. * // The semaphore can now be used.
} * }
} * }
</pre> * </pre>
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -138,22 +138,22 @@ typedef QueueHandle_t SemaphoreHandle_t;
* hold the semaphore's data structures could not be allocated. * hold the semaphore's data structures could not be allocated.
* *
* Example usage: * Example usage:
<pre> * <pre>
SemaphoreHandle_t xSemaphore = NULL; * SemaphoreHandle_t xSemaphore = NULL;
*
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
// Semaphore cannot be used before a call to xSemaphoreCreateBinary(). * // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
// This is a macro so pass the variable in directly. * // This is a macro so pass the variable in directly.
xSemaphore = xSemaphoreCreateBinary(); * xSemaphore = xSemaphoreCreateBinary();
*
if( xSemaphore != NULL ) * if( xSemaphore != NULL )
{ * {
// The semaphore was created successfully. * // The semaphore was created successfully.
// The semaphore can now be used. * // The semaphore can now be used.
} * }
} * }
</pre> * </pre>
* \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -196,23 +196,23 @@ typedef QueueHandle_t SemaphoreHandle_t;
* returned. If pxSemaphoreBuffer is NULL then NULL is returned. * returned. If pxSemaphoreBuffer is NULL then NULL is returned.
* *
* Example usage: * Example usage:
<pre> * <pre>
SemaphoreHandle_t xSemaphore = NULL; * SemaphoreHandle_t xSemaphore = NULL;
StaticSemaphore_t xSemaphoreBuffer; * StaticSemaphore_t xSemaphoreBuffer;
*
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
// Semaphore cannot be used before a call to xSemaphoreCreateBinary(). * // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
// The semaphore's data structures will be placed in the xSemaphoreBuffer * // The semaphore's data structures will be placed in the xSemaphoreBuffer
// variable, the address of which is passed into the function. The * // variable, the address of which is passed into the function. The
// function's parameter is not NULL, so the function will not attempt any * // function's parameter is not NULL, so the function will not attempt any
// dynamic memory allocation, and therefore the function will not return * // dynamic memory allocation, and therefore the function will not return
// return NULL. * // return NULL.
xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer ); * xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
*
// Rest of task code goes here. * // Rest of task code goes here.
} * }
</pre> * </pre>
* \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -244,44 +244,44 @@ typedef QueueHandle_t SemaphoreHandle_t;
* if xBlockTime expired without the semaphore becoming available. * if xBlockTime expired without the semaphore becoming available.
* *
* Example usage: * Example usage:
<pre> * <pre>
SemaphoreHandle_t xSemaphore = NULL; * SemaphoreHandle_t xSemaphore = NULL;
*
// A task that creates a semaphore. * // A task that creates a semaphore.
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
// Create the semaphore to guard a shared resource. * // Create the semaphore to guard a shared resource.
xSemaphore = xSemaphoreCreateBinary(); * xSemaphore = xSemaphoreCreateBinary();
} * }
*
// A task that uses the semaphore. * // A task that uses the semaphore.
void vAnotherTask( void * pvParameters ) * void vAnotherTask( void * pvParameters )
{ * {
// ... Do other things. * // ... Do other things.
*
if( xSemaphore != NULL ) * if( xSemaphore != NULL )
{ * {
// See if we can obtain the semaphore. If the semaphore is not available * // See if we can obtain the semaphore. If the semaphore is not available
// wait 10 ticks to see if it becomes free. * // wait 10 ticks to see if it becomes free.
if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE ) * if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
{ * {
// We were able to obtain the semaphore and can now access the * // We were able to obtain the semaphore and can now access the
// shared resource. * // shared resource.
*
// ... * // ...
*
// We have finished accessing the shared resource. Release the * // We have finished accessing the shared resource. Release the
// semaphore. * // semaphore.
xSemaphoreGive( xSemaphore ); * xSemaphoreGive( xSemaphore );
} * }
else * else
{ * {
// We could not obtain the semaphore and can therefore not access * // We could not obtain the semaphore and can therefore not access
// the shared resource safely. * // the shared resource safely.
} * }
} * }
} * }
</pre> * </pre>
* \defgroup xSemaphoreTake xSemaphoreTake * \defgroup xSemaphoreTake xSemaphoreTake
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -323,58 +323,58 @@ typedef QueueHandle_t SemaphoreHandle_t;
* expired without the semaphore becoming available. * expired without the semaphore becoming available.
* *
* Example usage: * Example usage:
<pre> * <pre>
SemaphoreHandle_t xMutex = NULL; * SemaphoreHandle_t xMutex = NULL;
*
// A task that creates a mutex. * // A task that creates a mutex.
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
// Create the mutex to guard a shared resource. * // Create the mutex to guard a shared resource.
xMutex = xSemaphoreCreateRecursiveMutex(); * xMutex = xSemaphoreCreateRecursiveMutex();
} * }
*
// A task that uses the mutex. * // A task that uses the mutex.
void vAnotherTask( void * pvParameters ) * void vAnotherTask( void * pvParameters )
{ * {
// ... Do other things. * // ... Do other things.
*
if( xMutex != NULL ) * if( xMutex != NULL )
{ * {
// See if we can obtain the mutex. If the mutex is not available * // See if we can obtain the mutex. If the mutex is not available
// wait 10 ticks to see if it becomes free. * // wait 10 ticks to see if it becomes free.
if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE ) * if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
{ * {
// We were able to obtain the mutex and can now access the * // We were able to obtain the mutex and can now access the
// shared resource. * // shared resource.
*
// ... * // ...
// For some reason due to the nature of the code further calls to * // For some reason due to the nature of the code further calls to
// xSemaphoreTakeRecursive() are made on the same mutex. In real * // xSemaphoreTakeRecursive() are made on the same mutex. In real
// code these would not be just sequential calls as this would make * // code these would not be just sequential calls as this would make
// no sense. Instead the calls are likely to be buried inside * // no sense. Instead the calls are likely to be buried inside
// a more complex call structure. * // a more complex call structure.
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
*
// The mutex has now been 'taken' three times, so will not be * // The mutex has now been 'taken' three times, so will not be
// available to another task until it has also been given back * // available to another task until it has also been given back
// three times. Again it is unlikely that real code would have * // three times. Again it is unlikely that real code would have
// these calls sequentially, but instead buried in a more complex * // these calls sequentially, but instead buried in a more complex
// call structure. This is just for illustrative purposes. * // call structure. This is just for illustrative purposes.
xSemaphoreGiveRecursive( xMutex ); * xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex ); * xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex ); * xSemaphoreGiveRecursive( xMutex );
*
// Now the mutex can be taken by other tasks. * // Now the mutex can be taken by other tasks.
} * }
else * else
{ * {
// We could not obtain the mutex and can therefore not access * // We could not obtain the mutex and can therefore not access
// the shared resource safely. * // the shared resource safely.
} * }
} * }
} * }
</pre> * </pre>
* \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -405,41 +405,41 @@ typedef QueueHandle_t SemaphoreHandle_t;
* semaphore was not first obtained correctly. * semaphore was not first obtained correctly.
* *
* Example usage: * Example usage:
<pre> * <pre>
SemaphoreHandle_t xSemaphore = NULL; * SemaphoreHandle_t xSemaphore = NULL;
*
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
// Create the semaphore to guard a shared resource. * // Create the semaphore to guard a shared resource.
xSemaphore = vSemaphoreCreateBinary(); * xSemaphore = vSemaphoreCreateBinary();
*
if( xSemaphore != NULL ) * if( xSemaphore != NULL )
{ * {
if( xSemaphoreGive( xSemaphore ) != pdTRUE ) * if( xSemaphoreGive( xSemaphore ) != pdTRUE )
{ * {
// We would expect this call to fail because we cannot give * // We would expect this call to fail because we cannot give
// a semaphore without first "taking" it! * // a semaphore without first "taking" it!
} * }
*
// Obtain the semaphore - don't block if the semaphore is not * // Obtain the semaphore - don't block if the semaphore is not
// immediately available. * // immediately available.
if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) ) * if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
{ * {
// We now have the semaphore and can access the shared resource. * // We now have the semaphore and can access the shared resource.
*
// ... * // ...
*
// We have finished accessing the shared resource so can free the * // We have finished accessing the shared resource so can free the
// semaphore. * // semaphore.
if( xSemaphoreGive( xSemaphore ) != pdTRUE ) * if( xSemaphoreGive( xSemaphore ) != pdTRUE )
{ * {
// We would not expect this call to fail because we must have * // We would not expect this call to fail because we must have
// obtained the semaphore to get here. * // obtained the semaphore to get here.
} * }
} * }
} * }
} * }
</pre> * </pre>
* \defgroup xSemaphoreGive xSemaphoreGive * \defgroup xSemaphoreGive xSemaphoreGive
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -471,59 +471,59 @@ typedef QueueHandle_t SemaphoreHandle_t;
* @return pdTRUE if the semaphore was given. * @return pdTRUE if the semaphore was given.
* *
* Example usage: * Example usage:
<pre> * <pre>
SemaphoreHandle_t xMutex = NULL; * SemaphoreHandle_t xMutex = NULL;
*
// A task that creates a mutex. * // A task that creates a mutex.
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
// Create the mutex to guard a shared resource. * // Create the mutex to guard a shared resource.
xMutex = xSemaphoreCreateRecursiveMutex(); * xMutex = xSemaphoreCreateRecursiveMutex();
} * }
*
// A task that uses the mutex. * // A task that uses the mutex.
void vAnotherTask( void * pvParameters ) * void vAnotherTask( void * pvParameters )
{ * {
// ... Do other things. * // ... Do other things.
*
if( xMutex != NULL ) * if( xMutex != NULL )
{ * {
// See if we can obtain the mutex. If the mutex is not available * // See if we can obtain the mutex. If the mutex is not available
// wait 10 ticks to see if it becomes free. * // wait 10 ticks to see if it becomes free.
if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE ) * if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
{ * {
// We were able to obtain the mutex and can now access the * // We were able to obtain the mutex and can now access the
// shared resource. * // shared resource.
*
// ... * // ...
// For some reason due to the nature of the code further calls to * // For some reason due to the nature of the code further calls to
// xSemaphoreTakeRecursive() are made on the same mutex. In real * // xSemaphoreTakeRecursive() are made on the same mutex. In real
// code these would not be just sequential calls as this would make * // code these would not be just sequential calls as this would make
// no sense. Instead the calls are likely to be buried inside * // no sense. Instead the calls are likely to be buried inside
// a more complex call structure. * // a more complex call structure.
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
*
// The mutex has now been 'taken' three times, so will not be * // The mutex has now been 'taken' three times, so will not be
// available to another task until it has also been given back * // available to another task until it has also been given back
// three times. Again it is unlikely that real code would have * // three times. Again it is unlikely that real code would have
// these calls sequentially, it would be more likely that the calls * // these calls sequentially, it would be more likely that the calls
// to xSemaphoreGiveRecursive() would be called as a call stack * // to xSemaphoreGiveRecursive() would be called as a call stack
// unwound. This is just for demonstrative purposes. * // unwound. This is just for demonstrative purposes.
xSemaphoreGiveRecursive( xMutex ); * xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex ); * xSemaphoreGiveRecursive( xMutex );
xSemaphoreGiveRecursive( xMutex ); * xSemaphoreGiveRecursive( xMutex );
*
// Now the mutex can be taken by other tasks. * // Now the mutex can be taken by other tasks.
} * }
else * else
{ * {
// We could not obtain the mutex and can therefore not access * // We could not obtain the mutex and can therefore not access
// the shared resource safely. * // the shared resource safely.
} * }
} * }
} * }
</pre> * </pre>
* \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -534,10 +534,10 @@ typedef QueueHandle_t SemaphoreHandle_t;
/** /**
* semphr. h * semphr. h
* <pre> * <pre>
xSemaphoreGiveFromISR( * xSemaphoreGiveFromISR(
SemaphoreHandle_t xSemaphore, * SemaphoreHandle_t xSemaphore,
BaseType_t *pxHigherPriorityTaskWoken * BaseType_t *pxHigherPriorityTaskWoken
)</pre> * )</pre>
* *
* <i>Macro</i> to release a semaphore. The semaphore must have previously been * <i>Macro</i> to release a semaphore. The semaphore must have previously been
* created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting(). * created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting().
@ -559,64 +559,64 @@ typedef QueueHandle_t SemaphoreHandle_t;
* @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
* *
* Example usage: * Example usage:
<pre> * <pre>
\#define LONG_TIME 0xffff \#define LONG_TIME 0xffff
\#define TICKS_TO_WAIT 10 \#define TICKS_TO_WAIT 10
SemaphoreHandle_t xSemaphore = NULL; * SemaphoreHandle_t xSemaphore = NULL;
*
// Repetitive task. * // Repetitive task.
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
for( ;; ) * for( ;; )
{ * {
// We want this task to run every 10 ticks of a timer. The semaphore * // We want this task to run every 10 ticks of a timer. The semaphore
// was created before this task was started. * // was created before this task was started.
*
// Block waiting for the semaphore to become available. * // Block waiting for the semaphore to become available.
if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE ) * if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
{ * {
// It is time to execute. * // It is time to execute.
*
// ... * // ...
*
// We have finished our task. Return to the top of the loop where * // We have finished our task. Return to the top of the loop where
// we will block on the semaphore until it is time to execute * // we will block on the semaphore until it is time to execute
// again. Note when using the semaphore for synchronisation with an * // again. Note when using the semaphore for synchronisation with an
// ISR in this manner there is no need to 'give' the semaphore back. * // ISR in this manner there is no need to 'give' the semaphore back.
} * }
} * }
} * }
*
// Timer ISR * // Timer ISR
void vTimerISR( void * pvParameters ) * void vTimerISR( void * pvParameters )
{ * {
static uint8_t ucLocalTickCount = 0; * static uint8_t ucLocalTickCount = 0;
static BaseType_t xHigherPriorityTaskWoken; * static BaseType_t xHigherPriorityTaskWoken;
*
// A timer tick has occurred. * // A timer tick has occurred.
*
// ... Do other time functions. * // ... Do other time functions.
*
// Is it time for vATask () to run? * // Is it time for vATask () to run?
xHigherPriorityTaskWoken = pdFALSE; * xHigherPriorityTaskWoken = pdFALSE;
ucLocalTickCount++; * ucLocalTickCount++;
if( ucLocalTickCount >= TICKS_TO_WAIT ) * if( ucLocalTickCount >= TICKS_TO_WAIT )
{ * {
// Unblock the task by releasing the semaphore. * // Unblock the task by releasing the semaphore.
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken ); * xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
*
// Reset the count so we release the semaphore again in 10 ticks time. * // Reset the count so we release the semaphore again in 10 ticks time.
ucLocalTickCount = 0; * ucLocalTickCount = 0;
} * }
*
if( xHigherPriorityTaskWoken != pdFALSE ) * if( xHigherPriorityTaskWoken != pdFALSE )
{ * {
// We can force a context switch here. Context switching from an * // We can force a context switch here. Context switching from an
// ISR uses port specific syntax. Check the demo task for your port * // ISR uses port specific syntax. Check the demo task for your port
// to find the syntax required. * // to find the syntax required.
} * }
} * }
</pre> * </pre>
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -625,10 +625,10 @@ typedef QueueHandle_t SemaphoreHandle_t;
/** /**
* semphr. h * semphr. h
* <pre> * <pre>
xSemaphoreTakeFromISR( * xSemaphoreTakeFromISR(
SemaphoreHandle_t xSemaphore, * SemaphoreHandle_t xSemaphore,
BaseType_t *pxHigherPriorityTaskWoken * BaseType_t *pxHigherPriorityTaskWoken
)</pre> * )</pre>
* *
* <i>Macro</i> to take a semaphore from an ISR. The semaphore must have * <i>Macro</i> to take a semaphore from an ISR. The semaphore must have
* previously been created with a call to xSemaphoreCreateBinary() or * previously been created with a call to xSemaphoreCreateBinary() or
@ -692,22 +692,22 @@ typedef QueueHandle_t SemaphoreHandle_t;
* data structures then NULL is returned. * data structures then NULL is returned.
* *
* Example usage: * Example usage:
<pre> * <pre>
SemaphoreHandle_t xSemaphore; * SemaphoreHandle_t xSemaphore;
*
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
// Semaphore cannot be used before a call to xSemaphoreCreateMutex(). * // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
// This is a macro so pass the variable in directly. * // This is a macro so pass the variable in directly.
xSemaphore = xSemaphoreCreateMutex(); * xSemaphore = xSemaphoreCreateMutex();
*
if( xSemaphore != NULL ) * if( xSemaphore != NULL )
{ * {
// The semaphore was created successfully. * // The semaphore was created successfully.
// The semaphore can now be used. * // The semaphore can now be used.
} * }
} * }
</pre> * </pre>
* \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -754,21 +754,21 @@ typedef QueueHandle_t SemaphoreHandle_t;
* mutex is returned. If pxMutexBuffer was NULL then NULL is returned. * mutex is returned. If pxMutexBuffer was NULL then NULL is returned.
* *
* Example usage: * Example usage:
<pre> * <pre>
SemaphoreHandle_t xSemaphore; * SemaphoreHandle_t xSemaphore;
StaticSemaphore_t xMutexBuffer; * StaticSemaphore_t xMutexBuffer;
*
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
// A mutex cannot be used before it has been created. xMutexBuffer is * // A mutex cannot be used before it has been created. xMutexBuffer is
// into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is * // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
// attempted. * // attempted.
xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer ); * xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
*
// As no dynamic memory allocation was performed, xSemaphore cannot be NULL, * // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
// so there is no need to check it. * // so there is no need to check it.
} * }
</pre> * </pre>
* \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -821,22 +821,22 @@ typedef QueueHandle_t SemaphoreHandle_t;
* SemaphoreHandle_t. * SemaphoreHandle_t.
* *
* Example usage: * Example usage:
<pre> * <pre>
SemaphoreHandle_t xSemaphore; * SemaphoreHandle_t xSemaphore;
*
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
// Semaphore cannot be used before a call to xSemaphoreCreateMutex(). * // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
// This is a macro so pass the variable in directly. * // This is a macro so pass the variable in directly.
xSemaphore = xSemaphoreCreateRecursiveMutex(); * xSemaphore = xSemaphoreCreateRecursiveMutex();
*
if( xSemaphore != NULL ) * if( xSemaphore != NULL )
{ * {
// The semaphore was created successfully. * // The semaphore was created successfully.
// The semaphore can now be used. * // The semaphore can now be used.
} * }
} * }
</pre> * </pre>
* \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex * \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -893,23 +893,23 @@ typedef QueueHandle_t SemaphoreHandle_t;
* returned. * returned.
* *
* Example usage: * Example usage:
<pre> * <pre>
SemaphoreHandle_t xSemaphore; * SemaphoreHandle_t xSemaphore;
StaticSemaphore_t xMutexBuffer; * StaticSemaphore_t xMutexBuffer;
*
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
// A recursive semaphore cannot be used before it is created. Here a * // A recursive semaphore cannot be used before it is created. Here a
// recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic(). * // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
// The address of xMutexBuffer is passed into the function, and will hold * // The address of xMutexBuffer is passed into the function, and will hold
// the mutexes data structures - so no dynamic memory allocation will be * // the mutexes data structures - so no dynamic memory allocation will be
// attempted. * // attempted.
xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer ); * xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
*
// As no dynamic memory allocation was performed, xSemaphore cannot be NULL, * // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
// so there is no need to check it. * // so there is no need to check it.
} * }
</pre> * </pre>
* \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -971,25 +971,25 @@ typedef QueueHandle_t SemaphoreHandle_t;
* created. * created.
* *
* Example usage: * Example usage:
<pre> * <pre>
SemaphoreHandle_t xSemaphore; * SemaphoreHandle_t xSemaphore;
*
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
SemaphoreHandle_t xSemaphore = NULL; * SemaphoreHandle_t xSemaphore = NULL;
*
// Semaphore cannot be used before a call to xSemaphoreCreateCounting(). * // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
// The max value to which the semaphore can count should be 10, and the * // The max value to which the semaphore can count should be 10, and the
// initial value assigned to the count should be 0. * // initial value assigned to the count should be 0.
xSemaphore = xSemaphoreCreateCounting( 10, 0 ); * xSemaphore = xSemaphoreCreateCounting( 10, 0 );
*
if( xSemaphore != NULL ) * if( xSemaphore != NULL )
{ * {
// The semaphore was created successfully. * // The semaphore was created successfully.
// The semaphore can now be used. * // The semaphore can now be used.
} * }
} * }
</pre> * </pre>
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -1055,26 +1055,26 @@ typedef QueueHandle_t SemaphoreHandle_t;
* then NULL is returned. * then NULL is returned.
* *
* Example usage: * Example usage:
<pre> * <pre>
SemaphoreHandle_t xSemaphore; * SemaphoreHandle_t xSemaphore;
StaticSemaphore_t xSemaphoreBuffer; * StaticSemaphore_t xSemaphoreBuffer;
*
void vATask( void * pvParameters ) * void vATask( void * pvParameters )
{ * {
SemaphoreHandle_t xSemaphore = NULL; * SemaphoreHandle_t xSemaphore = NULL;
*
// Counting semaphore cannot be used before they have been created. Create * // Counting semaphore cannot be used before they have been created. Create
// a counting semaphore using xSemaphoreCreateCountingStatic(). The max * // a counting semaphore using xSemaphoreCreateCountingStatic(). The max
// value to which the semaphore can count is 10, and the initial value * // value to which the semaphore can count is 10, and the initial value
// assigned to the count will be 0. The address of xSemaphoreBuffer is * // assigned to the count will be 0. The address of xSemaphoreBuffer is
// passed in and will be used to hold the semaphore structure, so no dynamic * // passed in and will be used to hold the semaphore structure, so no dynamic
// memory allocation will be used. * // memory allocation will be used.
xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer ); * xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
*
// No memory allocation was attempted so xSemaphore cannot be NULL, so there * // No memory allocation was attempted so xSemaphore cannot be NULL, so there
// is no need to check its value. * // is no need to check its value.
} * }
</pre> * </pre>
* \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic
* \ingroup Semaphores * \ingroup Semaphores
*/ */
@ -1135,5 +1135,3 @@ typedef QueueHandle_t SemaphoreHandle_t;
#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) ) #define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
#endif /* SEMAPHORE_H */ #endif /* SEMAPHORE_H */

View file

@ -125,4 +125,3 @@
#endif /* STACK_MACROS_H */ #endif /* STACK_MACROS_H */

View file

@ -71,9 +71,9 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t;
/** /**
* message_buffer.h * message_buffer.h
* *
<pre> * <pre>
StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes ); * StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
</pre> * </pre>
* *
* Creates a new stream buffer using dynamically allocated memory. See * Creates a new stream buffer using dynamically allocated memory. See
* xStreamBufferCreateStatic() for a version that uses statically allocated * xStreamBufferCreateStatic() for a version that uses statically allocated
@ -107,29 +107,29 @@ StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTrigg
* buffer. * buffer.
* *
* Example use: * Example use:
<pre> * <pre>
*
void vAFunction( void ) * void vAFunction( void )
{ * {
StreamBufferHandle_t xStreamBuffer; * StreamBufferHandle_t xStreamBuffer;
const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10; * const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
*
// Create a stream buffer that can hold 100 bytes. The memory used to hold * // Create a stream buffer that can hold 100 bytes. The memory used to hold
// both the stream buffer structure and the data in the stream buffer is * // both the stream buffer structure and the data in the stream buffer is
// allocated dynamically. * // allocated dynamically.
xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel ); * xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
*
if( xStreamBuffer == NULL ) * if( xStreamBuffer == NULL )
{ * {
// There was not enough heap memory space available to create the * // There was not enough heap memory space available to create the
// stream buffer. * // stream buffer.
} * }
else * else
{ * {
// The stream buffer was created successfully and can now be used. * // The stream buffer was created successfully and can now be used.
} * }
} * }
</pre> * </pre>
* \defgroup xStreamBufferCreate xStreamBufferCreate * \defgroup xStreamBufferCreate xStreamBufferCreate
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
@ -138,12 +138,12 @@ const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes, * StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes, * size_t xTriggerLevelBytes,
uint8_t *pucStreamBufferStorageArea, * uint8_t *pucStreamBufferStorageArea,
StaticStreamBuffer_t *pxStaticStreamBuffer ); * StaticStreamBuffer_t *pxStaticStreamBuffer );
</pre> * </pre>
* Creates a new stream buffer using statically allocated memory. See * Creates a new stream buffer using statically allocated memory. See
* xStreamBufferCreate() for a version that uses dynamically allocated memory. * xStreamBufferCreate() for a version that uses dynamically allocated memory.
* *
@ -180,37 +180,37 @@ StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
* pxStaticstreamBuffer are NULL then NULL is returned. * pxStaticstreamBuffer are NULL then NULL is returned.
* *
* Example use: * Example use:
<pre> * <pre>
*
// Used to dimension the array used to hold the streams. The available space * // Used to dimension the array used to hold the streams. The available space
// will actually be one less than this, so 999. * // will actually be one less than this, so 999.
#define STORAGE_SIZE_BYTES 1000 #define STORAGE_SIZE_BYTES 1000
*
// Defines the memory that will actually hold the streams within the stream * // Defines the memory that will actually hold the streams within the stream
// buffer. * // buffer.
static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; * static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
*
// The variable used to hold the stream buffer structure. * // The variable used to hold the stream buffer structure.
StaticStreamBuffer_t xStreamBufferStruct; * StaticStreamBuffer_t xStreamBufferStruct;
*
void MyFunction( void ) * void MyFunction( void )
{ * {
StreamBufferHandle_t xStreamBuffer; * StreamBufferHandle_t xStreamBuffer;
const size_t xTriggerLevel = 1; * const size_t xTriggerLevel = 1;
*
xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ), * xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ),
xTriggerLevel, * xTriggerLevel,
ucBufferStorage, * ucBufferStorage,
&xStreamBufferStruct ); * &xStreamBufferStruct );
*
// As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer * // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
// parameters were NULL, xStreamBuffer will not be NULL, and can be used to * // parameters were NULL, xStreamBuffer will not be NULL, and can be used to
// reference the created stream buffer in other stream buffer API calls. * // reference the created stream buffer in other stream buffer API calls.
*
// Other code that uses the stream buffer can go here. * // Other code that uses the stream buffer can go here.
} * }
*
</pre> * </pre>
* \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
@ -219,12 +219,12 @@ const size_t xTriggerLevel = 1;
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, * size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
const void *pvTxData, * const void *pvTxData,
size_t xDataLengthBytes, * size_t xDataLengthBytes,
TickType_t xTicksToWait ); * TickType_t xTicksToWait );
</pre> * </pre>
* *
* Sends bytes to a stream buffer. The bytes are copied into the stream buffer. * Sends bytes to a stream buffer. The bytes are copied into the stream buffer.
* *
@ -274,37 +274,37 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
* write as many bytes as possible. * write as many bytes as possible.
* *
* Example use: * Example use:
<pre> * <pre>
void vAFunction( StreamBufferHandle_t xStreamBuffer ) * void vAFunction( StreamBufferHandle_t xStreamBuffer )
{ * {
size_t xBytesSent; * size_t xBytesSent;
uint8_t ucArrayToSend[] = { 0, 1, 2, 3 }; * uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
char *pcStringToSend = "String to send"; * char *pcStringToSend = "String to send";
const TickType_t x100ms = pdMS_TO_TICKS( 100 ); * const TickType_t x100ms = pdMS_TO_TICKS( 100 );
*
// Send an array to the stream buffer, blocking for a maximum of 100ms to * // Send an array to the stream buffer, blocking for a maximum of 100ms to
// wait for enough space to be available in the stream buffer. * // wait for enough space to be available in the stream buffer.
xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms ); * xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
*
if( xBytesSent != sizeof( ucArrayToSend ) ) * if( xBytesSent != sizeof( ucArrayToSend ) )
{ * {
// The call to xStreamBufferSend() times out before there was enough * // The call to xStreamBufferSend() times out before there was enough
// space in the buffer for the data to be written, but it did * // space in the buffer for the data to be written, but it did
// successfully write xBytesSent bytes. * // successfully write xBytesSent bytes.
} * }
*
// Send the string to the stream buffer. Return immediately if there is not * // Send the string to the stream buffer. Return immediately if there is not
// enough space in the buffer. * // enough space in the buffer.
xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 ); * xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
*
if( xBytesSent != strlen( pcStringToSend ) ) * if( xBytesSent != strlen( pcStringToSend ) )
{ * {
// The entire string could not be added to the stream buffer because * // The entire string could not be added to the stream buffer because
// there was not enough free space in the buffer, but xBytesSent bytes * // there was not enough free space in the buffer, but xBytesSent bytes
// were sent. Could try again to send the remaining bytes. * // were sent. Could try again to send the remaining bytes.
} * }
} * }
</pre> * </pre>
* \defgroup xStreamBufferSend xStreamBufferSend * \defgroup xStreamBufferSend xStreamBufferSend
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
@ -316,12 +316,12 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, * size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
const void *pvTxData, * const void *pvTxData,
size_t xDataLengthBytes, * size_t xDataLengthBytes,
BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t *pxHigherPriorityTaskWoken );
</pre> * </pre>
* *
* Interrupt safe version of the API function that sends a stream of bytes to * Interrupt safe version of the API function that sends a stream of bytes to
* the stream buffer. * the stream buffer.
@ -373,39 +373,39 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
* space for all the bytes to be written. * space for all the bytes to be written.
* *
* Example use: * Example use:
<pre> * <pre>
// A stream buffer that has already been created. * // A stream buffer that has already been created.
StreamBufferHandle_t xStreamBuffer; * StreamBufferHandle_t xStreamBuffer;
*
void vAnInterruptServiceRoutine( void ) * void vAnInterruptServiceRoutine( void )
{ * {
size_t xBytesSent; * size_t xBytesSent;
char *pcStringToSend = "String to send"; * char *pcStringToSend = "String to send";
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
*
// Attempt to send the string to the stream buffer. * // Attempt to send the string to the stream buffer.
xBytesSent = xStreamBufferSendFromISR( xStreamBuffer, * xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
( void * ) pcStringToSend, * ( void * ) pcStringToSend,
strlen( pcStringToSend ), * strlen( pcStringToSend ),
&xHigherPriorityTaskWoken ); * &xHigherPriorityTaskWoken );
*
if( xBytesSent != strlen( pcStringToSend ) ) * if( xBytesSent != strlen( pcStringToSend ) )
{ * {
// There was not enough free space in the stream buffer for the entire * // There was not enough free space in the stream buffer for the entire
// string to be written, ut xBytesSent bytes were written. * // string to be written, ut xBytesSent bytes were written.
} * }
*
// If xHigherPriorityTaskWoken was set to pdTRUE inside * // If xHigherPriorityTaskWoken was set to pdTRUE inside
// xStreamBufferSendFromISR() then a task that has a priority above the * // xStreamBufferSendFromISR() then a task that has a priority above the
// priority of the currently executing task was unblocked and a context * // priority of the currently executing task was unblocked and a context
// switch should be performed to ensure the ISR returns to the unblocked * // switch should be performed to ensure the ISR returns to the unblocked
// task. In most FreeRTOS ports this is done by simply passing * // task. In most FreeRTOS ports this is done by simply passing
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the * // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
// variables value, and perform the context switch if necessary. Check the * // variables value, and perform the context switch if necessary. Check the
// documentation for the port in use for port specific instructions. * // documentation for the port in use for port specific instructions.
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} * }
</pre> * </pre>
* \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
@ -417,12 +417,12 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, * size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
void *pvRxData, * void *pvRxData,
size_t xBufferLengthBytes, * size_t xBufferLengthBytes,
TickType_t xTicksToWait ); * TickType_t xTicksToWait );
</pre> * </pre>
* *
* Receives bytes from a stream buffer. * Receives bytes from a stream buffer.
* *
@ -472,29 +472,29 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
* out before xBufferLengthBytes were available. * out before xBufferLengthBytes were available.
* *
* Example use: * Example use:
<pre> * <pre>
void vAFunction( StreamBuffer_t xStreamBuffer ) * void vAFunction( StreamBuffer_t xStreamBuffer )
{ * {
uint8_t ucRxData[ 20 ]; * uint8_t ucRxData[ 20 ];
size_t xReceivedBytes; * size_t xReceivedBytes;
const TickType_t xBlockTime = pdMS_TO_TICKS( 20 ); * const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
*
// Receive up to another sizeof( ucRxData ) bytes from the stream buffer. * // Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
// Wait in the Blocked state (so not using any CPU processing time) for a * // Wait in the Blocked state (so not using any CPU processing time) for a
// maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be * // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
// available. * // available.
xReceivedBytes = xStreamBufferReceive( xStreamBuffer, * xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
( void * ) ucRxData, * ( void * ) ucRxData,
sizeof( ucRxData ), * sizeof( ucRxData ),
xBlockTime ); * xBlockTime );
*
if( xReceivedBytes > 0 ) * if( xReceivedBytes > 0 )
{ * {
// A ucRxData contains another xRecievedBytes bytes of data, which can * // A ucRxData contains another xRecievedBytes bytes of data, which can
// be processed here.... * // be processed here....
} * }
} * }
</pre> * </pre>
* \defgroup xStreamBufferReceive xStreamBufferReceive * \defgroup xStreamBufferReceive xStreamBufferReceive
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
@ -506,12 +506,12 @@ size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, * size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
void *pvRxData, * void *pvRxData,
size_t xBufferLengthBytes, * size_t xBufferLengthBytes,
BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t *pxHigherPriorityTaskWoken );
</pre> * </pre>
* *
* An interrupt safe version of the API function that receives bytes from a * An interrupt safe version of the API function that receives bytes from a
* stream buffer. * stream buffer.
@ -548,39 +548,39 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
* @return The number of bytes read from the stream buffer, if any. * @return The number of bytes read from the stream buffer, if any.
* *
* Example use: * Example use:
<pre> * <pre>
// A stream buffer that has already been created. * // A stream buffer that has already been created.
StreamBuffer_t xStreamBuffer; * StreamBuffer_t xStreamBuffer;
*
void vAnInterruptServiceRoutine( void ) * void vAnInterruptServiceRoutine( void )
{ * {
uint8_t ucRxData[ 20 ]; * uint8_t ucRxData[ 20 ];
size_t xReceivedBytes; * size_t xReceivedBytes;
BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
*
// Receive the next stream from the stream buffer. * // Receive the next stream from the stream buffer.
xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer, * xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
( void * ) ucRxData, * ( void * ) ucRxData,
sizeof( ucRxData ), * sizeof( ucRxData ),
&xHigherPriorityTaskWoken ); * &xHigherPriorityTaskWoken );
*
if( xReceivedBytes > 0 ) * if( xReceivedBytes > 0 )
{ * {
// ucRxData contains xReceivedBytes read from the stream buffer. * // ucRxData contains xReceivedBytes read from the stream buffer.
// Process the stream here.... * // Process the stream here....
} * }
*
// If xHigherPriorityTaskWoken was set to pdTRUE inside * // If xHigherPriorityTaskWoken was set to pdTRUE inside
// xStreamBufferReceiveFromISR() then a task that has a priority above the * // xStreamBufferReceiveFromISR() then a task that has a priority above the
// priority of the currently executing task was unblocked and a context * // priority of the currently executing task was unblocked and a context
// switch should be performed to ensure the ISR returns to the unblocked * // switch should be performed to ensure the ISR returns to the unblocked
// task. In most FreeRTOS ports this is done by simply passing * // task. In most FreeRTOS ports this is done by simply passing
// xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the * // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
// variables value, and perform the context switch if necessary. Check the * // variables value, and perform the context switch if necessary. Check the
// documentation for the port in use for port specific instructions. * // documentation for the port in use for port specific instructions.
taskYIELD_FROM_ISR( xHigherPriorityTaskWoken ); * taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} * }
</pre> * </pre>
* \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
@ -592,9 +592,9 @@ size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ); * void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
</pre> * </pre>
* *
* Deletes a stream buffer that was previously created using a call to * Deletes a stream buffer that was previously created using a call to
* xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream * xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream
@ -614,9 +614,9 @@ void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTI
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ); * BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
</pre> * </pre>
* *
* Queries a stream buffer to see if it is full. A stream buffer is full if it * Queries a stream buffer to see if it is full. A stream buffer is full if it
* does not have any free space, and therefore cannot accept any more data. * does not have any free space, and therefore cannot accept any more data.
@ -634,9 +634,9 @@ BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ); * BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
</pre> * </pre>
* *
* Queries a stream buffer to see if it is empty. A stream buffer is empty if * Queries a stream buffer to see if it is empty. A stream buffer is empty if
* it does not contain any data. * it does not contain any data.
@ -654,9 +654,9 @@ BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ); * BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
</pre> * </pre>
* *
* Resets a stream buffer to its initial, empty, state. Any data that was in * Resets a stream buffer to its initial, empty, state. Any data that was in
* the stream buffer is discarded. A stream buffer can only be reset if there * the stream buffer is discarded. A stream buffer can only be reset if there
@ -677,9 +677,9 @@ BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_F
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ); * size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
</pre> * </pre>
* *
* Queries a stream buffer to see how much free space it contains, which is * Queries a stream buffer to see how much free space it contains, which is
* equal to the amount of data that can be sent to the stream buffer before it * equal to the amount of data that can be sent to the stream buffer before it
@ -698,9 +698,9 @@ size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVIL
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ); * size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
</pre> * </pre>
* *
* Queries a stream buffer to see how much data it contains, which is equal to * Queries a stream buffer to see how much data it contains, which is equal to
* the number of bytes that can be read from the stream buffer before the stream * the number of bytes that can be read from the stream buffer before the stream
@ -719,9 +719,9 @@ size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILE
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ); * BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
</pre> * </pre>
* *
* A stream buffer's trigger level is the number of bytes that must be in the * A stream buffer's trigger level is the number of bytes that must be in the
* stream buffer before a task that is blocked on the stream buffer to * stream buffer before a task that is blocked on the stream buffer to
@ -751,14 +751,15 @@ BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, siz
* \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION; BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
size_t xTriggerLevel ) PRIVILEGED_FUNCTION;
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
</pre> * </pre>
* *
* For advanced users only. * For advanced users only.
* *
@ -790,14 +791,15 @@ BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer
* \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
/** /**
* stream_buffer.h * stream_buffer.h
* *
<pre> * <pre>
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); * BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
</pre> * </pre>
* *
* For advanced users only. * For advanced users only.
* *
@ -830,7 +832,8 @@ BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuf
* \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR
* \ingroup StreamBufferManagement * \ingroup StreamBufferManagement
*/ */
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
/* Functions below here are not part of the public API. */ /* Functions below here are not part of the public API. */
StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
@ -846,7 +849,8 @@ StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION; void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer,
UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -33,7 +33,7 @@
#endif #endif
/*lint -save -e537 This headers are only multiply included if the application code /*lint -save -e537 This headers are only multiply included if the application code
happens to also be including task.h. */ * happens to also be including task.h. */
#include "task.h" #include "task.h"
/*lint -restore */ /*lint -restore */
@ -46,10 +46,10 @@ extern "C" {
*----------------------------------------------------------*/ *----------------------------------------------------------*/
/* IDs for commands that can be sent/received on the timer queue. These are to /* IDs for commands that can be sent/received on the timer queue. These are to
be used solely through the macros that make up the public software timer API, * be used solely through the macros that make up the public software timer API,
as defined below. The commands that are sent from interrupts must use the * as defined below. The commands that are sent from interrupts must use the
highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task * highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task
or interrupt version of the queue send function should be used. */ * or interrupt version of the queue send function should be used. */
#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 ) #define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 )
#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) #define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 )
#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 ) #define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 )
@ -84,7 +84,8 @@ typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer );
* Defines the prototype to which functions used with the * Defines the prototype to which functions used with the
* xTimerPendFunctionCallFromISR() function must conform. * xTimerPendFunctionCallFromISR() function must conform.
*/ */
typedef void (*PendedFunction_t)( void *, uint32_t ); typedef void (* PendedFunction_t)( void *,
uint32_t );
/** /**
* TimerHandle_t xTimerCreate( const char * const pcTimerName, * TimerHandle_t xTimerCreate( const char * const pcTimerName,
@ -403,7 +404,8 @@ void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* *
* See the xTimerCreate() API function example usage scenario. * See the xTimerCreate() API function example usage scenario.
*/ */
void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION; void vTimerSetTimerID( TimerHandle_t xTimer,
void * pvNewID ) PRIVILEGED_FUNCTION;
/** /**
* BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );
@ -1183,7 +1185,10 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;
* } * }
* @endverbatim * @endverbatim
*/ */
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend,
void * pvParameter1,
uint32_t ulParameter2,
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
/** /**
* BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
@ -1217,7 +1222,10 @@ BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void
* timer daemon task, otherwise pdFALSE is returned. * timer daemon task, otherwise pdFALSE is returned.
* *
*/ */
BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
void * pvParameter1,
uint32_t ulParameter2,
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
/** /**
* const char * const pcTimerGetName( TimerHandle_t xTimer ); * const char * const pcTimerGetName( TimerHandle_t xTimer );
@ -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 * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
* enter the dormant state after it expires. * enter the dormant state after it expires.
*/ */
void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION; void vTimerSetReloadMode( TimerHandle_t xTimer,
const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION;
/** /**
* UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ); * UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer );
@ -1292,10 +1301,15 @@ TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
* for use by the kernel only. * for use by the kernel only.
*/ */
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; BaseType_t xTimerGenericCommand( TimerHandle_t xTimer,
const BaseType_t xCommandID,
const TickType_t xOptionalValue,
BaseType_t * const pxHigherPriorityTaskWoken,
const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
#if ( configUSE_TRACE_FACILITY == 1 ) #if ( configUSE_TRACE_FACILITY == 1 )
void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION; void vTimerSetTimerNumber( TimerHandle_t xTimer,
UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION;
UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
#endif #endif
@ -1303,6 +1317,3 @@ BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommand
} }
#endif #endif
#endif /* TIMERS_H */ #endif /* TIMERS_H */

89
list.c
View file

@ -36,23 +36,23 @@
void vListInitialise( List_t * const pxList ) void vListInitialise( List_t * const pxList )
{ {
/* The list structure contains a list item which is used to mark the /* The list structure contains a list item which is used to mark the
end of the list. To initialise the list the list end is inserted * end of the list. To initialise the list the list end is inserted
as the only list entry. */ * as the only list entry. */
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
/* The list end value is the highest possible value in the list to /* The list end value is the highest possible value in the list to
ensure it remains at the end of the list. */ * ensure it remains at the end of the list. */
pxList->xListEnd.xItemValue = portMAX_DELAY; pxList->xListEnd.xItemValue = portMAX_DELAY;
/* The list end next and previous pointers point to itself so we know /* The list end next and previous pointers point to itself so we know
when the list is empty. */ * when the list is empty. */
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
pxList->uxNumberOfItems = ( UBaseType_t ) 0U; pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
/* Write known values into the list if /* Write known values into the list if
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
} }
@ -64,25 +64,26 @@ void vListInitialiseItem( ListItem_t * const pxItem )
pxItem->pxContainer = NULL; pxItem->pxContainer = NULL;
/* Write known values into the list item if /* Write known values into the list item if
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) void vListInsertEnd( List_t * const pxList,
ListItem_t * const pxNewListItem )
{ {
ListItem_t * const pxIndex = pxList->pxIndex; ListItem_t * const pxIndex = pxList->pxIndex;
/* Only effective when configASSERT() is also defined, these tests may catch /* Only effective when configASSERT() is also defined, these tests may catch
the list data structures being overwritten in memory. They will not catch * the list data structures being overwritten in memory. They will not catch
data errors caused by incorrect configuration or use of FreeRTOS. */ * data errors caused by incorrect configuration or use of FreeRTOS. */
listTEST_LIST_INTEGRITY( pxList ); listTEST_LIST_INTEGRITY( pxList );
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
/* Insert a new list item into pxList, but rather than sort the list, /* Insert a new list item into pxList, but rather than sort the list,
makes the new list item the last item to be removed by a call to * makes the new list item the last item to be removed by a call to
listGET_OWNER_OF_NEXT_ENTRY(). */ * listGET_OWNER_OF_NEXT_ENTRY(). */
pxNewListItem->pxNext = pxIndex; pxNewListItem->pxNext = pxIndex;
pxNewListItem->pxPrevious = pxIndex->pxPrevious; pxNewListItem->pxPrevious = pxIndex->pxPrevious;
@ -99,25 +100,26 @@ ListItem_t * const pxIndex = pxList->pxIndex;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) void vListInsert( List_t * const pxList,
ListItem_t * const pxNewListItem )
{ {
ListItem_t * pxIterator; ListItem_t * pxIterator;
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
/* Only effective when configASSERT() is also defined, these tests may catch /* Only effective when configASSERT() is also defined, these tests may catch
the list data structures being overwritten in memory. They will not catch * the list data structures being overwritten in memory. They will not catch
data errors caused by incorrect configuration or use of FreeRTOS. */ * data errors caused by incorrect configuration or use of FreeRTOS. */
listTEST_LIST_INTEGRITY( pxList ); listTEST_LIST_INTEGRITY( pxList );
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
/* Insert the new list item into the list, sorted in xItemValue order. /* Insert the new list item into the list, sorted in xItemValue order.
*
If the list already contains a list item with the same item value then the * If the list already contains a list item with the same item value then the
new list item should be placed after it. This ensures that TCBs which are * new list item should be placed after it. This ensures that TCBs which are
stored in ready lists (all of which have the same xItemValue value) get a * stored in ready lists (all of which have the same xItemValue value) get a
share of the CPU. However, if the xItemValue is the same as the back marker * share of the CPU. However, if the xItemValue is the same as the back marker
the iteration loop below will not end. Therefore the value is checked * the iteration loop below will not end. Therefore the value is checked
first, and the algorithm slightly modified if necessary. */ * first, and the algorithm slightly modified if necessary. */
if( xValueOfInsertion == portMAX_DELAY ) if( xValueOfInsertion == portMAX_DELAY )
{ {
pxIterator = pxList->xListEnd.pxPrevious; pxIterator = pxList->xListEnd.pxPrevious;
@ -125,31 +127,31 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
else else
{ {
/* *** NOTE *********************************************************** /* *** NOTE ***********************************************************
If you find your application is crashing here then likely causes are * If you find your application is crashing here then likely causes are
listed below. In addition see https://www.freertos.org/FAQHelp.html for * listed below. In addition see https://www.freertos.org/FAQHelp.html for
more tips, and ensure configASSERT() is defined! * more tips, and ensure configASSERT() is defined!
https://www.freertos.org/a00110.html#configASSERT * https://www.freertos.org/a00110.html#configASSERT
*
1) Stack overflow - * 1) Stack overflow -
see https://www.freertos.org/Stacks-and-stack-overflow-checking.html * see https://www.freertos.org/Stacks-and-stack-overflow-checking.html
2) Incorrect interrupt priority assignment, especially on Cortex-M * 2) Incorrect interrupt priority assignment, especially on Cortex-M
parts where numerically high priority values denote low actual * parts where numerically high priority values denote low actual
interrupt priorities, which can seem counter intuitive. See * interrupt priorities, which can seem counter intuitive. See
https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition * https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
of configMAX_SYSCALL_INTERRUPT_PRIORITY on * of configMAX_SYSCALL_INTERRUPT_PRIORITY on
https://www.freertos.org/a00110.html * https://www.freertos.org/a00110.html
3) Calling an API function from within a critical section or when * 3) Calling an API function from within a critical section or when
the scheduler is suspended, or calling an API function that does * the scheduler is suspended, or calling an API function that does
not end in "FromISR" from an interrupt. * not end in "FromISR" from an interrupt.
4) Using a queue or semaphore before it has been initialised or * 4) Using a queue or semaphore before it has been initialised or
before the scheduler has been started (are interrupts firing * before the scheduler has been started (are interrupts firing
before vTaskStartScheduler() has been called?). * before vTaskStartScheduler() has been called?).
**********************************************************************/ **********************************************************************/
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */ for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
{ {
/* There is nothing to do here, just iterating to the wanted /* There is nothing to do here, just iterating to the wanted
insertion position. */ * insertion position. */
} }
} }
@ -159,7 +161,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
pxIterator->pxNext = pxNewListItem; pxIterator->pxNext = pxNewListItem;
/* Remember which list the item is in. This allows fast removal of the /* Remember which list the item is in. This allows fast removal of the
item later. */ * item later. */
pxNewListItem->pxContainer = pxList; pxNewListItem->pxContainer = pxList;
( pxList->uxNumberOfItems )++; ( pxList->uxNumberOfItems )++;
@ -169,7 +171,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{ {
/* The list item knows which list it is in. Obtain the list from the list /* The list item knows which list it is in. Obtain the list from the list
item. */ * item. */
List_t * const pxList = pxItemToRemove->pxContainer; List_t * const pxList = pxItemToRemove->pxContainer;
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
@ -194,4 +196,3 @@ List_t * const pxList = pxItemToRemove->pxContainer;
return pxList->uxNumberOfItems; return pxList->uxNumberOfItems;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -85,6 +85,7 @@
/* Ensure the SysTick is clocked at the same frequency as the core. */ /* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#else #else
/* The way the SysTick is clocked is not modified in case it is not the /* The way the SysTick is clocked is not modified in case it is not the
* same a the core. */ * same a the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 0 ) #define portNVIC_SYSTICK_CLK_BIT ( 0 )
@ -205,6 +206,7 @@
#define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_XPSR ( 0x01000000 )
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
/** /**
* @brief Initial EXC_RETURN value. * @brief Initial EXC_RETURN value.
* *
@ -221,6 +223,7 @@
*/ */
#define portINITIAL_EXC_RETURN ( 0xfffffffd ) #define portINITIAL_EXC_RETURN ( 0xfffffffd )
#else #else
/** /**
* @brief Initial EXC_RETURN value. * @brief Initial EXC_RETURN value.
* *
@ -285,6 +288,7 @@
static void prvTaskExitError( void ); static void prvTaskExitError( void );
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Setup the Memory Protection Unit (MPU). * @brief Setup the Memory Protection Unit (MPU).
*/ */
@ -292,6 +296,7 @@ static void prvTaskExitError( void );
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
#if ( configENABLE_FPU == 1 ) #if ( configENABLE_FPU == 1 )
/** /**
* @brief Setup the Floating Point Unit (FPU). * @brief Setup the Floating Point Unit (FPU).
*/ */
@ -347,6 +352,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVI
static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Saved as part of the task context to indicate which context the * @brief Saved as part of the task context to indicate which context the
* task is using on the secure side. * task is using on the secure side.
@ -355,6 +361,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
#if ( configUSE_TICKLESS_IDLE == 1 ) #if ( configUSE_TICKLESS_IDLE == 1 )
/** /**
* @brief The number of SysTick increments that make up one tick period. * @brief The number of SysTick increments that make up one tick period.
*/ */
@ -396,6 +403,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
* tick periods. -1 is used because this code will execute part way * tick periods. -1 is used because this code will execute part way
* through one of the tick periods. */ * through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation ) if( ulReloadValue > ulStoppedTimerCompensation )
{ {
ulReloadValue -= ulStoppedTimerCompensation; ulReloadValue -= ulStoppedTimerCompensation;
@ -446,12 +454,14 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
* so a copy is taken. */ * so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime; xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "dsb" ::: "memory" );
__asm volatile ( "wfi" ); __asm volatile ( "wfi" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
} }
configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
/* Re-enable interrupts to allow the interrupt that brought the MCU /* Re-enable interrupts to allow the interrupt that brought the MCU
@ -590,6 +600,7 @@ volatile uint32_t ulDummy = 0UL;
static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */
{ {
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_start__;
@ -600,7 +611,7 @@ volatile uint32_t ulDummy = 0UL;
extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __unprivileged_flash_end__;
extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_start__;
extern uint32_t * __privileged_sram_end__; extern uint32_t * __privileged_sram_end__;
#else #else /* if defined( __ARMCC_VERSION ) */
/* Declaration when these variable are exported from linker scripts. */ /* Declaration when these variable are exported from linker scripts. */
extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_start__[];
extern uint32_t __privileged_functions_end__[]; extern uint32_t __privileged_functions_end__[];
@ -753,6 +764,7 @@ void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION
{ {
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_start__;
@ -783,7 +795,7 @@ uint8_t ucSVCNumber;
{ {
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
case portSVC_ALLOCATE_SECURE_CONTEXT: case portSVC_ALLOCATE_SECURE_CONTEXT:
{
/* R0 contains the stack size passed as parameter to the /* R0 contains the stack size passed as parameter to the
* vPortAllocateSecureContext function. */ * vPortAllocateSecureContext function. */
ulR0 = pulCallerStackAddress[ 0 ]; ulR0 = pulCallerStackAddress[ 0 ];
@ -800,7 +812,7 @@ uint8_t ucSVCNumber;
/* Allocate and load a context for the secure task. */ /* Allocate and load a context for the secure task. */
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
} }
#else #else /* if ( configENABLE_MPU == 1 ) */
{ {
/* Allocate and load a context for the secure task. */ /* Allocate and load a context for the secure task. */
xSecureContext = SecureContext_AllocateContext( ulR0 ); xSecureContext = SecureContext_AllocateContext( ulR0 );
@ -809,22 +821,18 @@ uint8_t ucSVCNumber;
configASSERT( xSecureContext != NULL ); configASSERT( xSecureContext != NULL );
SecureContext_LoadContext( xSecureContext ); SecureContext_LoadContext( xSecureContext );
}
break; break;
case portSVC_FREE_SECURE_CONTEXT: case portSVC_FREE_SECURE_CONTEXT:
{
/* R0 contains the secure context handle to be freed. */ /* R0 contains the secure context handle to be freed. */
ulR0 = pulCallerStackAddress[ 0 ]; ulR0 = pulCallerStackAddress[ 0 ];
/* Free the secure context. */ /* Free the secure context. */
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 );
}
break; break;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER: case portSVC_START_SCHEDULER:
{
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
{ {
/* De-prioritize the non-secure exceptions so that the /* De-prioritize the non-secure exceptions so that the
@ -846,36 +854,39 @@ uint8_t ucSVCNumber;
/* Setup the context of the first task so that the first task starts /* Setup the context of the first task so that the first task starts
* executing. */ * executing. */
vRestoreContextOfFirstTask(); vRestoreContextOfFirstTask();
}
break; break;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
case portSVC_RAISE_PRIVILEGE: case portSVC_RAISE_PRIVILEGE:
{
/* Only raise the privilege, if the svc was raised from any of /* Only raise the privilege, if the svc was raised from any of
* the system calls. */ * the system calls. */
if( ulPC >= ( uint32_t ) __syscalls_flash_start__ && if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) &&
ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) )
{ {
vRaisePrivilege(); vRaisePrivilege();
} }
}
break; break;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
default: default:
{
/* Incorrect SVC call. */ /* Incorrect SVC call. */
configASSERT( pdFALSE ); configASSERT( pdFALSE );
} }
} }
}
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack,
TaskFunction_t pxCode,
void * pvParameters,
BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */
#else #else
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) /* PRIVILEGED_FUNCTION */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack,
TaskFunction_t pxCode,
void * pvParameters ) /* PRIVILEGED_FUNCTION */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
{ {
/* Simulate the stack frame as it would be created by a context switch /* Simulate the stack frame as it would be created by a context switch
@ -896,6 +907,7 @@ uint8_t ucSVCNumber;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
{ {
pxTopOfStack--; pxTopOfStack--;
if( xRunPrivileged == pdTRUE ) if( xRunPrivileged == pdTRUE )
{ {
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
@ -957,6 +969,7 @@ uint8_t ucSVCNumber;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
{ {
pxTopOfStack--; pxTopOfStack--;
if( xRunPrivileged == pdTRUE ) if( xRunPrivileged == pdTRUE )
{ {
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
@ -1030,7 +1043,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
const struct xMEMORY_REGION * const xRegions,
StackType_t * pxBottomOfStack,
uint32_t ulStackDepth )
{ {
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
int32_t lIndex = 0; int32_t lIndex = 0;

View file

@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *

View file

@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *

View file

@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *

View file

@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *

View file

@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *

View file

@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *

View file

@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *

View file

@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *

View file

@ -95,7 +95,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
uint32_t ulIsTaskPrivileged )
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
@ -103,6 +104,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
uint8_t * pucStackMemory = NULL; uint8_t * pucStackMemory = NULL;
uint32_t ulIPSR; uint32_t ulIPSR;
SecureContextHandle_t xSecureContextHandle = NULL; SecureContextHandle_t xSecureContextHandle = NULL;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
uint32_t * pulCurrentStackPointer = NULL; uint32_t * pulCurrentStackPointer = NULL;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
@ -143,6 +145,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
* context switch. */ * context switch. */
pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart; pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
pulCurrentStackPointer--; pulCurrentStackPointer--;
if( ulIsTaskPrivileged ) if( ulIsTaskPrivileged )
{ {
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED; *( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
@ -161,7 +164,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
/* Current SP is set to the starting of the stack. This /* Current SP is set to the starting of the stack. This
* value programmed in the PSP register on context switch. */ * value programmed in the PSP register on context switch. */
xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart; xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
} }
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
} }

View file

@ -69,7 +69,8 @@ void SecureContext_Init( void );
* otherwise. * otherwise.
*/ */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged ); SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
uint32_t ulIsTaskPrivileged );
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ); SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */

View file

@ -62,6 +62,7 @@
/* Allocate the memory for the heap. */ /* Allocate the memory for the heap. */
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) #if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
/* The application writer has already defined the array used for the RTOS /* The application writer has already defined the array used for the RTOS
* heap - probably so it can be placed in a special segment or address. */ * heap - probably so it can be placed in a special segment or address. */
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
@ -190,6 +191,7 @@ uint8_t *puc;
/* Do the block being inserted, and the block it is being inserted after /* Do the block being inserted, and the block it is being inserted after
* make a contiguous block of memory? */ * make a contiguous block of memory? */
puc = ( uint8_t * ) pxIterator; puc = ( uint8_t * ) pxIterator;
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
{ {
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
@ -203,6 +205,7 @@ uint8_t *puc;
/* Do the block being inserted, and the block it is being inserted before /* Do the block being inserted, and the block it is being inserted before
* make a contiguous block of memory? */ * make a contiguous block of memory? */
puc = ( uint8_t * ) pxBlockToInsert; puc = ( uint8_t * ) pxBlockToInsert;
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
{ {
if( pxIterator->pxNextFreeBlock != pxEnd ) if( pxIterator->pxNextFreeBlock != pxEnd )
@ -288,6 +291,7 @@ void *pvReturn = NULL;
* one of adequate size is found. */ * one of adequate size is found. */
pxPreviousBlock = &xStart; pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock; pxBlock = xStart.pxNextFreeBlock;
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
{ {
pxPreviousBlock = pxBlock; pxPreviousBlock = pxBlock;
@ -375,7 +379,7 @@ void *pvReturn = NULL;
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
#endif #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
return pvReturn; return pvReturn;

View file

@ -126,7 +126,7 @@
{ \ { \
secureportDISABLE_SECURE_INTERRUPTS(); \ secureportDISABLE_SECURE_INTERRUPTS(); \
secureportDISABLE_NON_SECURE_INTERRUPTS(); \ secureportDISABLE_NON_SECURE_INTERRUPTS(); \
for( ;; ); \ for( ; ; ) {; } \
} }
#endif /* __SECURE_PORT_MACROS_H__ */ #endif /* __SECURE_PORT_MACROS_H__ */

View file

@ -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 + Call to taskYIELD() from within tick ISR has been replaced by the more
efficient portSWITCH_CONTEXT(). + efficient portSWITCH_CONTEXT().
+ ISR function definitions renamed to include the prv prefix. + ISR function definitions renamed to include the prv prefix.
+
Changes from V2.6.1 + Changes from V2.6.1
+
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION + Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
macro to be consistent with the later ports. + macro to be consistent with the later ports.
*/ */
/*----------------------------------------------------------- /*-----------------------------------------------------------
@ -67,14 +67,16 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz );
static void prvExitFunction( void ); static void prvExitFunction( void );
/* The ISR used depends on whether the preemptive or cooperative scheduler /* The ISR used depends on whether the preemptive or cooperative scheduler
is being used. */ * is being used. */
#if ( configUSE_PREEMPTION == 1 ) #if ( configUSE_PREEMPTION == 1 )
/* Tick service routine used by the scheduler when preemptive scheduling is /* Tick service routine used by the scheduler when preemptive scheduling is
being used. */ * being used. */
static void __interrupt __far prvPreemptiveTick( void ); static void __interrupt __far prvPreemptiveTick( void );
#else #else
/* Tick service routine used by the scheduler when cooperative scheduling is /* Tick service routine used by the scheduler when cooperative scheduling is
being used. */ * being used. */
static void __interrupt __far prvNonPreemptiveTick( void ); static void __interrupt __far prvNonPreemptiveTick( void );
#endif #endif
@ -87,8 +89,8 @@ static void __interrupt __far prvYieldProcessor( void );
static BaseType_t xSchedulerRunning = pdFALSE; static BaseType_t xSchedulerRunning = pdFALSE;
/* Points to the original routine installed on the vector we use for manual /* Points to the original routine installed on the vector we use for manual
context switches. This is then used to restore the original routine during * context switches. This is then used to restore the original routine during
prvExitFunction(). */ * prvExitFunction(). */
static void( __interrupt __far * pxOldSwitchISR )(); static void( __interrupt __far * pxOldSwitchISR )();
/* Used to restore the original DOS context when the scheduler is ended. */ /* Used to restore the original DOS context when the scheduler is ended. */
@ -102,11 +104,11 @@ BaseType_t xPortStartScheduler( void )
/* This is called with interrupts already disabled. */ /* This is called with interrupts already disabled. */
/* Remember what was on the interrupts we are going to use /* Remember what was on the interrupts we are going to use
so we can put them back later if required. */ * so we can put them back later if required. */
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER ); pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
/* Put our manual switch (yield) function on a known /* Put our manual switch (yield) function on a known
vector. */ * vector. */
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor ); _dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
#if ( configUSE_PREEMPTION == 1 ) #if ( configUSE_PREEMPTION == 1 )
@ -142,7 +144,7 @@ BaseType_t xPortStartScheduler( void )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The ISR used depends on whether the preemptive or cooperative scheduler /* The ISR used depends on whether the preemptive or cooperative scheduler
is being used. */ * is being used. */
#if ( configUSE_PREEMPTION == 1 ) #if ( configUSE_PREEMPTION == 1 )
static void __interrupt __far prvPreemptiveTick( void ) static void __interrupt __far prvPreemptiveTick( void )
{ {
@ -156,15 +158,15 @@ is being used. */
/* Reset the PIC ready for the next time. */ /* Reset the PIC ready for the next time. */
portRESET_PIC(); portRESET_PIC();
} }
#else #else /* if ( configUSE_PREEMPTION == 1 ) */
static void __interrupt __far prvNonPreemptiveTick( void ) static void __interrupt __far prvNonPreemptiveTick( void )
{ {
/* Same as preemptive tick, but the cooperative scheduler is being used /* Same as preemptive tick, but the cooperative scheduler is being used
so we don't have to switch in the context of the next task. */ * so we don't have to switch in the context of the next task. */
xTaskIncrementTick(); xTaskIncrementTick();
portRESET_PIC(); portRESET_PIC();
} }
#endif #endif /* if ( configUSE_PREEMPTION == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void __interrupt __far prvYieldProcessor( void ) static void __interrupt __far prvYieldProcessor( void )
@ -177,8 +179,8 @@ static void __interrupt __far prvYieldProcessor( void )
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Jump back to the processor state prior to starting the /* Jump back to the processor state prior to starting the
scheduler. This means we are not going to be using a * scheduler. This means we are not going to be using a
task stack frame so the task can be deleted. */ * task stack frame so the task can be deleted. */
longjmp( xJumpBuf, 1 ); longjmp( xJumpBuf, 1 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -189,18 +191,19 @@ const uint16_t usTimerDisable = 0x0000;
uint16_t usTimer0Control; uint16_t usTimer0Control;
/* Interrupts should be disabled here anyway - but no /* Interrupts should be disabled here anyway - but no
harm in making sure. */ * harm in making sure. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
if( xSchedulerRunning == pdTRUE ) if( xSchedulerRunning == pdTRUE )
{ {
/* Put back the switch interrupt routines that was in place /* Put back the switch interrupt routines that was in place
before the scheduler started. */ * before the scheduler started. */
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR ); _dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
} }
/* Disable the timer used for the tick to ensure the scheduler is /* Disable the timer used for the tick to ensure the scheduler is
not called before restoring interrupts. There was previously nothing * not called before restoring interrupts. There was previously nothing
on this timer so there is no old ISR to restore. */ * on this timer so there is no old ISR to restore. */
portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerDisable ); portOUTPUT_WORD( portTIMER_1_CONTROL_REGISTER, usTimerDisable );
/* Restart the DOS tick. */ /* Restart the DOS tick. */
@ -240,4 +243,3 @@ uint32_t ulTimerCount = ulClockFrequency / ulTickRateHz;
/*lint +e950 */ /*lint +e950 */

View file

@ -60,7 +60,8 @@ typedef unsigned short UBaseType_t;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section handling. */ /* Critical section handling. */
#define portENTER_CRITICAL() __asm{ pushf } \ #define portENTER_CRITICAL() \
__asm{ pushf } \
__asm{ cli } \ __asm{ cli } \
#define portEXIT_CRITICAL() __asm{ popf } #define portEXIT_CRITICAL() __asm{ popf }
@ -93,4 +94,3 @@ typedef unsigned short UBaseType_t;
#define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters ) #define portTASK_FUNCTION( vTaskFunction, vParameters ) void vTaskFunction( void * pvParameters )
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -25,15 +25,15 @@
*/ */
/* /*
Changes from V2.6.1 * Changes from V2.6.1
*
+ Replaced the sUsingPreemption variable with the configUSE_PREEMPTION + Replaced the sUsingPreemption variable with the configUSE_PREEMPTION
macro to be consistent with the later ports. + macro to be consistent with the later ports.
+
Changes from V4.0.1 + Changes from V4.0.1
+
+ Add function prvSetTickFrequencyDefault() to set the DOS tick back to + Add function prvSetTickFrequencyDefault() to set the DOS tick back to
its proper value when the scheduler exits. + its proper value when the scheduler exits.
*/ */
#include <stdlib.h> #include <stdlib.h>
@ -60,19 +60,21 @@ static void prvSetTickFrequency( uint32_t ulTickRateHz );
static void prvExitFunction( void ); static void prvExitFunction( void );
/* Either chain to the DOS tick (which itself clears the PIC) or clear the PIC /* Either chain to the DOS tick (which itself clears the PIC) or clear the PIC
directly. We chain to the DOS tick as close as possible to the standard DOS * directly. We chain to the DOS tick as close as possible to the standard DOS
tick rate. */ * tick rate. */
static void prvPortResetPIC( void ); static void prvPortResetPIC( void );
/* The ISR used depends on whether the preemptive or cooperative /* The ISR used depends on whether the preemptive or cooperative
scheduler is being used. */ * scheduler is being used. */
#if ( configUSE_PREEMPTION == 1 ) #if ( configUSE_PREEMPTION == 1 )
/* Tick service routine used by the scheduler when preemptive scheduling is /* Tick service routine used by the scheduler when preemptive scheduling is
being used. */ * being used. */
static void __interrupt __far prvPreemptiveTick( void ); static void __interrupt __far prvPreemptiveTick( void );
#else #else
/* Tick service routine used by the scheduler when cooperative scheduling is /* Tick service routine used by the scheduler when cooperative scheduling is
being used. */ * being used. */
static void __interrupt __far prvNonPreemptiveTick( void ); static void __interrupt __far prvNonPreemptiveTick( void );
#endif #endif
@ -80,7 +82,7 @@ scheduler is being used. */
static void __interrupt __far prvYieldProcessor( void ); static void __interrupt __far prvYieldProcessor( void );
/* Set the tick frequency back so the floppy drive works correctly when the /* Set the tick frequency back so the floppy drive works correctly when the
scheduler exits. */ * scheduler exits. */
static void prvSetTickFrequencyDefault( void ); static void prvSetTickFrequencyDefault( void );
/*lint -e956 File scopes necessary here. */ /*lint -e956 File scopes necessary here. */
@ -110,7 +112,7 @@ pxISR pxOriginalTickISR;
/* This is called with interrupts already disabled. */ /* This is called with interrupts already disabled. */
/* Remember what was on the interrupts we are going to use /* Remember what was on the interrupts we are going to use
so we can put them back later if required. */ * so we can put them back later if required. */
pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER ); pxOldSwitchISR = _dos_getvect( portSWITCH_INT_NUMBER );
pxOriginalTickISR = _dos_getvect( portTIMER_INT_NUMBER ); pxOriginalTickISR = _dos_getvect( portTIMER_INT_NUMBER );
pxOldSwitchISRPlus1 = _dos_getvect( portSWITCH_INT_NUMBER + 1 ); pxOldSwitchISRPlus1 = _dos_getvect( portSWITCH_INT_NUMBER + 1 );
@ -118,15 +120,15 @@ pxISR pxOriginalTickISR;
prvSetTickFrequency( configTICK_RATE_HZ ); prvSetTickFrequency( configTICK_RATE_HZ );
/* Put our manual switch (yield) function on a known /* Put our manual switch (yield) function on a known
vector. */ * vector. */
_dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor ); _dos_setvect( portSWITCH_INT_NUMBER, prvYieldProcessor );
/* Put the old tick on a different interrupt number so we can /* Put the old tick on a different interrupt number so we can
call it when we want. */ * call it when we want. */
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOriginalTickISR ); _dos_setvect( portSWITCH_INT_NUMBER + 1, pxOriginalTickISR );
/* The ISR used depends on whether the preemptive or cooperative /* The ISR used depends on whether the preemptive or cooperative
scheduler is being used. */ * scheduler is being used. */
#if ( configUSE_PREEMPTION == 1 ) #if ( configUSE_PREEMPTION == 1 )
{ {
/* Put our tick switch function on the timer interrupt. */ /* Put our tick switch function on the timer interrupt. */
@ -140,8 +142,8 @@ pxISR pxOriginalTickISR;
#endif #endif
/* Setup a counter that is used to call the DOS interrupt as close /* Setup a counter that is used to call the DOS interrupt as close
to it's original frequency as can be achieved given our chosen tick * to it's original frequency as can be achieved given our chosen tick
frequency. */ * frequency. */
sDOSTickCounter = portTICKS_PER_DOS_TICK; sDOSTickCounter = portTICKS_PER_DOS_TICK;
/* Clean up function if we want to return to DOS. */ /* Clean up function if we want to return to DOS. */
@ -163,7 +165,7 @@ pxISR pxOriginalTickISR;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* The ISR used depends on whether the preemptive or cooperative /* The ISR used depends on whether the preemptive or cooperative
scheduler is being used. */ * scheduler is being used. */
#if ( configUSE_PREEMPTION == 1 ) #if ( configUSE_PREEMPTION == 1 )
static void __interrupt __far prvPreemptiveTick( void ) static void __interrupt __far prvPreemptiveTick( void )
{ {
@ -177,15 +179,15 @@ scheduler is being used. */
/* Reset the PIC ready for the next time. */ /* Reset the PIC ready for the next time. */
prvPortResetPIC(); prvPortResetPIC();
} }
#else #else /* if ( configUSE_PREEMPTION == 1 ) */
static void __interrupt __far prvNonPreemptiveTick( void ) static void __interrupt __far prvNonPreemptiveTick( void )
{ {
/* Same as preemptive tick, but the cooperative scheduler is being used /* Same as preemptive tick, but the cooperative scheduler is being used
so we don't have to switch in the context of the next task. */ * so we don't have to switch in the context of the next task. */
xTaskIncrementTick(); xTaskIncrementTick();
prvPortResetPIC(); prvPortResetPIC();
} }
#endif #endif /* if ( configUSE_PREEMPTION == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void __interrupt __far prvYieldProcessor( void ) static void __interrupt __far prvYieldProcessor( void )
@ -198,19 +200,22 @@ static void __interrupt __far prvYieldProcessor( void )
static void prvPortResetPIC( void ) static void prvPortResetPIC( void )
{ {
/* We are going to call the DOS tick interrupt at as close a /* We are going to call the DOS tick interrupt at as close a
frequency to the normal DOS tick as possible. */ * frequency to the normal DOS tick as possible. */
/* WE SHOULD NOT DO THIS IF YIELD WAS CALLED. */ /* WE SHOULD NOT DO THIS IF YIELD WAS CALLED. */
--sDOSTickCounter; --sDOSTickCounter;
if( sDOSTickCounter <= 0 ) if( sDOSTickCounter <= 0 )
{ {
sDOSTickCounter = ( int16_t ) portTICKS_PER_DOS_TICK; sDOSTickCounter = ( int16_t ) portTICKS_PER_DOS_TICK;
__asm{ int portSWITCH_INT_NUMBER + 1 }; __asm {
int portSWITCH_INT_NUMBER + 1
};
} }
else else
{ {
/* Reset the PIC as the DOS tick is not being called to /* Reset the PIC as the DOS tick is not being called to
do it. */ * do it. */
__asm __asm
{ {
mov al, 20H mov al, 20H
@ -223,8 +228,8 @@ static void prvPortResetPIC( void )
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Jump back to the processor state prior to starting the /* Jump back to the processor state prior to starting the
scheduler. This means we are not going to be using a * scheduler. This means we are not going to be using a
task stack frame so the task can be deleted. */ * task stack frame so the task can be deleted. */
longjmp( xJumpBuf, 1 ); longjmp( xJumpBuf, 1 );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -234,8 +239,9 @@ static void prvExitFunction( void )
void( __interrupt __far * pxOriginalTickISR )(); void( __interrupt __far * pxOriginalTickISR )();
/* Interrupts should be disabled here anyway - but no /* Interrupts should be disabled here anyway - but no
harm in making sure. */ * harm in making sure. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
if( xSchedulerRunning == pdTRUE ) if( xSchedulerRunning == pdTRUE )
{ {
/* Set the DOS tick back onto the timer ticker. */ /* Set the DOS tick back onto the timer ticker. */
@ -244,12 +250,13 @@ void ( __interrupt __far *pxOriginalTickISR )();
prvSetTickFrequencyDefault(); prvSetTickFrequencyDefault();
/* Put back the switch interrupt routines that was in place /* Put back the switch interrupt routines that was in place
before the scheduler started. */ * before the scheduler started. */
_dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR ); _dos_setvect( portSWITCH_INT_NUMBER, pxOldSwitchISR );
_dos_setvect( portSWITCH_INT_NUMBER + 1, pxOldSwitchISRPlus1 ); _dos_setvect( portSWITCH_INT_NUMBER + 1, pxOldSwitchISRPlus1 );
} }
/* The tick timer is back how DOS wants it. We can re-enable /* The tick timer is back how DOS wants it. We can re-enable
interrupts without the scheduler being called. */ * interrupts without the scheduler being called. */
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -284,4 +291,3 @@ const uint16_t us8254_CTR0_MODE3 = ( uint16_t ) 0x36;
/*lint +e950 */ /*lint +e950 */

View file

@ -60,7 +60,8 @@ typedef unsigned short UBaseType_t;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section management. */ /* Critical section management. */
#define portENTER_CRITICAL() __asm{ pushf } \ #define portENTER_CRITICAL() \
__asm{ pushf } \
__asm{ cli } \ __asm{ cli } \
#define portEXIT_CRITICAL() __asm{ popf } #define portEXIT_CRITICAL() __asm{ popf }
@ -93,4 +94,3 @@ typedef unsigned short UBaseType_t;
#define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void * pvParameters ) #define portTASK_FUNCTION( vTaskFunction, pvParameters ) void vTaskFunction( void * pvParameters )
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -46,10 +46,10 @@ void portSWITCH_CONTEXT( void );
void portFIRST_CONTEXT( void ); void portFIRST_CONTEXT( void );
/* There are slightly different versions depending on whether you are building /* There are slightly different versions depending on whether you are building
to include debugger information. If debugger information is used then there * to include debugger information. If debugger information is used then there
are a couple of extra bytes left of the ISR stack (presumably for use by the * are a couple of extra bytes left of the ISR stack (presumably for use by the
debugger). The true stack pointer is then stored in the bp register. We add * debugger). The true stack pointer is then stored in the bp register. We add
2 to the stack pointer to remove the extra bytes before we restore our context. */ * 2 to the stack pointer to remove the extra bytes before we restore our context. */
#define portSWITCH_CONTEXT() \ #define portSWITCH_CONTEXT() \
asm { mov ax, seg pxCurrentTCB } \ asm { mov ax, seg pxCurrentTCB } \
@ -82,5 +82,4 @@ debugger). The true stack pointer is then stored in the bp register. We add
__asm { iret } __asm { iret }
#endif #endif /* ifndef PORT_ASM_H */

View file

@ -25,14 +25,14 @@
*/ */
/* /*
Changes from V1.00: * Changes from V1.00:
*
+ pxPortInitialiseStack() now initialises the stack of new tasks to the + pxPortInitialiseStack() now initialises the stack of new tasks to the
same format used by the compiler. This allows the compiler generated + same format used by the compiler. This allows the compiler generated
interrupt mechanism to be used for context switches. + interrupt mechanism to be used for context switches.
+
Changes from V2.6.1 + Changes from V2.6.1
+
+ Move usPortCheckFreeStackSpace() to tasks.c. + Move usPortCheckFreeStackSpace() to tasks.c.
*/ */
@ -44,12 +44,14 @@ Changes from V2.6.1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* See header file for description. */ /* See header file for description. */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
StackType_t DS_Reg = 0; StackType_t DS_Reg = 0;
/* Place a few bytes of known values on the bottom of the stack. /* Place a few bytes of known values on the bottom of the stack.
This is just useful for debugging. */ * This is just useful for debugging. */
*pxTopOfStack = 0x1111; *pxTopOfStack = 0x1111;
pxTopOfStack--; pxTopOfStack--;
@ -66,8 +68,8 @@ StackType_t DS_Reg = 0;
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */ /*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
/* We are going to start the scheduler using a return from interrupt /* We are going to start the scheduler using a return from interrupt
instruction to load the program counter, so first there would be the * instruction to load the program counter, so first there would be the
function call with parameters preamble. */ * function call with parameters preamble. */
*pxTopOfStack = FP_SEG( pvParameters ); *pxTopOfStack = FP_SEG( pvParameters );
pxTopOfStack--; pxTopOfStack--;
@ -87,8 +89,8 @@ StackType_t DS_Reg = 0;
pxTopOfStack--; pxTopOfStack--;
/* The remaining registers would be pushed on the stack by our context /* The remaining registers would be pushed on the stack by our context
switch function. These are loaded with values simply to make debugging * switch function. These are loaded with values simply to make debugging
easier. */ * easier. */
*pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */ *pxTopOfStack = ( StackType_t ) 0xAAAA; /* AX */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */ *pxTopOfStack = ( StackType_t ) 0xBBBB; /* BX */
@ -101,7 +103,9 @@ StackType_t DS_Reg = 0;
pxTopOfStack--; pxTopOfStack--;
/* We need the true data segment. */ /* We need the true data segment. */
__asm{ MOV DS_Reg, DS }; __asm {
MOV DS_Reg, DS
};
*pxTopOfStack = DS_Reg; /* DS */ *pxTopOfStack = DS_Reg; /* DS */
pxTopOfStack--; pxTopOfStack--;
@ -116,4 +120,3 @@ StackType_t DS_Reg = 0;
return pxTopOfStack; return pxTopOfStack;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -33,7 +33,7 @@
#include "task.h" #include "task.h"
#if ( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 ) #if ( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 )
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
#endif #endif
#ifndef configSYSTICK_CLOCK_HZ #ifndef configSYSTICK_CLOCK_HZ
@ -41,8 +41,9 @@
/* Ensure the SysTick is clocked at the same frequency as the core. */ /* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#else #else
/* The way the SysTick is clocked is not modified in case it is not the same /* 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 ) #define portNVIC_SYSTICK_CLK_BIT ( 0 )
#endif #endif
@ -81,12 +82,12 @@
#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) #define portMAX_24_BIT_NUMBER ( 0xffffffUL )
/* A fiddle factor to estimate the number of SysTick counts that would have /* A fiddle factor to estimate the number of SysTick counts that would have
occurred while the SysTick counter is stopped during tickless idle * occurred while the SysTick counter is stopped during tickless idle
calculations. */ * calculations. */
#define portMISSED_COUNTS_FACTOR ( 45UL ) #define portMISSED_COUNTS_FACTOR ( 45UL )
/* For strict compliance with the Cortex-M spec the task start address should /* For strict compliance with the Cortex-M spec the task start address should
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
/* /*
@ -114,11 +115,11 @@ static void prvTaskExitError( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY /* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY
setting. */ * setting. */
const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY; const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY;
/* Each task maintains its own interrupt status in the critical nesting /* Each task maintains its own interrupt status in the critical nesting
variable. */ * variable. */
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/* /*
@ -165,10 +166,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
void * pvParameters ) void * pvParameters )
{ {
/* Simulate the stack frame as it would be created by a context switch /* Simulate the stack frame as it would be created by a context switch
interrupt. */ * interrupt. */
/* Offset added to account for the way the MCU uses the stack on entry/exit /* Offset added to account for the way the MCU uses the stack on entry/exit
of interrupts, and to ensure alignment. */ * of interrupts, and to ensure alignment. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */
@ -190,14 +191,17 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
static void prvTaskExitError( void ) static void prvTaskExitError( void )
{ {
/* A function that implements a task must not exit or attempt to return to /* A function that implements a task must not exit or attempt to return to
its caller as there is nothing to return to. If a task wants to exit it * its caller as there is nothing to return to. If a task wants to exit it
should instead call vTaskDelete( NULL ). * should instead call vTaskDelete( NULL ).
*
Artificially force an assert() to be triggered if configASSERT() is * Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */ * defined, then stop here so application writers can catch the error. */
configASSERT( uxCriticalNesting == ~0UL ); configASSERT( uxCriticalNesting == ~0UL );
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -213,15 +217,15 @@ BaseType_t xPortStartScheduler( void )
volatile uint8_t ucMaxPriorityValue; volatile uint8_t ucMaxPriorityValue;
/* Determine the maximum priority from which ISR safe FreeRTOS API /* Determine the maximum priority from which ISR safe FreeRTOS API
functions can be called. ISR safe functions are those that end in * functions can be called. ISR safe functions are those that end in
"FromISR". FreeRTOS maintains separate thread and ISR API functions to * "FromISR". FreeRTOS maintains separate thread and ISR API functions to
ensure interrupt entry is as fast and simple as possible. * ensure interrupt entry is as fast and simple as possible.
*
Save the interrupt priority value that is about to be clobbered. */ * Save the interrupt priority value that is about to be clobbered. */
ulOriginalPriority = *pucFirstUserPriorityRegister; ulOriginalPriority = *pucFirstUserPriorityRegister;
/* Determine the number of priority bits available. First write to all /* Determine the number of priority bits available. First write to all
possible bits. */ * possible bits. */
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
/* Read the value back to see how many bits stuck. */ /* Read the value back to see how many bits stuck. */
@ -231,8 +235,9 @@ BaseType_t xPortStartScheduler( void )
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
/* Calculate the maximum acceptable priority group value for the number /* Calculate the maximum acceptable priority group value for the number
of bits read back. */ * of bits read back. */
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{ {
ulMaxPRIGROUPValue--; ulMaxPRIGROUPValue--;
@ -242,8 +247,8 @@ BaseType_t xPortStartScheduler( void )
#ifdef __NVIC_PRIO_BITS #ifdef __NVIC_PRIO_BITS
{ {
/* Check the CMSIS configuration that defines the number of /* Check the CMSIS configuration that defines the number of
priority bits matches the number of priority bits actually queried * priority bits matches the number of priority bits actually queried
from the hardware. */ * from the hardware. */
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
} }
#endif #endif
@ -251,19 +256,19 @@ BaseType_t xPortStartScheduler( void )
#ifdef configPRIO_BITS #ifdef configPRIO_BITS
{ {
/* Check the FreeRTOS configuration that defines the number of /* Check the FreeRTOS configuration that defines the number of
priority bits matches the number of priority bits actually queried * priority bits matches the number of priority bits actually queried
from the hardware. */ * from the hardware. */
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
} }
#endif #endif
/* Shift the priority group value back to its position within the AIRCR /* Shift the priority group value back to its position within the AIRCR
register. */ * register. */
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
/* Restore the clobbered interrupt priority register to its original /* Restore the clobbered interrupt priority register to its original
value. */ * value. */
*pucFirstUserPriorityRegister = ulOriginalPriority; *pucFirstUserPriorityRegister = ulOriginalPriority;
} }
#endif /* conifgASSERT_DEFINED */ #endif /* conifgASSERT_DEFINED */
@ -273,7 +278,7 @@ BaseType_t xPortStartScheduler( void )
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
/* Start the timer that generates the tick ISR. Interrupts are disabled /* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */ * here already. */
vPortSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialise the critical nesting count ready for the first task. */ /* Initialise the critical nesting count ready for the first task. */
@ -290,7 +295,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented in ports where there is nothing to return to. /* Not implemented in ports where there is nothing to return to.
Artificially force an assert. */ * Artificially force an assert. */
configASSERT( uxCriticalNesting == 1000UL ); configASSERT( uxCriticalNesting == 1000UL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -301,10 +306,10 @@ void vPortEnterCritical( void )
uxCriticalNesting++; uxCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so /* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context. Only API * assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if * functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the * the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */ * assert function also uses a critical section. */
if( uxCriticalNesting == 1 ) if( uxCriticalNesting == 1 )
{ {
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
@ -316,6 +321,7 @@ void vPortExitCritical( void )
{ {
configASSERT( uxCriticalNesting ); configASSERT( uxCriticalNesting );
uxCriticalNesting--; uxCriticalNesting--;
if( uxCriticalNesting == 0 ) if( uxCriticalNesting == 0 )
{ {
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
@ -326,16 +332,16 @@ void vPortExitCritical( void )
void xPortSysTickHandler( void ) void xPortSysTickHandler( void )
{ {
/* The SysTick runs at the lowest interrupt priority, so when this interrupt /* The SysTick runs at the lowest interrupt priority, so when this interrupt
executes all interrupts must be unmasked. There is therefore no need to * executes all interrupts must be unmasked. There is therefore no need to
save and then restore the interrupt mask value as its value is already * save and then restore the interrupt mask value as its value is already
known. */ * known. */
( void ) portSET_INTERRUPT_MASK_FROM_ISR(); ( void ) portSET_INTERRUPT_MASK_FROM_ISR();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
} }
@ -358,44 +364,44 @@ void xPortSysTickHandler( void )
} }
/* Stop the SysTick momentarily. The time the SysTick is stopped for /* Stop the SysTick momentarily. The time the SysTick is stopped for
is accounted for as best it can be, but using the tickless mode will * is accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the * inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */ * kernel with respect to calendar time. */
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
/* Calculate the reload value required to wait xExpectedIdleTime /* Calculate the reload value required to wait xExpectedIdleTime
tick periods. -1 is used because this code will execute part way * tick periods. -1 is used because this code will execute part way
through one of the tick periods. */ * through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation ) if( ulReloadValue > ulStoppedTimerCompensation )
{ {
ulReloadValue -= ulStoppedTimerCompensation; ulReloadValue -= ulStoppedTimerCompensation;
} }
/* Enter a critical section but don't use the taskENTER_CRITICAL() /* Enter a critical section but don't use the taskENTER_CRITICAL()
method as that will mask interrupts that should exit sleep mode. */ * method as that will mask interrupts that should exit sleep mode. */
__asm( " cpsid i"); __asm( " cpsid i");
__asm( " dsb"); __asm( " dsb");
__asm( " isb"); __asm( " isb");
/* If a context switch is pending or a task is waiting for the scheduler /* If a context switch is pending or a task is waiting for the scheduler
to be unsuspended then abandon the low power entry. */ * to be unsuspended then abandon the low power entry. */
if( eTaskConfirmSleepModeStatus() == eAbortSleep ) if( eTaskConfirmSleepModeStatus() == eAbortSleep )
{ {
/* Restart from whatever is left in the count register to complete /* Restart from whatever is left in the count register to complete
this tick period. */ * this tick period. */
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* Restart SysTick. */ /* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
/* Reset the reload register to the value required for normal tick /* Reset the reload register to the value required for normal tick
periods. */ * periods. */
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
/* Re-enable interrupts - see comments above __disable_interrupt() /* Re-enable interrupts - see comments above __disable_interrupt()
call above. */ * call above. */
__asm( " cpsie i"); __asm( " cpsie i");
} }
else else
@ -404,69 +410,71 @@ void xPortSysTickHandler( void )
portNVIC_SYSTICK_LOAD_REG = ulReloadValue; portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
/* Clear the SysTick count flag and set the count value back to /* Clear the SysTick count flag and set the count value back to
zero. */ * zero. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
/* Restart SysTick. */ /* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
set its parameter to 0 to indicate that its implementation contains * set its parameter to 0 to indicate that its implementation contains
its own wait for interrupt or wait for event instruction, and so wfi * its own wait for interrupt or wait for event instruction, and so wfi
should not be executed again. However, the original expected idle * should not be executed again. However, the original expected idle
time variable must remain unmodified, so a copy is taken. */ * time variable must remain unmodified, so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime; xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm( " dsb"); __asm( " dsb");
__asm( " wfi"); __asm( " wfi");
__asm( " isb"); __asm( " isb");
} }
configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
/* Re-enable interrupts to allow the interrupt that brought the MCU /* Re-enable interrupts to allow the interrupt that brought the MCU
out of sleep mode to execute immediately. see comments above * out of sleep mode to execute immediately. see comments above
__disable_interrupt() call above. */ * __disable_interrupt() call above. */
__asm( " cpsie i"); __asm( " cpsie i");
__asm( " dsb"); __asm( " dsb");
__asm( " isb"); __asm( " isb");
/* Disable interrupts again because the clock is about to be stopped /* Disable interrupts again because the clock is about to be stopped
and interrupts that execute while the clock is stopped will increase * and interrupts that execute while the clock is stopped will increase
any slippage between the time maintained by the RTOS and calendar * any slippage between the time maintained by the RTOS and calendar
time. */ * time. */
__asm( " cpsid i"); __asm( " cpsid i");
__asm( " dsb"); __asm( " dsb");
__asm( " isb"); __asm( " isb");
/* Disable the SysTick clock without reading the /* Disable the SysTick clock without reading the
portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_CTRL_REG register to ensure the
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
the time the SysTick is stopped for is accounted for as best it can * the time the SysTick is stopped for is accounted for as best it can
be, but using the tickless mode will inevitably result in some tiny * be, but using the tickless mode will inevitably result in some tiny
drift of the time maintained by the kernel with respect to calendar * drift of the time maintained by the kernel with respect to calendar
time*/ * time*/
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT ); portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
/* Determine if the SysTick clock has already counted to zero and /* Determine if the SysTick clock has already counted to zero and
been set back to the current reload value (the reload back being * been set back to the current reload value (the reload back being
correct for the entire expected idle time) or if the SysTick is yet * correct for the entire expected idle time) or if the SysTick is yet
to count to zero (in which case an interrupt other than the SysTick * to count to zero (in which case an interrupt other than the SysTick
must have brought the system out of sleep mode). */ * must have brought the system out of sleep mode). */
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
{ {
uint32_t ulCalculatedLoadValue; uint32_t ulCalculatedLoadValue;
/* The tick interrupt is already pending, and the SysTick count /* The tick interrupt is already pending, and the SysTick count
reloaded with ulReloadValue. Reset the * reloaded with ulReloadValue. Reset the
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick * portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
period. */ * period. */
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
/* Don't allow a tiny value, or values that have somehow /* Don't allow a tiny value, or values that have somehow
underflowed because the post sleep hook did something * underflowed because the post sleep hook did something
that took too long. */ * that took too long. */
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
{ {
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
@ -475,30 +483,30 @@ void xPortSysTickHandler( void )
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
/* As the pending tick will be processed as soon as this /* As the pending tick will be processed as soon as this
function exits, the tick value maintained by the tick is stepped * function exits, the tick value maintained by the tick is stepped
forward by one less than the time spent waiting. */ * forward by one less than the time spent waiting. */
ulCompleteTickPeriods = xExpectedIdleTime - 1UL; ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
} }
else else
{ {
/* Something other than the tick interrupt ended the sleep. /* Something other than the tick interrupt ended the sleep.
Work out how long the sleep lasted rounded to complete tick * Work out how long the sleep lasted rounded to complete tick
periods (not the ulReload value which accounted for part * periods (not the ulReload value which accounted for part
ticks). */ * ticks). */
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* How many complete tick periods passed while the processor /* How many complete tick periods passed while the processor
was waiting? */ * was waiting? */
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
/* The reload value is set to whatever fraction of a single tick /* The reload value is set to whatever fraction of a single tick
period remains. */ * period remains. */
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
} }
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard * again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
value. */ * value. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
vTaskStepTick( ulCompleteTickPeriods ); vTaskStepTick( ulCompleteTickPeriods );
@ -555,66 +563,45 @@ void vPortSetupTimerInterrupt( void )
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
/* The following assertion will fail if a service routine (ISR) for /* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above * an interrupt that has been assigned a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
function. ISR safe FreeRTOS API functions must *only* be called * function. ISR safe FreeRTOS API functions must *only* be called
from interrupts that have been assigned a priority at or below * from interrupts that have been assigned a priority at or below
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Numerically low interrupt priority numbers represent logically high * Numerically low interrupt priority numbers represent logically high
interrupt priorities, therefore the priority of the interrupt must * interrupt priorities, therefore the priority of the interrupt must
be set to a value equal to or numerically *higher* than * be set to a value equal to or numerically *higher* than
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Interrupts that use the FreeRTOS API must not be left at their * Interrupts that use the FreeRTOS API must not be left at their
default priority of zero as that is the highest possible priority, * default priority of zero as that is the highest possible priority,
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
and therefore also guaranteed to be invalid. * and therefore also guaranteed to be invalid.
*
FreeRTOS maintains separate thread and ISR API functions to ensure * FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible. * interrupt entry is as fast and simple as possible.
*
The following links provide detailed information: * The following links provide detailed information:
http://www.freertos.org/RTOS-Cortex-M3-M4.html * http://www.freertos.org/RTOS-Cortex-M3-M4.html
http://www.freertos.org/FAQHelp.html */ * http://www.freertos.org/FAQHelp.html */
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
} }
/* Priority grouping: The interrupt controller (NVIC) allows the bits /* Priority grouping: The interrupt controller (NVIC) allows the bits
that define each interrupt's priority to be split between bits that * that define each interrupt's priority to be split between bits that
define the interrupt's pre-emption priority bits and bits that define * define the interrupt's pre-emption priority bits and bits that define
the interrupt's sub-priority. For simplicity all bits must be defined * the interrupt's sub-priority. For simplicity all bits must be defined
to be pre-emption priority bits. The following assertion will fail if * to be pre-emption priority bits. The following assertion will fail if
this is not the case (if some bits represent a sub-priority). * this is not the case (if some bits represent a sub-priority).
*
If the application only uses CMSIS libraries for interrupt * If the application only uses CMSIS libraries for interrupt
configuration then the correct setting can be achieved on all Cortex-M * configuration then the correct setting can be achieved on all Cortex-M
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
scheduler. Note however that some vendor specific peripheral libraries * scheduler. Note however that some vendor specific peripheral libraries
assume a non-zero priority group setting, in which cases using a value * assume a non-zero priority group setting, in which cases using a value
of zero will result in unpredictable behaviour. */ * of zero will result in unpredictable behaviour. */
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
} }
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */

View file

@ -63,7 +63,7 @@ typedef unsigned long UBaseType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -146,8 +146,8 @@ extern void vPortExitCritical( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are /* Task function macros as described on the FreeRTOS.org WEB site. These are
not necessary for to use this port. They are defined so the common demo files * not necessary for to use this port. They are defined so the common demo files
(which build with all the ports) will build. */ * (which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -167,4 +167,3 @@ not necessary for to use this port. They are defined so the common demo files
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -37,7 +37,7 @@
#endif #endif
#if ( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 ) #if ( configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 )
#error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
#endif #endif
#ifndef configSYSTICK_CLOCK_HZ #ifndef configSYSTICK_CLOCK_HZ
@ -45,8 +45,9 @@
/* Ensure the SysTick is clocked at the same frequency as the core. */ /* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#else #else
/* The way the SysTick is clocked is not modified in case it is not the same /* 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 ) #define portNVIC_SYSTICK_CLK_BIT ( 0 )
#endif #endif
@ -90,12 +91,12 @@
#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) #define portMAX_24_BIT_NUMBER ( 0xffffffUL )
/* A fiddle factor to estimate the number of SysTick counts that would have /* A fiddle factor to estimate the number of SysTick counts that would have
occurred while the SysTick counter is stopped during tickless idle * occurred while the SysTick counter is stopped during tickless idle
calculations. */ * calculations. */
#define portMISSED_COUNTS_FACTOR ( 45UL ) #define portMISSED_COUNTS_FACTOR ( 45UL )
/* For strict compliance with the Cortex-M spec the task start address should /* For strict compliance with the Cortex-M spec the task start address should
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
/* /*
@ -128,11 +129,11 @@ static void prvTaskExitError( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY /* Required to allow portasm.asm access the configMAX_SYSCALL_INTERRUPT_PRIORITY
setting. */ * setting. */
const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY; const uint32_t ulMaxSyscallInterruptPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY;
/* Each task maintains its own interrupt status in the critical nesting /* Each task maintains its own interrupt status in the critical nesting
variable. */ * variable. */
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/* /*
@ -174,13 +175,15 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
/* Simulate the stack frame as it would be created by a context switch /* Simulate the stack frame as it would be created by a context switch
interrupt. */ * interrupt. */
/* Offset added to account for the way the MCU uses the stack on entry/exit /* Offset added to account for the way the MCU uses the stack on entry/exit
of interrupts, and to ensure alignment. */ * of interrupts, and to ensure alignment. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */
@ -194,7 +197,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
/* A save method is being used that requires each task to maintain its /* A save method is being used that requires each task to maintain its
own exec return value. */ * own exec return value. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = portINITIAL_EXC_RETURN; *pxTopOfStack = portINITIAL_EXC_RETURN;
@ -207,14 +210,17 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
static void prvTaskExitError( void ) static void prvTaskExitError( void )
{ {
/* A function that implements a task must not exit or attempt to return to /* A function that implements a task must not exit or attempt to return to
its caller as there is nothing to return to. If a task wants to exit it * its caller as there is nothing to return to. If a task wants to exit it
should instead call vTaskDelete( NULL ). * should instead call vTaskDelete( NULL ).
*
Artificially force an assert() to be triggered if configASSERT() is * Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */ * defined, then stop here so application writers can catch the error. */
configASSERT( uxCriticalNesting == ~0UL ); configASSERT( uxCriticalNesting == ~0UL );
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -230,15 +236,15 @@ BaseType_t xPortStartScheduler( void )
volatile uint8_t ucMaxPriorityValue; volatile uint8_t ucMaxPriorityValue;
/* Determine the maximum priority from which ISR safe FreeRTOS API /* Determine the maximum priority from which ISR safe FreeRTOS API
functions can be called. ISR safe functions are those that end in * functions can be called. ISR safe functions are those that end in
"FromISR". FreeRTOS maintains separate thread and ISR API functions to * "FromISR". FreeRTOS maintains separate thread and ISR API functions to
ensure interrupt entry is as fast and simple as possible. * ensure interrupt entry is as fast and simple as possible.
*
Save the interrupt priority value that is about to be clobbered. */ * Save the interrupt priority value that is about to be clobbered. */
ulOriginalPriority = *pucFirstUserPriorityRegister; ulOriginalPriority = *pucFirstUserPriorityRegister;
/* Determine the number of priority bits available. First write to all /* Determine the number of priority bits available. First write to all
possible bits. */ * possible bits. */
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
/* Read the value back to see how many bits stuck. */ /* Read the value back to see how many bits stuck. */
@ -248,8 +254,9 @@ BaseType_t xPortStartScheduler( void )
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
/* Calculate the maximum acceptable priority group value for the number /* Calculate the maximum acceptable priority group value for the number
of bits read back. */ * of bits read back. */
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{ {
ulMaxPRIGROUPValue--; ulMaxPRIGROUPValue--;
@ -259,8 +266,8 @@ BaseType_t xPortStartScheduler( void )
#ifdef __NVIC_PRIO_BITS #ifdef __NVIC_PRIO_BITS
{ {
/* Check the CMSIS configuration that defines the number of /* Check the CMSIS configuration that defines the number of
priority bits matches the number of priority bits actually queried * priority bits matches the number of priority bits actually queried
from the hardware. */ * from the hardware. */
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
} }
#endif #endif
@ -268,19 +275,19 @@ BaseType_t xPortStartScheduler( void )
#ifdef configPRIO_BITS #ifdef configPRIO_BITS
{ {
/* Check the FreeRTOS configuration that defines the number of /* Check the FreeRTOS configuration that defines the number of
priority bits matches the number of priority bits actually queried * priority bits matches the number of priority bits actually queried
from the hardware. */ * from the hardware. */
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
} }
#endif #endif
/* Shift the priority group value back to its position within the AIRCR /* Shift the priority group value back to its position within the AIRCR
register. */ * register. */
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
/* Restore the clobbered interrupt priority register to its original /* Restore the clobbered interrupt priority register to its original
value. */ * value. */
*pucFirstUserPriorityRegister = ulOriginalPriority; *pucFirstUserPriorityRegister = ulOriginalPriority;
} }
#endif /* conifgASSERT_DEFINED */ #endif /* conifgASSERT_DEFINED */
@ -290,7 +297,7 @@ BaseType_t xPortStartScheduler( void )
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
/* Start the timer that generates the tick ISR. Interrupts are disabled /* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */ * here already. */
vPortSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialise the critical nesting count ready for the first task. */ /* Initialise the critical nesting count ready for the first task. */
@ -313,7 +320,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented in ports where there is nothing to return to. /* Not implemented in ports where there is nothing to return to.
Artificially force an assert. */ * Artificially force an assert. */
configASSERT( uxCriticalNesting == 1000UL ); configASSERT( uxCriticalNesting == 1000UL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -324,10 +331,10 @@ void vPortEnterCritical( void )
uxCriticalNesting++; uxCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so /* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context. Only API * assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if * functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the * the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */ * assert function also uses a critical section. */
if( uxCriticalNesting == 1 ) if( uxCriticalNesting == 1 )
{ {
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
@ -339,6 +346,7 @@ void vPortExitCritical( void )
{ {
configASSERT( uxCriticalNesting ); configASSERT( uxCriticalNesting );
uxCriticalNesting--; uxCriticalNesting--;
if( uxCriticalNesting == 0 ) if( uxCriticalNesting == 0 )
{ {
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
@ -349,16 +357,16 @@ void vPortExitCritical( void )
void xPortSysTickHandler( void ) void xPortSysTickHandler( void )
{ {
/* The SysTick runs at the lowest interrupt priority, so when this interrupt /* The SysTick runs at the lowest interrupt priority, so when this interrupt
executes all interrupts must be unmasked. There is therefore no need to * executes all interrupts must be unmasked. There is therefore no need to
save and then restore the interrupt mask value as its value is already * save and then restore the interrupt mask value as its value is already
known. */ * known. */
( void ) portSET_INTERRUPT_MASK_FROM_ISR(); ( void ) portSET_INTERRUPT_MASK_FROM_ISR();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
} }
@ -381,44 +389,44 @@ void xPortSysTickHandler( void )
} }
/* Stop the SysTick momentarily. The time the SysTick is stopped for /* Stop the SysTick momentarily. The time the SysTick is stopped for
is accounted for as best it can be, but using the tickless mode will * is accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the * inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */ * kernel with respect to calendar time. */
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
/* Calculate the reload value required to wait xExpectedIdleTime /* Calculate the reload value required to wait xExpectedIdleTime
tick periods. -1 is used because this code will execute part way * tick periods. -1 is used because this code will execute part way
through one of the tick periods. */ * through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation ) if( ulReloadValue > ulStoppedTimerCompensation )
{ {
ulReloadValue -= ulStoppedTimerCompensation; ulReloadValue -= ulStoppedTimerCompensation;
} }
/* Enter a critical section but don't use the taskENTER_CRITICAL() /* Enter a critical section but don't use the taskENTER_CRITICAL()
method as that will mask interrupts that should exit sleep mode. */ * method as that will mask interrupts that should exit sleep mode. */
__asm( " cpsid i"); __asm( " cpsid i");
__asm( " dsb"); __asm( " dsb");
__asm( " isb"); __asm( " isb");
/* If a context switch is pending or a task is waiting for the scheduler /* If a context switch is pending or a task is waiting for the scheduler
to be unsuspended then abandon the low power entry. */ * to be unsuspended then abandon the low power entry. */
if( eTaskConfirmSleepModeStatus() == eAbortSleep ) if( eTaskConfirmSleepModeStatus() == eAbortSleep )
{ {
/* Restart from whatever is left in the count register to complete /* Restart from whatever is left in the count register to complete
this tick period. */ * this tick period. */
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* Restart SysTick. */ /* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
/* Reset the reload register to the value required for normal tick /* Reset the reload register to the value required for normal tick
periods. */ * periods. */
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
/* Re-enable interrupts - see comments above __disable_interrupt() /* Re-enable interrupts - see comments above __disable_interrupt()
call above. */ * call above. */
__asm( " cpsie i"); __asm( " cpsie i");
} }
else else
@ -427,69 +435,71 @@ void xPortSysTickHandler( void )
portNVIC_SYSTICK_LOAD_REG = ulReloadValue; portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
/* Clear the SysTick count flag and set the count value back to /* Clear the SysTick count flag and set the count value back to
zero. */ * zero. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
/* Restart SysTick. */ /* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
set its parameter to 0 to indicate that its implementation contains * set its parameter to 0 to indicate that its implementation contains
its own wait for interrupt or wait for event instruction, and so wfi * its own wait for interrupt or wait for event instruction, and so wfi
should not be executed again. However, the original expected idle * should not be executed again. However, the original expected idle
time variable must remain unmodified, so a copy is taken. */ * time variable must remain unmodified, so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime; xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm( " dsb"); __asm( " dsb");
__asm( " wfi"); __asm( " wfi");
__asm( " isb"); __asm( " isb");
} }
configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
/* Re-enable interrupts to allow the interrupt that brought the MCU /* Re-enable interrupts to allow the interrupt that brought the MCU
out of sleep mode to execute immediately. see comments above * out of sleep mode to execute immediately. see comments above
__disable_interrupt() call above. */ * __disable_interrupt() call above. */
__asm( " cpsie i"); __asm( " cpsie i");
__asm( " dsb"); __asm( " dsb");
__asm( " isb"); __asm( " isb");
/* Disable interrupts again because the clock is about to be stopped /* Disable interrupts again because the clock is about to be stopped
and interrupts that execute while the clock is stopped will increase * and interrupts that execute while the clock is stopped will increase
any slippage between the time maintained by the RTOS and calendar * any slippage between the time maintained by the RTOS and calendar
time. */ * time. */
__asm( " cpsid i"); __asm( " cpsid i");
__asm( " dsb"); __asm( " dsb");
__asm( " isb"); __asm( " isb");
/* Disable the SysTick clock without reading the /* Disable the SysTick clock without reading the
portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_CTRL_REG register to ensure the
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
the time the SysTick is stopped for is accounted for as best it can * the time the SysTick is stopped for is accounted for as best it can
be, but using the tickless mode will inevitably result in some tiny * be, but using the tickless mode will inevitably result in some tiny
drift of the time maintained by the kernel with respect to calendar * drift of the time maintained by the kernel with respect to calendar
time*/ * time*/
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT ); portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
/* Determine if the SysTick clock has already counted to zero and /* Determine if the SysTick clock has already counted to zero and
been set back to the current reload value (the reload back being * been set back to the current reload value (the reload back being
correct for the entire expected idle time) or if the SysTick is yet * correct for the entire expected idle time) or if the SysTick is yet
to count to zero (in which case an interrupt other than the SysTick * to count to zero (in which case an interrupt other than the SysTick
must have brought the system out of sleep mode). */ * must have brought the system out of sleep mode). */
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
{ {
uint32_t ulCalculatedLoadValue; uint32_t ulCalculatedLoadValue;
/* The tick interrupt is already pending, and the SysTick count /* The tick interrupt is already pending, and the SysTick count
reloaded with ulReloadValue. Reset the * reloaded with ulReloadValue. Reset the
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick * portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
period. */ * period. */
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
/* Don't allow a tiny value, or values that have somehow /* Don't allow a tiny value, or values that have somehow
underflowed because the post sleep hook did something * underflowed because the post sleep hook did something
that took too long. */ * that took too long. */
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
{ {
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
@ -498,30 +508,30 @@ void xPortSysTickHandler( void )
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
/* As the pending tick will be processed as soon as this /* As the pending tick will be processed as soon as this
function exits, the tick value maintained by the tick is stepped * function exits, the tick value maintained by the tick is stepped
forward by one less than the time spent waiting. */ * forward by one less than the time spent waiting. */
ulCompleteTickPeriods = xExpectedIdleTime - 1UL; ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
} }
else else
{ {
/* Something other than the tick interrupt ended the sleep. /* Something other than the tick interrupt ended the sleep.
Work out how long the sleep lasted rounded to complete tick * Work out how long the sleep lasted rounded to complete tick
periods (not the ulReload value which accounted for part * periods (not the ulReload value which accounted for part
ticks). */ * ticks). */
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* How many complete tick periods passed while the processor /* How many complete tick periods passed while the processor
was waiting? */ * was waiting? */
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
/* The reload value is set to whatever fraction of a single tick /* The reload value is set to whatever fraction of a single tick
period remains. */ * period remains. */
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
} }
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard * again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
value. */ * value. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
vTaskStepTick( ulCompleteTickPeriods ); vTaskStepTick( ulCompleteTickPeriods );
@ -578,66 +588,45 @@ void vPortSetupTimerInterrupt( void )
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
/* The following assertion will fail if a service routine (ISR) for /* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above * an interrupt that has been assigned a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
function. ISR safe FreeRTOS API functions must *only* be called * function. ISR safe FreeRTOS API functions must *only* be called
from interrupts that have been assigned a priority at or below * from interrupts that have been assigned a priority at or below
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Numerically low interrupt priority numbers represent logically high * Numerically low interrupt priority numbers represent logically high
interrupt priorities, therefore the priority of the interrupt must * interrupt priorities, therefore the priority of the interrupt must
be set to a value equal to or numerically *higher* than * be set to a value equal to or numerically *higher* than
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Interrupts that use the FreeRTOS API must not be left at their * Interrupts that use the FreeRTOS API must not be left at their
default priority of zero as that is the highest possible priority, * default priority of zero as that is the highest possible priority,
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
and therefore also guaranteed to be invalid. * and therefore also guaranteed to be invalid.
*
FreeRTOS maintains separate thread and ISR API functions to ensure * FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible. * interrupt entry is as fast and simple as possible.
*
The following links provide detailed information: * The following links provide detailed information:
http://www.freertos.org/RTOS-Cortex-M3-M4.html * http://www.freertos.org/RTOS-Cortex-M3-M4.html
http://www.freertos.org/FAQHelp.html */ * http://www.freertos.org/FAQHelp.html */
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
} }
/* Priority grouping: The interrupt controller (NVIC) allows the bits /* Priority grouping: The interrupt controller (NVIC) allows the bits
that define each interrupt's priority to be split between bits that * that define each interrupt's priority to be split between bits that
define the interrupt's pre-emption priority bits and bits that define * define the interrupt's pre-emption priority bits and bits that define
the interrupt's sub-priority. For simplicity all bits must be defined * the interrupt's sub-priority. For simplicity all bits must be defined
to be pre-emption priority bits. The following assertion will fail if * to be pre-emption priority bits. The following assertion will fail if
this is not the case (if some bits represent a sub-priority). * this is not the case (if some bits represent a sub-priority).
*
If the application only uses CMSIS libraries for interrupt * If the application only uses CMSIS libraries for interrupt
configuration then the correct setting can be achieved on all Cortex-M * configuration then the correct setting can be achieved on all Cortex-M
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
scheduler. Note however that some vendor specific peripheral libraries * scheduler. Note however that some vendor specific peripheral libraries
assume a non-zero priority group setting, in which cases using a value * assume a non-zero priority group setting, in which cases using a value
of zero will result in unpredictable behaviour. */ * of zero will result in unpredictable behaviour. */
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
} }
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */

View file

@ -63,7 +63,7 @@ typedef unsigned long UBaseType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -140,8 +140,8 @@ extern void vPortExitCritical( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are /* Task function macros as described on the FreeRTOS.org WEB site. These are
not necessary for to use this port. They are defined so the common demo files * not necessary for to use this port. They are defined so the common demo files
(which build with all the ports) will build. */ * (which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -161,4 +161,3 @@ not necessary for to use this port. They are defined so the common demo files
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -56,7 +56,7 @@ uint32_t ulCriticalNesting = 9999;
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
/* The number of words on the stack frame between the saved Top Of Stack and /* The number of words on the stack frame between the saved Top Of Stack and
R0 (in which the parameters are passed. */ * R0 (in which the parameters are passed. */
#define portSPACE_BETWEEN_TOS_AND_PARAMETERS ( 12 ) #define portSPACE_BETWEEN_TOS_AND_PARAMETERS ( 12 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -67,7 +67,7 @@ extern void vPortStartFirstTask( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Saved as part of the task context. Set to pdFALSE if the task does not /* Saved as part of the task context. Set to pdFALSE if the task does not
require an FPU context. */ * require an FPU context. */
uint32_t ulTaskHasFPUContext = 0; uint32_t ulTaskHasFPUContext = 0;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -76,7 +76,9 @@ uint32_t ulTaskHasFPUContext = 0;
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
StackType_t * pxOriginalTOS; StackType_t * pxOriginalTOS;
@ -90,11 +92,11 @@ StackType_t *pxOriginalTOS;
#endif #endif
/* Setup the initial stack of the task. The stack is set exactly as /* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */ * expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which is the start of the as /* First on the stack is the return address - which is the start of the as
the task has not executed yet. The offset is added to make the return * the task has not executed yet. The offset is added to make the return
address appear as it would within an IRQ ISR. */ * address appear as it would within an IRQ ISR. */
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE; *pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--; pxTopOfStack--;
@ -130,11 +132,11 @@ StackType_t *pxOriginalTOS;
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */ *pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
pxTopOfStack--; pxTopOfStack--;
} }
#else #else /* ifdef portPRELOAD_TASK_REGISTERS */
{ {
pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS; pxTopOfStack -= portSPACE_BETWEEN_TOS_AND_PARAMETERS;
} }
#endif #endif /* ifdef portPRELOAD_TASK_REGISTERS */
/* Function parameters are passed in R0. */ /* Function parameters are passed in R0. */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
@ -154,8 +156,8 @@ StackType_t *pxOriginalTOS;
pxTopOfStack--; pxTopOfStack--;
/* The last thing on the stack is the tasks ulUsingFPU value, which by /* The last thing on the stack is the tasks ulUsingFPU value, which by
default is set to indicate that the stack frame does not include FPU * default is set to indicate that the stack frame does not include FPU
registers. */ * registers. */
*pxTopOfStack = pdFALSE; *pxTopOfStack = pdFALSE;
} }
#endif #endif
@ -206,7 +208,7 @@ BaseType_t xPortStartScheduler(void)
ulCriticalNesting = 0; ulCriticalNesting = 0;
/* Start the first task. This is done from portASM.asm as ARM mode must be /* Start the first task. This is done from portASM.asm as ARM mode must be
used. */ * used. */
vPortStartFirstTask(); vPortStartFirstTask();
/* Should not get here! */ /* Should not get here! */
@ -220,7 +222,7 @@ BaseType_t xPortStartScheduler(void)
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented in ports where there is nothing to return to. /* Not implemented in ports where there is nothing to return to.
Artificially force an assert. */ * Artificially force an assert. */
configASSERT( ulCriticalNesting == 1000UL ); configASSERT( ulCriticalNesting == 1000UL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -235,11 +237,11 @@ void vPortEndScheduler(void)
portRTI_INTFLAG_REG = 0x00000001; portRTI_INTFLAG_REG = 0x00000001;
/* Increment the tick count - this may make a delaying task ready /* Increment the tick count - this may make a delaying task ready
to run - but a context switch is not performed. */ * to run - but a context switch is not performed. */
xTaskIncrementTick(); xTaskIncrementTick();
} }
#else #else /* if configUSE_PREEMPTION == 0 */
/* /*
************************************************************************** **************************************************************************
@ -250,7 +252,7 @@ void vPortEndScheduler(void)
*/ */
void vPortPreemptiveTick( void ); void vPortPreemptiveTick( void );
#endif #endif /* if configUSE_PREEMPTION == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -263,8 +265,8 @@ void vPortEnterCritical( void )
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
/* Now interrupts are disabled ulCriticalNesting can be accessed /* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times * directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */ * portENTER_CRITICAL() has been called. */
ulCriticalNesting++; ulCriticalNesting++;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -281,7 +283,7 @@ void vPortExitCritical( void )
ulCriticalNesting--; ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be /* If the nesting level has reached zero then interrupts should be
re-enabled. */ * re-enabled. */
if( ulCriticalNesting == 0 ) if( ulCriticalNesting == 0 )
{ {
/* Enable interrupts as per portENABLE_INTERRUPTS(). */ /* Enable interrupts as per portENABLE_INTERRUPTS(). */
@ -298,7 +300,7 @@ void vPortExitCritical( void )
extern void vPortInitialiseFPSCR( void ); extern void vPortInitialiseFPSCR( void );
/* A task is registering the fact that it needs an FPU context. Set the /* A task is registering the fact that it needs an FPU context. Set the
FPU flag (saved as part of the task context. */ * FPU flag (saved as part of the task context. */
ulTaskHasFPUContext = pdTRUE; ulTaskHasFPUContext = pdTRUE;
/* Initialise the floating point status register. */ /* Initialise the floating point status register. */
@ -308,4 +310,3 @@ void vPortExitCritical( void )
#endif /* __TI_VFP_SUPPORT__ */ #endif /* __TI_VFP_SUPPORT__ */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -58,7 +58,7 @@ typedef unsigned long UBaseType_t;
#define portMAX_DELAY ( TickType_t ) 0xFFFFFFFFF #define portMAX_DELAY ( TickType_t ) 0xFFFFFFFFF
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#endif #endif
@ -113,4 +113,3 @@ extern void vPortYield( void );
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#endif /* __PORTMACRO_H__ */ #endif /* __PORTMACRO_H__ */

View file

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

View file

@ -33,24 +33,24 @@
*----------------------------------------------------------*/ *----------------------------------------------------------*/
/* Constants required for hardware setup. The tick ISR runs off the ACLK, /* Constants required for hardware setup. The tick ISR runs off the ACLK,
not the MCLK. */ * not the MCLK. */
#define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 ) #define portACLK_FREQUENCY_HZ ( ( TickType_t ) 32768 )
#define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 ) #define portINITIAL_CRITICAL_NESTING ( ( uint16_t ) 10 )
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 ) #define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x08 )
/* We require the address of the pxCurrentTCB variable, but don't want to know /* We require the address of the pxCurrentTCB variable, but don't want to know
any details of its type. */ * any details of its type. */
typedef void TCB_t; typedef void TCB_t;
extern volatile TCB_t * volatile pxCurrentTCB; extern volatile TCB_t * volatile pxCurrentTCB;
/* Each task maintains a count of the critical section nesting depth. Each /* Each task maintains a count of the critical section nesting depth. Each
time a critical section is entered the count is incremented. Each time a * time a critical section is entered the count is incremented. Each time a
critical section is exited the count is decremented - with interrupts only * critical section is exited the count is decremented - with interrupts only
being re-enabled if the count is zero. * being re-enabled if the count is zero.
*
usCriticalNesting will get set to zero when the scheduler starts, but must * usCriticalNesting will get set to zero when the scheduler starts, but must
not be initialised to zero as this will cause problems during the startup * not be initialised to zero as this will cause problems during the startup
sequence. */ * sequence. */
volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING; volatile uint16_t usCriticalNesting = portINITIAL_CRITICAL_NESTING;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -68,25 +68,27 @@ void vPortSetupTimerInterrupt( void );
* *
* See the header file portable.h. * See the header file portable.h.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
uint16_t * pusTopOfStack; uint16_t * pusTopOfStack;
uint32_t * pulTopOfStack, ulTemp; uint32_t * pulTopOfStack, ulTemp;
/* /*
Place a few bytes of known values on the bottom of the stack. * Place a few bytes of known values on the bottom of the stack.
This is just useful for debugging and can be included if required. * This is just useful for debugging and can be included if required.
*
* pxTopOfStack = ( StackType_t ) 0x1111; * pxTopOfStack = ( StackType_t ) 0x1111;
pxTopOfStack--; * pxTopOfStack--;
* pxTopOfStack = ( StackType_t ) 0x2222; * pxTopOfStack = ( StackType_t ) 0x2222;
pxTopOfStack--; * pxTopOfStack--;
* pxTopOfStack = ( StackType_t ) 0x3333; * pxTopOfStack = ( StackType_t ) 0x3333;
pxTopOfStack--; * pxTopOfStack--;
*/ */
/* Data types are need either 16 bits or 32 bits depending on the data /* Data types are need either 16 bits or 32 bits depending on the data
and code model used. */ * and code model used. */
if( sizeof( pxCode ) == sizeof( uint16_t ) ) if( sizeof( pxCode ) == sizeof( uint16_t ) )
{ {
pusTopOfStack = ( uint16_t * ) pxTopOfStack; pusTopOfStack = ( uint16_t * ) pxTopOfStack;
@ -135,19 +137,19 @@ uint32_t *pulTopOfStack, ulTemp;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x4444; *pxTopOfStack = ( StackType_t ) 0x4444;
pxTopOfStack--; pxTopOfStack--;
#else #else /* ifdef PRELOAD_REGISTER_VALUES */
pxTopOfStack -= 3; pxTopOfStack -= 3;
*pxTopOfStack = ( StackType_t ) pvParameters; *pxTopOfStack = ( StackType_t ) pvParameters;
pxTopOfStack -= 9; pxTopOfStack -= 9;
#endif #endif /* ifdef PRELOAD_REGISTER_VALUES */
/* A variable is used to keep track of the critical section nesting. /* A variable is used to keep track of the critical section nesting.
This variable has to be stored as part of the task context and is * This variable has to be stored as part of the task context and is
initially set to zero. */ * initially set to zero. */
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING; *pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
/* Return a pointer to the top of the stack we have generated so this can /* Return a pointer to the top of the stack we have generated so this can
be stored in the task control block for the task. */ * be stored in the task control block for the task. */
return pxTopOfStack; return pxTopOfStack;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -155,7 +157,7 @@ uint32_t *pulTopOfStack, ulTemp;
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* It is unlikely that the MSP430 port will get stopped. If required simply /* It is unlikely that the MSP430 port will get stopped. If required simply
disable the tick interrupt here. */ * disable the tick interrupt here. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -182,5 +184,3 @@ extern void vPortTickISR( void );
vPortCooperativeTickISR(); vPortCooperativeTickISR();
#endif #endif
} }

View file

@ -135,8 +135,7 @@ extern void vTaskSwitchContext( void );
void vApplicationSetupTimerInterrupt( void ); void vApplicationSetupTimerInterrupt( void );
/* sizeof( int ) != sizeof( long ) so a full printf() library is required if /* sizeof( int ) != sizeof( long ) so a full printf() library is required if
run time stats information is to be displayed. */ * run time stats information is to be displayed. */
#define portLU_PRINTF_SPECIFIER_REQUIRED #define portLU_PRINTF_SPECIFIER_REQUIRED
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -44,17 +44,20 @@ asm void interrupt VectorNumber_VL1swi vPortYieldISR( void );
static void prvSetupTimerInterrupt( void ); static void prvSetupTimerInterrupt( void );
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This /* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
will be set to 0 prior to the first task being started. */ * will be set to 0 prior to the first task being started. */
static uint32_t ulCriticalNesting = 0x9999UL; static uint32_t ulCriticalNesting = 0x9999UL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
StackType_t *pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
uint32_t ulOriginalA5; uint32_t ulOriginalA5;
__asm{ MOVE.L A5, ulOriginalA5 }; __asm {
MOVE.L A5, ulOriginalA5
};
*pxTopOfStack = ( StackType_t ) 0xDEADBEEF; *pxTopOfStack = ( StackType_t ) 0xDEADBEEF;
@ -105,7 +108,7 @@ static void prvSetupTimerInterrupt( void )
RTCMOD = portRTC_CLOCK_HZ / configTICK_RATE_HZ; RTCMOD = portRTC_CLOCK_HZ / configTICK_RATE_HZ;
/* Enable the RTC to generate interrupts - interrupts are already disabled /* Enable the RTC to generate interrupts - interrupts are already disabled
when this code executes. */ * when this code executes. */
RTCSC_RTIE = 1; RTCSC_RTIE = 1;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -121,19 +124,20 @@ void vPortEnterCritical( void )
if( ulCriticalNesting == 0UL ) if( ulCriticalNesting == 0UL )
{ {
/* Guard against context switches being pended simultaneously with a /* Guard against context switches being pended simultaneously with a
critical section being entered. */ * critical section being entered. */
do do
{ {
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
if( INTC_FRC == 0UL ) if( INTC_FRC == 0UL )
{ {
break; break;
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} while( 1 ); } while( 1 );
} }
ulCriticalNesting++; ulCriticalNesting++;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -141,6 +145,7 @@ void vPortEnterCritical( void )
void vPortExitCritical( void ) void vPortExitCritical( void )
{ {
ulCriticalNesting--; ulCriticalNesting--;
if( ulCriticalNesting == 0 ) if( ulCriticalNesting == 0 )
{ {
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
@ -179,4 +184,3 @@ uint32_t ulSavedInterruptMask;
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
} }

View file

@ -100,7 +100,8 @@ extern void vPortClearInterruptMaskFromISR( UBaseType_t );
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
if( xSwitchRequired != pdFALSE ) \
{ \ { \
portYIELD(); \ portYIELD(); \
} }
@ -111,4 +112,3 @@ extern void vPortClearInterruptMaskFromISR( UBaseType_t );
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -35,7 +35,7 @@
#define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000 ) #define portINITIAL_STATUS_REGISTER ( ( StackType_t ) 0x2000 )
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This /* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
will be set to 0 prior to the first task being started. */ * will be set to 0 prior to the first task being started. */
static uint32_t ulCriticalNesting = 0x9999UL; static uint32_t ulCriticalNesting = 0x9999UL;
@ -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 = ( StackType_t ) pvParameters;
pxTopOfStack--; pxTopOfStack--;
@ -105,19 +107,20 @@ void vPortEnterCritical( void )
if( ulCriticalNesting == 0UL ) if( ulCriticalNesting == 0UL )
{ {
/* Guard against context switches being pended simultaneously with a /* Guard against context switches being pended simultaneously with a
critical section being entered. */ * critical section being entered. */
do do
{ {
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
if( MCF_INTC0_INTFRCH == 0UL ) if( MCF_INTC0_INTFRCH == 0UL )
{ {
break; break;
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} while( 1 ); } while( 1 );
} }
ulCriticalNesting++; ulCriticalNesting++;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -125,6 +128,7 @@ void vPortEnterCritical( void )
void vPortExitCritical( void ) void vPortExitCritical( void )
{ {
ulCriticalNesting--; ulCriticalNesting--;
if( ulCriticalNesting == 0 ) if( ulCriticalNesting == 0 )
{ {
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
@ -143,4 +147,3 @@ uint32_t ulSavedInterruptMask;
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -99,7 +99,8 @@ extern void vPortClearInterruptMaskFromISR( UBaseType_t );
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
if( xSwitchRequired != pdFALSE ) \
{ \ { \
portYIELD(); \ portYIELD(); \
} }
@ -110,4 +111,3 @@ extern void vPortClearInterruptMaskFromISR( UBaseType_t );
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -41,7 +41,7 @@
static void prvSetupTimerInterrupt( void ); static void prvSetupTimerInterrupt( void );
/* Interrupt service routines have to be in non-banked memory - as does the /* Interrupt service routines have to be in non-banked memory - as does the
scheduler startup function. */ * scheduler startup function. */
#pragma CODE_SEG __NEAR_SEG NON_BANKED #pragma CODE_SEG __NEAR_SEG NON_BANKED
/* Manual context switch function. This is the SWI ISR. */ /* Manual context switch function. This is the SWI ISR. */
@ -51,19 +51,19 @@ scheduler startup function. */
void interrupt vPortTickInterrupt( void ); void interrupt vPortTickInterrupt( void );
/* Simply called by xPortStartScheduler(). xPortStartScheduler() does not /* Simply called by xPortStartScheduler(). xPortStartScheduler() does not
start the scheduler directly because the header file containing the * start the scheduler directly because the header file containing the
xPortStartScheduler() prototype is part of the common kernel code, and * xPortStartScheduler() prototype is part of the common kernel code, and
therefore cannot use the CODE_SEG pragma. */ * therefore cannot use the CODE_SEG pragma. */
static BaseType_t xBankedStartScheduler( void ); static BaseType_t xBankedStartScheduler( void );
#pragma CODE_SEG DEFAULT #pragma CODE_SEG DEFAULT
/* Calls to portENTER_CRITICAL() can be nested. When they are nested the /* Calls to portENTER_CRITICAL() can be nested. When they are nested the
critical section should not be left (i.e. interrupts should not be re-enabled) * critical section should not be left (i.e. interrupts should not be re-enabled)
until the nesting depth reaches 0. This variable simply tracks the nesting * until the nesting depth reaches 0. This variable simply tracks the nesting
depth. Each task maintains it's own critical nesting depth variable so * depth. Each task maintains it's own critical nesting depth variable so
uxCriticalNesting is saved and restored from the task stack during a context * uxCriticalNesting is saved and restored from the task stack during a context
switch. */ * switch. */
volatile UBaseType_t uxCriticalNesting = 0xff; volatile UBaseType_t uxCriticalNesting = 0xff;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -71,25 +71,27 @@ volatile UBaseType_t uxCriticalNesting = 0xff;
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
/* /*
Place a few bytes of known values on the bottom of the stack. * Place a few bytes of known values on the bottom of the stack.
This can be uncommented to provide useful stack markers when debugging. * This can be uncommented to provide useful stack markers when debugging.
*
* pxTopOfStack = ( StackType_t ) 0x11; * pxTopOfStack = ( StackType_t ) 0x11;
pxTopOfStack--; * pxTopOfStack--;
* pxTopOfStack = ( StackType_t ) 0x22; * pxTopOfStack = ( StackType_t ) 0x22;
pxTopOfStack--; * pxTopOfStack--;
* pxTopOfStack = ( StackType_t ) 0x33; * pxTopOfStack = ( StackType_t ) 0x33;
pxTopOfStack--; * pxTopOfStack--;
*/ */
/* Setup the initial stack of the task. The stack is set exactly as /* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. In this case the stack as * expected by the portRESTORE_CONTEXT() macro. In this case the stack as
expected by the HCS12 RTI instruction. */ * expected by the HCS12 RTI instruction. */
/* The address of the task function is placed in the stack byte at a time. */ /* The address of the task function is placed in the stack byte at a time. */
@ -121,7 +123,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
pxTopOfStack--; pxTopOfStack--;
/* CCR: Note that when the task starts interrupts will be enabled since /* CCR: Note that when the task starts interrupts will be enabled since
"I" bit of CCR is cleared */ * "I" bit of CCR is cleared */
*pxTopOfStack = ( StackType_t ) 0x00; *pxTopOfStack = ( StackType_t ) 0x00;
pxTopOfStack--; pxTopOfStack--;
@ -132,7 +134,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
#endif #endif
/* Finally the critical nesting depth is initialised with 0 (not within /* Finally the critical nesting depth is initialised with 0 (not within
a critical section). */ * a critical section). */
*pxTopOfStack = ( StackType_t ) 0x00; *pxTopOfStack = ( StackType_t ) 0x00;
return pxTopOfStack; return pxTopOfStack;
@ -155,10 +157,10 @@ static void prvSetupTimerInterrupt( void )
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
/* xPortStartScheduler() does not start the scheduler directly because /* xPortStartScheduler() does not start the scheduler directly because
the header file containing the xPortStartScheduler() prototype is part * the header file containing the xPortStartScheduler() prototype is part
of the common kernel code, and therefore cannot use the CODE_SEG pragma. * of the common kernel code, and therefore cannot use the CODE_SEG pragma.
Instead it simply calls the locally defined xBankedStartScheduler() - * Instead it simply calls the locally defined xBankedStartScheduler() -
which does use the CODE_SEG pragma. */ * which does use the CODE_SEG pragma. */
return xBankedStartScheduler(); return xBankedStartScheduler();
} }
@ -169,7 +171,7 @@ BaseType_t xPortStartScheduler( void )
static BaseType_t xBankedStartScheduler( void ) static BaseType_t xBankedStartScheduler( void )
{ {
/* Configure the timer that will generate the RTOS tick. Interrupts are /* Configure the timer that will generate the RTOS tick. Interrupts are
disabled when this function is called. */ * disabled when this function is called. */
prvSetupTimerInterrupt(); prvSetupTimerInterrupt();
/* Restore the context of the first task. */ /* Restore the context of the first task. */
@ -220,17 +222,15 @@ void interrupt vPortTickInterrupt( void )
TFLG1 = 1; TFLG1 = 1;
/* Restore the context of a task - which may be a different task /* Restore the context of a task - which may be a different task
to that interrupted. */ * to that interrupted. */
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
#else #else /* if configUSE_PREEMPTION == 1 */
{ {
xTaskIncrementTick(); xTaskIncrementTick();
TFLG1 = 1; TFLG1 = 1;
} }
#endif #endif /* if configUSE_PREEMPTION == 1 */
} }
#pragma CODE_SEG DEFAULT #pragma CODE_SEG DEFAULT

View file

@ -116,6 +116,7 @@ typedef unsigned char UBaseType_t;
*/ */
#ifdef BANKED_MODEL #ifdef BANKED_MODEL
/* /*
* Load the stack pointer for the task, then pull the critical nesting * Load the stack pointer for the task, then pull the critical nesting
* count and PPAGE register from the stack. The remains of the * count and PPAGE register from the stack. The remains of the
@ -151,7 +152,7 @@ typedef unsigned char UBaseType_t;
__asm( "ldx pxCurrentTCB" ); \ __asm( "ldx pxCurrentTCB" ); \
__asm( "sts 0, x" ); \ __asm( "sts 0, x" ); \
} }
#else #else /* ifdef BANKED_MODEL */
/* /*
* These macros are as per the BANKED versions above, but without saving * These macros are as per the BANKED versions above, but without saving
@ -179,7 +180,7 @@ typedef unsigned char UBaseType_t;
__asm( "ldx pxCurrentTCB" ); \ __asm( "ldx pxCurrentTCB" ); \
__asm( "sts 0, x" ); \ __asm( "sts 0, x" ); \
} }
#endif #endif /* ifdef BANKED_MODEL */
/* /*
* Utility macro to call macros above in correct order in order to perform a * Utility macro to call macros above in correct order in order to perform a
@ -198,4 +199,3 @@ typedef unsigned char UBaseType_t;
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -30,8 +30,8 @@
*/ */
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when * all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */ * task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* Scheduler includes. */ /* Scheduler includes. */
@ -86,7 +86,8 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -99,7 +100,8 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -112,7 +114,12 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -125,7 +132,13 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #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; TaskHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -137,7 +150,8 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
#endif /* configSUPPORT_STATIC_ALLOCATION */ #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(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -158,7 +172,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( INCLUDE_vTaskDelayUntil == 1 ) #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(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -206,7 +221,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( INCLUDE_vTaskPrioritySet == 1 ) #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(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -230,14 +246,17 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 ) #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(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState ); vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState );
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
} }
#endif #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
@ -377,7 +396,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_APPLICATION_TASK_TAG == 1 ) #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(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -401,7 +421,9 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) #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(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -412,7 +434,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) #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; void * pvReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -421,11 +444,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return pvReturn; return pvReturn;
} }
#endif #endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_APPLICATION_TASK_TAG == 1 ) #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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -434,11 +458,13 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return xReturn; return xReturn;
} }
#endif #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 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; UBaseType_t uxReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -447,7 +473,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return uxReturn; return uxReturn;
} }
#endif #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) /* FREERTOS_SYSTEM_CALL */ 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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -534,7 +561,11 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_TASK_NOTIFICATIONS == 1 ) #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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -543,11 +574,15 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return xReturn; return xReturn;
} }
#endif #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -556,11 +591,13 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return xReturn; return xReturn;
} }
#endif #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#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; uint32_t ulReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -569,11 +606,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return ulReturn; return ulReturn;
} }
#endif #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -582,11 +620,13 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return xReturn; return xReturn;
} }
#endif #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#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; uint32_t ulReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -595,11 +635,13 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return ulReturn; return ulReturn;
} }
#endif #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 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; QueueHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -608,11 +650,15 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return xReturn; return xReturn;
} }
#endif #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configSUPPORT_STATIC_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; QueueHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -621,10 +667,11 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return xReturn; 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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); 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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); 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 xRunningPrivileged = xPortRaisePrivilege();
BaseType_t xReturn; 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 xRunningPrivileged = xPortRaisePrivilege();
BaseType_t xReturn; 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 xRunningPrivileged = xPortRaisePrivilege();
BaseType_t xReturn; BaseType_t xReturn;
@ -728,7 +783,8 @@ BaseType_t xReturn;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) #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; QueueHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -737,11 +793,12 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return xReturn; return xReturn;
} }
#endif #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_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; QueueHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -750,12 +807,14 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return xReturn; return xReturn;
} }
#endif #endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_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; QueueHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -764,11 +823,12 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return xReturn; return xReturn;
} }
#endif #endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_RECURSIVE_MUTEXES == 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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -777,7 +837,7 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return xReturn; return xReturn;
} }
#endif #endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_RECURSIVE_MUTEXES == 1 ) #if ( configUSE_RECURSIVE_MUTEXES == 1 )
@ -807,7 +867,8 @@ BaseType_t xReturn;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 ) #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; QueueSetMemberHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -816,11 +877,12 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return xReturn; return xReturn;
} }
#endif #endif /* if ( configUSE_QUEUE_SETS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -829,11 +891,12 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return xReturn; return xReturn;
} }
#endif #endif /* if ( configUSE_QUEUE_SETS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -842,11 +905,12 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return xReturn; return xReturn;
} }
#endif #endif /* if ( configUSE_QUEUE_SETS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if configQUEUE_REGISTRY_SIZE > 0 #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(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -880,7 +944,7 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
return pcReturn; return pcReturn;
} }
#endif #endif /* if configQUEUE_REGISTRY_SIZE > 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void MPU_vQueueDelete( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ 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 ) ) #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; TimerHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -958,11 +1026,16 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn; return xReturn;
} }
#endif #endif /* if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configSUPPORT_STATIC_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; TimerHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -972,7 +1045,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn; return xReturn;
} }
#endif #endif /* if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_TIMERS == 1 ) #if ( configUSE_TIMERS == 1 )
@ -986,11 +1059,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return pvReturn; return pvReturn;
} }
#endif #endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#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(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1011,7 +1085,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn; return xReturn;
} }
#endif #endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_TIMERS == 1 ) #if ( configUSE_TIMERS == 1 )
@ -1025,11 +1099,14 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn; return xReturn;
} }
#endif #endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( 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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1039,11 +1116,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn; return xReturn;
} }
#endif #endif /* if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( 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(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1077,7 +1155,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return pcReturn; return pcReturn;
} }
#endif #endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_TIMERS == 1 ) #if ( configUSE_TIMERS == 1 )
@ -1091,7 +1169,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn; return xReturn;
} }
#endif #endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_TIMERS == 1 ) #if ( configUSE_TIMERS == 1 )
@ -1105,11 +1183,15 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn; return xReturn;
} }
#endif #endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1119,7 +1201,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn; return xReturn;
} }
#endif #endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
@ -1133,7 +1215,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn; return xReturn;
} }
#endif #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
@ -1147,10 +1229,14 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn; 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; EventBits_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); 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; EventBits_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); 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; EventBits_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); 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; EventBits_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); 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; size_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); 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; size_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); 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 xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1325,7 +1423,9 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #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; StreamBufferHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1339,7 +1439,11 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #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; StreamBufferHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1354,18 +1458,18 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/* Functions that the application writer wants to execute in privileged mode /* Functions that the application writer wants to execute in privileged mode
can be defined in application_defined_privileged_functions.h. The functions * 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 * must take the same format as those above whereby the privilege state on exit
equals the privilege state on entry. For example: * equals the privilege state on entry. For example:
*
void MPU_FunctionName( [parameters ] ) * void MPU_FunctionName( [parameters ] )
{ * {
BaseType_t xRunningPrivileged = xPortRaisePrivilege(); * BaseType_t xRunningPrivileged = xPortRaisePrivilege();
*
FunctionName( [parameters ] ); * FunctionName( [parameters ] );
*
vPortResetPrivilege( xRunningPrivileged ); * vPortResetPrivilege( xRunningPrivileged );
} * }
*/ */
#if configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS == 1 #if configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS == 1

View file

@ -72,22 +72,24 @@ extern void vPortISRStartFirstTask( void );
* *
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
StackType_t * pxOriginalTOS; StackType_t * pxOriginalTOS;
pxOriginalTOS = pxTopOfStack; pxOriginalTOS = pxTopOfStack;
/* To ensure asserts in tasks.c don't fail, although in this case the assert /* To ensure asserts in tasks.c don't fail, although in this case the assert
is not really required. */ * is not really required. */
pxTopOfStack--; pxTopOfStack--;
/* Setup the initial stack of the task. The stack is set exactly as /* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */ * expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the /* First on the stack is the return address - which in this case is the
start of the task. The offset is added to make the return address appear * start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */ * as it would within an IRQ ISR. */
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE; *pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--; pxTopOfStack--;
@ -121,12 +123,12 @@ StackType_t *pxOriginalTOS;
pxTopOfStack--; pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in /* When the task starts is will expect to find the function parameter in
R0. */ * R0. */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
pxTopOfStack--; pxTopOfStack--;
/* The last thing onto the stack is the status register, which is set for /* The last thing onto the stack is the status register, which is set for
system mode, with interrupts enabled. */ * system mode, with interrupts enabled. */
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
#ifdef THUMB_INTERWORK #ifdef THUMB_INTERWORK
@ -139,9 +141,9 @@ StackType_t *pxOriginalTOS;
pxTopOfStack--; pxTopOfStack--;
/* Some optimisation levels use the stack differently to others. This /* Some optimisation levels use the stack differently to others. This
means the interrupt flags cannot always be stored on the stack and will * means the interrupt flags cannot always be stored on the stack and will
instead be stored in a variable, which is then saved as part of the * instead be stored in a variable, which is then saved as part of the
tasks context. */ * tasks context. */
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING; *pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
return pxTopOfStack; return pxTopOfStack;
@ -151,7 +153,7 @@ StackType_t *pxOriginalTOS;
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
/* Start the timer that generates the tick ISR. Interrupts are disabled /* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */ * here already. */
prvSetupTimerInterrupt(); prvSetupTimerInterrupt();
/* Start the first task. */ /* Start the first task. */
@ -165,7 +167,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* It is unlikely that the ARM port will require this function as there /* It is unlikely that the ARM port will require this function as there
is nothing to return to. */ * is nothing to return to. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -189,8 +191,8 @@ volatile uint32_t ulDummy;
ulDummy = portTIMER_REG_BASE_PTR->TC_SR; ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
/* Store interrupt handler function address in tick timer vector register... /* Store interrupt handler function address in tick timer vector register...
The ISR installed depends on whether the preemptive or cooperative * The ISR installed depends on whether the preemptive or cooperative
scheduler is being used. */ * scheduler is being used. */
#if configUSE_PREEMPTION == 1 #if configUSE_PREEMPTION == 1
{ {
extern void( vPreemptiveTick )( void ); extern void( vPreemptiveTick )( void );
@ -207,8 +209,8 @@ volatile uint32_t ulDummy;
AT91C_BASE_AIC->AIC_SMR[ portTIMER_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | portTICK_PRIORITY_6; AT91C_BASE_AIC->AIC_SMR[ portTIMER_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | portTICK_PRIORITY_6;
/* Enable the tick timer interrupt... /* Enable the tick timer interrupt...
*
First at timer level */ * First at timer level */
portTIMER_REG_BASE_PTR->TC_IER = TC_CPCS; portTIMER_REG_BASE_PTR->TC_IER = TC_CPCS;
/* Then at the AIC level. */ /* Then at the AIC level. */
@ -218,14 +220,14 @@ volatile uint32_t ulDummy;
if( ( configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 2 ) ) <= 0xFFFF ) if( ( configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 2 ) ) <= 0xFFFF )
{ {
/* The tick rate is fast enough for us to use the faster timer input /* The tick rate is fast enough for us to use the faster timer input
clock (main clock / 2). */ * clock (main clock / 2). */
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK2 | TC_BURST_NONE | TC_CPCTRG; portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK2 | TC_BURST_NONE | TC_CPCTRG;
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 2 ); portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 2 );
} }
else else
{ {
/* We must use a slower timer input clock (main clock / 8) because the /* We must use a slower timer input clock (main clock / 8) because the
tick rate is too slow for the faster input clock. */ * tick rate is too slow for the faster input clock. */
portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK8 | TC_BURST_NONE | TC_CPCTRG; portTIMER_REG_BASE_PTR->TC_CMR = TC_WAVE | TC_CLKS_MCK8 | TC_BURST_NONE | TC_CPCTRG;
portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 8 ); portTIMER_REG_BASE_PTR->TC_RC = configCPU_CLOCK_HZ / ( configTICK_RATE_HZ * 8 );
} }
@ -234,4 +236,3 @@ volatile uint32_t ulDummy;
portTIMER_REG_BASE_PTR->TC_CCR = TC_SWTRG | TC_CLKEN; portTIMER_REG_BASE_PTR->TC_CCR = TC_SWTRG | TC_CLKEN;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -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 + 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 ) void vPortISRStartFirstTask( void )
{ {
/* Simply start the scheduler. This is included here as it can only be /* Simply start the scheduler. This is included here as it can only be
called from ARM mode. */ * called from ARM mode. */
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -81,8 +81,8 @@ void vPortISRStartFirstTask( void )
void vPortYieldProcessor( void ) void vPortYieldProcessor( void )
{ {
/* Within an IRQ ISR the link register has an offset from the true return /* Within an IRQ ISR the link register has an offset from the true return
address, but an SWI ISR does not. Add the offset manually so the same * address, but an SWI ISR does not. Add the offset manually so the same
ISR return code can be used in both cases. */ * ISR return code can be used in both cases. */
asm volatile ( "ADD LR, LR, #4"); asm volatile ( "ADD LR, LR, #4");
/* Perform the context switch. First save the context of the current task. */ /* Perform the context switch. First save the context of the current task. */
@ -104,7 +104,7 @@ void vPortYieldProcessor( void )
#if configUSE_PREEMPTION == 0 #if configUSE_PREEMPTION == 0
/* The cooperative scheduler requires a normal IRQ service routine to /* The cooperative scheduler requires a normal IRQ service routine to
simply increment the system tick. */ * simply increment the system tick. */
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) ); void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
void vNonPreemptiveTick( void ) void vNonPreemptiveTick( void )
{ {
@ -122,7 +122,7 @@ void vPortYieldProcessor( void )
#else /* else preemption is turned on */ #else /* else preemption is turned on */
/* The preemptive scheduler is defined as "naked" as the full context is /* The preemptive scheduler is defined as "naked" as the full context is
saved on entry as part of the context switch. */ * saved on entry as part of the context switch. */
void vPreemptiveTick( void ) __attribute__( ( naked ) ); void vPreemptiveTick( void ) __attribute__( ( naked ) );
void vPreemptiveTick( void ) void vPreemptiveTick( void )
{ {
@ -130,14 +130,14 @@ void vPortYieldProcessor( void )
portSAVE_CONTEXT(); portSAVE_CONTEXT();
/* WARNING - Do not use local (stack) variables here. Use globals /* WARNING - Do not use local (stack) variables here. Use globals
if you must! */ * if you must! */
static volatile uint32_t ulDummy; static volatile uint32_t ulDummy;
/* Clear tick timer interrupt indication. */ /* Clear tick timer interrupt indication. */
ulDummy = portTIMER_REG_BASE_PTR->TC_SR; ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
/* Increment the RTOS tick count, then look for the highest priority /* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */ * task that is ready to run. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
vTaskSwitchContext(); vTaskSwitchContext();
@ -150,7 +150,7 @@ void vPortYieldProcessor( void )
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
#endif #endif /* if configUSE_PREEMPTION == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
@ -189,9 +189,9 @@ void vPortYieldProcessor( void )
#endif /* THUMB_INTERWORK */ #endif /* THUMB_INTERWORK */
/* The code generated by the GCC compiler uses the stack in different ways at /* The code generated by the GCC compiler uses the stack in different ways at
different optimisation levels. The interrupt flags can therefore not always * different optimisation levels. The interrupt flags can therefore not always
be saved to the stack. Instead the critical section nesting level is stored * be saved to the stack. Instead the critical section nesting level is stored
in a variable, which is then saved as part of the stack context. */ * in a variable, which is then saved as part of the stack context. */
void vPortEnterCritical( void ) void vPortEnterCritical( void )
{ {
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */ /* Disable interrupts as per portDISABLE_INTERRUPTS(); */
@ -203,8 +203,8 @@ void vPortEnterCritical( void )
"LDMIA SP!, {R0}"); /* Pop R0. */ "LDMIA SP!, {R0}"); /* Pop R0. */
/* Now interrupts are disabled ulCriticalNesting can be accessed /* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times * directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */ * portENTER_CRITICAL() has been called. */
ulCriticalNesting++; ulCriticalNesting++;
} }
@ -216,7 +216,7 @@ void vPortExitCritical( void )
ulCriticalNesting--; ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be /* If the nesting level has reached zero then interrupts should be
re-enabled. */ * re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING ) if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{ {
/* Enable interrupts as per portEXIT_CRITICAL(). */ /* Enable interrupts as per portEXIT_CRITICAL(). */
@ -229,4 +229,3 @@ void vPortExitCritical( void )
} }
} }
} }

View file

@ -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. + Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
+
Changes from V3.2.4 + Changes from V3.2.4
+
+ Removed the use of the %0 parameter within the assembler macros and + Removed the use of the %0 parameter within the assembler macros and
replaced them with hard coded registers. This will ensure the + replaced them with hard coded registers. This will ensure the
assembler does not select the link register as the temp register as + assembler does not select the link register as the temp register as
was occasionally happening previously. + was occasionally happening previously.
+
+ The assembler statements are now included in a single asm block rather + The assembler statements are now included in a single asm block rather
than each line having its own asm block. + than each line having its own asm block.
+
Changes from V4.5.0 + Changes from V4.5.0
+
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros + Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
and replaced them with portYIELD_FROM_ISR() macro. Application code + and replaced them with portYIELD_FROM_ISR() macro. Application code
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT() + should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
macros as per the V4.5.1 demo code. + macros as per the V4.5.1 demo code.
*/ */
#ifndef PORTMACRO_H #ifndef PORTMACRO_H
@ -251,4 +251,3 @@ extern void vPortExitCritical( void );
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,51 +1,50 @@
//* ---------------------------------------------------------------------------- /** ---------------------------------------------------------------------------- */
//* ATMEL Microcontroller Software Support - ROUSSET - /** ATMEL Microcontroller Software Support - ROUSSET - */
//* ---------------------------------------------------------------------------- /** ---------------------------------------------------------------------------- */
//* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR /** DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */
//* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF /** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE /** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */
//* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, /** DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */
//* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT /** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, /** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
//* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF /** OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
//* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING /** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
//* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, /** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
//* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
//* ---------------------------------------------------------------------------- /** ---------------------------------------------------------------------------- */
//* File Name : lib_AT91SAM7X256.h /** File Name : lib_AT91SAM7X256.h */
//* Object : AT91SAM7X256 inlined functions /** Object : AT91SAM7X256 inlined functions */
//* Generated : AT91 SW Application Group 05/20/2005 (16:22:29) /** Generated : AT91 SW Application Group 05/20/2005 (16:22:29) */
//* /** */
//* CVS Reference : /lib_dbgu.h/1.1/Fri Jan 31 12:18:40 2003// /** CVS Reference : /lib_dbgu.h/1.1/Fri Jan 31 12:18:40 2003// */
//* CVS Reference : /lib_pmc_SAM7X.h/1.1/Tue Feb 1 08:32:10 2005// /** CVS Reference : /lib_pmc_SAM7X.h/1.1/Tue Feb 1 08:32:10 2005// */
//* CVS Reference : /lib_VREG_6085B.h/1.1/Tue Feb 1 16:20:47 2005// /** CVS Reference : /lib_VREG_6085B.h/1.1/Tue Feb 1 16:20:47 2005// */
//* CVS Reference : /lib_rstc_6098A.h/1.1/Wed Oct 6 10:39:20 2004// /** CVS Reference : /lib_rstc_6098A.h/1.1/Wed Oct 6 10:39:20 2004// */
//* CVS Reference : /lib_ssc.h/1.4/Fri Jan 31 12:19:20 2003// /** CVS Reference : /lib_ssc.h/1.4/Fri Jan 31 12:19:20 2003// */
//* CVS Reference : /lib_wdtc_6080A.h/1.1/Wed Oct 6 10:38:30 2004// /** CVS Reference : /lib_wdtc_6080A.h/1.1/Wed Oct 6 10:38:30 2004// */
//* CVS Reference : /lib_usart.h/1.5/Thu Nov 21 16:01:54 2002// /** CVS Reference : /lib_usart.h/1.5/Thu Nov 21 16:01:54 2002// */
//* CVS Reference : /lib_spi2.h/1.1/Mon Aug 25 14:23:52 2003// /** CVS Reference : /lib_spi2.h/1.1/Mon Aug 25 14:23:52 2003// */
//* CVS Reference : /lib_pitc_6079A.h/1.2/Tue Nov 9 14:43:56 2004// /** CVS Reference : /lib_pitc_6079A.h/1.2/Tue Nov 9 14:43:56 2004// */
//* CVS Reference : /lib_aic_6075b.h/1.1/Fri May 20 14:01:19 2005// /** CVS Reference : /lib_aic_6075b.h/1.1/Fri May 20 14:01:19 2005// */
//* CVS Reference : /lib_aes_6149a.h/1.1/Mon Jan 17 07:43:09 2005// /** CVS Reference : /lib_aes_6149a.h/1.1/Mon Jan 17 07:43:09 2005// */
//* CVS Reference : /lib_twi.h/1.3/Mon Jul 19 14:27:58 2004// /** CVS Reference : /lib_twi.h/1.3/Mon Jul 19 14:27:58 2004// */
//* CVS Reference : /lib_adc.h/1.6/Fri Oct 17 09:12:38 2003// /** CVS Reference : /lib_adc.h/1.6/Fri Oct 17 09:12:38 2003// */
//* CVS Reference : /lib_rttc_6081A.h/1.1/Wed Oct 6 10:39:38 2004// /** CVS Reference : /lib_rttc_6081A.h/1.1/Wed Oct 6 10:39:38 2004// */
//* CVS Reference : /lib_udp.h/1.4/Wed Feb 16 08:39:34 2005// /** CVS Reference : /lib_udp.h/1.4/Wed Feb 16 08:39:34 2005// */
//* CVS Reference : /lib_des3_6150a.h/1.1/Mon Jan 17 09:19:19 2005// /** CVS Reference : /lib_des3_6150a.h/1.1/Mon Jan 17 09:19:19 2005// */
//* CVS Reference : /lib_tc_1753b.h/1.1/Fri Jan 31 12:20:02 2003// /** CVS Reference : /lib_tc_1753b.h/1.1/Fri Jan 31 12:20:02 2003// */
//* CVS Reference : /lib_MC_SAM7X.h/1.1/Thu Mar 25 15:19:14 2004// /** CVS Reference : /lib_MC_SAM7X.h/1.1/Thu Mar 25 15:19:14 2004// */
//* CVS Reference : /lib_pio.h/1.3/Fri Jan 31 12:18:56 2003// /** CVS Reference : /lib_pio.h/1.3/Fri Jan 31 12:18:56 2003// */
//* CVS Reference : /lib_can_AT91.h/1.4/Fri Oct 17 09:12:50 2003// /** CVS Reference : /lib_can_AT91.h/1.4/Fri Oct 17 09:12:50 2003// */
//* CVS Reference : /lib_PWM_SAM.h/1.3/Thu Jan 22 10:10:50 2004// /** CVS Reference : /lib_PWM_SAM.h/1.3/Thu Jan 22 10:10:50 2004// */
//* CVS Reference : /lib_pdc.h/1.2/Tue Jul 2 13:29:40 2002// /** CVS Reference : /lib_pdc.h/1.2/Tue Jul 2 13:29:40 2002// */
//* ---------------------------------------------------------------------------- /** ---------------------------------------------------------------------------- */
#include "AT91SAM7X256.h" #include "AT91SAM7X256.h"
//*---------------------------------------------------------------------------- /**---------------------------------------------------------------------------- */
//* \fn AT91F_AIC_ConfigureIt /** \fn AT91F_AIC_ConfigureIt */
//* \brief Interrupt Handler Initialization /** \brief Interrupt Handler Initialization */
//*---------------------------------------------------------------------------- /**---------------------------------------------------------------------------- */

File diff suppressed because it is too large Load diff

View file

@ -81,22 +81,24 @@ extern void vPortISRStartFirstTask( void );
* *
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
StackType_t * pxOriginalTOS; StackType_t * pxOriginalTOS;
pxOriginalTOS = pxTopOfStack; pxOriginalTOS = pxTopOfStack;
/* To ensure asserts in tasks.c don't fail, although in this case the assert /* To ensure asserts in tasks.c don't fail, although in this case the assert
is not really required. */ * is not really required. */
pxTopOfStack--; pxTopOfStack--;
/* Setup the initial stack of the task. The stack is set exactly as /* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */ * expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the /* First on the stack is the return address - which in this case is the
start of the task. The offset is added to make the return address appear * start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */ * as it would within an IRQ ISR. */
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE; *pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--; pxTopOfStack--;
@ -130,12 +132,12 @@ StackType_t *pxOriginalTOS;
pxTopOfStack--; pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in /* When the task starts is will expect to find the function parameter in
R0. */ * R0. */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
pxTopOfStack--; pxTopOfStack--;
/* The last thing onto the stack is the status register, which is set for /* The last thing onto the stack is the status register, which is set for
system mode, with interrupts enabled. */ * system mode, with interrupts enabled. */
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
#ifdef THUMB_INTERWORK #ifdef THUMB_INTERWORK
@ -148,9 +150,9 @@ StackType_t *pxOriginalTOS;
pxTopOfStack--; pxTopOfStack--;
/* Some optimisation levels use the stack differently to others. This /* Some optimisation levels use the stack differently to others. This
means the interrupt flags cannot always be stored on the stack and will * means the interrupt flags cannot always be stored on the stack and will
instead be stored in a variable, which is then saved as part of the * instead be stored in a variable, which is then saved as part of the
tasks context. */ * tasks context. */
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING; *pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
return pxTopOfStack; return pxTopOfStack;
@ -160,7 +162,7 @@ StackType_t *pxOriginalTOS;
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
/* Start the timer that generates the tick ISR. Interrupts are disabled /* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */ * here already. */
prvSetupTimerInterrupt(); prvSetupTimerInterrupt();
/* Start the first task. */ /* Start the first task. */
@ -174,7 +176,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* It is unlikely that the ARM port will require this function as there /* It is unlikely that the ARM port will require this function as there
is nothing to return to. */ * is nothing to return to. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -186,27 +188,20 @@ static void prvSetupTimerInterrupt( void )
AT91PS_PITC pxPIT = AT91C_BASE_PITC; AT91PS_PITC pxPIT = AT91C_BASE_PITC;
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends /* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
on whether the preemptive or cooperative scheduler is being used. */ * on whether the preemptive or cooperative scheduler is being used. */
#if configUSE_PREEMPTION == 0 #if configUSE_PREEMPTION == 0
extern void( vNonPreemptiveTick ) ( void ); extern void( vNonPreemptiveTick ) ( void );
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vNonPreemptiveTick ); AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vNonPreemptiveTick );
#else #else
extern void( vPreemptiveTick )( void ); extern void( vPreemptiveTick )( void );
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vPreemptiveTick ); AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void ( * )( void ) )vPreemptiveTick );
#endif #endif
/* Configure the PIT period. */ /* Configure the PIT period. */
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE; pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
/* Enable the interrupt. Global interrupts are disables at this point so /* Enable the interrupt. Global interrupts are disables at this point so
this is safe. */ * this is safe. */
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS; AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -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 + The assembler statements are now included in a single asm block rather
than each line having its own asm block. + than each line having its own asm block.
*/ */
/* Scheduler includes. */ /* Scheduler includes. */
@ -67,7 +67,7 @@ void vPortISRStartFirstTask( void );
void vPortISRStartFirstTask( void ) void vPortISRStartFirstTask( void )
{ {
/* Simply start the scheduler. This is included here as it can only be /* Simply start the scheduler. This is included here as it can only be
called from ARM mode. */ * called from ARM mode. */
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -83,8 +83,8 @@ void vPortISRStartFirstTask( void )
void vPortYieldProcessor( void ) void vPortYieldProcessor( void )
{ {
/* Within an IRQ ISR the link register has an offset from the true return /* Within an IRQ ISR the link register has an offset from the true return
address, but an SWI ISR does not. Add the offset manually so the same * address, but an SWI ISR does not. Add the offset manually so the same
ISR return code can be used in both cases. */ * ISR return code can be used in both cases. */
__asm volatile ( "ADD LR, LR, #4"); __asm volatile ( "ADD LR, LR, #4");
/* Perform the context switch. First save the context of the current task. */ /* Perform the context switch. First save the context of the current task. */
@ -106,15 +106,15 @@ void vPortYieldProcessor( void )
#if configUSE_PREEMPTION == 0 #if configUSE_PREEMPTION == 0
/* The cooperative scheduler requires a normal IRQ service routine to /* The cooperative scheduler requires a normal IRQ service routine to
simply increment the system tick. */ * simply increment the system tick. */
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) ); void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
void vNonPreemptiveTick( void ) void vNonPreemptiveTick( void )
{ {
uint32_t ulDummy; uint32_t ulDummy;
/* Increment the tick count - which may wake some tasks but as the /* Increment the tick count - which may wake some tasks but as the
preemptive scheduler is not being used any woken task is not given * preemptive scheduler is not being used any woken task is not given
processor time no matter what its priority. */ * processor time no matter what its priority. */
xTaskIncrementTick(); xTaskIncrementTick();
/* Clear the PIT interrupt. */ /* Clear the PIT interrupt. */
@ -124,10 +124,10 @@ void vPortYieldProcessor( void )
AT91C_BASE_AIC->AIC_EOICR = ulDummy; AT91C_BASE_AIC->AIC_EOICR = ulDummy;
} }
#else #else /* if configUSE_PREEMPTION == 0 */
/* The preemptive scheduler is defined as "naked" as the full context is /* The preemptive scheduler is defined as "naked" as the full context is
saved on entry as part of the context switch. */ * saved on entry as part of the context switch. */
void vPreemptiveTick( void ) __attribute__( ( naked ) ); void vPreemptiveTick( void ) __attribute__( ( naked ) );
void vPreemptiveTick( void ) void vPreemptiveTick( void )
{ {
@ -147,7 +147,7 @@ void vPortYieldProcessor( void )
portRESTORE_CONTEXT(); 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 /* The code generated by the GCC compiler uses the stack in different ways at
different optimisation levels. The interrupt flags can therefore not always * different optimisation levels. The interrupt flags can therefore not always
be saved to the stack. Instead the critical section nesting level is stored * be saved to the stack. Instead the critical section nesting level is stored
in a variable, which is then saved as part of the stack context. */ * in a variable, which is then saved as part of the stack context. */
void vPortEnterCritical( void ) void vPortEnterCritical( void )
{ {
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */ /* Disable interrupts as per portDISABLE_INTERRUPTS(); */
@ -197,8 +197,8 @@ void vPortEnterCritical( void )
"LDMIA SP!, {R0}"); /* Pop R0. */ "LDMIA SP!, {R0}"); /* Pop R0. */
/* Now interrupts are disabled ulCriticalNesting can be accessed /* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times * directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */ * portENTER_CRITICAL() has been called. */
ulCriticalNesting++; ulCriticalNesting++;
} }
@ -210,7 +210,7 @@ void vPortExitCritical( void )
ulCriticalNesting--; ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be /* If the nesting level has reached zero then interrupts should be
re-enabled. */ * re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING ) if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{ {
/* Enable interrupts as per portEXIT_CRITICAL(). */ /* Enable interrupts as per portEXIT_CRITICAL(). */
@ -223,4 +223,3 @@ void vPortExitCritical( void )
} }
} }
} }

View file

@ -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. + Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
+
Changes from V3.2.4 + Changes from V3.2.4
+
+ Removed the use of the %0 parameter within the assembler macros and + Removed the use of the %0 parameter within the assembler macros and
replaced them with hard coded registers. This will ensure the + replaced them with hard coded registers. This will ensure the
assembler does not select the link register as the temp register as + assembler does not select the link register as the temp register as
was occasionally happening previously. + was occasionally happening previously.
+
+ The assembler statements are now included in a single asm block rather + The assembler statements are now included in a single asm block rather
than each line having its own asm block. + than each line having its own asm block.
+
Changes from V4.5.0 + Changes from V4.5.0
+
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros + Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
and replaced them with portYIELD_FROM_ISR() macro. Application code + and replaced them with portYIELD_FROM_ISR() macro. Application code
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT() + should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
macros as per the V4.5.1 demo code. + macros as per the V4.5.1 demo code.
*/ */
#ifndef PORTMACRO_H #ifndef PORTMACRO_H
@ -245,4 +245,3 @@ extern void vPortExitCritical( void );
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -77,22 +77,24 @@ extern void vPortISRStartFirstTask( void );
* *
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
StackType_t * pxOriginalTOS; StackType_t * pxOriginalTOS;
pxOriginalTOS = pxTopOfStack; pxOriginalTOS = pxTopOfStack;
/* To ensure asserts in tasks.c don't fail, although in this case the assert /* To ensure asserts in tasks.c don't fail, although in this case the assert
is not really required. */ * is not really required. */
pxTopOfStack--; pxTopOfStack--;
/* Setup the initial stack of the task. The stack is set exactly as /* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */ * expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the /* First on the stack is the return address - which in this case is the
start of the task. The offset is added to make the return address appear * start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */ * as it would within an IRQ ISR. */
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE; *pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--; pxTopOfStack--;
@ -126,12 +128,12 @@ StackType_t *pxOriginalTOS;
pxTopOfStack--; pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in /* When the task starts is will expect to find the function parameter in
R0. */ * R0. */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
pxTopOfStack--; pxTopOfStack--;
/* The last thing onto the stack is the status register, which is set for /* The last thing onto the stack is the status register, which is set for
system mode, with interrupts enabled. */ * system mode, with interrupts enabled. */
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 ) if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
@ -143,9 +145,9 @@ StackType_t *pxOriginalTOS;
pxTopOfStack--; pxTopOfStack--;
/* Some optimisation levels use the stack differently to others. This /* Some optimisation levels use the stack differently to others. This
means the interrupt flags cannot always be stored on the stack and will * means the interrupt flags cannot always be stored on the stack and will
instead be stored in a variable, which is then saved as part of the * instead be stored in a variable, which is then saved as part of the
tasks context. */ * tasks context. */
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING; *pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
return pxTopOfStack; return pxTopOfStack;
@ -155,7 +157,7 @@ StackType_t *pxOriginalTOS;
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
/* Start the timer that generates the tick ISR. Interrupts are disabled /* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */ * here already. */
prvSetupTimerInterrupt(); prvSetupTimerInterrupt();
/* Start the first task. */ /* Start the first task. */
@ -169,7 +171,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* It is unlikely that the ARM port will require this function as there /* It is unlikely that the ARM port will require this function as there
is nothing to return to. */ * is nothing to return to. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -179,17 +181,18 @@ void vPortEndScheduler( void )
static void prvSetupTimerInterrupt( void ) static void prvSetupTimerInterrupt( void )
{ {
uint32_t ulCompareMatch; uint32_t ulCompareMatch;
extern void( vTickISR )( void ); extern void( vTickISR )( void );
/* A 1ms tick does not require the use of the timer prescale. This is /* A 1ms tick does not require the use of the timer prescale. This is
defaulted to zero but can be used if necessary. */ * defaulted to zero but can be used if necessary. */
T0_PR = portPRESCALE_VALUE; T0_PR = portPRESCALE_VALUE;
/* Calculate the match value required for our wanted tick rate. */ /* Calculate the match value required for our wanted tick rate. */
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ; ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
/* Protect against divide by zero. Using an if() statement still results /* Protect against divide by zero. Using an if() statement still results
in a warning - hence the #if. */ * in a warning - hence the #if. */
#if portPRESCALE_VALUE != 0 #if portPRESCALE_VALUE != 0
{ {
ulCompareMatch /= ( portPRESCALE_VALUE + 1 ); ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
@ -205,16 +208,13 @@ extern void ( vTickISR )( void );
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT; VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
/* The ISR installed depends on whether the preemptive or cooperative /* The ISR installed depends on whether the preemptive or cooperative
scheduler is being used. */ * scheduler is being used. */
VICVectAddr0 = ( int32_t ) vTickISR; VICVectAddr0 = ( int32_t ) vTickISR;
VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE; VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
/* Start the timer - interrupts are disabled when this function is called /* Start the timer - interrupts are disabled when this function is called
so it is okay to do this here. */ * so it is okay to do this here. */
T0_TCR = portENABLE_TIMER; T0_TCR = portENABLE_TIMER;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -32,21 +32,21 @@
*----------------------------------------------------------*/ *----------------------------------------------------------*/
/* /*
Changes from V2.5.2 * Changes from V2.5.2
*
+ The critical section management functions have been changed. These no + The critical section management functions have been changed. These no
longer modify the stack and are safe to use at all optimisation levels. + longer modify the stack and are safe to use at all optimisation levels.
The functions are now also the same for both ARM and THUMB modes. + The functions are now also the same for both ARM and THUMB modes.
+
Changes from V2.6.0 + Changes from V2.6.0
+
+ Removed the 'static' from the definition of vNonPreemptiveTick() to + Removed the 'static' from the definition of vNonPreemptiveTick() to
allow the demo to link when using the cooperative scheduler. + allow the demo to link when using the cooperative scheduler.
+
Changes from V3.2.4 + Changes from V3.2.4
+
+ The assembler statements are now included in a single asm block rather + The assembler statements are now included in a single asm block rather
than each line having its own asm block. + than each line having its own asm block.
*/ */
@ -76,7 +76,7 @@ void vPortISRStartFirstTask( void );
void vPortISRStartFirstTask( void ) void vPortISRStartFirstTask( void )
{ {
/* Simply start the scheduler. This is included here as it can only be /* Simply start the scheduler. This is included here as it can only be
called from ARM mode. */ * called from ARM mode. */
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -92,8 +92,8 @@ void vPortISRStartFirstTask( void )
void vPortYieldProcessor( void ) void vPortYieldProcessor( void )
{ {
/* Within an IRQ ISR the link register has an offset from the true return /* Within an IRQ ISR the link register has an offset from the true return
address, but an SWI ISR does not. Add the offset manually so the same * address, but an SWI ISR does not. Add the offset manually so the same
ISR return code can be used in both cases. */ * ISR return code can be used in both cases. */
__asm volatile ( "ADD LR, LR, #4"); __asm volatile ( "ADD LR, LR, #4");
/* Perform the context switch. First save the context of the current task. */ /* Perform the context switch. First save the context of the current task. */
@ -117,7 +117,7 @@ void vTickISR( void )
portSAVE_CONTEXT(); portSAVE_CONTEXT();
/* Increment the RTOS tick count, then look for the highest priority /* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */ * task that is ready to run. */
__asm volatile __asm volatile
( (
" bl xTaskIncrementTick \t\n"\ " bl xTaskIncrementTick \t\n"\
@ -172,9 +172,9 @@ void vTickISR( void )
#endif /* THUMB_INTERWORK */ #endif /* THUMB_INTERWORK */
/* The code generated by the GCC compiler uses the stack in different ways at /* The code generated by the GCC compiler uses the stack in different ways at
different optimisation levels. The interrupt flags can therefore not always * different optimisation levels. The interrupt flags can therefore not always
be saved to the stack. Instead the critical section nesting level is stored * be saved to the stack. Instead the critical section nesting level is stored
in a variable, which is then saved as part of the stack context. */ * in a variable, which is then saved as part of the stack context. */
void vPortEnterCritical( void ) void vPortEnterCritical( void )
{ {
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */ /* Disable interrupts as per portDISABLE_INTERRUPTS(); */
@ -186,8 +186,8 @@ void vPortEnterCritical( void )
"LDMIA SP!, {R0}"); /* Pop R0. */ "LDMIA SP!, {R0}"); /* Pop R0. */
/* Now interrupts are disabled ulCriticalNesting can be accessed /* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times * directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */ * portENTER_CRITICAL() has been called. */
ulCriticalNesting++; ulCriticalNesting++;
} }
@ -199,7 +199,7 @@ void vPortExitCritical( void )
ulCriticalNesting--; ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be /* If the nesting level has reached zero then interrupts should be
re-enabled. */ * re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING ) if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{ {
/* Enable interrupts as per portEXIT_CRITICAL(). */ /* Enable interrupts as per portEXIT_CRITICAL(). */

View file

@ -222,4 +222,3 @@ extern void vPortExitCritical( void );
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -77,22 +77,24 @@ extern void vPortISRStartFirstTask( void );
* *
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
StackType_t * pxOriginalTOS; StackType_t * pxOriginalTOS;
pxOriginalTOS = pxTopOfStack; pxOriginalTOS = pxTopOfStack;
/* To ensure asserts in tasks.c don't fail, although in this case the assert /* To ensure asserts in tasks.c don't fail, although in this case the assert
is not really required. */ * is not really required. */
pxTopOfStack--; pxTopOfStack--;
/* Setup the initial stack of the task. The stack is set exactly as /* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */ * expected by the portRESTORE_CONTEXT() macro. */
/* First on the stack is the return address - which in this case is the /* First on the stack is the return address - which in this case is the
start of the task. The offset is added to make the return address appear * start of the task. The offset is added to make the return address appear
as it would within an IRQ ISR. */ * as it would within an IRQ ISR. */
*pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE; *pxTopOfStack = ( StackType_t ) pxCode + portINSTRUCTION_SIZE;
pxTopOfStack--; pxTopOfStack--;
@ -126,12 +128,12 @@ StackType_t *pxOriginalTOS;
pxTopOfStack--; pxTopOfStack--;
/* When the task starts is will expect to find the function parameter in /* When the task starts is will expect to find the function parameter in
R0. */ * R0. */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
pxTopOfStack--; pxTopOfStack--;
/* The last thing onto the stack is the status register, which is set for /* The last thing onto the stack is the status register, which is set for
system mode, with interrupts enabled. */ * system mode, with interrupts enabled. */
*pxTopOfStack = ( StackType_t ) portINITIAL_SPSR; *pxTopOfStack = ( StackType_t ) portINITIAL_SPSR;
if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 ) if( ( ( uint32_t ) pxCode & 0x01UL ) != 0x00 )
@ -143,9 +145,9 @@ StackType_t *pxOriginalTOS;
pxTopOfStack--; pxTopOfStack--;
/* Some optimisation levels use the stack differently to others. This /* Some optimisation levels use the stack differently to others. This
means the interrupt flags cannot always be stored on the stack and will * means the interrupt flags cannot always be stored on the stack and will
instead be stored in a variable, which is then saved as part of the * instead be stored in a variable, which is then saved as part of the
tasks context. */ * tasks context. */
*pxTopOfStack = portNO_CRITICAL_SECTION_NESTING; *pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
return pxTopOfStack; return pxTopOfStack;
@ -155,7 +157,7 @@ StackType_t *pxOriginalTOS;
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
/* Start the timer that generates the tick ISR. Interrupts are disabled /* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */ * here already. */
prvSetupTimerInterrupt(); prvSetupTimerInterrupt();
/* Start the first task. */ /* Start the first task. */
@ -169,7 +171,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* It is unlikely that the ARM port will require this function as there /* It is unlikely that the ARM port will require this function as there
is nothing to return to. */ * is nothing to return to. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -185,14 +187,14 @@ uint32_t ulCompareMatch;
T0CTCR = 0; /* Timer mode */ T0CTCR = 0; /* Timer mode */
/* A 1ms tick does not require the use of the timer prescale. This is /* A 1ms tick does not require the use of the timer prescale. This is
defaulted to zero but can be used if necessary. */ * defaulted to zero but can be used if necessary. */
T0PR = portPRESCALE_VALUE; T0PR = portPRESCALE_VALUE;
/* Calculate the match value required for our wanted tick rate. */ /* Calculate the match value required for our wanted tick rate. */
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ; ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
/* Protect against divide by zero. Using an if() statement still results /* Protect against divide by zero. Using an if() statement still results
in a warning - hence the #if. */ * in a warning - hence the #if. */
#if portPRESCALE_VALUE != 0 #if portPRESCALE_VALUE != 0
{ {
ulCompareMatch /= ( portPRESCALE_VALUE + 1 ); ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
@ -207,7 +209,7 @@ uint32_t ulCompareMatch;
VICIntEnable = 0x00000010; VICIntEnable = 0x00000010;
/* The ISR installed depends on whether the preemptive or cooperative /* The ISR installed depends on whether the preemptive or cooperative
scheduler is being used. */ * scheduler is being used. */
#if configUSE_PREEMPTION == 1 #if configUSE_PREEMPTION == 1
{ {
extern void( vPreemptiveTick )( void ); extern void( vPreemptiveTick )( void );
@ -223,10 +225,7 @@ uint32_t ulCompareMatch;
VICVectCntl4 = 1; VICVectCntl4 = 1;
/* Start the timer - interrupts are disabled when this function is called /* Start the timer - interrupts are disabled when this function is called
so it is okay to do this here. */ * so it is okay to do this here. */
T0TCR = portENABLE_TIMER; T0TCR = portENABLE_TIMER;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -58,7 +58,7 @@ void vPortISRStartFirstTask( void );
void vPortISRStartFirstTask( void ) void vPortISRStartFirstTask( void )
{ {
/* Simply start the scheduler. This is included here as it can only be /* Simply start the scheduler. This is included here as it can only be
called from ARM mode. */ * called from ARM mode. */
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -74,8 +74,8 @@ void vPortISRStartFirstTask( void )
void vPortYieldProcessor( void ) void vPortYieldProcessor( void )
{ {
/* Within an IRQ ISR the link register has an offset from the true return /* Within an IRQ ISR the link register has an offset from the true return
address, but an SWI ISR does not. Add the offset manually so the same * address, but an SWI ISR does not. Add the offset manually so the same
ISR return code can be used in both cases. */ * ISR return code can be used in both cases. */
__asm volatile ( "ADD LR, LR, #4"); __asm volatile ( "ADD LR, LR, #4");
/* Perform the context switch. First save the context of the current task. */ /* Perform the context switch. First save the context of the current task. */
@ -98,7 +98,7 @@ void vPortYieldProcessor( void )
#if configUSE_PREEMPTION == 0 #if configUSE_PREEMPTION == 0
/* The cooperative scheduler requires a normal IRQ service routine to /* The cooperative scheduler requires a normal IRQ service routine to
simply increment the system tick. */ * simply increment the system tick. */
void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) ); void vNonPreemptiveTick( void ) __attribute__( ( interrupt( "IRQ" ) ) );
void vNonPreemptiveTick( void ) void vNonPreemptiveTick( void )
{ {
@ -107,10 +107,10 @@ void vPortYieldProcessor( void )
VICVectAddr = portCLEAR_VIC_INTERRUPT; VICVectAddr = portCLEAR_VIC_INTERRUPT;
} }
#else #else /* if configUSE_PREEMPTION == 0 */
/* The preemptive scheduler is defined as "naked" as the full context is /* The preemptive scheduler is defined as "naked" as the full context is
saved on entry as part of the context switch. */ * saved on entry as part of the context switch. */
void vPreemptiveTick( void ) __attribute__( ( naked ) ); void vPreemptiveTick( void ) __attribute__( ( naked ) );
void vPreemptiveTick( void ) void vPreemptiveTick( void )
{ {
@ -118,7 +118,7 @@ void vPortYieldProcessor( void )
portSAVE_CONTEXT(); portSAVE_CONTEXT();
/* Increment the RTOS tick count, then look for the highest priority /* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */ * task that is ready to run. */
__asm volatile __asm volatile
( (
" bl xTaskIncrementTick \t\n"\ " bl xTaskIncrementTick \t\n"\
@ -136,7 +136,7 @@ void vPortYieldProcessor( void )
portRESTORE_CONTEXT(); portRESTORE_CONTEXT();
} }
#endif #endif /* if configUSE_PREEMPTION == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
@ -175,9 +175,9 @@ void vPortYieldProcessor( void )
#endif /* THUMB_INTERWORK */ #endif /* THUMB_INTERWORK */
/* The code generated by the GCC compiler uses the stack in different ways at /* The code generated by the GCC compiler uses the stack in different ways at
different optimisation levels. The interrupt flags can therefore not always * different optimisation levels. The interrupt flags can therefore not always
be saved to the stack. Instead the critical section nesting level is stored * be saved to the stack. Instead the critical section nesting level is stored
in a variable, which is then saved as part of the stack context. */ * in a variable, which is then saved as part of the stack context. */
void vPortEnterCritical( void ) void vPortEnterCritical( void )
{ {
/* Disable interrupts as per portDISABLE_INTERRUPTS(); */ /* Disable interrupts as per portDISABLE_INTERRUPTS(); */
@ -189,8 +189,8 @@ void vPortEnterCritical( void )
"LDMIA SP!, {R0}"); /* Pop R0. */ "LDMIA SP!, {R0}"); /* Pop R0. */
/* Now interrupts are disabled ulCriticalNesting can be accessed /* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times * directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */ * portENTER_CRITICAL() has been called. */
ulCriticalNesting++; ulCriticalNesting++;
} }
@ -202,7 +202,7 @@ void vPortExitCritical( void )
ulCriticalNesting--; ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be /* If the nesting level has reached zero then interrupts should be
re-enabled. */ * re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING ) if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{ {
/* Enable interrupts as per portEXIT_CRITICAL(). */ /* Enable interrupts as per portEXIT_CRITICAL(). */

View file

@ -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. + Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
+
Changes from V3.2.4 + Changes from V3.2.4
+
+ Removed the use of the %0 parameter within the assembler macros and + Removed the use of the %0 parameter within the assembler macros and
replaced them with hard coded registers. This will ensure the + replaced them with hard coded registers. This will ensure the
assembler does not select the link register as the temp register as + assembler does not select the link register as the temp register as
was occasionally happening previously. + was occasionally happening previously.
+
+ The assembler statements are now included in a single asm block rather + The assembler statements are now included in a single asm block rather
than each line having its own asm block. + than each line having its own asm block.
+
Changes from V4.5.0 + Changes from V4.5.0
+
+ Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros + Removed the portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros
and replaced them with portYIELD_FROM_ISR() macro. Application code + and replaced them with portYIELD_FROM_ISR() macro. Application code
should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT() + should now make use of the portSAVE_CONTEXT() and portRESTORE_CONTEXT()
macros as per the V4.5.1 demo code. + macros as per the V4.5.1 demo code.
*/ */
#ifndef PORTMACRO_H #ifndef PORTMACRO_H
@ -245,4 +245,3 @@ extern void vPortExitCritical( void );
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -32,23 +32,23 @@
#include "task.h" #include "task.h"
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS #ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
#endif #endif
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET #ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
#endif #endif
#ifndef configUNIQUE_INTERRUPT_PRIORITIES #ifndef configUNIQUE_INTERRUPT_PRIORITIES
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
#endif #endif
#ifndef configSETUP_TICK_INTERRUPT #ifndef configSETUP_TICK_INTERRUPT
#error configSETUP_TICK_INTERRUPT() must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #error configSETUP_TICK_INTERRUPT() must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
#endif /* configSETUP_TICK_INTERRUPT */ #endif /* configSETUP_TICK_INTERRUPT */
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY #ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
#endif #endif
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0 #if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
@ -72,24 +72,24 @@
#endif #endif
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in /* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
portmacro.h. */ * portmacro.h. */
#ifndef configCLEAR_TICK_INTERRUPT #ifndef configCLEAR_TICK_INTERRUPT
#define configCLEAR_TICK_INTERRUPT() #define configCLEAR_TICK_INTERRUPT()
#endif #endif
/* A critical section is exited when the critical section nesting count reaches /* A critical section is exited when the critical section nesting count reaches
this value. */ * this value. */
#define portNO_CRITICAL_NESTING ( ( size_t ) 0 ) #define portNO_CRITICAL_NESTING ( ( size_t ) 0 )
/* In all GICs 255 can be written to the priority mask register to unmask all /* In all GICs 255 can be written to the priority mask register to unmask all
(but the lowest) interrupt priority. */ * (but the lowest) interrupt priority. */
#define portUNMASK_VALUE ( 0xFFUL ) #define portUNMASK_VALUE ( 0xFFUL )
/* Tasks are not created with a floating point context, but can be given a /* Tasks are not created with a floating point context, but can be given a
floating point context after they have been created. A variable is stored as * floating point context after they have been created. A variable is stored as
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task * part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
does not have an FPU context, or any other value if the task does have an FPU * does not have an FPU context, or any other value if the task does have an FPU
context. */ * context. */
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) #define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
/* Constants required to setup the initial task context. */ /* Constants required to setup the initial task context. */
@ -107,7 +107,7 @@ context. */
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary /* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
point is zero. */ * point is zero. */
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 ) #define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
/* Masks all bits in the APSR other than the mode bits. */ /* Masks all bits in the APSR other than the mode bits. */
@ -142,21 +142,21 @@ extern void vPortRestoreTaskContext( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* A variable is used to keep track of the critical section nesting. This /* A variable is used to keep track of the critical section nesting. This
variable has to be stored as part of the task context and must be initialised to * variable has to be stored as part of the task context and must be initialised to
a non zero value to ensure interrupts don't inadvertently become unmasked before * a non zero value to ensure interrupts don't inadvertently become unmasked before
the scheduler starts. As it is stored as part of the task context it will * the scheduler starts. As it is stored as part of the task context it will
automatically be set to 0 when the first task is started. */ * automatically be set to 0 when the first task is started. */
volatile uint64_t ullCriticalNesting = 9999ULL; volatile uint64_t ullCriticalNesting = 9999ULL;
/* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero /* Saved as part of the task context. If ullPortTaskHasFPUContext is non-zero
then floating point context must be saved and restored for the task. */ * then floating point context must be saved and restored for the task. */
uint64_t ullPortTaskHasFPUContext = pdFALSE; uint64_t ullPortTaskHasFPUContext = pdFALSE;
/* Set to 1 to pend a context switch from an ISR. */ /* Set to 1 to pend a context switch from an ISR. */
uint64_t ullPortYieldRequired = pdFALSE; uint64_t ullPortYieldRequired = pdFALSE;
/* Counts the interrupt nesting depth. A context switch is only performed if /* Counts the interrupt nesting depth. A context switch is only performed if
if the nesting depth is 0. */ * if the nesting depth is 0. */
uint64_t ullPortInterruptNesting = 0; uint64_t ullPortInterruptNesting = 0;
/* Used in the ASM code. */ /* Used in the ASM code. */
@ -170,10 +170,12 @@ __attribute__(( used )) const uint64_t ullMaxAPIPriorityMask = ( configMAX_API_C
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
/* Setup the initial stack of the task. The stack is set exactly as /* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */ * expected by the portRESTORE_CONTEXT() macro. */
/* First all the general purpose registers. */ /* First all the general purpose registers. */
pxTopOfStack--; pxTopOfStack--;
@ -249,13 +251,13 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
pxTopOfStack--; pxTopOfStack--;
/* The task will start with a critical nesting count of 0 as interrupts are /* The task will start with a critical nesting count of 0 as interrupts are
enabled. */ * enabled. */
*pxTopOfStack = portNO_CRITICAL_NESTING; *pxTopOfStack = portNO_CRITICAL_NESTING;
pxTopOfStack--; pxTopOfStack--;
/* The task will start without a floating point context. A task that uses /* The task will start without a floating point context. A task that uses
the floating point hardware must call vPortTaskUsesFPU() before executing * the floating point hardware must call vPortTaskUsesFPU() before executing
any floating point instructions. */ * any floating point instructions. */
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
return pxTopOfStack; return pxTopOfStack;
@ -273,12 +275,12 @@ uint32_t ulAPSR;
volatile uint8_t ucMaxPriorityValue; volatile uint8_t ucMaxPriorityValue;
/* Determine how many priority bits are implemented in the GIC. /* Determine how many priority bits are implemented in the GIC.
*
Save the interrupt priority value that is about to be clobbered. */ * Save the interrupt priority value that is about to be clobbered. */
ulOriginalPriority = *pucFirstUserPriorityRegister; ulOriginalPriority = *pucFirstUserPriorityRegister;
/* Determine the number of priority bits available. First write to /* Determine the number of priority bits available. First write to
all possible bits. */ * all possible bits. */
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
/* Read the value back to see how many bits stuck. */ /* Read the value back to see how many bits stuck. */
@ -291,13 +293,13 @@ uint32_t ulAPSR;
} }
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read /* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
value. */ * value. */
configASSERT( ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY ); configASSERT( ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY );
/* Restore the clobbered interrupt priority register to its original /* Restore the clobbered interrupt priority register to its original
value. */ * value. */
*pucFirstUserPriorityRegister = ulOriginalPriority; *pucFirstUserPriorityRegister = ulOriginalPriority;
} }
#endif /* conifgASSERT_DEFINED */ #endif /* conifgASSERT_DEFINED */
@ -310,23 +312,25 @@ uint32_t ulAPSR;
#if defined( GUEST ) #if defined( GUEST )
#warning Building for execution as a guest under XEN. THIS IS NOT A FULLY TESTED PATH. #warning Building for execution as a guest under XEN. THIS IS NOT A FULLY TESTED PATH.
configASSERT( ulAPSR == portEL1 ); configASSERT( ulAPSR == portEL1 );
if( ulAPSR == portEL1 ) if( ulAPSR == portEL1 )
#else #else
configASSERT( ulAPSR == portEL3 ); configASSERT( ulAPSR == portEL3 );
if( ulAPSR == portEL3 ) if( ulAPSR == portEL3 )
#endif #endif
{ {
/* Only continue if the binary point value is set to its lowest possible /* Only continue if the binary point value is set to its lowest possible
setting. See the comments in vPortValidateInterruptPriority() below for * setting. See the comments in vPortValidateInterruptPriority() below for
more information. */ * more information. */
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ) if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
{ {
/* Interrupts are turned off in the CPU itself to ensure a tick does /* Interrupts are turned off in the CPU itself to ensure a tick does
not execute while the scheduler is being started. Interrupts are * not execute while the scheduler is being started. Interrupts are
automatically turned back on in the CPU when the first task starts * automatically turned back on in the CPU when the first task starts
executing. */ * executing. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
/* Start the timer that generates the tick ISR. */ /* Start the timer that generates the tick ISR. */
@ -344,7 +348,7 @@ uint32_t ulAPSR;
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented in ports where there is nothing to return to. /* Not implemented in ports where there is nothing to return to.
Artificially force an assert. */ * Artificially force an assert. */
configASSERT( ullCriticalNesting == 1000ULL ); configASSERT( ullCriticalNesting == 1000ULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -355,15 +359,15 @@ void vPortEnterCritical( void )
uxPortSetInterruptMask(); uxPortSetInterruptMask();
/* Now interrupts are disabled ullCriticalNesting can be accessed /* Now interrupts are disabled ullCriticalNesting can be accessed
directly. Increment ullCriticalNesting to keep a count of how many times * directly. Increment ullCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */ * portENTER_CRITICAL() has been called. */
ullCriticalNesting++; ullCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so /* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context. Only API * assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if * functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the * the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */ * assert function also uses a critical section. */
if( ullCriticalNesting == 1ULL ) if( ullCriticalNesting == 1ULL )
{ {
configASSERT( ullPortInterruptNesting == 0 ); configASSERT( ullPortInterruptNesting == 0 );
@ -376,15 +380,15 @@ void vPortExitCritical( void )
if( ullCriticalNesting > portNO_CRITICAL_NESTING ) if( ullCriticalNesting > portNO_CRITICAL_NESTING )
{ {
/* Decrement the nesting count as the critical section is being /* Decrement the nesting count as the critical section is being
exited. */ * exited. */
ullCriticalNesting--; ullCriticalNesting--;
/* If the nesting level has reached zero then all interrupt /* If the nesting level has reached zero then all interrupt
priorities must be re-enabled. */ * priorities must be re-enabled. */
if( ullCriticalNesting == portNO_CRITICAL_NESTING ) if( ullCriticalNesting == portNO_CRITICAL_NESTING )
{ {
/* Critical nesting has reached zero so all interrupt priorities /* Critical nesting has reached zero so all interrupt priorities
should be unmasked. */ * should be unmasked. */
portCLEAR_INTERRUPT_MASK(); portCLEAR_INTERRUPT_MASK();
} }
} }
@ -411,10 +415,10 @@ void FreeRTOS_Tick_Handler( void )
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */
/* Set interrupt mask before altering scheduler structures. The tick /* Set interrupt mask before altering scheduler structures. The tick
handler runs at the lowest priority, so interrupts cannot already be masked, * handler runs at the lowest priority, so interrupts cannot already be masked,
so there is no need to save and restore the current mask value. It is * so there is no need to save and restore the current mask value. It is
necessary to turn off interrupts in the CPU itself while the ICCPMR is being * necessary to turn off interrupts in the CPU itself while the ICCPMR is being
updated. */ * updated. */
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
__asm volatile ( "dsb sy \n" __asm volatile ( "dsb sy \n"
"isb sy \n"::: "memory" ); "isb sy \n"::: "memory" );
@ -437,11 +441,11 @@ void FreeRTOS_Tick_Handler( void )
void vPortTaskUsesFPU( void ) void vPortTaskUsesFPU( void )
{ {
/* A task is registering the fact that it needs an FPU context. Set the /* A task is registering the fact that it needs an FPU context. Set the
FPU flag (which is saved as part of the task context). */ * FPU flag (which is saved as part of the task context). */
ullPortTaskHasFPUContext = pdTRUE; ullPortTaskHasFPUContext = pdTRUE;
/* Consider initialising the FPSR here - but probably not necessary in /* Consider initialising the FPSR here - but probably not necessary in
AArch64. */ * AArch64. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -459,8 +463,9 @@ UBaseType_t uxPortSetInterruptMask( void )
uint32_t ulReturn; uint32_t ulReturn;
/* Interrupt in the CPU must be turned off while the ICCPMR is being /* Interrupt in the CPU must be turned off while the ICCPMR is being
updated. */ * updated. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
{ {
/* Interrupts were already masked. */ /* Interrupts were already masked. */
@ -473,6 +478,7 @@ uint32_t ulReturn;
__asm volatile ( "dsb sy \n" __asm volatile ( "dsb sy \n"
"isb sy \n"::: "memory" ); "isb sy \n"::: "memory" );
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
return ulReturn; return ulReturn;
@ -484,34 +490,33 @@ uint32_t ulReturn;
void vPortValidateInterruptPriority( void ) void vPortValidateInterruptPriority( void )
{ {
/* The following assertion will fail if a service routine (ISR) for /* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above * an interrupt that has been assigned a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
function. ISR safe FreeRTOS API functions must *only* be called * function. ISR safe FreeRTOS API functions must *only* be called
from interrupts that have been assigned a priority at or below * from interrupts that have been assigned a priority at or below
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Numerically low interrupt priority numbers represent logically high * Numerically low interrupt priority numbers represent logically high
interrupt priorities, therefore the priority of the interrupt must * interrupt priorities, therefore the priority of the interrupt must
be set to a value equal to or numerically *higher* than * be set to a value equal to or numerically *higher* than
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
FreeRTOS maintains separate thread and ISR API functions to ensure * FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible. */ * interrupt entry is as fast and simple as possible. */
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
/* Priority grouping: The interrupt controller (GIC) allows the bits /* Priority grouping: The interrupt controller (GIC) allows the bits
that define each interrupt's priority to be split between bits that * that define each interrupt's priority to be split between bits that
define the interrupt's pre-emption priority bits and bits that define * define the interrupt's pre-emption priority bits and bits that define
the interrupt's sub-priority. For simplicity all bits must be defined * the interrupt's sub-priority. For simplicity all bits must be defined
to be pre-emption priority bits. The following assertion will fail if * to be pre-emption priority bits. The following assertion will fail if
this is not the case (if some bits represent a sub-priority). * this is not the case (if some bits represent a sub-priority).
*
The priority grouping is configured by the GIC's binary point register * The priority grouping is configured by the GIC's binary point register
(ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest * (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
possible value (which may be above 0). */ * possible value (which may be above 0). */
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
} }
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -58,7 +58,7 @@ typedef uint64_t TickType_t;
#define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff ) #define portMAX_DELAY ( ( TickType_t ) 0xffffffffffffffff )
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -90,6 +90,7 @@ extern uint64_t ullPortYieldRequired; \
#else #else
#define portYIELD() __asm volatile ( "SMC 0" ::: "memory" ) #define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
#endif #endif
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Critical section control * Critical section control
*----------------------------------------------------------*/ *----------------------------------------------------------*/
@ -112,7 +113,7 @@ extern void vPortInstallFreeRTOSVectorTable( void );
/* These macros do not globally disable/enable interrupts. They do mask off /* These macros do not globally disable/enable interrupts. They do mask off
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ * interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
#define portENTER_CRITICAL() vPortEnterCritical(); #define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical(); #define portEXIT_CRITICAL() vPortExitCritical();
#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask() #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 /* Task function macros as described on the FreeRTOS.org WEB site. These are
not required for this port but included in case common demo code that uses these * not required for this port but included in case common demo code that uses these
macros is used. */ * macros is used. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/* Prototype of the FreeRTOS tick handler. This must be installed as the /* Prototype of the FreeRTOS tick handler. This must be installed as the
handler for whichever peripheral is used to generate the RTOS tick. */ * handler for whichever peripheral is used to generate the RTOS tick. */
void FreeRTOS_Tick_Handler( void ); void FreeRTOS_Tick_Handler( void );
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() /* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
before any floating point instructions are executed. */ * before any floating point instructions are executed. */
void vPortTaskUsesFPU( void ); void vPortTaskUsesFPU( void );
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
@ -169,7 +170,7 @@ void vPortTaskUsesFPU( void );
/* The number of bits to shift for an interrupt priority is dependent on the /* The number of bits to shift for an interrupt priority is dependent on the
number of bits implemented by the interrupt controller. */ * number of bits implemented by the interrupt controller. */
#if configUNIQUE_INTERRUPT_PRIORITIES == 16 #if configUNIQUE_INTERRUPT_PRIORITIES == 16
#define portPRIORITY_SHIFT 4 #define portPRIORITY_SHIFT 4
#define portMAX_BINARY_POINT_VALUE 3 #define portMAX_BINARY_POINT_VALUE 3
@ -185,9 +186,9 @@ number of bits implemented by the interrupt controller. */
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256 #elif configUNIQUE_INTERRUPT_PRIORITIES == 256
#define portPRIORITY_SHIFT 0 #define portPRIORITY_SHIFT 0
#define portMAX_BINARY_POINT_VALUE 0 #define portMAX_BINARY_POINT_VALUE 0
#else #else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
#endif #endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
/* Interrupt controller access addresses. */ /* Interrupt controller access addresses. */
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 ) #define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
@ -207,4 +208,3 @@ number of bits implemented by the interrupt controller. */
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -32,23 +32,23 @@
#include "task.h" #include "task.h"
#ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS #ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS
#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
#endif #endif
#ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET #ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET
#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
#endif #endif
#ifndef configUNIQUE_INTERRUPT_PRIORITIES #ifndef configUNIQUE_INTERRUPT_PRIORITIES
#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
#endif #endif
#ifndef configSETUP_TICK_INTERRUPT #ifndef configSETUP_TICK_INTERRUPT
#error configSETUP_TICK_INTERRUPT() must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #error configSETUP_TICK_INTERRUPT() must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
#endif /* configSETUP_TICK_INTERRUPT */ #endif /* configSETUP_TICK_INTERRUPT */
#ifndef configMAX_API_CALL_INTERRUPT_PRIORITY #ifndef configMAX_API_CALL_INTERRUPT_PRIORITY
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http: /*www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html */
#endif #endif
#if configMAX_API_CALL_INTERRUPT_PRIORITY == 0 #if configMAX_API_CALL_INTERRUPT_PRIORITY == 0
@ -72,24 +72,24 @@
#endif #endif
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in /* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
portmacro.h. */ * portmacro.h. */
#ifndef configCLEAR_TICK_INTERRUPT #ifndef configCLEAR_TICK_INTERRUPT
#define configCLEAR_TICK_INTERRUPT() #define configCLEAR_TICK_INTERRUPT()
#endif #endif
/* A critical section is exited when the critical section nesting count reaches /* A critical section is exited when the critical section nesting count reaches
this value. */ * this value. */
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 ) #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
/* In all GICs 255 can be written to the priority mask register to unmask all /* In all GICs 255 can be written to the priority mask register to unmask all
(but the lowest) interrupt priority. */ * (but the lowest) interrupt priority. */
#define portUNMASK_VALUE ( 0xFFUL ) #define portUNMASK_VALUE ( 0xFFUL )
/* Tasks are not created with a floating point context, but can be given a /* Tasks are not created with a floating point context, but can be given a
floating point context after they have been created. A variable is stored as * floating point context after they have been created. A variable is stored as
part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task * part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
does not have an FPU context, or any other value if the task does have an FPU * does not have an FPU context, or any other value if the task does have an FPU
context. */ * context. */
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 ) #define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
/* Constants required to setup the initial task context. */ /* Constants required to setup the initial task context. */
@ -99,19 +99,19 @@ context. */
#define portTHUMB_MODE_ADDRESS ( 0x01UL ) #define portTHUMB_MODE_ADDRESS ( 0x01UL )
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary /* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
point is zero. */ * point is zero. */
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 ) #define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
/* Masks all bits in the APSR other than the mode bits. */ /* Masks all bits in the APSR other than the mode bits. */
#define portAPSR_MODE_BITS_MASK ( 0x1F ) #define portAPSR_MODE_BITS_MASK ( 0x1F )
/* The value of the mode bits in the APSR when the CPU is executing in user /* The value of the mode bits in the APSR when the CPU is executing in user
mode. */ * mode. */
#define portAPSR_USER_MODE ( 0x10 ) #define portAPSR_USER_MODE ( 0x10 )
/* The critical section macros only mask interrupts up to an application /* The critical section macros only mask interrupts up to an application
determined priority level. Sometimes it is necessary to turn interrupt off in * determined priority level. Sometimes it is necessary to turn interrupt off in
the CPU itself before modifying certain hardware registers. */ * the CPU itself before modifying certain hardware registers. */
#define portCPU_IRQ_DISABLE() \ #define portCPU_IRQ_DISABLE() \
__asm volatile ( "CPSID i" ::: "memory" ); \ __asm volatile ( "CPSID i" ::: "memory" ); \
__asm volatile ( "DSB" ); \ __asm volatile ( "DSB" ); \
@ -138,8 +138,8 @@ the CPU itself before modifying certain hardware registers. */
#define portBIT_0_SET ( ( uint8_t ) 0x01 ) #define portBIT_0_SET ( ( uint8_t ) 0x01 )
/* Let the user override the pre-loading of the initial LR with the address of /* Let the user override the pre-loading of the initial LR with the address of
prvTaskExitError() in case it messes up unwinding of the stack in the * prvTaskExitError() in case it messes up unwinding of the stack in the
debugger. */ * debugger. */
#ifdef configTASK_RETURN_ADDRESS #ifdef configTASK_RETURN_ADDRESS
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
#else #else
@ -147,7 +147,7 @@ debugger. */
#endif #endif
/* The space on the stack required to hold the FPU registers. This is 32 64-bit /* The space on the stack required to hold the FPU registers. This is 32 64-bit
registers, plus a 32-bit status register. */ * registers, plus a 32-bit status register. */
#define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 ) #define portFPU_REGISTER_WORDS ( ( 32 * 2 ) + 1 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -187,21 +187,21 @@ void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* A variable is used to keep track of the critical section nesting. This /* A variable is used to keep track of the critical section nesting. This
variable has to be stored as part of the task context and must be initialised to * variable has to be stored as part of the task context and must be initialised to
a non zero value to ensure interrupts don't inadvertently become unmasked before * a non zero value to ensure interrupts don't inadvertently become unmasked before
the scheduler starts. As it is stored as part of the task context it will * the scheduler starts. As it is stored as part of the task context it will
automatically be set to 0 when the first task is started. */ * automatically be set to 0 when the first task is started. */
volatile uint32_t ulCriticalNesting = 9999UL; volatile uint32_t ulCriticalNesting = 9999UL;
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then /* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
a floating point context must be saved and restored for the task. */ * a floating point context must be saved and restored for the task. */
volatile uint32_t ulPortTaskHasFPUContext = pdFALSE; volatile uint32_t ulPortTaskHasFPUContext = pdFALSE;
/* Set to 1 to pend a context switch from an ISR. */ /* Set to 1 to pend a context switch from an ISR. */
volatile uint32_t ulPortYieldRequired = pdFALSE; volatile uint32_t ulPortYieldRequired = pdFALSE;
/* Counts the interrupt nesting depth. A context switch is only performed if /* Counts the interrupt nesting depth. A context switch is only performed if
if the nesting depth is 0. */ * if the nesting depth is 0. */
volatile uint32_t ulPortInterruptNesting = 0UL; volatile uint32_t ulPortInterruptNesting = 0UL;
/* Used in the asm file. */ /* Used in the asm file. */
@ -215,14 +215,16 @@ __attribute__(( used )) const uint32_t ulMaxAPIPriorityMask = ( configMAX_API_CA
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
/* Setup the initial stack of the task. The stack is set exactly as /* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. * expected by the portRESTORE_CONTEXT() macro.
*
The fist real value on the stack is the status register, which is set for * The fist real value on the stack is the status register, which is set for
system mode, with interrupts enabled. A few NULLs are added first to ensure * system mode, with interrupts enabled. A few NULLs are added first to ensure
GDB does not try decoding a non-existent return address. */ * GDB does not try decoding a non-existent return address. */
*pxTopOfStack = ( StackType_t ) NULL; *pxTopOfStack = ( StackType_t ) NULL;
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) NULL; *pxTopOfStack = ( StackType_t ) NULL;
@ -274,21 +276,21 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
pxTopOfStack--; pxTopOfStack--;
/* The task will start with a critical nesting count of 0 as interrupts are /* The task will start with a critical nesting count of 0 as interrupts are
enabled. */ * enabled. */
*pxTopOfStack = portNO_CRITICAL_NESTING; *pxTopOfStack = portNO_CRITICAL_NESTING;
#if ( configUSE_TASK_FPU_SUPPORT == 1 ) #if ( configUSE_TASK_FPU_SUPPORT == 1 )
{ {
/* The task will start without a floating point context. A task that /* The task will start without a floating point context. A task that
uses the floating point hardware must call vPortTaskUsesFPU() before * uses the floating point hardware must call vPortTaskUsesFPU() before
executing any floating point instructions. */ * executing any floating point instructions. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
} }
#elif ( configUSE_TASK_FPU_SUPPORT == 2 ) #elif ( configUSE_TASK_FPU_SUPPORT == 2 )
{ {
/* The task will start with a floating point context. Leave enough /* The task will start with a floating point context. Leave enough
space for the registers - and ensure they are initialised to 0. */ * space for the registers - and ensure they are initialised to 0. */
pxTopOfStack -= portFPU_REGISTER_WORDS; pxTopOfStack -= portFPU_REGISTER_WORDS;
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) ); memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
@ -296,11 +298,11 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
*pxTopOfStack = pdTRUE; *pxTopOfStack = pdTRUE;
ulPortTaskHasFPUContext = pdTRUE; ulPortTaskHasFPUContext = pdTRUE;
} }
#else #else /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
{ {
#error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined. #error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined.
} }
#endif #endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
return pxTopOfStack; return pxTopOfStack;
} }
@ -309,14 +311,17 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
static void prvTaskExitError( void ) static void prvTaskExitError( void )
{ {
/* A function that implements a task must not exit or attempt to return to /* A function that implements a task must not exit or attempt to return to
its caller as there is nothing to return to. If a task wants to exit it * its caller as there is nothing to return to. If a task wants to exit it
should instead call vTaskDelete( NULL ). * should instead call vTaskDelete( NULL ).
*
Artificially force an assert() to be triggered if configASSERT() is * Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */ * defined, then stop here so application writers can catch the error. */
configASSERT( ulPortInterruptNesting == ~0UL ); configASSERT( ulPortInterruptNesting == ~0UL );
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
for( ;; );
for( ; ; )
{
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -331,12 +336,12 @@ uint32_t ulAPSR;
volatile uint8_t ucMaxPriorityValue; volatile uint8_t ucMaxPriorityValue;
/* Determine how many priority bits are implemented in the GIC. /* Determine how many priority bits are implemented in the GIC.
*
Save the interrupt priority value that is about to be clobbered. */ * Save the interrupt priority value that is about to be clobbered. */
ulOriginalPriority = *pucFirstUserPriorityRegister; ulOriginalPriority = *pucFirstUserPriorityRegister;
/* Determine the number of priority bits available. First write to /* Determine the number of priority bits available. First write to
all possible bits. */ * all possible bits. */
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
/* Read the value back to see how many bits stuck. */ /* Read the value back to see how many bits stuck. */
@ -349,18 +354,18 @@ uint32_t ulAPSR;
} }
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read /* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
value. */ * value. */
configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY ); configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY );
/* Restore the clobbered interrupt priority register to its original /* Restore the clobbered interrupt priority register to its original
value. */ * value. */
*pucFirstUserPriorityRegister = ulOriginalPriority; *pucFirstUserPriorityRegister = ulOriginalPriority;
} }
#endif /* conifgASSERT_DEFINED */ #endif /* conifgASSERT_DEFINED */
/* Only continue if the CPU is not in User mode. The CPU must be in a /* Only continue if the CPU is not in User mode. The CPU must be in a
Privileged mode for the scheduler to start. */ * Privileged mode for the scheduler to start. */
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR )::"memory" ); __asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR )::"memory" );
ulAPSR &= portAPSR_MODE_BITS_MASK; ulAPSR &= portAPSR_MODE_BITS_MASK;
configASSERT( ulAPSR != portAPSR_USER_MODE ); configASSERT( ulAPSR != portAPSR_USER_MODE );
@ -368,16 +373,16 @@ uint32_t ulAPSR;
if( ulAPSR != portAPSR_USER_MODE ) if( ulAPSR != portAPSR_USER_MODE )
{ {
/* Only continue if the binary point value is set to its lowest possible /* Only continue if the binary point value is set to its lowest possible
setting. See the comments in vPortValidateInterruptPriority() below for * setting. See the comments in vPortValidateInterruptPriority() below for
more information. */ * more information. */
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ) if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
{ {
/* Interrupts are turned off in the CPU itself to ensure tick does /* Interrupts are turned off in the CPU itself to ensure tick does
not execute while the scheduler is being started. Interrupts are * not execute while the scheduler is being started. Interrupts are
automatically turned back on in the CPU when the first task starts * automatically turned back on in the CPU when the first task starts
executing. */ * executing. */
portCPU_IRQ_DISABLE(); portCPU_IRQ_DISABLE();
/* Start the timer that generates the tick ISR. */ /* Start the timer that generates the tick ISR. */
@ -389,10 +394,10 @@ uint32_t ulAPSR;
} }
/* Will only get here if vTaskStartScheduler() was called with the CPU in /* Will only get here if vTaskStartScheduler() was called with the CPU in
a non-privileged mode or the binary point register was not set to its lowest * a non-privileged mode or the binary point register was not set to its lowest
possible value. prvTaskExitError() is referenced to prevent a compiler * possible value. prvTaskExitError() is referenced to prevent a compiler
warning about it being defined but not referenced in the case that the user * warning about it being defined but not referenced in the case that the user
defines their own exit address. */ * defines their own exit address. */
( void ) prvTaskExitError; ( void ) prvTaskExitError;
return 0; return 0;
} }
@ -401,7 +406,7 @@ uint32_t ulAPSR;
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented in ports where there is nothing to return to. /* Not implemented in ports where there is nothing to return to.
Artificially force an assert. */ * Artificially force an assert. */
configASSERT( ulCriticalNesting == 1000UL ); configASSERT( ulCriticalNesting == 1000UL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -412,15 +417,15 @@ void vPortEnterCritical( void )
ulPortSetInterruptMask(); ulPortSetInterruptMask();
/* Now interrupts are disabled ulCriticalNesting can be accessed /* Now interrupts are disabled ulCriticalNesting can be accessed
directly. Increment ulCriticalNesting to keep a count of how many times * directly. Increment ulCriticalNesting to keep a count of how many times
portENTER_CRITICAL() has been called. */ * portENTER_CRITICAL() has been called. */
ulCriticalNesting++; ulCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so /* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context. Only API * assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if * functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the * the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */ * assert function also uses a critical section. */
if( ulCriticalNesting == 1 ) if( ulCriticalNesting == 1 )
{ {
configASSERT( ulPortInterruptNesting == 0 ); configASSERT( ulPortInterruptNesting == 0 );
@ -433,15 +438,15 @@ void vPortExitCritical( void )
if( ulCriticalNesting > portNO_CRITICAL_NESTING ) if( ulCriticalNesting > portNO_CRITICAL_NESTING )
{ {
/* Decrement the nesting count as the critical section is being /* Decrement the nesting count as the critical section is being
exited. */ * exited. */
ulCriticalNesting--; ulCriticalNesting--;
/* If the nesting level has reached zero then all interrupt /* If the nesting level has reached zero then all interrupt
priorities must be re-enabled. */ * priorities must be re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING ) if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{ {
/* Critical nesting has reached zero so all interrupt priorities /* Critical nesting has reached zero so all interrupt priorities
should be unmasked. */ * should be unmasked. */
portCLEAR_INTERRUPT_MASK(); portCLEAR_INTERRUPT_MASK();
} }
} }
@ -451,10 +456,10 @@ void vPortExitCritical( void )
void FreeRTOS_Tick_Handler( void ) void FreeRTOS_Tick_Handler( void )
{ {
/* Set interrupt mask before altering scheduler structures. The tick /* Set interrupt mask before altering scheduler structures. The tick
handler runs at the lowest priority, so interrupts cannot already be masked, * handler runs at the lowest priority, so interrupts cannot already be masked,
so there is no need to save and restore the current mask value. It is * so there is no need to save and restore the current mask value. It is
necessary to turn off interrupts in the CPU itself while the ICCPMR is being * necessary to turn off interrupts in the CPU itself while the ICCPMR is being
updated. */ * updated. */
portCPU_IRQ_DISABLE(); portCPU_IRQ_DISABLE();
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
__asm volatile ( "dsb \n" __asm volatile ( "dsb \n"
@ -480,7 +485,7 @@ void FreeRTOS_Tick_Handler( void )
uint32_t ulInitialFPSCR = 0; uint32_t ulInitialFPSCR = 0;
/* A task is registering the fact that it needs an FPU context. Set the /* A task is registering the fact that it needs an FPU context. Set the
FPU flag (which is saved as part of the task context). */ * FPU flag (which is saved as part of the task context). */
ulPortTaskHasFPUContext = pdTRUE; ulPortTaskHasFPUContext = pdTRUE;
/* Initialise the floating point status register. */ /* Initialise the floating point status register. */
@ -504,8 +509,9 @@ uint32_t ulPortSetInterruptMask( void )
uint32_t ulReturn; uint32_t ulReturn;
/* Interrupt in the CPU must be turned off while the ICCPMR is being /* Interrupt in the CPU must be turned off while the ICCPMR is being
updated. */ * updated. */
portCPU_IRQ_DISABLE(); portCPU_IRQ_DISABLE();
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ) if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
{ {
/* Interrupts were already masked. */ /* Interrupts were already masked. */
@ -518,6 +524,7 @@ uint32_t ulReturn;
__asm volatile ( "dsb \n" __asm volatile ( "dsb \n"
"isb \n"::: "memory" ); "isb \n"::: "memory" );
} }
portCPU_IRQ_ENABLE(); portCPU_IRQ_ENABLE();
return ulReturn; return ulReturn;
@ -529,31 +536,31 @@ uint32_t ulReturn;
void vPortValidateInterruptPriority( void ) void vPortValidateInterruptPriority( void )
{ {
/* The following assertion will fail if a service routine (ISR) for /* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above * an interrupt that has been assigned a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
function. ISR safe FreeRTOS API functions must *only* be called * function. ISR safe FreeRTOS API functions must *only* be called
from interrupts that have been assigned a priority at or below * from interrupts that have been assigned a priority at or below
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Numerically low interrupt priority numbers represent logically high * Numerically low interrupt priority numbers represent logically high
interrupt priorities, therefore the priority of the interrupt must * interrupt priorities, therefore the priority of the interrupt must
be set to a value equal to or numerically *higher* than * be set to a value equal to or numerically *higher* than
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
FreeRTOS maintains separate thread and ISR API functions to ensure * FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible. */ * interrupt entry is as fast and simple as possible. */
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) ); configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
/* Priority grouping: The interrupt controller (GIC) allows the bits /* Priority grouping: The interrupt controller (GIC) allows the bits
that define each interrupt's priority to be split between bits that * that define each interrupt's priority to be split between bits that
define the interrupt's pre-emption priority bits and bits that define * define the interrupt's pre-emption priority bits and bits that define
the interrupt's sub-priority. For simplicity all bits must be defined * the interrupt's sub-priority. For simplicity all bits must be defined
to be pre-emption priority bits. The following assertion will fail if * to be pre-emption priority bits. The following assertion will fail if
this is not the case (if some bits represent a sub-priority). * this is not the case (if some bits represent a sub-priority).
*
The priority grouping is configured by the GIC's binary point register * The priority grouping is configured by the GIC's binary point register
(ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest * (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest
possible value (which may be above 0). */ * possible value (which may be above 0). */
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
} }

View file

@ -58,7 +58,7 @@ typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -98,7 +98,7 @@ extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
extern void vPortInstallFreeRTOSVectorTable( void ); extern void vPortInstallFreeRTOSVectorTable( void );
/* These macros do not globally disable/enable interrupts. They do mask off /* These macros do not globally disable/enable interrupts. They do mask off
interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ * interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
#define portENTER_CRITICAL() vPortEnterCritical(); #define portENTER_CRITICAL() vPortEnterCritical();
#define portEXIT_CRITICAL() vPortExitCritical(); #define portEXIT_CRITICAL() vPortExitCritical();
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() #define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
@ -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 /* Task function macros as described on the FreeRTOS.org WEB site. These are
not required for this port but included in case common demo code that uses these * not required for this port but included in case common demo code that uses these
macros is used. */ * macros is used. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/* Prototype of the FreeRTOS tick handler. This must be installed as the /* Prototype of the FreeRTOS tick handler. This must be installed as the
handler for whichever peripheral is used to generate the RTOS tick. */ * handler for whichever peripheral is used to generate the RTOS tick. */
void FreeRTOS_Tick_Handler( void ); void FreeRTOS_Tick_Handler( void );
/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are /* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
created without an FPU context and must call vPortTaskUsesFPU() to give * created without an FPU context and must call vPortTaskUsesFPU() to give
themselves an FPU context before using any FPU instructions. If * themselves an FPU context before using any FPU instructions. If
configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context * configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
by default. */ * by default. */
#if ( configUSE_TASK_FPU_SUPPORT != 2 ) #if ( configUSE_TASK_FPU_SUPPORT != 2 )
void vPortTaskUsesFPU( void ); void vPortTaskUsesFPU( void );
#else #else
/* Each task has an FPU context already, so define this function away to /* 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() #define vPortTaskUsesFPU()
#endif #endif
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #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 /* The number of bits to shift for an interrupt priority is dependent on the
number of bits implemented by the interrupt controller. */ * number of bits implemented by the interrupt controller. */
#if configUNIQUE_INTERRUPT_PRIORITIES == 16 #if configUNIQUE_INTERRUPT_PRIORITIES == 16
#define portPRIORITY_SHIFT 4 #define portPRIORITY_SHIFT 4
#define portMAX_BINARY_POINT_VALUE 3 #define portMAX_BINARY_POINT_VALUE 3
@ -182,9 +183,9 @@ number of bits implemented by the interrupt controller. */
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256 #elif configUNIQUE_INTERRUPT_PRIORITIES == 256
#define portPRIORITY_SHIFT 0 #define portPRIORITY_SHIFT 0
#define portMAX_BINARY_POINT_VALUE 0 #define portMAX_BINARY_POINT_VALUE 0
#else #else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
#endif #endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
/* Interrupt controller access addresses. */ /* Interrupt controller access addresses. */
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 ) #define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
@ -204,4 +205,3 @@ number of bits implemented by the interrupt controller. */
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -54,15 +54,15 @@
#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) #define portMAX_24_BIT_NUMBER ( 0xffffffUL )
/* A fiddle factor to estimate the number of SysTick counts that would have /* A fiddle factor to estimate the number of SysTick counts that would have
occurred while the SysTick counter is stopped during tickless idle * occurred while the SysTick counter is stopped during tickless idle
calculations. */ * calculations. */
#ifndef portMISSED_COUNTS_FACTOR #ifndef portMISSED_COUNTS_FACTOR
#define portMISSED_COUNTS_FACTOR ( 45UL ) #define portMISSED_COUNTS_FACTOR ( 45UL )
#endif #endif
/* Let the user override the pre-loading of the initial LR with the address of /* Let the user override the pre-loading of the initial LR with the address of
prvTaskExitError() in case it messes up unwinding of the stack in the * prvTaskExitError() in case it messes up unwinding of the stack in the
debugger. */ * debugger. */
#ifdef configTASK_RETURN_ADDRESS #ifdef configTASK_RETURN_ADDRESS
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
#else #else
@ -96,7 +96,7 @@ static void prvTaskExitError( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Each task maintains its own interrupt status in the critical nesting /* Each task maintains its own interrupt status in the critical nesting
variable. */ * variable. */
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -129,10 +129,12 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
/* Simulate the stack frame as it would be created by a context switch /* Simulate the stack frame as it would be created by a context switch
interrupt. */ * interrupt. */
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */
pxTopOfStack--; pxTopOfStack--;
@ -152,22 +154,23 @@ static void prvTaskExitError( void )
volatile uint32_t ulDummy = 0UL; volatile uint32_t ulDummy = 0UL;
/* A function that implements a task must not exit or attempt to return to /* A function that implements a task must not exit or attempt to return to
its caller as there is nothing to return to. If a task wants to exit it * its caller as there is nothing to return to. If a task wants to exit it
should instead call vTaskDelete( NULL ). * should instead call vTaskDelete( NULL ).
*
Artificially force an assert() to be triggered if configASSERT() is * Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */ * defined, then stop here so application writers can catch the error. */
configASSERT( uxCriticalNesting == ~0UL ); configASSERT( uxCriticalNesting == ~0UL );
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
while( ulDummy == 0 ) while( ulDummy == 0 )
{ {
/* This file calls prvTaskExitError() after the scheduler has been /* This file calls prvTaskExitError() after the scheduler has been
started to remove a compiler warning about the function being defined * started to remove a compiler warning about the function being defined
but never called. ulDummy is used purely to quieten other warnings * but never called. ulDummy is used purely to quieten other warnings
about code appearing after this function is called - making ulDummy * about code appearing after this function is called - making ulDummy
volatile makes the compiler think the function could return and * volatile makes the compiler think the function could return and
therefore not output an 'unreachable code' warning for code that appears * therefore not output an 'unreachable code' warning for code that appears
after it. */ * after it. */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -175,15 +178,15 @@ volatile uint32_t ulDummy = 0UL;
void vPortSVCHandler( void ) void vPortSVCHandler( void )
{ {
/* This function is no longer used, but retained for backward /* This function is no longer used, but retained for backward
compatibility. */ * compatibility. */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortStartFirstTask( void ) void vPortStartFirstTask( void )
{ {
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
table offset register that can be used to locate the initial stack value. * table offset register that can be used to locate the initial stack value.
Not all M0 parts have the application vector table at address 0. */ * Not all M0 parts have the application vector table at address 0. */
__asm volatile ( __asm volatile (
" .syntax unified \n" " .syntax unified \n"
" ldr r2, pxCurrentTCBConst2 \n"/* Obtain location of pxCurrentTCB. */ " ldr r2, pxCurrentTCBConst2 \n"/* Obtain location of pxCurrentTCB. */
@ -217,7 +220,7 @@ BaseType_t xPortStartScheduler( void )
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
/* Start the timer that generates the tick ISR. Interrupts are disabled /* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */ * here already. */
vPortSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialise the critical nesting count ready for the first task. */ /* Initialise the critical nesting count ready for the first task. */
@ -227,11 +230,11 @@ BaseType_t xPortStartScheduler( void )
vPortStartFirstTask(); vPortStartFirstTask();
/* Should never get here as the tasks will now be executing! Call the task /* Should never get here as the tasks will now be executing! Call the task
exit error function to prevent compiler warnings about a static function * exit error function to prevent compiler warnings about a static function
not being called in the case that the application writer overrides this * not being called in the case that the application writer overrides this
functionality by defining configTASK_RETURN_ADDRESS. Call * functionality by defining configTASK_RETURN_ADDRESS. Call
vTaskSwitchContext() so link time optimisation does not remove the * vTaskSwitchContext() so link time optimisation does not remove the
symbol. */ * symbol. */
vTaskSwitchContext(); vTaskSwitchContext();
prvTaskExitError(); prvTaskExitError();
@ -243,7 +246,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented in ports where there is nothing to return to. /* Not implemented in ports where there is nothing to return to.
Artificially force an assert. */ * Artificially force an assert. */
configASSERT( uxCriticalNesting == 1000UL ); configASSERT( uxCriticalNesting == 1000UL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -254,7 +257,7 @@ void vPortYield( void )
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
/* Barriers are normally not required but do ensure the code is completely /* Barriers are normally not required but do ensure the code is completely
within the specified behaviour for the architecture. */ * within the specified behaviour for the architecture. */
__asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "dsb" ::: "memory" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
} }
@ -273,6 +276,7 @@ void vPortExitCritical( void )
{ {
configASSERT( uxCriticalNesting ); configASSERT( uxCriticalNesting );
uxCriticalNesting--; uxCriticalNesting--;
if( uxCriticalNesting == 0 ) if( uxCriticalNesting == 0 )
{ {
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
@ -406,43 +410,44 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
} }
/* Stop the SysTick momentarily. The time the SysTick is stopped for /* Stop the SysTick momentarily. The time the SysTick is stopped for
is accounted for as best it can be, but using the tickless mode will * is accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the * inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */ * kernel with respect to calendar time. */
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
/* Calculate the reload value required to wait xExpectedIdleTime /* Calculate the reload value required to wait xExpectedIdleTime
tick periods. -1 is used because this code will execute part way * tick periods. -1 is used because this code will execute part way
through one of the tick periods. */ * through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation ) if( ulReloadValue > ulStoppedTimerCompensation )
{ {
ulReloadValue -= ulStoppedTimerCompensation; ulReloadValue -= ulStoppedTimerCompensation;
} }
/* Enter a critical section but don't use the taskENTER_CRITICAL() /* Enter a critical section but don't use the taskENTER_CRITICAL()
method as that will mask interrupts that should exit sleep mode. */ * method as that will mask interrupts that should exit sleep mode. */
__asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "cpsid i" ::: "memory" );
__asm volatile ( "dsb" ); __asm volatile ( "dsb" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
/* If a context switch is pending or a task is waiting for the scheduler /* If a context switch is pending or a task is waiting for the scheduler
to be unsuspended then abandon the low power entry. */ * to be unsuspended then abandon the low power entry. */
if( eTaskConfirmSleepModeStatus() == eAbortSleep ) if( eTaskConfirmSleepModeStatus() == eAbortSleep )
{ {
/* Restart from whatever is left in the count register to complete /* Restart from whatever is left in the count register to complete
this tick period. */ * this tick period. */
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* Restart SysTick. */ /* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
/* Reset the reload register to the value required for normal tick /* Reset the reload register to the value required for normal tick
periods. */ * periods. */
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
/* Re-enable interrupts - see comments above the cpsid instruction() /* Re-enable interrupts - see comments above the cpsid instruction()
above. */ * above. */
__asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "cpsie i" ::: "memory" );
} }
else else
@ -451,69 +456,71 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
portNVIC_SYSTICK_LOAD_REG = ulReloadValue; portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
/* Clear the SysTick count flag and set the count value back to /* Clear the SysTick count flag and set the count value back to
zero. */ * zero. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
/* Restart SysTick. */ /* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
set its parameter to 0 to indicate that its implementation contains * set its parameter to 0 to indicate that its implementation contains
its own wait for interrupt or wait for event instruction, and so wfi * its own wait for interrupt or wait for event instruction, and so wfi
should not be executed again. However, the original expected idle * should not be executed again. However, the original expected idle
time variable must remain unmodified, so a copy is taken. */ * time variable must remain unmodified, so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime; xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "dsb" ::: "memory" );
__asm volatile ( "wfi" ); __asm volatile ( "wfi" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
} }
configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
/* Re-enable interrupts to allow the interrupt that brought the MCU /* Re-enable interrupts to allow the interrupt that brought the MCU
out of sleep mode to execute immediately. see comments above * out of sleep mode to execute immediately. see comments above
__disable_interrupt() call above. */ * __disable_interrupt() call above. */
__asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "cpsie i" ::: "memory" );
__asm volatile ( "dsb" ); __asm volatile ( "dsb" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
/* Disable interrupts again because the clock is about to be stopped /* Disable interrupts again because the clock is about to be stopped
and interrupts that execute while the clock is stopped will increase * and interrupts that execute while the clock is stopped will increase
any slippage between the time maintained by the RTOS and calendar * any slippage between the time maintained by the RTOS and calendar
time. */ * time. */
__asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "cpsid i" ::: "memory" );
__asm volatile ( "dsb" ); __asm volatile ( "dsb" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
/* Disable the SysTick clock without reading the /* Disable the SysTick clock without reading the
portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_CTRL_REG register to ensure the
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
the time the SysTick is stopped for is accounted for as best it can * the time the SysTick is stopped for is accounted for as best it can
be, but using the tickless mode will inevitably result in some tiny * be, but using the tickless mode will inevitably result in some tiny
drift of the time maintained by the kernel with respect to calendar * drift of the time maintained by the kernel with respect to calendar
time*/ * time*/
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT ); portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
/* Determine if the SysTick clock has already counted to zero and /* Determine if the SysTick clock has already counted to zero and
been set back to the current reload value (the reload back being * been set back to the current reload value (the reload back being
correct for the entire expected idle time) or if the SysTick is yet * correct for the entire expected idle time) or if the SysTick is yet
to count to zero (in which case an interrupt other than the SysTick * to count to zero (in which case an interrupt other than the SysTick
must have brought the system out of sleep mode). */ * must have brought the system out of sleep mode). */
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
{ {
uint32_t ulCalculatedLoadValue; uint32_t ulCalculatedLoadValue;
/* The tick interrupt is already pending, and the SysTick count /* The tick interrupt is already pending, and the SysTick count
reloaded with ulReloadValue. Reset the * reloaded with ulReloadValue. Reset the
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick * portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
period. */ * period. */
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
/* Don't allow a tiny value, or values that have somehow /* Don't allow a tiny value, or values that have somehow
underflowed because the post sleep hook did something * underflowed because the post sleep hook did something
that took too long. */ * that took too long. */
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
{ {
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
@ -522,30 +529,30 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
/* As the pending tick will be processed as soon as this /* As the pending tick will be processed as soon as this
function exits, the tick value maintained by the tick is stepped * function exits, the tick value maintained by the tick is stepped
forward by one less than the time spent waiting. */ * forward by one less than the time spent waiting. */
ulCompleteTickPeriods = xExpectedIdleTime - 1UL; ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
} }
else else
{ {
/* Something other than the tick interrupt ended the sleep. /* Something other than the tick interrupt ended the sleep.
Work out how long the sleep lasted rounded to complete tick * Work out how long the sleep lasted rounded to complete tick
periods (not the ulReload value which accounted for part * periods (not the ulReload value which accounted for part
ticks). */ * ticks). */
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* How many complete tick periods passed while the processor /* How many complete tick periods passed while the processor
was waiting? */ * was waiting? */
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
/* The reload value is set to whatever fraction of a single tick /* The reload value is set to whatever fraction of a single tick
period remains. */ * period remains. */
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
} }
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard * again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
value. */ * value. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
vTaskStepTick( ulCompleteTickPeriods ); vTaskStepTick( ulCompleteTickPeriods );

View file

@ -63,7 +63,7 @@ typedef unsigned long UBaseType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -121,4 +121,3 @@ extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__((naked)
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -85,6 +85,7 @@
/* Ensure the SysTick is clocked at the same frequency as the core. */ /* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#else #else
/* The way the SysTick is clocked is not modified in case it is not the /* The way the SysTick is clocked is not modified in case it is not the
* same a the core. */ * same a the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 0 ) #define portNVIC_SYSTICK_CLK_BIT ( 0 )
@ -205,6 +206,7 @@
#define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_XPSR ( 0x01000000 )
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
/** /**
* @brief Initial EXC_RETURN value. * @brief Initial EXC_RETURN value.
* *
@ -221,6 +223,7 @@
*/ */
#define portINITIAL_EXC_RETURN ( 0xfffffffd ) #define portINITIAL_EXC_RETURN ( 0xfffffffd )
#else #else
/** /**
* @brief Initial EXC_RETURN value. * @brief Initial EXC_RETURN value.
* *
@ -285,6 +288,7 @@
static void prvTaskExitError( void ); static void prvTaskExitError( void );
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Setup the Memory Protection Unit (MPU). * @brief Setup the Memory Protection Unit (MPU).
*/ */
@ -292,6 +296,7 @@ static void prvTaskExitError( void );
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
#if ( configENABLE_FPU == 1 ) #if ( configENABLE_FPU == 1 )
/** /**
* @brief Setup the Floating Point Unit (FPU). * @brief Setup the Floating Point Unit (FPU).
*/ */
@ -347,6 +352,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVI
static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Saved as part of the task context to indicate which context the * @brief Saved as part of the task context to indicate which context the
* task is using on the secure side. * task is using on the secure side.
@ -355,6 +361,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
#if ( configUSE_TICKLESS_IDLE == 1 ) #if ( configUSE_TICKLESS_IDLE == 1 )
/** /**
* @brief The number of SysTick increments that make up one tick period. * @brief The number of SysTick increments that make up one tick period.
*/ */
@ -396,6 +403,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
* tick periods. -1 is used because this code will execute part way * tick periods. -1 is used because this code will execute part way
* through one of the tick periods. */ * through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation ) if( ulReloadValue > ulStoppedTimerCompensation )
{ {
ulReloadValue -= ulStoppedTimerCompensation; ulReloadValue -= ulStoppedTimerCompensation;
@ -446,12 +454,14 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
* so a copy is taken. */ * so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime; xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "dsb" ::: "memory" );
__asm volatile ( "wfi" ); __asm volatile ( "wfi" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
} }
configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
/* Re-enable interrupts to allow the interrupt that brought the MCU /* Re-enable interrupts to allow the interrupt that brought the MCU
@ -590,6 +600,7 @@ volatile uint32_t ulDummy = 0UL;
static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */
{ {
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_start__;
@ -600,7 +611,7 @@ volatile uint32_t ulDummy = 0UL;
extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __unprivileged_flash_end__;
extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_start__;
extern uint32_t * __privileged_sram_end__; extern uint32_t * __privileged_sram_end__;
#else #else /* if defined( __ARMCC_VERSION ) */
/* Declaration when these variable are exported from linker scripts. */ /* Declaration when these variable are exported from linker scripts. */
extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_start__[];
extern uint32_t __privileged_functions_end__[]; extern uint32_t __privileged_functions_end__[];
@ -753,6 +764,7 @@ void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION
{ {
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_start__;
@ -783,7 +795,7 @@ uint8_t ucSVCNumber;
{ {
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
case portSVC_ALLOCATE_SECURE_CONTEXT: case portSVC_ALLOCATE_SECURE_CONTEXT:
{
/* R0 contains the stack size passed as parameter to the /* R0 contains the stack size passed as parameter to the
* vPortAllocateSecureContext function. */ * vPortAllocateSecureContext function. */
ulR0 = pulCallerStackAddress[ 0 ]; ulR0 = pulCallerStackAddress[ 0 ];
@ -800,7 +812,7 @@ uint8_t ucSVCNumber;
/* Allocate and load a context for the secure task. */ /* Allocate and load a context for the secure task. */
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
} }
#else #else /* if ( configENABLE_MPU == 1 ) */
{ {
/* Allocate and load a context for the secure task. */ /* Allocate and load a context for the secure task. */
xSecureContext = SecureContext_AllocateContext( ulR0 ); xSecureContext = SecureContext_AllocateContext( ulR0 );
@ -809,22 +821,18 @@ uint8_t ucSVCNumber;
configASSERT( xSecureContext != NULL ); configASSERT( xSecureContext != NULL );
SecureContext_LoadContext( xSecureContext ); SecureContext_LoadContext( xSecureContext );
}
break; break;
case portSVC_FREE_SECURE_CONTEXT: case portSVC_FREE_SECURE_CONTEXT:
{
/* R0 contains the secure context handle to be freed. */ /* R0 contains the secure context handle to be freed. */
ulR0 = pulCallerStackAddress[ 0 ]; ulR0 = pulCallerStackAddress[ 0 ];
/* Free the secure context. */ /* Free the secure context. */
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 );
}
break; break;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER: case portSVC_START_SCHEDULER:
{
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
{ {
/* De-prioritize the non-secure exceptions so that the /* De-prioritize the non-secure exceptions so that the
@ -846,36 +854,39 @@ uint8_t ucSVCNumber;
/* Setup the context of the first task so that the first task starts /* Setup the context of the first task so that the first task starts
* executing. */ * executing. */
vRestoreContextOfFirstTask(); vRestoreContextOfFirstTask();
}
break; break;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
case portSVC_RAISE_PRIVILEGE: case portSVC_RAISE_PRIVILEGE:
{
/* Only raise the privilege, if the svc was raised from any of /* Only raise the privilege, if the svc was raised from any of
* the system calls. */ * the system calls. */
if( ulPC >= ( uint32_t ) __syscalls_flash_start__ && if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) &&
ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) )
{ {
vRaisePrivilege(); vRaisePrivilege();
} }
}
break; break;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
default: default:
{
/* Incorrect SVC call. */ /* Incorrect SVC call. */
configASSERT( pdFALSE ); configASSERT( pdFALSE );
} }
} }
}
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack,
TaskFunction_t pxCode,
void * pvParameters,
BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */
#else #else
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) /* PRIVILEGED_FUNCTION */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack,
TaskFunction_t pxCode,
void * pvParameters ) /* PRIVILEGED_FUNCTION */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
{ {
/* Simulate the stack frame as it would be created by a context switch /* Simulate the stack frame as it would be created by a context switch
@ -896,6 +907,7 @@ uint8_t ucSVCNumber;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
{ {
pxTopOfStack--; pxTopOfStack--;
if( xRunPrivileged == pdTRUE ) if( xRunPrivileged == pdTRUE )
{ {
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
@ -957,6 +969,7 @@ uint8_t ucSVCNumber;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
{ {
pxTopOfStack--; pxTopOfStack--;
if( xRunPrivileged == pdTRUE ) if( xRunPrivileged == pdTRUE )
{ {
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
@ -1030,7 +1043,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
const struct xMEMORY_REGION * const xRegions,
StackType_t * pxBottomOfStack,
uint32_t ulStackDepth )
{ {
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
int32_t lIndex = 0; int32_t lIndex = 0;

View file

@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *

View file

@ -95,7 +95,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
uint32_t ulIsTaskPrivileged )
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
@ -103,6 +104,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
uint8_t * pucStackMemory = NULL; uint8_t * pucStackMemory = NULL;
uint32_t ulIPSR; uint32_t ulIPSR;
SecureContextHandle_t xSecureContextHandle = NULL; SecureContextHandle_t xSecureContextHandle = NULL;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
uint32_t * pulCurrentStackPointer = NULL; uint32_t * pulCurrentStackPointer = NULL;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
@ -143,6 +145,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
* context switch. */ * context switch. */
pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart; pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
pulCurrentStackPointer--; pulCurrentStackPointer--;
if( ulIsTaskPrivileged ) if( ulIsTaskPrivileged )
{ {
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED; *( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
@ -161,7 +164,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
/* Current SP is set to the starting of the stack. This /* Current SP is set to the starting of the stack. This
* value programmed in the PSP register on context switch. */ * value programmed in the PSP register on context switch. */
xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart; xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
} }
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
} }

View file

@ -69,7 +69,8 @@ void SecureContext_Init( void );
* otherwise. * otherwise.
*/ */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged ); SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
uint32_t ulIsTaskPrivileged );
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ); SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */

View file

@ -62,6 +62,7 @@
/* Allocate the memory for the heap. */ /* Allocate the memory for the heap. */
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) #if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
/* The application writer has already defined the array used for the RTOS /* The application writer has already defined the array used for the RTOS
* heap - probably so it can be placed in a special segment or address. */ * heap - probably so it can be placed in a special segment or address. */
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
@ -190,6 +191,7 @@ uint8_t *puc;
/* Do the block being inserted, and the block it is being inserted after /* Do the block being inserted, and the block it is being inserted after
* make a contiguous block of memory? */ * make a contiguous block of memory? */
puc = ( uint8_t * ) pxIterator; puc = ( uint8_t * ) pxIterator;
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
{ {
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
@ -203,6 +205,7 @@ uint8_t *puc;
/* Do the block being inserted, and the block it is being inserted before /* Do the block being inserted, and the block it is being inserted before
* make a contiguous block of memory? */ * make a contiguous block of memory? */
puc = ( uint8_t * ) pxBlockToInsert; puc = ( uint8_t * ) pxBlockToInsert;
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
{ {
if( pxIterator->pxNextFreeBlock != pxEnd ) if( pxIterator->pxNextFreeBlock != pxEnd )
@ -288,6 +291,7 @@ void *pvReturn = NULL;
* one of adequate size is found. */ * one of adequate size is found. */
pxPreviousBlock = &xStart; pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock; pxBlock = xStart.pxNextFreeBlock;
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
{ {
pxPreviousBlock = pxBlock; pxPreviousBlock = pxBlock;
@ -375,7 +379,7 @@ void *pvReturn = NULL;
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
#endif #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
return pvReturn; return pvReturn;

View file

@ -126,7 +126,7 @@
{ \ { \
secureportDISABLE_SECURE_INTERRUPTS(); \ secureportDISABLE_SECURE_INTERRUPTS(); \
secureportDISABLE_NON_SECURE_INTERRUPTS(); \ secureportDISABLE_NON_SECURE_INTERRUPTS(); \
for( ;; ); \ for( ; ; ) {; } \
} }
#endif /* __SECURE_PORT_MACROS_H__ */ #endif /* __SECURE_PORT_MACROS_H__ */

View file

@ -85,6 +85,7 @@
/* Ensure the SysTick is clocked at the same frequency as the core. */ /* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#else #else
/* The way the SysTick is clocked is not modified in case it is not the /* The way the SysTick is clocked is not modified in case it is not the
* same a the core. */ * same a the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 0 ) #define portNVIC_SYSTICK_CLK_BIT ( 0 )
@ -205,6 +206,7 @@
#define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_XPSR ( 0x01000000 )
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
/** /**
* @brief Initial EXC_RETURN value. * @brief Initial EXC_RETURN value.
* *
@ -221,6 +223,7 @@
*/ */
#define portINITIAL_EXC_RETURN ( 0xfffffffd ) #define portINITIAL_EXC_RETURN ( 0xfffffffd )
#else #else
/** /**
* @brief Initial EXC_RETURN value. * @brief Initial EXC_RETURN value.
* *
@ -285,6 +288,7 @@
static void prvTaskExitError( void ); static void prvTaskExitError( void );
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Setup the Memory Protection Unit (MPU). * @brief Setup the Memory Protection Unit (MPU).
*/ */
@ -292,6 +296,7 @@ static void prvTaskExitError( void );
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
#if ( configENABLE_FPU == 1 ) #if ( configENABLE_FPU == 1 )
/** /**
* @brief Setup the Floating Point Unit (FPU). * @brief Setup the Floating Point Unit (FPU).
*/ */
@ -347,6 +352,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVI
static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Saved as part of the task context to indicate which context the * @brief Saved as part of the task context to indicate which context the
* task is using on the secure side. * task is using on the secure side.
@ -355,6 +361,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
#if ( configUSE_TICKLESS_IDLE == 1 ) #if ( configUSE_TICKLESS_IDLE == 1 )
/** /**
* @brief The number of SysTick increments that make up one tick period. * @brief The number of SysTick increments that make up one tick period.
*/ */
@ -396,6 +403,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
* tick periods. -1 is used because this code will execute part way * tick periods. -1 is used because this code will execute part way
* through one of the tick periods. */ * through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation ) if( ulReloadValue > ulStoppedTimerCompensation )
{ {
ulReloadValue -= ulStoppedTimerCompensation; ulReloadValue -= ulStoppedTimerCompensation;
@ -446,12 +454,14 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
* so a copy is taken. */ * so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime; xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "dsb" ::: "memory" );
__asm volatile ( "wfi" ); __asm volatile ( "wfi" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
} }
configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
/* Re-enable interrupts to allow the interrupt that brought the MCU /* Re-enable interrupts to allow the interrupt that brought the MCU
@ -590,6 +600,7 @@ volatile uint32_t ulDummy = 0UL;
static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */
{ {
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_start__;
@ -600,7 +611,7 @@ volatile uint32_t ulDummy = 0UL;
extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __unprivileged_flash_end__;
extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_start__;
extern uint32_t * __privileged_sram_end__; extern uint32_t * __privileged_sram_end__;
#else #else /* if defined( __ARMCC_VERSION ) */
/* Declaration when these variable are exported from linker scripts. */ /* Declaration when these variable are exported from linker scripts. */
extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_start__[];
extern uint32_t __privileged_functions_end__[]; extern uint32_t __privileged_functions_end__[];
@ -753,6 +764,7 @@ void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION
{ {
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_start__;
@ -783,7 +795,7 @@ uint8_t ucSVCNumber;
{ {
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
case portSVC_ALLOCATE_SECURE_CONTEXT: case portSVC_ALLOCATE_SECURE_CONTEXT:
{
/* R0 contains the stack size passed as parameter to the /* R0 contains the stack size passed as parameter to the
* vPortAllocateSecureContext function. */ * vPortAllocateSecureContext function. */
ulR0 = pulCallerStackAddress[ 0 ]; ulR0 = pulCallerStackAddress[ 0 ];
@ -800,7 +812,7 @@ uint8_t ucSVCNumber;
/* Allocate and load a context for the secure task. */ /* Allocate and load a context for the secure task. */
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
} }
#else #else /* if ( configENABLE_MPU == 1 ) */
{ {
/* Allocate and load a context for the secure task. */ /* Allocate and load a context for the secure task. */
xSecureContext = SecureContext_AllocateContext( ulR0 ); xSecureContext = SecureContext_AllocateContext( ulR0 );
@ -809,22 +821,18 @@ uint8_t ucSVCNumber;
configASSERT( xSecureContext != NULL ); configASSERT( xSecureContext != NULL );
SecureContext_LoadContext( xSecureContext ); SecureContext_LoadContext( xSecureContext );
}
break; break;
case portSVC_FREE_SECURE_CONTEXT: case portSVC_FREE_SECURE_CONTEXT:
{
/* R0 contains the secure context handle to be freed. */ /* R0 contains the secure context handle to be freed. */
ulR0 = pulCallerStackAddress[ 0 ]; ulR0 = pulCallerStackAddress[ 0 ];
/* Free the secure context. */ /* Free the secure context. */
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 );
}
break; break;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER: case portSVC_START_SCHEDULER:
{
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
{ {
/* De-prioritize the non-secure exceptions so that the /* De-prioritize the non-secure exceptions so that the
@ -846,36 +854,39 @@ uint8_t ucSVCNumber;
/* Setup the context of the first task so that the first task starts /* Setup the context of the first task so that the first task starts
* executing. */ * executing. */
vRestoreContextOfFirstTask(); vRestoreContextOfFirstTask();
}
break; break;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
case portSVC_RAISE_PRIVILEGE: case portSVC_RAISE_PRIVILEGE:
{
/* Only raise the privilege, if the svc was raised from any of /* Only raise the privilege, if the svc was raised from any of
* the system calls. */ * the system calls. */
if( ulPC >= ( uint32_t ) __syscalls_flash_start__ && if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) &&
ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) )
{ {
vRaisePrivilege(); vRaisePrivilege();
} }
}
break; break;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
default: default:
{
/* Incorrect SVC call. */ /* Incorrect SVC call. */
configASSERT( pdFALSE ); configASSERT( pdFALSE );
} }
} }
}
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack,
TaskFunction_t pxCode,
void * pvParameters,
BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */
#else #else
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) /* PRIVILEGED_FUNCTION */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack,
TaskFunction_t pxCode,
void * pvParameters ) /* PRIVILEGED_FUNCTION */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
{ {
/* Simulate the stack frame as it would be created by a context switch /* Simulate the stack frame as it would be created by a context switch
@ -896,6 +907,7 @@ uint8_t ucSVCNumber;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
{ {
pxTopOfStack--; pxTopOfStack--;
if( xRunPrivileged == pdTRUE ) if( xRunPrivileged == pdTRUE )
{ {
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
@ -957,6 +969,7 @@ uint8_t ucSVCNumber;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
{ {
pxTopOfStack--; pxTopOfStack--;
if( xRunPrivileged == pdTRUE ) if( xRunPrivileged == pdTRUE )
{ {
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
@ -1030,7 +1043,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
const struct xMEMORY_REGION * const xRegions,
StackType_t * pxBottomOfStack,
uint32_t ulStackDepth )
{ {
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
int32_t lIndex = 0; int32_t lIndex = 0;

View file

@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *

View file

@ -33,8 +33,8 @@
#include "task.h" #include "task.h"
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is /* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
defined. The value should also ensure backward compatibility. * defined. The value should also ensure backward compatibility.
FreeRTOS.org versions prior to V4.4.0 did not include this definition. */ * FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
#ifndef configKERNEL_INTERRUPT_PRIORITY #ifndef configKERNEL_INTERRUPT_PRIORITY
#define configKERNEL_INTERRUPT_PRIORITY 255 #define configKERNEL_INTERRUPT_PRIORITY 255
#endif #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. */ /* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#else #else
/* The way the SysTick is clocked is not modified in case it is not the same /* 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 ) #define portNVIC_SYSTICK_CLK_BIT ( 0 )
#endif #endif
@ -84,17 +85,17 @@ FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) #define portMAX_24_BIT_NUMBER ( 0xffffffUL )
/* A fiddle factor to estimate the number of SysTick counts that would have /* A fiddle factor to estimate the number of SysTick counts that would have
occurred while the SysTick counter is stopped during tickless idle * occurred while the SysTick counter is stopped during tickless idle
calculations. */ * calculations. */
#define portMISSED_COUNTS_FACTOR ( 45UL ) #define portMISSED_COUNTS_FACTOR ( 45UL )
/* For strict compliance with the Cortex-M spec the task start address should /* For strict compliance with the Cortex-M spec the task start address should
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
/* Let the user override the pre-loading of the initial LR with the address of /* Let the user override the pre-loading of the initial LR with the address of
prvTaskExitError() in case it messes up unwinding of the stack in the * prvTaskExitError() in case it messes up unwinding of the stack in the
debugger. */ * debugger. */
#ifdef configTASK_RETURN_ADDRESS #ifdef configTASK_RETURN_ADDRESS
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
#else #else
@ -128,7 +129,7 @@ static void prvTaskExitError( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Each task maintains its own interrupt status in the critical nesting /* Each task maintains its own interrupt status in the critical nesting
variable. */ * variable. */
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/* /*
@ -170,10 +171,12 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
/* Simulate the stack frame as it would be created by a context switch /* Simulate the stack frame as it would be created by a context switch
interrupt. */ * interrupt. */
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */
pxTopOfStack--; pxTopOfStack--;
@ -193,22 +196,23 @@ static void prvTaskExitError( void )
volatile uint32_t ulDummy = 0UL; volatile uint32_t ulDummy = 0UL;
/* A function that implements a task must not exit or attempt to return to /* A function that implements a task must not exit or attempt to return to
its caller as there is nothing to return to. If a task wants to exit it * its caller as there is nothing to return to. If a task wants to exit it
should instead call vTaskDelete( NULL ). * should instead call vTaskDelete( NULL ).
*
Artificially force an assert() to be triggered if configASSERT() is * Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */ * defined, then stop here so application writers can catch the error. */
configASSERT( uxCriticalNesting == ~0UL ); configASSERT( uxCriticalNesting == ~0UL );
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
while( ulDummy == 0 ) while( ulDummy == 0 )
{ {
/* This file calls prvTaskExitError() after the scheduler has been /* This file calls prvTaskExitError() after the scheduler has been
started to remove a compiler warning about the function being defined * started to remove a compiler warning about the function being defined
but never called. ulDummy is used purely to quieten other warnings * but never called. ulDummy is used purely to quieten other warnings
about code appearing after this function is called - making ulDummy * about code appearing after this function is called - making ulDummy
volatile makes the compiler think the function could return and * volatile makes the compiler think the function could return and
therefore not output an 'unreachable code' warning for code that appears * therefore not output an 'unreachable code' warning for code that appears
after it. */ * after it. */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -257,7 +261,7 @@ static void prvPortStartFirstTask( void )
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. /* 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 ); configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
#if ( configASSERT_DEFINED == 1 ) #if ( configASSERT_DEFINED == 1 )
@ -267,15 +271,15 @@ BaseType_t xPortStartScheduler( void )
volatile uint8_t ucMaxPriorityValue; volatile uint8_t ucMaxPriorityValue;
/* Determine the maximum priority from which ISR safe FreeRTOS API /* Determine the maximum priority from which ISR safe FreeRTOS API
functions can be called. ISR safe functions are those that end in * functions can be called. ISR safe functions are those that end in
"FromISR". FreeRTOS maintains separate thread and ISR API functions to * "FromISR". FreeRTOS maintains separate thread and ISR API functions to
ensure interrupt entry is as fast and simple as possible. * ensure interrupt entry is as fast and simple as possible.
*
Save the interrupt priority value that is about to be clobbered. */ * Save the interrupt priority value that is about to be clobbered. */
ulOriginalPriority = *pucFirstUserPriorityRegister; ulOriginalPriority = *pucFirstUserPriorityRegister;
/* Determine the number of priority bits available. First write to all /* Determine the number of priority bits available. First write to all
possible bits. */ * possible bits. */
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
/* Read the value back to see how many bits stuck. */ /* Read the value back to see how many bits stuck. */
@ -285,8 +289,9 @@ BaseType_t xPortStartScheduler( void )
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
/* Calculate the maximum acceptable priority group value for the number /* Calculate the maximum acceptable priority group value for the number
of bits read back. */ * of bits read back. */
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{ {
ulMaxPRIGROUPValue--; ulMaxPRIGROUPValue--;
@ -296,8 +301,8 @@ BaseType_t xPortStartScheduler( void )
#ifdef __NVIC_PRIO_BITS #ifdef __NVIC_PRIO_BITS
{ {
/* Check the CMSIS configuration that defines the number of /* Check the CMSIS configuration that defines the number of
priority bits matches the number of priority bits actually queried * priority bits matches the number of priority bits actually queried
from the hardware. */ * from the hardware. */
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
} }
#endif #endif
@ -305,19 +310,19 @@ BaseType_t xPortStartScheduler( void )
#ifdef configPRIO_BITS #ifdef configPRIO_BITS
{ {
/* Check the FreeRTOS configuration that defines the number of /* Check the FreeRTOS configuration that defines the number of
priority bits matches the number of priority bits actually queried * priority bits matches the number of priority bits actually queried
from the hardware. */ * from the hardware. */
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
} }
#endif #endif
/* Shift the priority group value back to its position within the AIRCR /* Shift the priority group value back to its position within the AIRCR
register. */ * register. */
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
/* Restore the clobbered interrupt priority register to its original /* Restore the clobbered interrupt priority register to its original
value. */ * value. */
*pucFirstUserPriorityRegister = ulOriginalPriority; *pucFirstUserPriorityRegister = ulOriginalPriority;
} }
#endif /* conifgASSERT_DEFINED */ #endif /* conifgASSERT_DEFINED */
@ -327,7 +332,7 @@ BaseType_t xPortStartScheduler( void )
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
/* Start the timer that generates the tick ISR. Interrupts are disabled /* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */ * here already. */
vPortSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialise the critical nesting count ready for the first task. */ /* Initialise the critical nesting count ready for the first task. */
@ -337,11 +342,11 @@ BaseType_t xPortStartScheduler( void )
prvPortStartFirstTask(); prvPortStartFirstTask();
/* Should never get here as the tasks will now be executing! Call the task /* Should never get here as the tasks will now be executing! Call the task
exit error function to prevent compiler warnings about a static function * exit error function to prevent compiler warnings about a static function
not being called in the case that the application writer overrides this * not being called in the case that the application writer overrides this
functionality by defining configTASK_RETURN_ADDRESS. Call * functionality by defining configTASK_RETURN_ADDRESS. Call
vTaskSwitchContext() so link time optimisation does not remove the * vTaskSwitchContext() so link time optimisation does not remove the
symbol. */ * symbol. */
vTaskSwitchContext(); vTaskSwitchContext();
prvTaskExitError(); prvTaskExitError();
@ -353,7 +358,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented in ports where there is nothing to return to. /* Not implemented in ports where there is nothing to return to.
Artificially force an assert. */ * Artificially force an assert. */
configASSERT( uxCriticalNesting == 1000UL ); configASSERT( uxCriticalNesting == 1000UL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -364,10 +369,10 @@ void vPortEnterCritical( void )
uxCriticalNesting++; uxCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so /* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context. Only API * assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if * functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the * the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */ * assert function also uses a critical section. */
if( uxCriticalNesting == 1 ) if( uxCriticalNesting == 1 )
{ {
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
@ -379,6 +384,7 @@ void vPortExitCritical( void )
{ {
configASSERT( uxCriticalNesting ); configASSERT( uxCriticalNesting );
uxCriticalNesting--; uxCriticalNesting--;
if( uxCriticalNesting == 0 ) if( uxCriticalNesting == 0 )
{ {
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
@ -426,16 +432,16 @@ void xPortPendSVHandler( void )
void xPortSysTickHandler( void ) void xPortSysTickHandler( void )
{ {
/* The SysTick runs at the lowest interrupt priority, so when this interrupt /* The SysTick runs at the lowest interrupt priority, so when this interrupt
executes all interrupts must be unmasked. There is therefore no need to * executes all interrupts must be unmasked. There is therefore no need to
save and then restore the interrupt mask value as its value is already * save and then restore the interrupt mask value as its value is already
known. */ * known. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
} }
@ -457,43 +463,44 @@ void xPortSysTickHandler( void )
} }
/* Stop the SysTick momentarily. The time the SysTick is stopped for /* Stop the SysTick momentarily. The time the SysTick is stopped for
is accounted for as best it can be, but using the tickless mode will * is accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the * inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */ * kernel with respect to calendar time. */
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
/* Calculate the reload value required to wait xExpectedIdleTime /* Calculate the reload value required to wait xExpectedIdleTime
tick periods. -1 is used because this code will execute part way * tick periods. -1 is used because this code will execute part way
through one of the tick periods. */ * through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation ) if( ulReloadValue > ulStoppedTimerCompensation )
{ {
ulReloadValue -= ulStoppedTimerCompensation; ulReloadValue -= ulStoppedTimerCompensation;
} }
/* Enter a critical section but don't use the taskENTER_CRITICAL() /* Enter a critical section but don't use the taskENTER_CRITICAL()
method as that will mask interrupts that should exit sleep mode. */ * method as that will mask interrupts that should exit sleep mode. */
__asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "cpsid i" ::: "memory" );
__asm volatile ( "dsb" ); __asm volatile ( "dsb" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
/* If a context switch is pending or a task is waiting for the scheduler /* If a context switch is pending or a task is waiting for the scheduler
to be unsuspended then abandon the low power entry. */ * to be unsuspended then abandon the low power entry. */
if( eTaskConfirmSleepModeStatus() == eAbortSleep ) if( eTaskConfirmSleepModeStatus() == eAbortSleep )
{ {
/* Restart from whatever is left in the count register to complete /* Restart from whatever is left in the count register to complete
this tick period. */ * this tick period. */
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* Restart SysTick. */ /* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
/* Reset the reload register to the value required for normal tick /* Reset the reload register to the value required for normal tick
periods. */ * periods. */
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
/* Re-enable interrupts - see comments above the cpsid instruction() /* Re-enable interrupts - see comments above the cpsid instruction()
above. */ * above. */
__asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "cpsie i" ::: "memory" );
} }
else else
@ -502,69 +509,71 @@ void xPortSysTickHandler( void )
portNVIC_SYSTICK_LOAD_REG = ulReloadValue; portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
/* Clear the SysTick count flag and set the count value back to /* Clear the SysTick count flag and set the count value back to
zero. */ * zero. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
/* Restart SysTick. */ /* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
set its parameter to 0 to indicate that its implementation contains * set its parameter to 0 to indicate that its implementation contains
its own wait for interrupt or wait for event instruction, and so wfi * its own wait for interrupt or wait for event instruction, and so wfi
should not be executed again. However, the original expected idle * should not be executed again. However, the original expected idle
time variable must remain unmodified, so a copy is taken. */ * time variable must remain unmodified, so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime; xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "dsb" ::: "memory" );
__asm volatile ( "wfi" ); __asm volatile ( "wfi" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
} }
configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
/* Re-enable interrupts to allow the interrupt that brought the MCU /* Re-enable interrupts to allow the interrupt that brought the MCU
out of sleep mode to execute immediately. see comments above * out of sleep mode to execute immediately. see comments above
__disable_interrupt() call above. */ * __disable_interrupt() call above. */
__asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "cpsie i" ::: "memory" );
__asm volatile ( "dsb" ); __asm volatile ( "dsb" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
/* Disable interrupts again because the clock is about to be stopped /* Disable interrupts again because the clock is about to be stopped
and interrupts that execute while the clock is stopped will increase * and interrupts that execute while the clock is stopped will increase
any slippage between the time maintained by the RTOS and calendar * any slippage between the time maintained by the RTOS and calendar
time. */ * time. */
__asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "cpsid i" ::: "memory" );
__asm volatile ( "dsb" ); __asm volatile ( "dsb" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
/* Disable the SysTick clock without reading the /* Disable the SysTick clock without reading the
portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_CTRL_REG register to ensure the
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
the time the SysTick is stopped for is accounted for as best it can * the time the SysTick is stopped for is accounted for as best it can
be, but using the tickless mode will inevitably result in some tiny * be, but using the tickless mode will inevitably result in some tiny
drift of the time maintained by the kernel with respect to calendar * drift of the time maintained by the kernel with respect to calendar
time*/ * time*/
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT ); portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
/* Determine if the SysTick clock has already counted to zero and /* Determine if the SysTick clock has already counted to zero and
been set back to the current reload value (the reload back being * been set back to the current reload value (the reload back being
correct for the entire expected idle time) or if the SysTick is yet * correct for the entire expected idle time) or if the SysTick is yet
to count to zero (in which case an interrupt other than the SysTick * to count to zero (in which case an interrupt other than the SysTick
must have brought the system out of sleep mode). */ * must have brought the system out of sleep mode). */
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
{ {
uint32_t ulCalculatedLoadValue; uint32_t ulCalculatedLoadValue;
/* The tick interrupt is already pending, and the SysTick count /* The tick interrupt is already pending, and the SysTick count
reloaded with ulReloadValue. Reset the * reloaded with ulReloadValue. Reset the
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick * portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
period. */ * period. */
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
/* Don't allow a tiny value, or values that have somehow /* Don't allow a tiny value, or values that have somehow
underflowed because the post sleep hook did something * underflowed because the post sleep hook did something
that took too long. */ * that took too long. */
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
{ {
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
@ -573,30 +582,30 @@ void xPortSysTickHandler( void )
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
/* As the pending tick will be processed as soon as this /* As the pending tick will be processed as soon as this
function exits, the tick value maintained by the tick is stepped * function exits, the tick value maintained by the tick is stepped
forward by one less than the time spent waiting. */ * forward by one less than the time spent waiting. */
ulCompleteTickPeriods = xExpectedIdleTime - 1UL; ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
} }
else else
{ {
/* Something other than the tick interrupt ended the sleep. /* Something other than the tick interrupt ended the sleep.
Work out how long the sleep lasted rounded to complete tick * Work out how long the sleep lasted rounded to complete tick
periods (not the ulReload value which accounted for part * periods (not the ulReload value which accounted for part
ticks). */ * ticks). */
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* How many complete tick periods passed while the processor /* How many complete tick periods passed while the processor
was waiting? */ * was waiting? */
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
/* The reload value is set to whatever fraction of a single tick /* The reload value is set to whatever fraction of a single tick
period remains. */ * period remains. */
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
} }
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard * again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
value. */ * value. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
vTaskStepTick( ulCompleteTickPeriods ); vTaskStepTick( ulCompleteTickPeriods );
@ -652,66 +661,45 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
/* The following assertion will fail if a service routine (ISR) for /* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above * an interrupt that has been assigned a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
function. ISR safe FreeRTOS API functions must *only* be called * function. ISR safe FreeRTOS API functions must *only* be called
from interrupts that have been assigned a priority at or below * from interrupts that have been assigned a priority at or below
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Numerically low interrupt priority numbers represent logically high * Numerically low interrupt priority numbers represent logically high
interrupt priorities, therefore the priority of the interrupt must * interrupt priorities, therefore the priority of the interrupt must
be set to a value equal to or numerically *higher* than * be set to a value equal to or numerically *higher* than
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Interrupts that use the FreeRTOS API must not be left at their * Interrupts that use the FreeRTOS API must not be left at their
default priority of zero as that is the highest possible priority, * default priority of zero as that is the highest possible priority,
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
and therefore also guaranteed to be invalid. * and therefore also guaranteed to be invalid.
*
FreeRTOS maintains separate thread and ISR API functions to ensure * FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible. * interrupt entry is as fast and simple as possible.
*
The following links provide detailed information: * The following links provide detailed information:
http://www.freertos.org/RTOS-Cortex-M3-M4.html * http://www.freertos.org/RTOS-Cortex-M3-M4.html
http://www.freertos.org/FAQHelp.html */ * http://www.freertos.org/FAQHelp.html */
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
} }
/* Priority grouping: The interrupt controller (NVIC) allows the bits /* Priority grouping: The interrupt controller (NVIC) allows the bits
that define each interrupt's priority to be split between bits that * that define each interrupt's priority to be split between bits that
define the interrupt's pre-emption priority bits and bits that define * define the interrupt's pre-emption priority bits and bits that define
the interrupt's sub-priority. For simplicity all bits must be defined * the interrupt's sub-priority. For simplicity all bits must be defined
to be pre-emption priority bits. The following assertion will fail if * to be pre-emption priority bits. The following assertion will fail if
this is not the case (if some bits represent a sub-priority). * this is not the case (if some bits represent a sub-priority).
*
If the application only uses CMSIS libraries for interrupt * If the application only uses CMSIS libraries for interrupt
configuration then the correct setting can be achieved on all Cortex-M * configuration then the correct setting can be achieved on all Cortex-M
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
scheduler. Note however that some vendor specific peripheral libraries * scheduler. Note however that some vendor specific peripheral libraries
assume a non-zero priority group setting, in which cases using a value * assume a non-zero priority group setting, in which cases using a value
of zero will result in unpredictable behaviour. */ * of zero will result in unpredictable behaviour. */
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
} }
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */

View file

@ -63,7 +63,7 @@ typedef unsigned long UBaseType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -82,7 +82,7 @@ typedef unsigned long UBaseType_t;
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
\ \
/* Barriers are normally not required but do ensure the code is completely \ /* Barriers are normally not required but do ensure the code is completely \
within the specified behaviour for the architecture. */ \ * within the specified behaviour for the architecture. */\
__asm volatile ( "dsb" ::: "memory" ); \ __asm volatile ( "dsb" ::: "memory" ); \
__asm volatile ( "isb" ); \ __asm volatile ( "isb" ); \
} }
@ -106,8 +106,8 @@ extern void vPortExitCritical( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are /* Task function macros as described on the FreeRTOS.org WEB site. These are
not necessary for to use this port. They are defined so the common demo files * not necessary for to use this port. They are defined so the common demo files
(which build with all the ports) will build. */ * (which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -132,6 +132,7 @@ not necessary for to use this port. They are defined so the common demo files
uint8_t ucReturn; uint8_t ucReturn;
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
return ucReturn; return ucReturn;
} }
@ -221,7 +222,7 @@ uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
); );
/* This return will not be reached but is necessary to prevent compiler /* This return will not be reached but is necessary to prevent compiler
warnings. */ * warnings. */
return ulOriginalBASEPRI; return ulOriginalBASEPRI;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -242,4 +243,3 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -85,6 +85,7 @@
/* Ensure the SysTick is clocked at the same frequency as the core. */ /* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#else #else
/* The way the SysTick is clocked is not modified in case it is not the /* The way the SysTick is clocked is not modified in case it is not the
* same a the core. */ * same a the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 0 ) #define portNVIC_SYSTICK_CLK_BIT ( 0 )
@ -205,6 +206,7 @@
#define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_XPSR ( 0x01000000 )
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
/** /**
* @brief Initial EXC_RETURN value. * @brief Initial EXC_RETURN value.
* *
@ -221,6 +223,7 @@
*/ */
#define portINITIAL_EXC_RETURN ( 0xfffffffd ) #define portINITIAL_EXC_RETURN ( 0xfffffffd )
#else #else
/** /**
* @brief Initial EXC_RETURN value. * @brief Initial EXC_RETURN value.
* *
@ -285,6 +288,7 @@
static void prvTaskExitError( void ); static void prvTaskExitError( void );
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Setup the Memory Protection Unit (MPU). * @brief Setup the Memory Protection Unit (MPU).
*/ */
@ -292,6 +296,7 @@ static void prvTaskExitError( void );
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
#if ( configENABLE_FPU == 1 ) #if ( configENABLE_FPU == 1 )
/** /**
* @brief Setup the Floating Point Unit (FPU). * @brief Setup the Floating Point Unit (FPU).
*/ */
@ -347,6 +352,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVI
static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Saved as part of the task context to indicate which context the * @brief Saved as part of the task context to indicate which context the
* task is using on the secure side. * task is using on the secure side.
@ -355,6 +361,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
#if ( configUSE_TICKLESS_IDLE == 1 ) #if ( configUSE_TICKLESS_IDLE == 1 )
/** /**
* @brief The number of SysTick increments that make up one tick period. * @brief The number of SysTick increments that make up one tick period.
*/ */
@ -396,6 +403,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
* tick periods. -1 is used because this code will execute part way * tick periods. -1 is used because this code will execute part way
* through one of the tick periods. */ * through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation ) if( ulReloadValue > ulStoppedTimerCompensation )
{ {
ulReloadValue -= ulStoppedTimerCompensation; ulReloadValue -= ulStoppedTimerCompensation;
@ -446,12 +454,14 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
* so a copy is taken. */ * so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime; xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "dsb" ::: "memory" );
__asm volatile ( "wfi" ); __asm volatile ( "wfi" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
} }
configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
/* Re-enable interrupts to allow the interrupt that brought the MCU /* Re-enable interrupts to allow the interrupt that brought the MCU
@ -590,6 +600,7 @@ volatile uint32_t ulDummy = 0UL;
static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */
{ {
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_start__;
@ -600,7 +611,7 @@ volatile uint32_t ulDummy = 0UL;
extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __unprivileged_flash_end__;
extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_start__;
extern uint32_t * __privileged_sram_end__; extern uint32_t * __privileged_sram_end__;
#else #else /* if defined( __ARMCC_VERSION ) */
/* Declaration when these variable are exported from linker scripts. */ /* Declaration when these variable are exported from linker scripts. */
extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_start__[];
extern uint32_t __privileged_functions_end__[]; extern uint32_t __privileged_functions_end__[];
@ -753,6 +764,7 @@ void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION
{ {
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_start__;
@ -783,7 +795,7 @@ uint8_t ucSVCNumber;
{ {
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
case portSVC_ALLOCATE_SECURE_CONTEXT: case portSVC_ALLOCATE_SECURE_CONTEXT:
{
/* R0 contains the stack size passed as parameter to the /* R0 contains the stack size passed as parameter to the
* vPortAllocateSecureContext function. */ * vPortAllocateSecureContext function. */
ulR0 = pulCallerStackAddress[ 0 ]; ulR0 = pulCallerStackAddress[ 0 ];
@ -800,7 +812,7 @@ uint8_t ucSVCNumber;
/* Allocate and load a context for the secure task. */ /* Allocate and load a context for the secure task. */
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
} }
#else #else /* if ( configENABLE_MPU == 1 ) */
{ {
/* Allocate and load a context for the secure task. */ /* Allocate and load a context for the secure task. */
xSecureContext = SecureContext_AllocateContext( ulR0 ); xSecureContext = SecureContext_AllocateContext( ulR0 );
@ -809,22 +821,18 @@ uint8_t ucSVCNumber;
configASSERT( xSecureContext != NULL ); configASSERT( xSecureContext != NULL );
SecureContext_LoadContext( xSecureContext ); SecureContext_LoadContext( xSecureContext );
}
break; break;
case portSVC_FREE_SECURE_CONTEXT: case portSVC_FREE_SECURE_CONTEXT:
{
/* R0 contains the secure context handle to be freed. */ /* R0 contains the secure context handle to be freed. */
ulR0 = pulCallerStackAddress[ 0 ]; ulR0 = pulCallerStackAddress[ 0 ];
/* Free the secure context. */ /* Free the secure context. */
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 );
}
break; break;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER: case portSVC_START_SCHEDULER:
{
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
{ {
/* De-prioritize the non-secure exceptions so that the /* De-prioritize the non-secure exceptions so that the
@ -846,36 +854,39 @@ uint8_t ucSVCNumber;
/* Setup the context of the first task so that the first task starts /* Setup the context of the first task so that the first task starts
* executing. */ * executing. */
vRestoreContextOfFirstTask(); vRestoreContextOfFirstTask();
}
break; break;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
case portSVC_RAISE_PRIVILEGE: case portSVC_RAISE_PRIVILEGE:
{
/* Only raise the privilege, if the svc was raised from any of /* Only raise the privilege, if the svc was raised from any of
* the system calls. */ * the system calls. */
if( ulPC >= ( uint32_t ) __syscalls_flash_start__ && if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) &&
ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) )
{ {
vRaisePrivilege(); vRaisePrivilege();
} }
}
break; break;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
default: default:
{
/* Incorrect SVC call. */ /* Incorrect SVC call. */
configASSERT( pdFALSE ); configASSERT( pdFALSE );
} }
} }
}
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack,
TaskFunction_t pxCode,
void * pvParameters,
BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */
#else #else
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) /* PRIVILEGED_FUNCTION */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack,
TaskFunction_t pxCode,
void * pvParameters ) /* PRIVILEGED_FUNCTION */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
{ {
/* Simulate the stack frame as it would be created by a context switch /* Simulate the stack frame as it would be created by a context switch
@ -896,6 +907,7 @@ uint8_t ucSVCNumber;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
{ {
pxTopOfStack--; pxTopOfStack--;
if( xRunPrivileged == pdTRUE ) if( xRunPrivileged == pdTRUE )
{ {
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
@ -957,6 +969,7 @@ uint8_t ucSVCNumber;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
{ {
pxTopOfStack--; pxTopOfStack--;
if( xRunPrivileged == pdTRUE ) if( xRunPrivileged == pdTRUE )
{ {
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
@ -1030,7 +1043,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
const struct xMEMORY_REGION * const xRegions,
StackType_t * pxBottomOfStack,
uint32_t ulStackDepth )
{ {
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
int32_t lIndex = 0; int32_t lIndex = 0;

View file

@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *

View file

@ -95,7 +95,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
uint32_t ulIsTaskPrivileged )
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
@ -103,6 +104,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
uint8_t * pucStackMemory = NULL; uint8_t * pucStackMemory = NULL;
uint32_t ulIPSR; uint32_t ulIPSR;
SecureContextHandle_t xSecureContextHandle = NULL; SecureContextHandle_t xSecureContextHandle = NULL;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
uint32_t * pulCurrentStackPointer = NULL; uint32_t * pulCurrentStackPointer = NULL;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
@ -143,6 +145,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
* context switch. */ * context switch. */
pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart; pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
pulCurrentStackPointer--; pulCurrentStackPointer--;
if( ulIsTaskPrivileged ) if( ulIsTaskPrivileged )
{ {
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED; *( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
@ -161,7 +164,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
/* Current SP is set to the starting of the stack. This /* Current SP is set to the starting of the stack. This
* value programmed in the PSP register on context switch. */ * value programmed in the PSP register on context switch. */
xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart; xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
} }
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
} }

View file

@ -69,7 +69,8 @@ void SecureContext_Init( void );
* otherwise. * otherwise.
*/ */
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged ); SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
uint32_t ulIsTaskPrivileged );
#else /* configENABLE_MPU */ #else /* configENABLE_MPU */
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ); SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */

View file

@ -62,6 +62,7 @@
/* Allocate the memory for the heap. */ /* Allocate the memory for the heap. */
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) #if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
/* The application writer has already defined the array used for the RTOS /* The application writer has already defined the array used for the RTOS
* heap - probably so it can be placed in a special segment or address. */ * heap - probably so it can be placed in a special segment or address. */
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ]; extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
@ -190,6 +191,7 @@ uint8_t *puc;
/* Do the block being inserted, and the block it is being inserted after /* Do the block being inserted, and the block it is being inserted after
* make a contiguous block of memory? */ * make a contiguous block of memory? */
puc = ( uint8_t * ) pxIterator; puc = ( uint8_t * ) pxIterator;
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
{ {
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
@ -203,6 +205,7 @@ uint8_t *puc;
/* Do the block being inserted, and the block it is being inserted before /* Do the block being inserted, and the block it is being inserted before
* make a contiguous block of memory? */ * make a contiguous block of memory? */
puc = ( uint8_t * ) pxBlockToInsert; puc = ( uint8_t * ) pxBlockToInsert;
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
{ {
if( pxIterator->pxNextFreeBlock != pxEnd ) if( pxIterator->pxNextFreeBlock != pxEnd )
@ -288,6 +291,7 @@ void *pvReturn = NULL;
* one of adequate size is found. */ * one of adequate size is found. */
pxPreviousBlock = &xStart; pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock; pxBlock = xStart.pxNextFreeBlock;
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
{ {
pxPreviousBlock = pxBlock; pxPreviousBlock = pxBlock;
@ -375,7 +379,7 @@ void *pvReturn = NULL;
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
} }
#endif #endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 ); secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
return pvReturn; return pvReturn;

View file

@ -126,7 +126,7 @@
{ \ { \
secureportDISABLE_SECURE_INTERRUPTS(); \ secureportDISABLE_SECURE_INTERRUPTS(); \
secureportDISABLE_NON_SECURE_INTERRUPTS(); \ secureportDISABLE_NON_SECURE_INTERRUPTS(); \
for( ;; ); \ for( ; ; ) {; } \
} }
#endif /* __SECURE_PORT_MACROS_H__ */ #endif /* __SECURE_PORT_MACROS_H__ */

View file

@ -85,6 +85,7 @@
/* Ensure the SysTick is clocked at the same frequency as the core. */ /* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#else #else
/* The way the SysTick is clocked is not modified in case it is not the /* The way the SysTick is clocked is not modified in case it is not the
* same a the core. */ * same a the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 0 ) #define portNVIC_SYSTICK_CLK_BIT ( 0 )
@ -205,6 +206,7 @@
#define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_XPSR ( 0x01000000 )
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) #if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
/** /**
* @brief Initial EXC_RETURN value. * @brief Initial EXC_RETURN value.
* *
@ -221,6 +223,7 @@
*/ */
#define portINITIAL_EXC_RETURN ( 0xfffffffd ) #define portINITIAL_EXC_RETURN ( 0xfffffffd )
#else #else
/** /**
* @brief Initial EXC_RETURN value. * @brief Initial EXC_RETURN value.
* *
@ -285,6 +288,7 @@
static void prvTaskExitError( void ); static void prvTaskExitError( void );
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Setup the Memory Protection Unit (MPU). * @brief Setup the Memory Protection Unit (MPU).
*/ */
@ -292,6 +296,7 @@ static void prvTaskExitError( void );
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
#if ( configENABLE_FPU == 1 ) #if ( configENABLE_FPU == 1 )
/** /**
* @brief Setup the Floating Point Unit (FPU). * @brief Setup the Floating Point Unit (FPU).
*/ */
@ -347,6 +352,7 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) PRIVI
static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Saved as part of the task context to indicate which context the * @brief Saved as part of the task context to indicate which context the
* task is using on the secure side. * task is using on the secure side.
@ -355,6 +361,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
#if ( configUSE_TICKLESS_IDLE == 1 ) #if ( configUSE_TICKLESS_IDLE == 1 )
/** /**
* @brief The number of SysTick increments that make up one tick period. * @brief The number of SysTick increments that make up one tick period.
*/ */
@ -396,6 +403,7 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
* tick periods. -1 is used because this code will execute part way * tick periods. -1 is used because this code will execute part way
* through one of the tick periods. */ * through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation ) if( ulReloadValue > ulStoppedTimerCompensation )
{ {
ulReloadValue -= ulStoppedTimerCompensation; ulReloadValue -= ulStoppedTimerCompensation;
@ -446,12 +454,14 @@ static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
* so a copy is taken. */ * so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime; xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "dsb" ::: "memory" );
__asm volatile ( "wfi" ); __asm volatile ( "wfi" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
} }
configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
/* Re-enable interrupts to allow the interrupt that brought the MCU /* Re-enable interrupts to allow the interrupt that brought the MCU
@ -590,6 +600,7 @@ volatile uint32_t ulDummy = 0UL;
static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */ static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */
{ {
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_start__;
@ -600,7 +611,7 @@ volatile uint32_t ulDummy = 0UL;
extern uint32_t * __unprivileged_flash_end__; extern uint32_t * __unprivileged_flash_end__;
extern uint32_t * __privileged_sram_start__; extern uint32_t * __privileged_sram_start__;
extern uint32_t * __privileged_sram_end__; extern uint32_t * __privileged_sram_end__;
#else #else /* if defined( __ARMCC_VERSION ) */
/* Declaration when these variable are exported from linker scripts. */ /* Declaration when these variable are exported from linker scripts. */
extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_start__[];
extern uint32_t __privileged_functions_end__[]; extern uint32_t __privileged_functions_end__[];
@ -753,6 +764,7 @@ void vPortSVCHandler_C( uint32_t *pulCallerStackAddress ) /* PRIVILEGED_FUNCTION
{ {
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_start__;
@ -783,7 +795,7 @@ uint8_t ucSVCNumber;
{ {
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
case portSVC_ALLOCATE_SECURE_CONTEXT: case portSVC_ALLOCATE_SECURE_CONTEXT:
{
/* R0 contains the stack size passed as parameter to the /* R0 contains the stack size passed as parameter to the
* vPortAllocateSecureContext function. */ * vPortAllocateSecureContext function. */
ulR0 = pulCallerStackAddress[ 0 ]; ulR0 = pulCallerStackAddress[ 0 ];
@ -800,7 +812,7 @@ uint8_t ucSVCNumber;
/* Allocate and load a context for the secure task. */ /* Allocate and load a context for the secure task. */
xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged );
} }
#else #else /* if ( configENABLE_MPU == 1 ) */
{ {
/* Allocate and load a context for the secure task. */ /* Allocate and load a context for the secure task. */
xSecureContext = SecureContext_AllocateContext( ulR0 ); xSecureContext = SecureContext_AllocateContext( ulR0 );
@ -809,22 +821,18 @@ uint8_t ucSVCNumber;
configASSERT( xSecureContext != NULL ); configASSERT( xSecureContext != NULL );
SecureContext_LoadContext( xSecureContext ); SecureContext_LoadContext( xSecureContext );
}
break; break;
case portSVC_FREE_SECURE_CONTEXT: case portSVC_FREE_SECURE_CONTEXT:
{
/* R0 contains the secure context handle to be freed. */ /* R0 contains the secure context handle to be freed. */
ulR0 = pulCallerStackAddress[ 0 ]; ulR0 = pulCallerStackAddress[ 0 ];
/* Free the secure context. */ /* Free the secure context. */
SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 );
}
break; break;
#endif /* configENABLE_TRUSTZONE */ #endif /* configENABLE_TRUSTZONE */
case portSVC_START_SCHEDULER: case portSVC_START_SCHEDULER:
{
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
{ {
/* De-prioritize the non-secure exceptions so that the /* De-prioritize the non-secure exceptions so that the
@ -846,36 +854,39 @@ uint8_t ucSVCNumber;
/* Setup the context of the first task so that the first task starts /* Setup the context of the first task so that the first task starts
* executing. */ * executing. */
vRestoreContextOfFirstTask(); vRestoreContextOfFirstTask();
}
break; break;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
case portSVC_RAISE_PRIVILEGE: case portSVC_RAISE_PRIVILEGE:
{
/* Only raise the privilege, if the svc was raised from any of /* Only raise the privilege, if the svc was raised from any of
* the system calls. */ * the system calls. */
if( ulPC >= ( uint32_t ) __syscalls_flash_start__ && if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) &&
ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) )
{ {
vRaisePrivilege(); vRaisePrivilege();
} }
}
break; break;
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
default: default:
{
/* Incorrect SVC call. */ /* Incorrect SVC call. */
configASSERT( pdFALSE ); configASSERT( pdFALSE );
} }
} }
}
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack,
TaskFunction_t pxCode,
void * pvParameters,
BaseType_t xRunPrivileged ) /* PRIVILEGED_FUNCTION */
#else #else
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) /* PRIVILEGED_FUNCTION */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
StackType_t * pxEndOfStack,
TaskFunction_t pxCode,
void * pvParameters ) /* PRIVILEGED_FUNCTION */
#endif /* configENABLE_MPU */ #endif /* configENABLE_MPU */
{ {
/* Simulate the stack frame as it would be created by a context switch /* Simulate the stack frame as it would be created by a context switch
@ -896,6 +907,7 @@ uint8_t ucSVCNumber;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
{ {
pxTopOfStack--; pxTopOfStack--;
if( xRunPrivileged == pdTRUE ) if( xRunPrivileged == pdTRUE )
{ {
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
@ -957,6 +969,7 @@ uint8_t ucSVCNumber;
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
{ {
pxTopOfStack--; pxTopOfStack--;
if( xRunPrivileged == pdTRUE ) if( xRunPrivileged == pdTRUE )
{ {
*pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */ *pxTopOfStack = portINITIAL_CONTROL_PRIVILEGED; /* Slot used to hold this task's CONTROL value. */
@ -1030,7 +1043,10 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
const struct xMEMORY_REGION * const xRegions,
StackType_t * pxBottomOfStack,
uint32_t ulStackDepth )
{ {
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber; uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
int32_t lIndex = 0; int32_t lIndex = 0;

View file

@ -243,6 +243,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_TRUSTZONE == 1 ) #if ( configENABLE_TRUSTZONE == 1 )
/** /**
* @brief Allocate a secure context for the task. * @brief Allocate a secure context for the task.
* *
@ -268,6 +269,7 @@ typedef struct MPU_SETTINGS
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *

View file

@ -44,6 +44,7 @@
/* Ensure the SysTick is clocked at the same frequency as the core. */ /* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK ( 1UL << 2UL ) #define portNVIC_SYSTICK_CLK ( 1UL << 2UL )
#else #else
/* The way the SysTick is clocked is not modified in case it is not the same /* 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 ) #define portNVIC_SYSTICK_CLK ( 0 )
@ -190,7 +191,10 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, 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 /* Simulate the stack frame as it would be created by a context switch
* interrupt. */ * interrupt. */
@ -240,8 +244,10 @@ static void prvSVCHandler( uint32_t *pulParam )
{ {
uint8_t ucSVCNumber; uint8_t ucSVCNumber;
uint32_t ulPC; uint32_t ulPC;
#if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) #if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 )
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_start__;
@ -260,11 +266,14 @@ uint32_t ulPC;
switch( ucSVCNumber ) switch( ucSVCNumber )
{ {
case portSVC_START_SCHEDULER : portNVIC_SYSPRI1_REG |= portNVIC_SVC_PRI; case portSVC_START_SCHEDULER:
portNVIC_SYSPRI1_REG |= portNVIC_SVC_PRI;
prvRestoreContextOfFirstTask(); prvRestoreContextOfFirstTask();
break; 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 /* Barriers are normally not required
* but do ensure the code is completely * but do ensure the code is completely
* within the specified behaviour for the * within the specified behaviour for the
@ -279,8 +288,9 @@ uint32_t ulPC;
case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the
* svc was raised from any of the * svc was raised from any of the
* system calls. */ * 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 __asm volatile
( (
@ -290,9 +300,11 @@ uint32_t ulPC;
::: "r1", "memory" ::: "r1", "memory"
); );
} }
break; break;
#else #else /* if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */
case portSVC_RAISE_PRIVILEGE : __asm volatile case portSVC_RAISE_PRIVILEGE:
__asm volatile
( (
" mrs r1, control \n" /* Obtain current control value. */ " mrs r1, control \n" /* Obtain current control value. */
" bic r1, #1 \n" /* Set privilege bit. */ " 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 * functions can be called. ISR safe functions are those that end in
* "FromISR". FreeRTOS maintains separate thread and ISR API functions * "FromISR". FreeRTOS maintains separate thread and ISR API functions
* to ensure interrupt entry is as fast and simple as possible. * to ensure interrupt entry is as fast and simple as possible.
*
* Save the interrupt priority value that is about to be clobbered. */ * Save the interrupt priority value that is about to be clobbered. */
ulOriginalPriority = *pucFirstUserPriorityRegister; ulOriginalPriority = *pucFirstUserPriorityRegister;
@ -387,6 +399,7 @@ BaseType_t xPortStartScheduler( void )
/* Calculate the maximum acceptable priority group value for the number /* Calculate the maximum acceptable priority group value for the number
* of bits read back. */ * of bits read back. */
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{ {
ulMaxPRIGROUPValue--; ulMaxPRIGROUPValue--;
@ -483,10 +496,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
configASSERT( uxCriticalNesting ); configASSERT( uxCriticalNesting );
uxCriticalNesting--; uxCriticalNesting--;
if( uxCriticalNesting == 0 ) if( uxCriticalNesting == 0 )
{ {
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }
vPortResetPrivilege( xRunningPrivileged ); 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_start__[];
extern uint32_t __SRAM_segment_end__[]; extern uint32_t __SRAM_segment_end__[];
@ -817,20 +835,20 @@ uint32_t ul;
* function. ISR safe FreeRTOS API functions must *only* be called * function. ISR safe FreeRTOS API functions must *only* be called
* from interrupts that have been assigned a priority at or below * from interrupts that have been assigned a priority at or below
* configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
* Numerically low interrupt priority numbers represent logically high * Numerically low interrupt priority numbers represent logically high
* interrupt priorities, therefore the priority of the interrupt must * interrupt priorities, therefore the priority of the interrupt must
* be set to a value equal to or numerically *higher* than * be set to a value equal to or numerically *higher* than
* configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
* Interrupts that use the FreeRTOS API must not be left at their * Interrupts that use the FreeRTOS API must not be left at their
* default priority of zero as that is the highest possible priority, * default priority of zero as that is the highest possible priority,
* which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
* and therefore also guaranteed to be invalid. * and therefore also guaranteed to be invalid.
*
* FreeRTOS maintains separate thread and ISR API functions to ensure * FreeRTOS maintains separate thread and ISR API functions to ensure
* interrupt entry is as fast and simple as possible. * interrupt entry is as fast and simple as possible.
*
* The following links provide detailed information: * The following links provide detailed information:
* http://www.freertos.org/RTOS-Cortex-M3-M4.html * http://www.freertos.org/RTOS-Cortex-M3-M4.html
* http://www.freertos.org/FAQHelp.html */ * http://www.freertos.org/FAQHelp.html */
@ -843,7 +861,7 @@ uint32_t ul;
* the interrupt's sub-priority. For simplicity all bits must be defined * the interrupt's sub-priority. For simplicity all bits must be defined
* to be pre-emption priority bits. The following assertion will fail if * to be pre-emption priority bits. The following assertion will fail if
* this is not the case (if some bits represent a sub-priority). * this is not the case (if some bits represent a sub-priority).
*
* If the application only uses CMSIS libraries for interrupt * If the application only uses CMSIS libraries for interrupt
* configuration then the correct setting can be achieved on all Cortex-M * configuration then the correct setting can be achieved on all Cortex-M
* devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the

View file

@ -63,7 +63,7 @@ typedef unsigned long UBaseType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -125,7 +125,7 @@ typedef struct MPU_SETTINGS
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
\ \
/* Barriers are normally not required but do ensure the code is completely \ /* Barriers are normally not required but do ensure the code is completely \
within the specified behaviour for the architecture. */ \ * within the specified behaviour for the architecture. */\
__asm volatile ( "dsb" ::: "memory" ); \ __asm volatile ( "dsb" ::: "memory" ); \
__asm volatile ( "isb" ); \ __asm volatile ( "isb" ); \
} }
@ -149,8 +149,8 @@ extern void vPortExitCritical( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are /* Task function macros as described on the FreeRTOS.org WEB site. These are
not necessary for to use this port. They are defined so the common demo files * not necessary for to use this port. They are defined so the common demo files
(which build with all the ports) will build. */ * (which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -168,6 +168,7 @@ not necessary for to use this port. They are defined so the common demo files
uint8_t ucReturn; uint8_t ucReturn;
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
return ucReturn; return ucReturn;
} }
@ -278,7 +279,7 @@ uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
); );
/* This return will not be reached but is necessary to prevent compiler /* This return will not be reached but is necessary to prevent compiler
warnings. */ * warnings. */
return ulOriginalBASEPRI; return ulOriginalBASEPRI;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -295,7 +296,7 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
#ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY #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 #define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 0
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -304,4 +305,3 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -41,8 +41,9 @@
/* Ensure the SysTick is clocked at the same frequency as the core. */ /* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#else #else
/* The way the SysTick is clocked is not modified in case it is not the same /* 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 ) #define portNVIC_SYSTICK_CLK_BIT ( 0 )
#endif #endif
@ -59,7 +60,7 @@
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
/* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7 /* 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 portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) )
#define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL )
#define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL )
@ -92,17 +93,17 @@ r0p1 port. */
#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) #define portMAX_24_BIT_NUMBER ( 0xffffffUL )
/* For strict compliance with the Cortex-M spec the task start address should /* For strict compliance with the Cortex-M spec the task start address should
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
/* A fiddle factor to estimate the number of SysTick counts that would have /* A fiddle factor to estimate the number of SysTick counts that would have
occurred while the SysTick counter is stopped during tickless idle * occurred while the SysTick counter is stopped during tickless idle
calculations. */ * calculations. */
#define portMISSED_COUNTS_FACTOR ( 45UL ) #define portMISSED_COUNTS_FACTOR ( 45UL )
/* Let the user override the pre-loading of the initial LR with the address of /* Let the user override the pre-loading of the initial LR with the address of
prvTaskExitError() in case it messes up unwinding of the stack in the * prvTaskExitError() in case it messes up unwinding of the stack in the
debugger. */ * debugger. */
#ifdef configTASK_RETURN_ADDRESS #ifdef configTASK_RETURN_ADDRESS
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
#else #else
@ -141,7 +142,7 @@ static void prvTaskExitError( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Each task maintains its own interrupt status in the critical nesting /* Each task maintains its own interrupt status in the critical nesting
variable. */ * variable. */
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/* /*
@ -183,13 +184,15 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{ {
/* Simulate the stack frame as it would be created by a context switch /* Simulate the stack frame as it would be created by a context switch
interrupt. */ * interrupt. */
/* Offset added to account for the way the MCU uses the stack on entry/exit /* Offset added to account for the way the MCU uses the stack on entry/exit
of interrupts, and to ensure alignment. */ * of interrupts, and to ensure alignment. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */
@ -203,7 +206,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
/* A save method is being used that requires each task to maintain its /* A save method is being used that requires each task to maintain its
own exec return value. */ * own exec return value. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = portINITIAL_EXC_RETURN; *pxTopOfStack = portINITIAL_EXC_RETURN;
@ -218,22 +221,23 @@ static void prvTaskExitError( void )
volatile uint32_t ulDummy = 0; volatile uint32_t ulDummy = 0;
/* A function that implements a task must not exit or attempt to return to /* A function that implements a task must not exit or attempt to return to
its caller as there is nothing to return to. If a task wants to exit it * its caller as there is nothing to return to. If a task wants to exit it
should instead call vTaskDelete( NULL ). * should instead call vTaskDelete( NULL ).
*
Artificially force an assert() to be triggered if configASSERT() is * Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */ * defined, then stop here so application writers can catch the error. */
configASSERT( uxCriticalNesting == ~0UL ); configASSERT( uxCriticalNesting == ~0UL );
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
while( ulDummy == 0 ) while( ulDummy == 0 )
{ {
/* This file calls prvTaskExitError() after the scheduler has been /* This file calls prvTaskExitError() after the scheduler has been
started to remove a compiler warning about the function being defined * started to remove a compiler warning about the function being defined
but never called. ulDummy is used purely to quieten other warnings * but never called. ulDummy is used purely to quieten other warnings
about code appearing after this function is called - making ulDummy * about code appearing after this function is called - making ulDummy
volatile makes the compiler think the function could return and * volatile makes the compiler think the function could return and
therefore not output an 'unreachable code' warning for code that appears * therefore not output an 'unreachable code' warning for code that appears
after it. */ * after it. */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -260,9 +264,9 @@ void vPortSVCHandler( void )
static void prvPortStartFirstTask( void ) static void prvPortStartFirstTask( void )
{ {
/* Start the first task. This also clears the bit that indicates the FPU is /* 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 * 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 * would otherwise result in the unnecessary leaving of space in the SVC stack
for lazy saving of FPU registers. */ * for lazy saving of FPU registers. */
__asm volatile ( __asm volatile (
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
" ldr r0, [r0] \n" " ldr r0, [r0] \n"
@ -287,12 +291,12 @@ static void prvPortStartFirstTask( void )
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. /* 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 ); configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
/* This port can be used on all revisions of the Cortex-M7 core other than /* 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 * the r0p1 parts. r0p1 parts should use the port from the
/source/portable/GCC/ARM_CM7/r0p1 directory. */ * /source/portable/GCC/ARM_CM7/r0p1 directory. */
configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
@ -303,15 +307,15 @@ BaseType_t xPortStartScheduler( void )
volatile uint8_t ucMaxPriorityValue; volatile uint8_t ucMaxPriorityValue;
/* Determine the maximum priority from which ISR safe FreeRTOS API /* Determine the maximum priority from which ISR safe FreeRTOS API
functions can be called. ISR safe functions are those that end in * functions can be called. ISR safe functions are those that end in
"FromISR". FreeRTOS maintains separate thread and ISR API functions to * "FromISR". FreeRTOS maintains separate thread and ISR API functions to
ensure interrupt entry is as fast and simple as possible. * ensure interrupt entry is as fast and simple as possible.
*
Save the interrupt priority value that is about to be clobbered. */ * Save the interrupt priority value that is about to be clobbered. */
ulOriginalPriority = *pucFirstUserPriorityRegister; ulOriginalPriority = *pucFirstUserPriorityRegister;
/* Determine the number of priority bits available. First write to all /* Determine the number of priority bits available. First write to all
possible bits. */ * possible bits. */
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
/* Read the value back to see how many bits stuck. */ /* Read the value back to see how many bits stuck. */
@ -321,8 +325,9 @@ BaseType_t xPortStartScheduler( void )
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
/* Calculate the maximum acceptable priority group value for the number /* Calculate the maximum acceptable priority group value for the number
of bits read back. */ * of bits read back. */
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{ {
ulMaxPRIGROUPValue--; ulMaxPRIGROUPValue--;
@ -332,8 +337,8 @@ BaseType_t xPortStartScheduler( void )
#ifdef __NVIC_PRIO_BITS #ifdef __NVIC_PRIO_BITS
{ {
/* Check the CMSIS configuration that defines the number of /* Check the CMSIS configuration that defines the number of
priority bits matches the number of priority bits actually queried * priority bits matches the number of priority bits actually queried
from the hardware. */ * from the hardware. */
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
} }
#endif #endif
@ -341,19 +346,19 @@ BaseType_t xPortStartScheduler( void )
#ifdef configPRIO_BITS #ifdef configPRIO_BITS
{ {
/* Check the FreeRTOS configuration that defines the number of /* Check the FreeRTOS configuration that defines the number of
priority bits matches the number of priority bits actually queried * priority bits matches the number of priority bits actually queried
from the hardware. */ * from the hardware. */
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
} }
#endif #endif
/* Shift the priority group value back to its position within the AIRCR /* Shift the priority group value back to its position within the AIRCR
register. */ * register. */
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
/* Restore the clobbered interrupt priority register to its original /* Restore the clobbered interrupt priority register to its original
value. */ * value. */
*pucFirstUserPriorityRegister = ulOriginalPriority; *pucFirstUserPriorityRegister = ulOriginalPriority;
} }
#endif /* conifgASSERT_DEFINED */ #endif /* conifgASSERT_DEFINED */
@ -363,7 +368,7 @@ BaseType_t xPortStartScheduler( void )
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
/* Start the timer that generates the tick ISR. Interrupts are disabled /* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */ * here already. */
vPortSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialise the critical nesting count ready for the first task. */ /* Initialise the critical nesting count ready for the first task. */
@ -379,11 +384,11 @@ BaseType_t xPortStartScheduler( void )
prvPortStartFirstTask(); prvPortStartFirstTask();
/* Should never get here as the tasks will now be executing! Call the task /* Should never get here as the tasks will now be executing! Call the task
exit error function to prevent compiler warnings about a static function * exit error function to prevent compiler warnings about a static function
not being called in the case that the application writer overrides this * not being called in the case that the application writer overrides this
functionality by defining configTASK_RETURN_ADDRESS. Call * functionality by defining configTASK_RETURN_ADDRESS. Call
vTaskSwitchContext() so link time optimisation does not remove the * vTaskSwitchContext() so link time optimisation does not remove the
symbol. */ * symbol. */
vTaskSwitchContext(); vTaskSwitchContext();
prvTaskExitError(); prvTaskExitError();
@ -395,7 +400,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented in ports where there is nothing to return to. /* Not implemented in ports where there is nothing to return to.
Artificially force an assert. */ * Artificially force an assert. */
configASSERT( uxCriticalNesting == 1000UL ); configASSERT( uxCriticalNesting == 1000UL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -406,10 +411,10 @@ void vPortEnterCritical( void )
uxCriticalNesting++; uxCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so /* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context. Only API * assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if * functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the * the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */ * assert function also uses a critical section. */
if( uxCriticalNesting == 1 ) if( uxCriticalNesting == 1 )
{ {
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
@ -421,6 +426,7 @@ void vPortExitCritical( void )
{ {
configASSERT( uxCriticalNesting ); configASSERT( uxCriticalNesting );
uxCriticalNesting--; uxCriticalNesting--;
if( uxCriticalNesting == 0 ) if( uxCriticalNesting == 0 )
{ {
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
@ -488,16 +494,16 @@ void xPortPendSVHandler( void )
void xPortSysTickHandler( void ) void xPortSysTickHandler( void )
{ {
/* The SysTick runs at the lowest interrupt priority, so when this interrupt /* The SysTick runs at the lowest interrupt priority, so when this interrupt
executes all interrupts must be unmasked. There is therefore no need to * executes all interrupts must be unmasked. There is therefore no need to
save and then restore the interrupt mask value as its value is already * save and then restore the interrupt mask value as its value is already
known. */ * known. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
} }
@ -519,43 +525,44 @@ void xPortSysTickHandler( void )
} }
/* Stop the SysTick momentarily. The time the SysTick is stopped for /* Stop the SysTick momentarily. The time the SysTick is stopped for
is accounted for as best it can be, but using the tickless mode will * is accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the * inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */ * kernel with respect to calendar time. */
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
/* Calculate the reload value required to wait xExpectedIdleTime /* Calculate the reload value required to wait xExpectedIdleTime
tick periods. -1 is used because this code will execute part way * tick periods. -1 is used because this code will execute part way
through one of the tick periods. */ * through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation ) if( ulReloadValue > ulStoppedTimerCompensation )
{ {
ulReloadValue -= ulStoppedTimerCompensation; ulReloadValue -= ulStoppedTimerCompensation;
} }
/* Enter a critical section but don't use the taskENTER_CRITICAL() /* Enter a critical section but don't use the taskENTER_CRITICAL()
method as that will mask interrupts that should exit sleep mode. */ * method as that will mask interrupts that should exit sleep mode. */
__asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "cpsid i" ::: "memory" );
__asm volatile ( "dsb" ); __asm volatile ( "dsb" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
/* If a context switch is pending or a task is waiting for the scheduler /* If a context switch is pending or a task is waiting for the scheduler
to be unsuspended then abandon the low power entry. */ * to be unsuspended then abandon the low power entry. */
if( eTaskConfirmSleepModeStatus() == eAbortSleep ) if( eTaskConfirmSleepModeStatus() == eAbortSleep )
{ {
/* Restart from whatever is left in the count register to complete /* Restart from whatever is left in the count register to complete
this tick period. */ * this tick period. */
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* Restart SysTick. */ /* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
/* Reset the reload register to the value required for normal tick /* Reset the reload register to the value required for normal tick
periods. */ * periods. */
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
/* Re-enable interrupts - see comments above the cpsid instruction() /* Re-enable interrupts - see comments above the cpsid instruction()
above. */ * above. */
__asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "cpsie i" ::: "memory" );
} }
else else
@ -564,69 +571,71 @@ void xPortSysTickHandler( void )
portNVIC_SYSTICK_LOAD_REG = ulReloadValue; portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
/* Clear the SysTick count flag and set the count value back to /* Clear the SysTick count flag and set the count value back to
zero. */ * zero. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
/* Restart SysTick. */ /* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
set its parameter to 0 to indicate that its implementation contains * set its parameter to 0 to indicate that its implementation contains
its own wait for interrupt or wait for event instruction, and so wfi * its own wait for interrupt or wait for event instruction, and so wfi
should not be executed again. However, the original expected idle * should not be executed again. However, the original expected idle
time variable must remain unmodified, so a copy is taken. */ * time variable must remain unmodified, so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime; xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "dsb" ::: "memory" );
__asm volatile ( "wfi" ); __asm volatile ( "wfi" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
} }
configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
/* Re-enable interrupts to allow the interrupt that brought the MCU /* Re-enable interrupts to allow the interrupt that brought the MCU
out of sleep mode to execute immediately. see comments above * out of sleep mode to execute immediately. see comments above
__disable_interrupt() call above. */ * __disable_interrupt() call above. */
__asm volatile ( "cpsie i" ::: "memory" ); __asm volatile ( "cpsie i" ::: "memory" );
__asm volatile ( "dsb" ); __asm volatile ( "dsb" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
/* Disable interrupts again because the clock is about to be stopped /* Disable interrupts again because the clock is about to be stopped
and interrupts that execute while the clock is stopped will increase * and interrupts that execute while the clock is stopped will increase
any slippage between the time maintained by the RTOS and calendar * any slippage between the time maintained by the RTOS and calendar
time. */ * time. */
__asm volatile ( "cpsid i" ::: "memory" ); __asm volatile ( "cpsid i" ::: "memory" );
__asm volatile ( "dsb" ); __asm volatile ( "dsb" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
/* Disable the SysTick clock without reading the /* Disable the SysTick clock without reading the
portNVIC_SYSTICK_CTRL_REG register to ensure the * portNVIC_SYSTICK_CTRL_REG register to ensure the
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
the time the SysTick is stopped for is accounted for as best it can * the time the SysTick is stopped for is accounted for as best it can
be, but using the tickless mode will inevitably result in some tiny * be, but using the tickless mode will inevitably result in some tiny
drift of the time maintained by the kernel with respect to calendar * drift of the time maintained by the kernel with respect to calendar
time*/ * time*/
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT ); portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
/* Determine if the SysTick clock has already counted to zero and /* Determine if the SysTick clock has already counted to zero and
been set back to the current reload value (the reload back being * been set back to the current reload value (the reload back being
correct for the entire expected idle time) or if the SysTick is yet * correct for the entire expected idle time) or if the SysTick is yet
to count to zero (in which case an interrupt other than the SysTick * to count to zero (in which case an interrupt other than the SysTick
must have brought the system out of sleep mode). */ * must have brought the system out of sleep mode). */
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
{ {
uint32_t ulCalculatedLoadValue; uint32_t ulCalculatedLoadValue;
/* The tick interrupt is already pending, and the SysTick count /* The tick interrupt is already pending, and the SysTick count
reloaded with ulReloadValue. Reset the * reloaded with ulReloadValue. Reset the
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick * portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
period. */ * period. */
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
/* Don't allow a tiny value, or values that have somehow /* Don't allow a tiny value, or values that have somehow
underflowed because the post sleep hook did something * underflowed because the post sleep hook did something
that took too long. */ * that took too long. */
if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
{ {
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
@ -635,30 +644,30 @@ void xPortSysTickHandler( void )
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
/* As the pending tick will be processed as soon as this /* As the pending tick will be processed as soon as this
function exits, the tick value maintained by the tick is stepped * function exits, the tick value maintained by the tick is stepped
forward by one less than the time spent waiting. */ * forward by one less than the time spent waiting. */
ulCompleteTickPeriods = xExpectedIdleTime - 1UL; ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
} }
else else
{ {
/* Something other than the tick interrupt ended the sleep. /* Something other than the tick interrupt ended the sleep.
Work out how long the sleep lasted rounded to complete tick * Work out how long the sleep lasted rounded to complete tick
periods (not the ulReload value which accounted for part * periods (not the ulReload value which accounted for part
ticks). */ * ticks). */
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* How many complete tick periods passed while the processor /* How many complete tick periods passed while the processor
was waiting? */ * was waiting? */
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
/* The reload value is set to whatever fraction of a single tick /* The reload value is set to whatever fraction of a single tick
period remains. */ * period remains. */
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
} }
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard * again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
value. */ * value. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
vTaskStepTick( ulCompleteTickPeriods ); vTaskStepTick( ulCompleteTickPeriods );
@ -730,47 +739,45 @@ static void vPortEnableVFP( void )
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
/* The following assertion will fail if a service routine (ISR) for /* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above * an interrupt that has been assigned a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
function. ISR safe FreeRTOS API functions must *only* be called * function. ISR safe FreeRTOS API functions must *only* be called
from interrupts that have been assigned a priority at or below * from interrupts that have been assigned a priority at or below
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Numerically low interrupt priority numbers represent logically high * Numerically low interrupt priority numbers represent logically high
interrupt priorities, therefore the priority of the interrupt must * interrupt priorities, therefore the priority of the interrupt must
be set to a value equal to or numerically *higher* than * be set to a value equal to or numerically *higher* than
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Interrupts that use the FreeRTOS API must not be left at their * Interrupts that use the FreeRTOS API must not be left at their
default priority of zero as that is the highest possible priority, * default priority of zero as that is the highest possible priority,
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
and therefore also guaranteed to be invalid. * and therefore also guaranteed to be invalid.
*
FreeRTOS maintains separate thread and ISR API functions to ensure * FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible. * interrupt entry is as fast and simple as possible.
*
The following links provide detailed information: * The following links provide detailed information:
http://www.freertos.org/RTOS-Cortex-M3-M4.html * http://www.freertos.org/RTOS-Cortex-M3-M4.html
http://www.freertos.org/FAQHelp.html */ * http://www.freertos.org/FAQHelp.html */
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
} }
/* Priority grouping: The interrupt controller (NVIC) allows the bits /* Priority grouping: The interrupt controller (NVIC) allows the bits
that define each interrupt's priority to be split between bits that * that define each interrupt's priority to be split between bits that
define the interrupt's pre-emption priority bits and bits that define * define the interrupt's pre-emption priority bits and bits that define
the interrupt's sub-priority. For simplicity all bits must be defined * the interrupt's sub-priority. For simplicity all bits must be defined
to be pre-emption priority bits. The following assertion will fail if * to be pre-emption priority bits. The following assertion will fail if
this is not the case (if some bits represent a sub-priority). * this is not the case (if some bits represent a sub-priority).
*
If the application only uses CMSIS libraries for interrupt * If the application only uses CMSIS libraries for interrupt
configuration then the correct setting can be achieved on all Cortex-M * configuration then the correct setting can be achieved on all Cortex-M
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
scheduler. Note however that some vendor specific peripheral libraries * scheduler. Note however that some vendor specific peripheral libraries
assume a non-zero priority group setting, in which cases using a value * assume a non-zero priority group setting, in which cases using a value
of zero will result in unpredictable behaviour. */ * of zero will result in unpredictable behaviour. */
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
} }
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */

View file

@ -63,7 +63,7 @@ typedef unsigned long UBaseType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -82,7 +82,7 @@ typedef unsigned long UBaseType_t;
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
\ \
/* Barriers are normally not required but do ensure the code is completely \ /* Barriers are normally not required but do ensure the code is completely \
within the specified behaviour for the architecture. */ \ * within the specified behaviour for the architecture. */\
__asm volatile ( "dsb" ::: "memory" ); \ __asm volatile ( "dsb" ::: "memory" ); \
__asm volatile ( "isb" ); \ __asm volatile ( "isb" ); \
} }
@ -106,8 +106,8 @@ extern void vPortExitCritical( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are /* Task function macros as described on the FreeRTOS.org WEB site. These are
not necessary for to use this port. They are defined so the common demo files * not necessary for to use this port. They are defined so the common demo files
(which build with all the ports) will build. */ * (which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -132,6 +132,7 @@ not necessary for to use this port. They are defined so the common demo files
uint8_t ucReturn; uint8_t ucReturn;
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
return ucReturn; return ucReturn;
} }
@ -219,7 +220,7 @@ uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
); );
/* This return will not be reached but is necessary to prevent compiler /* This return will not be reached but is necessary to prevent compiler
warnings. */ * warnings. */
return ulOriginalBASEPRI; return ulOriginalBASEPRI;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -240,4 +241,3 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View file

@ -29,8 +29,8 @@
*----------------------------------------------------------*/ *----------------------------------------------------------*/
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when * all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */ * task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* Scheduler includes. */ /* 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. */ /* Ensure the SysTick is clocked at the same frequency as the core. */
#define portNVIC_SYSTICK_CLK ( 1UL << 2UL ) #define portNVIC_SYSTICK_CLK ( 1UL << 2UL )
#else #else
/* The way the SysTick is clocked is not modified in case it is not the same /* 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 ) #define portNVIC_SYSTICK_CLK ( 0 )
#endif #endif
@ -107,7 +108,7 @@ task.h is included from an application file. */
#define portOFFSET_TO_PC ( 6 ) #define portOFFSET_TO_PC ( 6 )
/* For strict compliance with the Cortex-M spec the task start address should /* For strict compliance with the Cortex-M spec the task start address should
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) #define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
/* /*
@ -184,8 +185,8 @@ extern void vPortResetPrivilege( BaseType_t xRunningPrivileged );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Each task maintains its own interrupt status in the critical nesting /* 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 * variable. Note this is not saved as part of the task context as context
switches can only occur when uxCriticalNesting is zero. */ * switches can only occur when uxCriticalNesting is zero. */
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/* /*
@ -204,10 +205,13 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
/* /*
* See header file for description. * See header file for description.
*/ */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, 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 /* Simulate the stack frame as it would be created by a context switch
interrupt. */ * interrupt. */
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */
pxTopOfStack--; pxTopOfStack--;
@ -218,7 +222,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
/* A save method is being used that requires each task to maintain its /* A save method is being used that requires each task to maintain its
own exec return value. */ * own exec return value. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = portINITIAL_EXC_RETURN; *pxTopOfStack = portINITIAL_EXC_RETURN;
@ -260,8 +264,10 @@ static void prvSVCHandler( uint32_t *pulParam )
{ {
uint8_t ucSVCNumber; uint8_t ucSVCNumber;
uint32_t ulPC; uint32_t ulPC;
#if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) #if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 )
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; extern uint32_t * __syscalls_flash_start__;
@ -274,21 +280,24 @@ uint32_t ulPC;
#endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */ #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */
/* The stack contains: r0, r1, r2, r3, r12, LR, PC and xPSR. The first /* 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 ]; ulPC = pulParam[ portOFFSET_TO_PC ];
ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ]; ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ];
switch( ucSVCNumber ) switch( ucSVCNumber )
{ {
case portSVC_START_SCHEDULER : portNVIC_SYSPRI1_REG |= portNVIC_SVC_PRI; case portSVC_START_SCHEDULER:
portNVIC_SYSPRI1_REG |= portNVIC_SVC_PRI;
prvRestoreContextOfFirstTask(); prvRestoreContextOfFirstTask();
break; 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 /* Barriers are normally not required
but do ensure the code is completely * but do ensure the code is completely
within the specified behaviour for the * within the specified behaviour for the
architecture. */ * architecture. */
__asm volatile ( "dsb" ::: "memory" ); __asm volatile ( "dsb" ::: "memory" );
__asm volatile ( "isb" ); __asm volatile ( "isb" );
@ -298,8 +307,9 @@ uint32_t ulPC;
case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the case portSVC_RAISE_PRIVILEGE: /* Only raise the privilege, if the
* svc was raised from any of the * svc was raised from any of the
* system calls. */ * 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 __asm volatile
( (
@ -309,9 +319,11 @@ uint32_t ulPC;
::: "r1", "memory" ::: "r1", "memory"
); );
} }
break; break;
#else #else /* if ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */
case portSVC_RAISE_PRIVILEGE : __asm volatile case portSVC_RAISE_PRIVILEGE:
__asm volatile
( (
" mrs r1, control \n" /* Obtain current control value. */ " mrs r1, control \n" /* Obtain current control value. */
" bic r1, #1 \n" /* Set privilege bit. */ " bic r1, #1 \n" /* Set privilege bit. */
@ -375,7 +387,7 @@ static void prvRestoreContextOfFirstTask( void )
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
{ {
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See /* 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 ) ); configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) );
#if ( configASSERT_DEFINED == 1 ) #if ( configASSERT_DEFINED == 1 )
@ -385,15 +397,15 @@ BaseType_t xPortStartScheduler( void )
volatile uint8_t ucMaxPriorityValue; volatile uint8_t ucMaxPriorityValue;
/* Determine the maximum priority from which ISR safe FreeRTOS API /* Determine the maximum priority from which ISR safe FreeRTOS API
functions can be called. ISR safe functions are those that end in * functions can be called. ISR safe functions are those that end in
"FromISR". FreeRTOS maintains separate thread and ISR API functions to * "FromISR". FreeRTOS maintains separate thread and ISR API functions to
ensure interrupt entry is as fast and simple as possible. * ensure interrupt entry is as fast and simple as possible.
*
Save the interrupt priority value that is about to be clobbered. */ * Save the interrupt priority value that is about to be clobbered. */
ulOriginalPriority = *pucFirstUserPriorityRegister; ulOriginalPriority = *pucFirstUserPriorityRegister;
/* Determine the number of priority bits available. First write to all /* Determine the number of priority bits available. First write to all
possible bits. */ * possible bits. */
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
/* Read the value back to see how many bits stuck. */ /* Read the value back to see how many bits stuck. */
@ -403,8 +415,9 @@ BaseType_t xPortStartScheduler( void )
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
/* Calculate the maximum acceptable priority group value for the number /* Calculate the maximum acceptable priority group value for the number
of bits read back. */ * of bits read back. */
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{ {
ulMaxPRIGROUPValue--; ulMaxPRIGROUPValue--;
@ -414,8 +427,8 @@ BaseType_t xPortStartScheduler( void )
#ifdef __NVIC_PRIO_BITS #ifdef __NVIC_PRIO_BITS
{ {
/* Check the CMSIS configuration that defines the number of /* Check the CMSIS configuration that defines the number of
priority bits matches the number of priority bits actually queried * priority bits matches the number of priority bits actually queried
from the hardware. */ * from the hardware. */
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
} }
#endif #endif
@ -423,26 +436,26 @@ BaseType_t xPortStartScheduler( void )
#ifdef configPRIO_BITS #ifdef configPRIO_BITS
{ {
/* Check the FreeRTOS configuration that defines the number of /* Check the FreeRTOS configuration that defines the number of
priority bits matches the number of priority bits actually queried * priority bits matches the number of priority bits actually queried
from the hardware. */ * from the hardware. */
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
} }
#endif #endif
/* Shift the priority group value back to its position within the AIRCR /* Shift the priority group value back to its position within the AIRCR
register. */ * register. */
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
/* Restore the clobbered interrupt priority register to its original /* Restore the clobbered interrupt priority register to its original
value. */ * value. */
*pucFirstUserPriorityRegister = ulOriginalPriority; *pucFirstUserPriorityRegister = ulOriginalPriority;
} }
#endif /* conifgASSERT_DEFINED */ #endif /* conifgASSERT_DEFINED */
/* Make PendSV and SysTick the same priority as the kernel, and the SVC /* 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 * handler higher priority so it can be used to exit a critical section (where
lower priorities are masked). */ * lower priorities are masked). */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
@ -450,7 +463,7 @@ BaseType_t xPortStartScheduler( void )
prvSetupMPU(); prvSetupMPU();
/* Start the timer that generates the tick ISR. Interrupts are disabled /* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */ * here already. */
vPortSetupTimerInterrupt(); vPortSetupTimerInterrupt();
/* Initialise the critical nesting count ready for the first task. */ /* Initialise the critical nesting count ready for the first task. */
@ -463,9 +476,9 @@ BaseType_t xPortStartScheduler( void )
*( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS;
/* Start the first task. This also clears the bit that indicates the FPU is /* 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 * 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 * would otherwise result in the unnecessary leaving of space in the SVC stack
for lazy saving of FPU registers. */ * for lazy saving of FPU registers. */
__asm volatile ( __asm volatile (
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
" ldr r0, [r0] \n" " ldr r0, [r0] \n"
@ -490,7 +503,7 @@ BaseType_t xPortStartScheduler( void )
void vPortEndScheduler( void ) void vPortEndScheduler( void )
{ {
/* Not implemented in ports where there is nothing to return to. /* Not implemented in ports where there is nothing to return to.
Artificially force an assert. */ * Artificially force an assert. */
configASSERT( uxCriticalNesting == 1000UL ); configASSERT( uxCriticalNesting == 1000UL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -512,10 +525,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
configASSERT( uxCriticalNesting ); configASSERT( uxCriticalNesting );
uxCriticalNesting--; uxCriticalNesting--;
if( uxCriticalNesting == 0 ) if( uxCriticalNesting == 0 )
{ {
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }
vPortResetPrivilege( xRunningPrivileged ); vPortResetPrivilege( xRunningPrivileged );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -639,6 +654,7 @@ static void vPortEnableVFP( void )
static void prvSetupMPU( void ) static void prvSetupMPU( void )
{ {
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_start__;
@ -655,7 +671,8 @@ static void prvSetupMPU( void )
extern uint32_t __FLASH_segment_end__[]; extern uint32_t __FLASH_segment_end__[];
extern uint32_t __privileged_data_start__[]; extern uint32_t __privileged_data_start__[];
extern uint32_t __privileged_data_end__[]; extern uint32_t __privileged_data_end__[];
#endif #endif /* if defined( __ARMCC_VERSION ) */
/* Check the expected MPU is present. */ /* Check the expected MPU is present. */
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
{ {
@ -670,7 +687,7 @@ static void prvSetupMPU( void )
( portMPU_REGION_ENABLE ); ( portMPU_REGION_ENABLE );
/* Setup the privileged flash for privileged only access. This is where /* 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_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_functions_start__ ) | /* Base address. */
( portMPU_REGION_VALID ) | ( portMPU_REGION_VALID ) |
( portPRIVILEGED_FLASH_REGION ); ( portPRIVILEGED_FLASH_REGION );
@ -681,7 +698,7 @@ static void prvSetupMPU( void )
( portMPU_REGION_ENABLE ); ( portMPU_REGION_ENABLE );
/* Setup the privileged data RAM region. This is where the kernel data /* 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_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */
( portMPU_REGION_VALID ) | ( portMPU_REGION_VALID ) |
( portPRIVILEGED_RAM_REGION ); ( portPRIVILEGED_RAM_REGION );
@ -692,7 +709,7 @@ static void prvSetupMPU( void )
( portMPU_REGION_ENABLE ); ( portMPU_REGION_ENABLE );
/* By default allow everything to access the general peripherals. The /* 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_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS ) |
( portMPU_REGION_VALID ) | ( portMPU_REGION_VALID ) |
( portGENERAL_PERIPHERALS_REGION ); ( portGENERAL_PERIPHERALS_REGION );
@ -715,7 +732,7 @@ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes )
uint32_t ulRegionSize, ulReturnValue = 4; uint32_t ulRegionSize, ulReturnValue = 4;
/* 32 is the smallest region size, 31 is the largest valid value for /* 32 is the smallest region size, 31 is the largest valid value for
ulReturnValue. */ * ulReturnValue. */
for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) ) for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) )
{ {
if( ulActualSizeInBytes <= ulRegionSize ) 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 /* 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 ); 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 ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __SRAM_segment_start__; 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 __SRAM_segment_end__[];
extern uint32_t __privileged_data_start__[]; extern uint32_t __privileged_data_start__[];
extern uint32_t __privileged_data_end__[]; extern uint32_t __privileged_data_end__[];
#endif #endif /* if defined( __ARMCC_VERSION ) */
int32_t lIndex; int32_t lIndex;
uint32_t ul; uint32_t ul;
@ -799,7 +820,7 @@ uint32_t ul;
( portMPU_REGION_ENABLE ); ( portMPU_REGION_ENABLE );
/* Re-instate the privileged only RAM region as xRegion[ 0 ] will have /* 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 = xMPUSettings->xRegion[ 1 ].ulRegionBaseAddress =
( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */ ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */
( portMPU_REGION_VALID ) | ( portMPU_REGION_VALID ) |
@ -821,9 +842,9 @@ uint32_t ul;
else else
{ {
/* This function is called automatically when the task is created - in /* This function is called automatically when the task is created - in
which case the stack region parameters will be valid. At all other * 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 * times the stack parameters will not be valid and it is assumed that the
stack region has already been configured. */ * stack region has already been configured. */
if( ulStackDepth > 0 ) if( ulStackDepth > 0 )
{ {
/* Define the region that allows access to the stack. */ /* Define the region that allows access to the stack. */
@ -846,8 +867,8 @@ uint32_t ul;
if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL ) if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL )
{ {
/* Translate the generic region definition contained in /* Translate the generic region definition contained in
xRegions into the CM3 specific MPU settings that are then * xRegions into the CM3 specific MPU settings that are then
stored in xMPUSettings. */ * stored in xMPUSettings. */
xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = xMPUSettings->xRegion[ ul ].ulRegionBaseAddress =
( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) | ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) |
( portMPU_REGION_VALID ) | ( portMPU_REGION_VALID ) |
@ -888,48 +909,46 @@ uint32_t ul;
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
/* The following assertion will fail if a service routine (ISR) for /* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above * an interrupt that has been assigned a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
function. ISR safe FreeRTOS API functions must *only* be called * function. ISR safe FreeRTOS API functions must *only* be called
from interrupts that have been assigned a priority at or below * from interrupts that have been assigned a priority at or below
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Numerically low interrupt priority numbers represent logically high * Numerically low interrupt priority numbers represent logically high
interrupt priorities, therefore the priority of the interrupt must * interrupt priorities, therefore the priority of the interrupt must
be set to a value equal to or numerically *higher* than * be set to a value equal to or numerically *higher* than
configMAX_SYSCALL_INTERRUPT_PRIORITY. * configMAX_SYSCALL_INTERRUPT_PRIORITY.
*
Interrupts that use the FreeRTOS API must not be left at their * Interrupts that use the FreeRTOS API must not be left at their
default priority of zero as that is the highest possible priority, * default priority of zero as that is the highest possible priority,
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
and therefore also guaranteed to be invalid. * and therefore also guaranteed to be invalid.
*
FreeRTOS maintains separate thread and ISR API functions to ensure * FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible. * interrupt entry is as fast and simple as possible.
*
The following links provide detailed information: * The following links provide detailed information:
http://www.freertos.org/RTOS-Cortex-M3-M4.html * http://www.freertos.org/RTOS-Cortex-M3-M4.html
http://www.freertos.org/FAQHelp.html */ * http://www.freertos.org/FAQHelp.html */
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
} }
/* Priority grouping: The interrupt controller (NVIC) allows the bits /* Priority grouping: The interrupt controller (NVIC) allows the bits
that define each interrupt's priority to be split between bits that * that define each interrupt's priority to be split between bits that
define the interrupt's pre-emption priority bits and bits that define * define the interrupt's pre-emption priority bits and bits that define
the interrupt's sub-priority. For simplicity all bits must be defined * the interrupt's sub-priority. For simplicity all bits must be defined
to be pre-emption priority bits. The following assertion will fail if * to be pre-emption priority bits. The following assertion will fail if
this is not the case (if some bits represent a sub-priority). * this is not the case (if some bits represent a sub-priority).
*
If the application only uses CMSIS libraries for interrupt * If the application only uses CMSIS libraries for interrupt
configuration then the correct setting can be achieved on all Cortex-M * configuration then the correct setting can be achieved on all Cortex-M
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
scheduler. Note however that some vendor specific peripheral libraries * scheduler. Note however that some vendor specific peripheral libraries
assume a non-zero priority group setting, in which cases using a value * assume a non-zero priority group setting, in which cases using a value
of zero will result in unpredicable behaviour. */ * of zero will result in unpredicable behaviour. */
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
} }
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

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