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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

89
list.c
View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -30,8 +30,8 @@
*/
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */
* all the API functions to use the MPU wrappers. That should only be done when
* task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* Scheduler includes. */
@ -86,7 +86,8 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
/*-----------------------------------------------------------*/
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition,
TaskHandle_t * pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -99,7 +100,8 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
/*-----------------------------------------------------------*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition,
TaskHandle_t * pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -112,7 +114,12 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
/*-----------------------------------------------------------*/
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode,
const char * const pcName,
uint16_t usStackDepth,
void * pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -125,7 +132,13 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
/*-----------------------------------------------------------*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) /* FREERTOS_SYSTEM_CALL */
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint32_t ulStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
StackType_t * const puxStackBuffer,
StaticTask_t * const pxTaskBuffer ) /* FREERTOS_SYSTEM_CALL */
{
TaskHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -137,7 +150,8 @@ void vPortResetPrivilege( BaseType_t xRunningPrivileged )
#endif /* configSUPPORT_STATIC_ALLOCATION */
/*-----------------------------------------------------------*/
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const xRegions ) /* FREERTOS_SYSTEM_CALL */
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask,
const MemoryRegion_t * const xRegions ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -158,7 +172,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/
#if ( INCLUDE_vTaskDelayUntil == 1 )
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, TickType_t xTimeIncrement ) /* FREERTOS_SYSTEM_CALL */
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
TickType_t xTimeIncrement ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -206,7 +221,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/
#if ( INCLUDE_vTaskPrioritySet == 1 )
void MPU_vTaskPrioritySet( TaskHandle_t pxTask, UBaseType_t uxNewPriority ) /* FREERTOS_SYSTEM_CALL */
void MPU_vTaskPrioritySet( TaskHandle_t pxTask,
UBaseType_t uxNewPriority ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -230,14 +246,17 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 )
void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) /* FREERTOS_SYSTEM_CALL */
void MPU_vTaskGetInfo( TaskHandle_t xTask,
TaskStatus_t * pxTaskStatus,
BaseType_t xGetFreeStackSpace,
eTaskState eState ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState );
vPortResetPrivilege( xRunningPrivileged );
}
#endif
#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */
/*-----------------------------------------------------------*/
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
@ -377,7 +396,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxTagValue ) /* FREERTOS_SYSTEM_CALL */
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask,
TaskHookFunction_t pxTagValue ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -401,7 +421,9 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) /* FREERTOS_SYSTEM_CALL */
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
BaseType_t xIndex,
void * pvValue ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -412,7 +434,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
void *MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) /* FREERTOS_SYSTEM_CALL */
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
BaseType_t xIndex ) /* FREERTOS_SYSTEM_CALL */
{
void * pvReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -421,11 +444,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged );
return pvReturn;
}
#endif
#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask,
void * pvParameter ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -434,11 +458,13 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
#endif
#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t *pxTaskStatusArray, UBaseType_t uxArraySize, uint32_t *pulTotalRunTime ) /* FREERTOS_SYSTEM_CALL */
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * pxTaskStatusArray,
UBaseType_t uxArraySize,
uint32_t * pulTotalRunTime ) /* FREERTOS_SYSTEM_CALL */
{
UBaseType_t uxReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -447,7 +473,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged );
return uxReturn;
}
#endif
#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */
/*-----------------------------------------------------------*/
BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) /* FREERTOS_SYSTEM_CALL */
@ -522,7 +548,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
}
/*-----------------------------------------------------------*/
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
TickType_t * const pxTicksToWait ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -534,7 +561,11 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify,
UBaseType_t uxIndexToNotify,
uint32_t ulValue,
eNotifyAction eAction,
uint32_t * pulPreviousNotificationValue ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -543,11 +574,15 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
#endif
#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn,
uint32_t ulBitsToClearOnEntry,
uint32_t ulBitsToClearOnExit,
uint32_t * pulNotificationValue,
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -556,11 +591,13 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
#endif
#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn,
BaseType_t xClearCountOnExit,
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
{
uint32_t ulReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -569,11 +606,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged );
return ulReturn;
}
#endif
#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask,
UBaseType_t uxIndexToClear ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -582,11 +620,13 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
#endif
#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ) /* FREERTOS_SYSTEM_CALL */
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask,
UBaseType_t uxIndexToClear,
uint32_t ulBitsToClear ) /* FREERTOS_SYSTEM_CALL */
{
uint32_t ulReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -595,11 +635,13 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged );
return ulReturn;
}
#endif
#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
/*-----------------------------------------------------------*/
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize, uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */
QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength,
UBaseType_t uxItemSize,
uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */
{
QueueHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -608,11 +650,15 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
#endif
#endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */
/*-----------------------------------------------------------*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength,
const UBaseType_t uxItemSize,
uint8_t * pucQueueStorage,
StaticQueue_t * pxStaticQueue,
const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */
{
QueueHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -621,10 +667,11 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
#endif
#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
/*-----------------------------------------------------------*/
BaseType_t MPU_xQueueGenericReset( QueueHandle_t pxQueue, BaseType_t xNewQueue ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xQueueGenericReset( QueueHandle_t pxQueue,
BaseType_t xNewQueue ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -635,7 +682,10 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
}
/*-----------------------------------------------------------*/
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue,
const void * const pvItemToQueue,
TickType_t xTicksToWait,
BaseType_t xCopyPosition ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -668,7 +718,9 @@ UBaseType_t uxReturn;
}
/*-----------------------------------------------------------*/
BaseType_t MPU_xQueueReceive( QueueHandle_t pxQueue, void * const pvBuffer, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xQueueReceive( QueueHandle_t pxQueue,
void * const pvBuffer,
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
BaseType_t xReturn;
@ -679,7 +731,9 @@ BaseType_t xReturn;
}
/*-----------------------------------------------------------*/
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue,
void * const pvBuffer,
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
BaseType_t xReturn;
@ -690,7 +744,8 @@ BaseType_t xReturn;
}
/*-----------------------------------------------------------*/
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue,
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
BaseType_t xReturn;
@ -728,7 +783,8 @@ BaseType_t xReturn;
/*-----------------------------------------------------------*/
#if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType,
StaticQueue_t * pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */
{
QueueHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -737,11 +793,12 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
#endif
#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue, UBaseType_t uxInitialCount ) /* FREERTOS_SYSTEM_CALL */
QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue,
UBaseType_t uxInitialCount ) /* FREERTOS_SYSTEM_CALL */
{
QueueHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -750,12 +807,14 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
#endif
#endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount,
const UBaseType_t uxInitialCount,
StaticQueue_t * pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */
{
QueueHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -764,11 +823,12 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
#endif
#endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_RECURSIVE_MUTEXES == 1 )
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xBlockTime ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex,
TickType_t xBlockTime ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -777,7 +837,7 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
#endif
#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_RECURSIVE_MUTEXES == 1 )
@ -807,7 +867,8 @@ BaseType_t xReturn;
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */
{
QueueSetMemberHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -816,11 +877,12 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
#endif
#endif /* if ( configUSE_QUEUE_SETS == 1 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -829,11 +891,12 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
#endif
#endif /* if ( configUSE_QUEUE_SETS == 1 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -842,11 +905,12 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged );
return xReturn;
}
#endif
#endif /* if ( configUSE_QUEUE_SETS == 1 ) */
/*-----------------------------------------------------------*/
#if configQUEUE_REGISTRY_SIZE > 0
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) /* FREERTOS_SYSTEM_CALL */
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue,
const char * pcName ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -880,7 +944,7 @@ BaseType_t xReturn;
vPortResetPrivilege( xRunningPrivileged );
return pcReturn;
}
#endif
#endif /* if configQUEUE_REGISTRY_SIZE > 0 */
/*-----------------------------------------------------------*/
void MPU_vQueueDelete( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */
@ -948,7 +1012,11 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) )
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) /* FREERTOS_SYSTEM_CALL */
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction ) /* FREERTOS_SYSTEM_CALL */
{
TimerHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -958,11 +1026,16 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn;
}
#endif
#endif /* if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) )
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) /* FREERTOS_SYSTEM_CALL */
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction,
StaticTimer_t * pxTimerBuffer ) /* FREERTOS_SYSTEM_CALL */
{
TimerHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -972,7 +1045,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn;
}
#endif
#endif /* if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_TIMERS == 1 )
@ -986,11 +1059,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return pvReturn;
}
#endif
#endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_TIMERS == 1 )
void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) /* FREERTOS_SYSTEM_CALL */
void MPU_vTimerSetTimerID( TimerHandle_t xTimer,
void * pvNewID ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1011,7 +1085,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn;
}
#endif
#endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_TIMERS == 1 )
@ -1025,11 +1099,14 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn;
}
#endif
#endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/
#if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
void * pvParameter1,
uint32_t ulParameter2,
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1039,11 +1116,12 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn;
}
#endif
#endif /* if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_TIMERS == 1 )
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer,
const UBaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1077,7 +1155,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return pcReturn;
}
#endif
#endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_TIMERS == 1 )
@ -1091,7 +1169,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn;
}
#endif
#endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_TIMERS == 1 )
@ -1105,11 +1183,15 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn;
}
#endif
#endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/
#if ( configUSE_TIMERS == 1 )
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer,
const BaseType_t xCommandID,
const TickType_t xOptionalValue,
BaseType_t * const pxHigherPriorityTaskWoken,
const TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1119,7 +1201,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn;
}
#endif
#endif /* if ( configUSE_TIMERS == 1 ) */
/*-----------------------------------------------------------*/
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
@ -1133,7 +1215,7 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn;
}
#endif
#endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */
/*-----------------------------------------------------------*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
@ -1147,10 +1229,14 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
return xReturn;
}
#endif
#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
/*-----------------------------------------------------------*/
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
{
EventBits_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1162,7 +1248,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
}
/*-----------------------------------------------------------*/
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) /* FREERTOS_SYSTEM_CALL */
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear ) /* FREERTOS_SYSTEM_CALL */
{
EventBits_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1174,7 +1261,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
}
/*-----------------------------------------------------------*/
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) /* FREERTOS_SYSTEM_CALL */
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet ) /* FREERTOS_SYSTEM_CALL */
{
EventBits_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1186,7 +1274,10 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
}
/*-----------------------------------------------------------*/
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
{
EventBits_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1207,7 +1298,10 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
}
/*-----------------------------------------------------------*/
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
const void * pvTxData,
size_t xDataLengthBytes,
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
{
size_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1231,7 +1325,10 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
}
/*-----------------------------------------------------------*/
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
void * pvRxData,
size_t xBufferLengthBytes,
TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */
{
size_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1312,7 +1409,8 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
}
/*-----------------------------------------------------------*/
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) /* FREERTOS_SYSTEM_CALL */
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
size_t xTriggerLevel ) /* FREERTOS_SYSTEM_CALL */
{
BaseType_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1325,7 +1423,9 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) /* FREERTOS_SYSTEM_CALL */
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes,
BaseType_t xIsMessageBuffer ) /* FREERTOS_SYSTEM_CALL */
{
StreamBufferHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1339,7 +1439,11 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/*-----------------------------------------------------------*/
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) /* FREERTOS_SYSTEM_CALL */
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes,
BaseType_t xIsMessageBuffer,
uint8_t * const pucStreamBufferStorageArea,
StaticStreamBuffer_t * const pxStaticStreamBuffer ) /* FREERTOS_SYSTEM_CALL */
{
StreamBufferHandle_t xReturn;
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
@ -1354,18 +1458,18 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
/* Functions that the application writer wants to execute in privileged mode
can be defined in application_defined_privileged_functions.h. The functions
must take the same format as those above whereby the privilege state on exit
equals the privilege state on entry. For example:
void MPU_FunctionName( [parameters ] )
{
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
FunctionName( [parameters ] );
vPortResetPrivilege( xRunningPrivileged );
}
* can be defined in application_defined_privileged_functions.h. The functions
* must take the same format as those above whereby the privilege state on exit
* equals the privilege state on entry. For example:
*
* void MPU_FunctionName( [parameters ] )
* {
* BaseType_t xRunningPrivileged = xPortRaisePrivilege();
*
* FunctionName( [parameters ] );
*
* vPortResetPrivilege( xRunningPrivileged );
* }
*/
#if configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS == 1

View file

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

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

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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

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

File diff suppressed because it is too large Load diff

View file

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

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

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

View file

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

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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