mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Kernel optimisations.
This commit is contained in:
parent
c9d9bddc3c
commit
ad8fa53043
|
@ -104,6 +104,38 @@
|
||||||
#ifndef LIST_H
|
#ifndef LIST_H
|
||||||
#define LIST_H
|
#define LIST_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The list structure members are modified from within interrupts, and therefore
|
||||||
|
* by rights should be declared volatile. However, they are only modified in a
|
||||||
|
* functionally atomic way (within critical sections of with the scheduler
|
||||||
|
* suspended) and are either passed by reference into a function or indexed via
|
||||||
|
* a volatile variable. Therefore, in all use cases tested so far, the volatile
|
||||||
|
* qualifier can be omitted in order to provide a moderate performance
|
||||||
|
* improvement without adversely affecting functional behaviour. The assembly
|
||||||
|
* instructions generated by the IAR, ARM and GCC compilers when the respective
|
||||||
|
* compiler's options were set for maximum optimisation has been inspected and
|
||||||
|
* deemed to be as intended. That said, as compiler technology advances, and
|
||||||
|
* especially if aggressive cross module optimisation is used (a use case that
|
||||||
|
* has not been exercised to any great extend) then it is feasible that the
|
||||||
|
* volatile qualifier will be needed for correct optimisation. It is expected
|
||||||
|
* that a compiler removing essential code because, without the volatile
|
||||||
|
* qualifier on the list structure members and with aggressive cross module
|
||||||
|
* optimisation, the compiler deemed the code unnecessary will result in
|
||||||
|
* complete and obvious failure of the scheduler. If this is ever experienced
|
||||||
|
* then the volatile qualifier can be inserted in the relevant places within the
|
||||||
|
* list structures by simply defining configLIST_VOLATILE to volatile in
|
||||||
|
* FreeRTOSConfig.h (as per the example at the bottom of this comment block).
|
||||||
|
* If configLIST_VOLATILE is not defined then the preprocessor directives below
|
||||||
|
* will simply #define configLIST_VOLATILE away completely.
|
||||||
|
*
|
||||||
|
* To use volatile list structure members then add the following line to
|
||||||
|
* FreeRTOSConfig.h (without the quotes):
|
||||||
|
* "#define configLIST_VOLATILE volatile"
|
||||||
|
*/
|
||||||
|
#ifndef configLIST_VOLATILE
|
||||||
|
#define configLIST_VOLATILE
|
||||||
|
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -112,19 +144,19 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
struct xLIST_ITEM
|
struct xLIST_ITEM
|
||||||
{
|
{
|
||||||
portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
configLIST_VOLATILE portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
||||||
volatile struct xLIST_ITEM * pxNext; /*< Pointer to the next xListItem in the list. */
|
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next xListItem in the list. */
|
||||||
volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */
|
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;/*< Pointer to the previous xListItem in the list. */
|
||||||
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
||||||
void * pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
||||||
};
|
};
|
||||||
typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */
|
typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */
|
||||||
|
|
||||||
struct xMINI_LIST_ITEM
|
struct xMINI_LIST_ITEM
|
||||||
{
|
{
|
||||||
portTickType xItemValue;
|
configLIST_VOLATILE portTickType xItemValue;
|
||||||
volatile struct xLIST_ITEM *pxNext;
|
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
|
||||||
volatile struct xLIST_ITEM *pxPrevious;
|
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
|
||||||
};
|
};
|
||||||
typedef struct xMINI_LIST_ITEM xMiniListItem;
|
typedef struct xMINI_LIST_ITEM xMiniListItem;
|
||||||
|
|
||||||
|
@ -133,9 +165,9 @@ typedef struct xMINI_LIST_ITEM xMiniListItem;
|
||||||
*/
|
*/
|
||||||
typedef struct xLIST
|
typedef struct xLIST
|
||||||
{
|
{
|
||||||
volatile unsigned portBASE_TYPE uxNumberOfItems;
|
configLIST_VOLATILE unsigned portBASE_TYPE uxNumberOfItems;
|
||||||
volatile xListItem * pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
|
xListItem * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
|
||||||
volatile xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
||||||
} xList;
|
} xList;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -286,7 +318,7 @@ xList * const pxConstList = ( pxList ); \
|
||||||
* \page vListInitialise vListInitialise
|
* \page vListInitialise vListInitialise
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInitialise( xList *pxList );
|
void vListInitialise( xList * const pxList );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Must be called before a list item is used. This sets the list container to
|
* Must be called before a list item is used. This sets the list container to
|
||||||
|
@ -297,7 +329,7 @@ void vListInitialise( xList *pxList );
|
||||||
* \page vListInitialiseItem vListInitialiseItem
|
* \page vListInitialiseItem vListInitialiseItem
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInitialiseItem( xListItem *pxItem );
|
void vListInitialiseItem( xListItem * const pxItem );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a list item into a list. The item will be inserted into the list in
|
* Insert a list item into a list. The item will be inserted into the list in
|
||||||
|
@ -310,7 +342,7 @@ void vListInitialiseItem( xListItem *pxItem );
|
||||||
* \page vListInsert vListInsert
|
* \page vListInsert vListInsert
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInsert( xList *pxList, xListItem *pxNewListItem );
|
void vListInsert( xList * const pxList, xListItem * const pxNewListItem );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a list item into a list. The item will be inserted in a position
|
* Insert a list item into a list. The item will be inserted in a position
|
||||||
|
@ -331,7 +363,7 @@ void vListInsert( xList *pxList, xListItem *pxNewListItem );
|
||||||
* \page vListInsertEnd vListInsertEnd
|
* \page vListInsertEnd vListInsertEnd
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );
|
void vListInsertEnd( xList * const pxList, xListItem * const pxNewListItem );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove an item from a list. The list item has a pointer to the list that
|
* Remove an item from a list. The list item has a pointer to the list that
|
||||||
|
@ -346,7 +378,7 @@ void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );
|
||||||
* \page uxListRemove uxListRemove
|
* \page uxListRemove uxListRemove
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
unsigned portBASE_TYPE uxListRemove( xListItem *pxItemToRemove );
|
unsigned portBASE_TYPE uxListRemove( xListItem * const pxItemToRemove );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
* PUBLIC LIST API documented in list.h
|
* PUBLIC LIST API documented in list.h
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInitialise( xList *pxList )
|
void vListInitialise( xList * const pxList )
|
||||||
{
|
{
|
||||||
/* The list structure contains a list item which is used to mark the
|
/* The list structure contains a list item which is used to mark the
|
||||||
end of the list. To initialise the list the list end is inserted
|
end of the list. To initialise the list the list end is inserted
|
||||||
|
@ -101,16 +101,16 @@ void vListInitialise( xList *pxList )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInitialiseItem( xListItem *pxItem )
|
void vListInitialiseItem( xListItem * const pxItem )
|
||||||
{
|
{
|
||||||
/* Make sure the list item is not recorded as being on a list. */
|
/* Make sure the list item is not recorded as being on a list. */
|
||||||
pxItem->pvContainer = NULL;
|
pxItem->pvContainer = NULL;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem )
|
void vListInsertEnd( xList * const pxList, xListItem * const pxNewListItem )
|
||||||
{
|
{
|
||||||
volatile xListItem * pxIndex;
|
xListItem * pxIndex;
|
||||||
|
|
||||||
/* Insert a new list item into pxList, but rather than sort the list,
|
/* Insert a new list item into pxList, but rather than sort the list,
|
||||||
makes the new list item the last item to be removed by a call to
|
makes the new list item the last item to be removed by a call to
|
||||||
|
@ -119,8 +119,8 @@ volatile xListItem * pxIndex;
|
||||||
|
|
||||||
pxNewListItem->pxNext = pxIndex;
|
pxNewListItem->pxNext = pxIndex;
|
||||||
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
||||||
pxIndex->pxPrevious->pxNext = ( volatile xListItem * ) pxNewListItem;
|
pxIndex->pxPrevious->pxNext = pxNewListItem;
|
||||||
pxIndex->pxPrevious = ( volatile xListItem * ) pxNewListItem;
|
pxIndex->pxPrevious = pxNewListItem;
|
||||||
|
|
||||||
/* Remember which list the item is in. */
|
/* Remember which list the item is in. */
|
||||||
pxNewListItem->pvContainer = ( void * ) pxList;
|
pxNewListItem->pvContainer = ( void * ) pxList;
|
||||||
|
@ -129,9 +129,9 @@ volatile xListItem * pxIndex;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInsert( xList *pxList, xListItem *pxNewListItem )
|
void vListInsert( xList * const pxList, xListItem * const pxNewListItem )
|
||||||
{
|
{
|
||||||
volatile xListItem *pxIterator;
|
xListItem *pxIterator;
|
||||||
portTickType xValueOfInsertion;
|
portTickType xValueOfInsertion;
|
||||||
|
|
||||||
/* Insert the new list item into the list, sorted in ulListItem order. */
|
/* Insert the new list item into the list, sorted in ulListItem order. */
|
||||||
|
@ -175,9 +175,9 @@ portTickType xValueOfInsertion;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxNewListItem->pxNext = pxIterator->pxNext;
|
pxNewListItem->pxNext = pxIterator->pxNext;
|
||||||
pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
|
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
|
||||||
pxNewListItem->pxPrevious = pxIterator;
|
pxNewListItem->pxPrevious = pxIterator;
|
||||||
pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem;
|
pxIterator->pxNext = pxNewListItem;
|
||||||
|
|
||||||
/* Remember which list the item is in. This allows fast removal of the
|
/* Remember which list the item is in. This allows fast removal of the
|
||||||
item later. */
|
item later. */
|
||||||
|
@ -187,7 +187,7 @@ portTickType xValueOfInsertion;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
unsigned portBASE_TYPE uxListRemove( xListItem *pxItemToRemove )
|
unsigned portBASE_TYPE uxListRemove( xListItem * const pxItemToRemove )
|
||||||
{
|
{
|
||||||
xList * pxList;
|
xList * pxList;
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
#include <intrinsics.h>
|
#include <intrinsics.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
|
@ -185,15 +185,21 @@
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif
|
#endif /* configASSERT */
|
||||||
|
|
||||||
#define portNOP() __asm volatile( "NOP" )
|
#define portNOP() __asm volatile( "NOP" )
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
} /* extern C */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Suppress warnings that are generated by the IAR tools, but cannot be
|
||||||
|
fixed in the source code because to do so would cause other compilers to
|
||||||
|
generate warnings. */
|
||||||
|
#pragma diag_suppress=Pe191
|
||||||
|
#pragma diag_suppress=Pa082
|
||||||
|
|
||||||
#endif /* __ICCARM__ */
|
#endif /* __ICCARM__ */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -245,9 +245,8 @@ static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
|
||||||
|
|
||||||
portBASE_TYPE xQueueGenericReset( xQueueHandle xQueue, portBASE_TYPE xNewQueue )
|
portBASE_TYPE xQueueGenericReset( xQueueHandle xQueue, portBASE_TYPE xNewQueue )
|
||||||
{
|
{
|
||||||
xQUEUE *pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
|
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
|
@ -447,9 +446,8 @@ xQueueHandle xReturn = NULL;
|
||||||
portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex )
|
portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex )
|
||||||
{
|
{
|
||||||
portBASE_TYPE xReturn;
|
portBASE_TYPE xReturn;
|
||||||
xQUEUE *pxMutex;
|
xQUEUE * const pxMutex = ( xQUEUE * ) xMutex;
|
||||||
|
|
||||||
pxMutex = ( xQUEUE * ) xMutex;
|
|
||||||
configASSERT( pxMutex );
|
configASSERT( pxMutex );
|
||||||
|
|
||||||
/* If this is the task that holds the mutex then pxMutexHolder will not
|
/* If this is the task that holds the mutex then pxMutexHolder will not
|
||||||
|
@ -498,9 +496,8 @@ xQueueHandle xReturn = NULL;
|
||||||
portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime )
|
portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime )
|
||||||
{
|
{
|
||||||
portBASE_TYPE xReturn;
|
portBASE_TYPE xReturn;
|
||||||
xQUEUE *pxMutex;
|
xQUEUE * const pxMutex = ( xQUEUE * ) xMutex;
|
||||||
|
|
||||||
pxMutex = ( xQUEUE * ) xMutex;
|
|
||||||
configASSERT( pxMutex );
|
configASSERT( pxMutex );
|
||||||
|
|
||||||
/* Comments regarding mutual exclusion as per those within
|
/* Comments regarding mutual exclusion as per those within
|
||||||
|
@ -565,9 +562,8 @@ signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
|
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
|
||||||
xTimeOutType xTimeOut;
|
xTimeOutType xTimeOut;
|
||||||
xQUEUE *pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
||||||
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
|
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
|
||||||
|
@ -724,9 +720,8 @@ xQUEUE *pxQueue;
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
|
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
|
||||||
xTimeOutType xTimeOut;
|
xTimeOutType xTimeOut;
|
||||||
xQUEUE *pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
||||||
|
|
||||||
|
@ -804,9 +799,8 @@ xQUEUE *pxQueue;
|
||||||
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
|
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
|
||||||
xTimeOutType xTimeOut;
|
xTimeOutType xTimeOut;
|
||||||
signed char *pcOriginalReadPosition;
|
signed char *pcOriginalReadPosition;
|
||||||
xQUEUE *pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
||||||
|
|
||||||
|
@ -825,7 +819,7 @@ xQUEUE *pxQueue;
|
||||||
{
|
{
|
||||||
traceQUEUE_RECEIVE( pxQueue );
|
traceQUEUE_RECEIVE( pxQueue );
|
||||||
|
|
||||||
/* We are actually removing data. */
|
/* Data is actually being removed (not just peeked). */
|
||||||
--( pxQueue->uxMessagesWaiting );
|
--( pxQueue->uxMessagesWaiting );
|
||||||
|
|
||||||
#if ( configUSE_MUTEXES == 1 )
|
#if ( configUSE_MUTEXES == 1 )
|
||||||
|
@ -934,9 +928,8 @@ signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle xQueue, const void *
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xReturn;
|
signed portBASE_TYPE xReturn;
|
||||||
unsigned portBASE_TYPE uxSavedInterruptStatus;
|
unsigned portBASE_TYPE uxSavedInterruptStatus;
|
||||||
xQUEUE *pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
||||||
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
|
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
|
||||||
|
@ -1048,9 +1041,8 @@ signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, void * const pvB
|
||||||
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
|
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
|
||||||
xTimeOutType xTimeOut;
|
xTimeOutType xTimeOut;
|
||||||
signed char *pcOriginalReadPosition;
|
signed char *pcOriginalReadPosition;
|
||||||
xQUEUE *pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
||||||
|
|
||||||
|
@ -1199,9 +1191,8 @@ signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle xQueue, void * const pvB
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xReturn;
|
signed portBASE_TYPE xReturn;
|
||||||
unsigned portBASE_TYPE uxSavedInterruptStatus;
|
unsigned portBASE_TYPE uxSavedInterruptStatus;
|
||||||
xQUEUE *pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
||||||
|
|
||||||
|
@ -1276,9 +1267,8 @@ signed portBASE_TYPE xQueuePeekFromISR( xQueueHandle xQueue, void * const pvBuff
|
||||||
signed portBASE_TYPE xReturn;
|
signed portBASE_TYPE xReturn;
|
||||||
unsigned portBASE_TYPE uxSavedInterruptStatus;
|
unsigned portBASE_TYPE uxSavedInterruptStatus;
|
||||||
signed char *pcOriginalReadPosition;
|
signed char *pcOriginalReadPosition;
|
||||||
xQUEUE *pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
|
||||||
|
|
||||||
|
@ -1353,9 +1343,8 @@ unsigned portBASE_TYPE uxReturn;
|
||||||
|
|
||||||
void vQueueDelete( xQueueHandle xQueue )
|
void vQueueDelete( xQueueHandle xQueue )
|
||||||
{
|
{
|
||||||
xQUEUE *pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
|
|
||||||
traceQUEUE_DELETE( pxQueue );
|
traceQUEUE_DELETE( pxQueue );
|
||||||
|
@ -1645,9 +1634,7 @@ signed portBASE_TYPE xReturn;
|
||||||
signed portBASE_TYPE xQueueCRSend( xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait )
|
signed portBASE_TYPE xQueueCRSend( xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait )
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xReturn;
|
signed portBASE_TYPE xReturn;
|
||||||
xQUEUE *pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
|
|
||||||
/* If the queue is already full we may have to block. A critical section
|
/* If the queue is already full we may have to block. A critical section
|
||||||
is required to prevent an interrupt removing something from the queue
|
is required to prevent an interrupt removing something from the queue
|
||||||
|
@ -1716,9 +1703,7 @@ signed portBASE_TYPE xReturn;
|
||||||
signed portBASE_TYPE xQueueCRReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait )
|
signed portBASE_TYPE xQueueCRReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait )
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xReturn;
|
signed portBASE_TYPE xReturn;
|
||||||
xQUEUE *pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
|
|
||||||
/* If the queue is already empty we may have to block. A critical section
|
/* If the queue is already empty we may have to block. A critical section
|
||||||
is required to prevent an interrupt adding something to the queue
|
is required to prevent an interrupt adding something to the queue
|
||||||
|
@ -1791,9 +1776,7 @@ signed portBASE_TYPE xReturn;
|
||||||
|
|
||||||
signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle xQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )
|
signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle xQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )
|
||||||
{
|
{
|
||||||
xQUEUE *pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
|
|
||||||
/* Cannot block within an ISR so if there is no space on the queue then
|
/* Cannot block within an ISR so if there is no space on the queue then
|
||||||
exit without doing anything. */
|
exit without doing anything. */
|
||||||
|
@ -1826,9 +1809,7 @@ signed portBASE_TYPE xReturn;
|
||||||
signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle xQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )
|
signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle xQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xReturn;
|
signed portBASE_TYPE xReturn;
|
||||||
xQUEUE * pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
|
|
||||||
/* We cannot block from an ISR, so check there is data available. If
|
/* We cannot block from an ISR, so check there is data available. If
|
||||||
not then just leave without doing anything. */
|
not then just leave without doing anything. */
|
||||||
|
@ -1917,9 +1898,7 @@ signed portBASE_TYPE xReturn;
|
||||||
|
|
||||||
void vQueueWaitForMessageRestricted( xQueueHandle xQueue, portTickType xTicksToWait )
|
void vQueueWaitForMessageRestricted( xQueueHandle xQueue, portTickType xTicksToWait )
|
||||||
{
|
{
|
||||||
xQUEUE *pxQueue;
|
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
|
||||||
|
|
||||||
pxQueue = ( xQUEUE * ) xQueue;
|
|
||||||
|
|
||||||
/* This function should not be called by application code hence the
|
/* This function should not be called by application code hence the
|
||||||
'Restricted' in its name. It is not part of the public API. It is
|
'Restricted' in its name. It is not part of the public API. It is
|
||||||
|
@ -1999,9 +1978,7 @@ signed portBASE_TYPE xReturn;
|
||||||
portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
|
portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
|
||||||
{
|
{
|
||||||
portBASE_TYPE xReturn;
|
portBASE_TYPE xReturn;
|
||||||
xQUEUE *pxQueueOrSemaphore;
|
xQUEUE * const pxQueueOrSemaphore = ( xQUEUE * ) xQueueOrSemaphore;
|
||||||
|
|
||||||
pxQueueOrSemaphore = ( xQUEUE * ) xQueueOrSemaphore;
|
|
||||||
|
|
||||||
if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet )
|
if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet )
|
||||||
{
|
{
|
||||||
|
|
|
@ -201,12 +201,11 @@ PRIVILEGED_DATA static xList xPendingReadyList; /*< Tasks that have been r
|
||||||
/* File private variables. --------------------------------*/
|
/* File private variables. --------------------------------*/
|
||||||
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0U;
|
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0U;
|
||||||
PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType ) 0U;
|
PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType ) 0U;
|
||||||
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY;
|
|
||||||
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY;
|
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY;
|
||||||
PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE;
|
PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE;
|
||||||
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE;
|
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE;
|
||||||
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxPendedTicks = ( unsigned portBASE_TYPE ) 0U;
|
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxPendedTicks = ( unsigned portBASE_TYPE ) 0U;
|
||||||
PRIVILEGED_DATA static volatile portBASE_TYPE xYieldPending = ( portBASE_TYPE ) pdFALSE;
|
PRIVILEGED_DATA static volatile portBASE_TYPE xYieldPending = ( portBASE_TYPE ) pdFALSE;
|
||||||
PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;
|
PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;
|
||||||
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0U;
|
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0U;
|
||||||
PRIVILEGED_DATA static volatile portTickType xNextTaskUnblockTime = ( portTickType ) portMAX_DELAY;
|
PRIVILEGED_DATA static volatile portTickType xNextTaskUnblockTime = ( portTickType ) portMAX_DELAY;
|
||||||
|
@ -214,7 +213,7 @@ PRIVILEGED_DATA static volatile portTickType xNextTaskUnblockTime = ( portTic
|
||||||
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
||||||
|
|
||||||
PRIVILEGED_DATA static unsigned long ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
|
PRIVILEGED_DATA static unsigned long ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
|
||||||
PRIVILEGED_DATA static unsigned long ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */
|
PRIVILEGED_DATA static unsigned long ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -587,13 +586,6 @@ tskTCB * pxNewTCB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember the top priority to make context switching faster. Use
|
|
||||||
the priority in pxNewTCB as this has been capped to a valid value. */
|
|
||||||
if( pxNewTCB->uxPriority > uxTopUsedPriority )
|
|
||||||
{
|
|
||||||
uxTopUsedPriority = pxNewTCB->uxPriority;
|
|
||||||
}
|
|
||||||
|
|
||||||
uxTaskNumber++;
|
uxTaskNumber++;
|
||||||
|
|
||||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
@ -662,7 +654,7 @@ tskTCB * pxNewTCB;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is the task waiting on an event also? */
|
/* Is the task waiting on an event also? */
|
||||||
if( pxTCB->xEventListItem.pvContainer != NULL )
|
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
|
||||||
{
|
{
|
||||||
uxListRemove( &( pxTCB->xEventListItem ) );
|
uxListRemove( &( pxTCB->xEventListItem ) );
|
||||||
}
|
}
|
||||||
|
@ -707,17 +699,21 @@ tskTCB * pxNewTCB;
|
||||||
|
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
{
|
{
|
||||||
|
/* Minor optimisation. The tick count cannot change in this
|
||||||
|
block. */
|
||||||
|
const portTickType xConstTickCount = xTickCount;
|
||||||
|
|
||||||
/* Generate the tick time at which the task wants to wake. */
|
/* Generate the tick time at which the task wants to wake. */
|
||||||
xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
|
xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
|
||||||
|
|
||||||
if( xTickCount < *pxPreviousWakeTime )
|
if( xConstTickCount < *pxPreviousWakeTime )
|
||||||
{
|
{
|
||||||
/* The tick count has overflowed since this function was
|
/* The tick count has overflowed since this function was
|
||||||
lasted called. In this case the only time we should ever
|
lasted called. In this case the only time we should ever
|
||||||
actually delay is if the wake time has also overflowed,
|
actually delay is if the wake time has also overflowed,
|
||||||
and the wake time is greater than the tick time. When this
|
and the wake time is greater than the tick time. When this
|
||||||
is the case it is as if neither time had overflowed. */
|
is the case it is as if neither time had overflowed. */
|
||||||
if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xTickCount ) )
|
if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) )
|
||||||
{
|
{
|
||||||
xShouldDelay = pdTRUE;
|
xShouldDelay = pdTRUE;
|
||||||
}
|
}
|
||||||
|
@ -727,7 +723,7 @@ tskTCB * pxNewTCB;
|
||||||
/* The tick time has not overflowed. In this case we will
|
/* The tick time has not overflowed. In this case we will
|
||||||
delay if either the wake time has overflowed, and/or the
|
delay if either the wake time has overflowed, and/or the
|
||||||
tick time is less than the wake time. */
|
tick time is less than the wake time. */
|
||||||
if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xTickCount ) )
|
if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) )
|
||||||
{
|
{
|
||||||
xShouldDelay = pdTRUE;
|
xShouldDelay = pdTRUE;
|
||||||
}
|
}
|
||||||
|
@ -825,9 +821,7 @@ tskTCB * pxNewTCB;
|
||||||
{
|
{
|
||||||
eTaskState eReturn;
|
eTaskState eReturn;
|
||||||
xList *pxStateList;
|
xList *pxStateList;
|
||||||
tskTCB *pxTCB;
|
const tskTCB * const pxTCB = ( tskTCB * ) xTask;
|
||||||
|
|
||||||
pxTCB = ( tskTCB * ) xTask;
|
|
||||||
|
|
||||||
if( pxTCB == pxCurrentTCB )
|
if( pxTCB == pxCurrentTCB )
|
||||||
{
|
{
|
||||||
|
@ -1048,7 +1042,7 @@ tskTCB * pxNewTCB;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is the task waiting on an event also? */
|
/* Is the task waiting on an event also? */
|
||||||
if( pxTCB->xEventListItem.pvContainer != NULL )
|
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
|
||||||
{
|
{
|
||||||
uxListRemove( &( pxTCB->xEventListItem ) );
|
uxListRemove( &( pxTCB->xEventListItem ) );
|
||||||
}
|
}
|
||||||
|
@ -1126,15 +1120,11 @@ tskTCB * pxNewTCB;
|
||||||
|
|
||||||
void vTaskResume( xTaskHandle xTaskToResume )
|
void vTaskResume( xTaskHandle xTaskToResume )
|
||||||
{
|
{
|
||||||
tskTCB *pxTCB;
|
tskTCB * const pxTCB = ( tskTCB * ) xTaskToResume;
|
||||||
|
|
||||||
/* It does not make sense to resume the calling task. */
|
/* It does not make sense to resume the calling task. */
|
||||||
configASSERT( xTaskToResume );
|
configASSERT( xTaskToResume );
|
||||||
|
|
||||||
/* Remove the task from whichever list it is currently in, and place
|
|
||||||
it in the ready list. */
|
|
||||||
pxTCB = ( tskTCB * ) xTaskToResume;
|
|
||||||
|
|
||||||
/* The parameter cannot be NULL as it is impossible to resume the
|
/* The parameter cannot be NULL as it is impossible to resume the
|
||||||
currently executing task. */
|
currently executing task. */
|
||||||
if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )
|
if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )
|
||||||
|
@ -1172,7 +1162,7 @@ tskTCB * pxNewTCB;
|
||||||
portBASE_TYPE xTaskResumeFromISR( xTaskHandle xTaskToResume )
|
portBASE_TYPE xTaskResumeFromISR( xTaskHandle xTaskToResume )
|
||||||
{
|
{
|
||||||
portBASE_TYPE xYieldRequired = pdFALSE;
|
portBASE_TYPE xYieldRequired = pdFALSE;
|
||||||
tskTCB *pxTCB;
|
tskTCB * const pxTCB = ( tskTCB * ) xTaskToResume;
|
||||||
unsigned portBASE_TYPE uxSavedInterruptStatus;
|
unsigned portBASE_TYPE uxSavedInterruptStatus;
|
||||||
|
|
||||||
configASSERT( xTaskToResume );
|
configASSERT( xTaskToResume );
|
||||||
|
@ -1195,8 +1185,6 @@ tskTCB * pxNewTCB;
|
||||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html */
|
http://www.freertos.org/RTOS-Cortex-M3-M4.html */
|
||||||
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
|
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
|
||||||
|
|
||||||
pxTCB = ( tskTCB * ) xTaskToResume;
|
|
||||||
|
|
||||||
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )
|
if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )
|
||||||
|
@ -1522,11 +1510,17 @@ unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )
|
||||||
|
|
||||||
#if ( configGENERATE_RUN_TIME_STATS == 1)
|
#if ( configGENERATE_RUN_TIME_STATS == 1)
|
||||||
{
|
{
|
||||||
*pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
|
if( pulTotalRunTime != NULL )
|
||||||
|
{
|
||||||
|
*pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
*pulTotalRunTime = 0;
|
if( pulTotalRunTime != NULL )
|
||||||
|
{
|
||||||
|
*pulTotalRunTime = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1585,75 +1579,82 @@ portBASE_TYPE xSwitchRequired = pdFALSE;
|
||||||
/* Increment the RTOS tick, switching the delayed and overflowed
|
/* Increment the RTOS tick, switching the delayed and overflowed
|
||||||
delayed lists if it wraps to 0. */
|
delayed lists if it wraps to 0. */
|
||||||
++xTickCount;
|
++xTickCount;
|
||||||
if( xTickCount == ( portTickType ) 0U )
|
|
||||||
{
|
|
||||||
taskSWITCH_DELAYED_LISTS();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See if this tick has made a timeout expire. Tasks are stored in the
|
|
||||||
queue in the order of their wake time - meaning once one tasks has been
|
|
||||||
found whose block time has not expired there is no need not look any
|
|
||||||
further down the list. */
|
|
||||||
if( xTickCount >= xNextTaskUnblockTime )
|
|
||||||
{
|
{
|
||||||
for( ;; )
|
/* Minor optimisation. The tick count cannot change in this
|
||||||
|
block. */
|
||||||
|
const portTickType xConstTickCount = xTickCount;
|
||||||
|
|
||||||
|
if( xConstTickCount == ( portTickType ) 0U )
|
||||||
{
|
{
|
||||||
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
|
taskSWITCH_DELAYED_LISTS();
|
||||||
{
|
}
|
||||||
/* The delayed list is empty. Set xNextTaskUnblockTime to
|
|
||||||
the maximum possible value so it is extremely unlikely that
|
|
||||||
the if( xTickCount >= xNextTaskUnblockTime ) test will pass
|
|
||||||
next time through. */
|
|
||||||
xNextTaskUnblockTime = portMAX_DELAY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* The delayed list is not empty, get the value of the item
|
|
||||||
at the head of the delayed list. This is the time at which
|
|
||||||
the task at the head of the delayed list must be removed
|
|
||||||
from the Blocked state. */
|
|
||||||
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
|
|
||||||
xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );
|
|
||||||
|
|
||||||
if( xTickCount < xItemValue )
|
/* See if this tick has made a timeout expire. Tasks are stored in the
|
||||||
|
queue in the order of their wake time - meaning once one tasks has been
|
||||||
|
found whose block time has not expired there is no need not look any
|
||||||
|
further down the list. */
|
||||||
|
if( xConstTickCount >= xNextTaskUnblockTime )
|
||||||
|
{
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
|
||||||
{
|
{
|
||||||
/* It is not time to unblock this item yet, but the item
|
/* The delayed list is empty. Set xNextTaskUnblockTime to
|
||||||
value is the time at which the task at the head of the
|
the maximum possible value so it is extremely unlikely that
|
||||||
blocked list must be removed from the Blocked state -
|
the if( xTickCount >= xNextTaskUnblockTime ) test will pass
|
||||||
so record the item value in xNextTaskUnblockTime. */
|
next time through. */
|
||||||
xNextTaskUnblockTime = xItemValue;
|
xNextTaskUnblockTime = portMAX_DELAY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* It is time to remove the item from the Blocked state. */
|
|
||||||
uxListRemove( &( pxTCB->xGenericListItem ) );
|
|
||||||
|
|
||||||
/* Is the task waiting on an event also? If so remove it
|
|
||||||
from the event list. */
|
|
||||||
if( pxTCB->xEventListItem.pvContainer != NULL )
|
|
||||||
{
|
{
|
||||||
uxListRemove( &( pxTCB->xEventListItem ) );
|
/* The delayed list is not empty, get the value of the item
|
||||||
}
|
at the head of the delayed list. This is the time at which
|
||||||
|
the task at the head of the delayed list must be removed
|
||||||
|
from the Blocked state. */
|
||||||
|
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
|
||||||
|
xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );
|
||||||
|
|
||||||
/* Place the unblocked task into the appropriate ready
|
if( xConstTickCount < xItemValue )
|
||||||
list. */
|
|
||||||
prvAddTaskToReadyList( pxTCB );
|
|
||||||
|
|
||||||
/* A task being unblocked cannot cause an immediate context
|
|
||||||
switch if preemption is turned off. */
|
|
||||||
#if ( configUSE_PREEMPTION == 1 )
|
|
||||||
{
|
|
||||||
/* Preemption is on, but a context switch should only
|
|
||||||
be performed if the unblocked task has a priority that
|
|
||||||
is equal to or higher than the currently executing
|
|
||||||
task. */
|
|
||||||
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
|
|
||||||
{
|
{
|
||||||
xSwitchRequired = pdTRUE;
|
/* It is not time to unblock this item yet, but the item
|
||||||
|
value is the time at which the task at the head of the
|
||||||
|
blocked list must be removed from the Blocked state -
|
||||||
|
so record the item value in xNextTaskUnblockTime. */
|
||||||
|
xNextTaskUnblockTime = xItemValue;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* It is time to remove the item from the Blocked state. */
|
||||||
|
uxListRemove( &( pxTCB->xGenericListItem ) );
|
||||||
|
|
||||||
|
/* Is the task waiting on an event also? If so remove it
|
||||||
|
from the event list. */
|
||||||
|
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
|
||||||
|
{
|
||||||
|
uxListRemove( &( pxTCB->xEventListItem ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Place the unblocked task into the appropriate ready
|
||||||
|
list. */
|
||||||
|
prvAddTaskToReadyList( pxTCB );
|
||||||
|
|
||||||
|
/* A task being unblocked cannot cause an immediate context
|
||||||
|
switch if preemption is turned off. */
|
||||||
|
#if ( configUSE_PREEMPTION == 1 )
|
||||||
|
{
|
||||||
|
/* Preemption is on, but a context switch should only
|
||||||
|
be performed if the unblocked task has a priority that
|
||||||
|
is equal to or higher than the currently executing
|
||||||
|
task. */
|
||||||
|
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
|
||||||
|
{
|
||||||
|
xSwitchRequired = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* configUSE_PREEMPTION */
|
||||||
}
|
}
|
||||||
#endif /* configUSE_PREEMPTION */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1999,6 +2000,9 @@ portBASE_TYPE xReturn;
|
||||||
|
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
|
/* Minor optimisation. The tick count cannot change in this block. */
|
||||||
|
const portTickType xConstTickCount = xTickCount;
|
||||||
|
|
||||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||||
/* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is
|
/* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is
|
||||||
the maximum block time then the task should block indefinitely, and
|
the maximum block time then the task should block indefinitely, and
|
||||||
|
@ -2010,7 +2014,7 @@ portBASE_TYPE xReturn;
|
||||||
else /* We are not blocking indefinitely, perform the checks below. */
|
else /* We are not blocking indefinitely, perform the checks below. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( ( portTickType ) xTickCount >= ( portTickType ) pxTimeOut->xTimeOnEntering ) )
|
if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( ( portTickType ) xConstTickCount >= ( portTickType ) pxTimeOut->xTimeOnEntering ) )
|
||||||
{
|
{
|
||||||
/* The tick count is greater than the time at which vTaskSetTimeout()
|
/* The tick count is greater than the time at which vTaskSetTimeout()
|
||||||
was called, but has also overflowed since vTaskSetTimeOut() was called.
|
was called, but has also overflowed since vTaskSetTimeOut() was called.
|
||||||
|
@ -2018,10 +2022,10 @@ portBASE_TYPE xReturn;
|
||||||
passed since vTaskSetTimeout() was called. */
|
passed since vTaskSetTimeout() was called. */
|
||||||
xReturn = pdTRUE;
|
xReturn = pdTRUE;
|
||||||
}
|
}
|
||||||
else if( ( ( portTickType ) ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ) ) < ( portTickType ) *pxTicksToWait )
|
else if( ( ( portTickType ) ( ( portTickType ) xConstTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ) ) < ( portTickType ) *pxTicksToWait )
|
||||||
{
|
{
|
||||||
/* Not a genuine timeout. Adjust parameters for time remaining. */
|
/* Not a genuine timeout. Adjust parameters for time remaining. */
|
||||||
*pxTicksToWait -= ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering );
|
*pxTicksToWait -= ( ( portTickType ) xConstTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering );
|
||||||
vTaskSetTimeOutState( pxTimeOut );
|
vTaskSetTimeOutState( pxTimeOut );
|
||||||
xReturn = pdFALSE;
|
xReturn = pdFALSE;
|
||||||
}
|
}
|
||||||
|
@ -2741,7 +2745,6 @@ tskTCB *pxNewTCB;
|
||||||
{
|
{
|
||||||
xTaskStatusType *pxTaskStatusArray;
|
xTaskStatusType *pxTaskStatusArray;
|
||||||
volatile unsigned portBASE_TYPE uxArraySize, x;
|
volatile unsigned portBASE_TYPE uxArraySize, x;
|
||||||
unsigned long ulTotalRunTime;
|
|
||||||
char cStatus;
|
char cStatus;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2782,7 +2785,7 @@ tskTCB *pxNewTCB;
|
||||||
if( pxTaskStatusArray != NULL )
|
if( pxTaskStatusArray != NULL )
|
||||||
{
|
{
|
||||||
/* Generate the (binary) data. */
|
/* Generate the (binary) data. */
|
||||||
uxArraySize = xTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
|
uxArraySize = xTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL );
|
||||||
|
|
||||||
/* Create a human readable table from the binary data. */
|
/* Create a human readable table from the binary data. */
|
||||||
for( x = 0; x < uxArraySize; x++ )
|
for( x = 0; x < uxArraySize; x++ )
|
||||||
|
@ -2825,7 +2828,7 @@ tskTCB *pxNewTCB;
|
||||||
{
|
{
|
||||||
xTaskStatusType *pxTaskStatusArray;
|
xTaskStatusType *pxTaskStatusArray;
|
||||||
volatile unsigned portBASE_TYPE uxArraySize, x;
|
volatile unsigned portBASE_TYPE uxArraySize, x;
|
||||||
unsigned long ulTotalRunTime, ulStatsAsPercentage;
|
unsigned long ulTotalTime, ulStatsAsPercentage;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PLEASE NOTE:
|
* PLEASE NOTE:
|
||||||
|
@ -2865,13 +2868,13 @@ tskTCB *pxNewTCB;
|
||||||
if( pxTaskStatusArray != NULL )
|
if( pxTaskStatusArray != NULL )
|
||||||
{
|
{
|
||||||
/* Generate the (binary) data. */
|
/* Generate the (binary) data. */
|
||||||
uxArraySize = xTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
|
uxArraySize = xTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime );
|
||||||
|
|
||||||
/* For percentage calculations. */
|
/* For percentage calculations. */
|
||||||
ulTotalRunTime /= 100UL;
|
ulTotalTime /= 100UL;
|
||||||
|
|
||||||
/* Avoid divide by zero errors. */
|
/* Avoid divide by zero errors. */
|
||||||
if( ulTotalRunTime > 0 )
|
if( ulTotalTime > 0 )
|
||||||
{
|
{
|
||||||
/* Create a human readable table from the binary data. */
|
/* Create a human readable table from the binary data. */
|
||||||
for( x = 0; x < uxArraySize; x++ )
|
for( x = 0; x < uxArraySize; x++ )
|
||||||
|
@ -2879,7 +2882,7 @@ tskTCB *pxNewTCB;
|
||||||
/* What percentage of the total run time has the task used?
|
/* What percentage of the total run time has the task used?
|
||||||
This will always be rounded down to the nearest integer.
|
This will always be rounded down to the nearest integer.
|
||||||
ulTotalRunTimeDiv100 has already been divided by 100. */
|
ulTotalRunTimeDiv100 has already been divided by 100. */
|
||||||
ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;
|
ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime;
|
||||||
|
|
||||||
if( ulStatsAsPercentage > 0UL )
|
if( ulStatsAsPercentage > 0UL )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue