mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2026-10-10 08:02:57 -04:00
Merge c48d9b0137 into 8be86d4a24
This commit is contained in:
commit
8dd2687b77
3 changed files with 214 additions and 1 deletions
|
|
@ -1626,6 +1626,22 @@
|
|||
#define traceRETURN_xTimerGetExpiryTime( xReturn )
|
||||
#endif
|
||||
|
||||
#ifndef traceENTER_uxTimerGetNumberOfTimers
|
||||
#define traceENTER_uxTimerGetNumberOfTimers()
|
||||
#endif
|
||||
|
||||
#ifndef traceRETURN_uxTimerGetNumberOfTimers
|
||||
#define traceRETURN_uxTimerGetNumberOfTimers( uxNumberOfTimers )
|
||||
#endif
|
||||
|
||||
#ifndef traceENTER_uxTimerGetSystemState
|
||||
#define traceENTER_uxTimerGetSystemState( pxTimerStatusArray, uxArraySize )
|
||||
#endif
|
||||
|
||||
#ifndef traceRETURN_uxTimerGetSystemState
|
||||
#define traceRETURN_uxTimerGetSystemState( uxNumberOfTimers )
|
||||
#endif
|
||||
|
||||
#ifndef traceENTER_xTimerGetStaticBuffer
|
||||
#define traceENTER_xTimerGetStaticBuffer( xTimer, ppxTimerBuffer )
|
||||
#endif
|
||||
|
|
@ -3327,8 +3343,9 @@ typedef struct xSTATIC_TIMER
|
|||
TaskFunction_t pvDummy6;
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxDummy7;
|
||||
void * pvDummy8;
|
||||
#endif
|
||||
uint8_t ucDummy8;
|
||||
uint8_t ucDummy9;
|
||||
} StaticTimer_t;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -77,6 +77,19 @@
|
|||
struct tmrTimerControl; /* The old naming convention is used to prevent breaking kernel aware debuggers. */
|
||||
typedef struct tmrTimerControl * TimerHandle_t;
|
||||
|
||||
/* Used with uxTimerGetSystemState() to return the state of each timer in the
|
||||
* timer registry. */
|
||||
typedef struct xTIMER_STATUS
|
||||
{
|
||||
TimerHandle_t xHandle; /* The handle of the timer. This value will be invalid if the timer is deleted after the structure is populated. */
|
||||
const char * pcTimerName; /* A pointer to the name assigned when the timer was created. */
|
||||
TickType_t xTimerPeriodInTicks; /* The timer's period in ticks. */
|
||||
TickType_t xNextExpiryTime; /* The next expiry time, or 0 if the timer is inactive. */
|
||||
void * pvTimerID; /* The application-supplied timer ID. */
|
||||
BaseType_t xIsActive; /* pdTRUE if the timer is active, otherwise pdFALSE. */
|
||||
BaseType_t xAutoReload; /* pdTRUE for an auto-reload timer, otherwise pdFALSE. */
|
||||
} TimerStatus_t;
|
||||
|
||||
/*
|
||||
* Defines the prototype to which timer callback functions must conform.
|
||||
*/
|
||||
|
|
@ -1333,6 +1346,50 @@ TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
|||
*/
|
||||
TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* configUSE_TRACE_FACILITY must be set to 1 for
|
||||
* uxTimerGetNumberOfTimers() to be available.
|
||||
*
|
||||
* @return The number of timers currently stored in the timer registry.
|
||||
*/
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxTimerGetNumberOfTimers( void ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* configUSE_TRACE_FACILITY must be set to 1 for
|
||||
* uxTimerGetSystemState() to be available.
|
||||
*
|
||||
* uxTimerGetSystemState() populates one TimerStatus_t structure for each
|
||||
* timer currently stored in the timer registry. Timers are automatically
|
||||
* added to the registry when they are created and removed when they are
|
||||
* deleted.
|
||||
*
|
||||
* This function is intended for debugging use and suspends the scheduler while
|
||||
* the registry is copied. The returned values provide a best-effort snapshot
|
||||
* of timer state. Timer commands still waiting in the timer command queue are
|
||||
* not reflected.
|
||||
*
|
||||
* TimerStatus_t contains borrowed handles and pointers. A timer handle becomes
|
||||
* invalid when that timer is deleted, and the application must ensure that the
|
||||
* memory referenced by timer names and IDs remains valid while it is used.
|
||||
*
|
||||
* When MPU wrappers are enabled, this API is privileged-only.
|
||||
*
|
||||
* @param pxTimerStatusArray A pointer to an array of TimerStatus_t structures.
|
||||
* The array must contain at least one entry for each timer in the registry. The
|
||||
* number of timers can be obtained using uxTimerGetNumberOfTimers().
|
||||
*
|
||||
* @param uxArraySize The number of TimerStatus_t entries in the array.
|
||||
*
|
||||
* @return The number of TimerStatus_t structures populated, or zero if the
|
||||
* supplied array is too small or pxTimerStatusArray is NULL.
|
||||
*/
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxTimerGetSystemState( TimerStatus_t * const pxTimerStatusArray,
|
||||
const UBaseType_t uxArraySize ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer,
|
||||
* StaticTimer_t ** ppxTimerBuffer );
|
||||
|
|
|
|||
139
timers.c
139
timers.c
|
|
@ -89,6 +89,7 @@
|
|||
portTIMER_CALLBACK_ATTRIBUTE TimerCallbackFunction_t pxCallbackFunction; /**< The function that will be called when the timer expires. */
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxTimerNumber; /**< An ID assigned by trace tools such as FreeRTOS+Trace */
|
||||
struct tmrTimerControl * pxNextTimer; /**< Points to the next timer in the timer registry. */
|
||||
#endif
|
||||
uint8_t ucStatus; /**< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */
|
||||
} xTIMER;
|
||||
|
|
@ -149,6 +150,11 @@
|
|||
PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL;
|
||||
PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
PRIVILEGED_DATA static Timer_t * pxTimerRegistry = NULL;
|
||||
PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTimers = 0U;
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
|
@ -157,6 +163,11 @@
|
|||
*/
|
||||
static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
static void prvAddTimerToRegistry( Timer_t * pxTimer ) PRIVILEGED_FUNCTION;
|
||||
static void prvRemoveTimerFromRegistry( Timer_t * pxTimer ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The timer service task (daemon). Timer functionality is controlled by this
|
||||
* task. Other tasks communicate with the timer service task using the
|
||||
|
|
@ -441,10 +452,56 @@
|
|||
pxNewTimer->ucStatus |= ( uint8_t ) tmrSTATUS_IS_AUTORELOAD;
|
||||
}
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
{
|
||||
prvAddTimerToRegistry( pxNewTimer );
|
||||
}
|
||||
#endif
|
||||
|
||||
traceTIMER_CREATE( pxNewTimer );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
static void prvAddTimerToRegistry( Timer_t * pxTimer )
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
pxTimer->pxNextTimer = pxTimerRegistry;
|
||||
pxTimerRegistry = pxTimer;
|
||||
uxCurrentNumberOfTimers++;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
|
||||
static void prvRemoveTimerFromRegistry( Timer_t * pxTimer )
|
||||
{
|
||||
Timer_t ** ppxTimer = &pxTimerRegistry;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
while( *ppxTimer != NULL )
|
||||
{
|
||||
if( *ppxTimer == pxTimer )
|
||||
{
|
||||
*ppxTimer = pxTimer->pxNextTimer;
|
||||
pxTimer->pxNextTimer = NULL;
|
||||
uxCurrentNumberOfTimers--;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
ppxTimer = &( ( *ppxTimer )->pxNextTimer );
|
||||
}
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xTimerGenericCommandFromTask( TimerHandle_t xTimer,
|
||||
const BaseType_t xCommandID,
|
||||
const TickType_t xOptionalValue,
|
||||
|
|
@ -1049,6 +1106,12 @@
|
|||
break;
|
||||
|
||||
case tmrCOMMAND_DELETE:
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
{
|
||||
prvRemoveTimerFromRegistry( pxTimer );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
{
|
||||
/* The timer has already been removed from the active list,
|
||||
|
|
@ -1312,6 +1375,75 @@
|
|||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
UBaseType_t uxTimerGetNumberOfTimers( void )
|
||||
{
|
||||
UBaseType_t uxNumberOfTimers;
|
||||
|
||||
traceENTER_uxTimerGetNumberOfTimers();
|
||||
|
||||
/* A critical section is not required because the variable is of
|
||||
* type UBaseType_t. */
|
||||
uxNumberOfTimers = uxCurrentNumberOfTimers;
|
||||
|
||||
traceRETURN_uxTimerGetNumberOfTimers( uxNumberOfTimers );
|
||||
|
||||
return uxNumberOfTimers;
|
||||
}
|
||||
|
||||
UBaseType_t uxTimerGetSystemState( TimerStatus_t * const pxTimerStatusArray,
|
||||
const UBaseType_t uxArraySize )
|
||||
{
|
||||
UBaseType_t uxNumberOfTimers = 0U;
|
||||
|
||||
traceENTER_uxTimerGetSystemState( pxTimerStatusArray, uxArraySize );
|
||||
|
||||
if( pxTimerStatusArray != NULL )
|
||||
{
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
if( uxArraySize >= uxCurrentNumberOfTimers )
|
||||
{
|
||||
Timer_t * pxTimer = pxTimerRegistry;
|
||||
UBaseType_t uxTimer = 0U;
|
||||
|
||||
while( pxTimer != NULL )
|
||||
{
|
||||
pxTimerStatusArray[ uxTimer ].xHandle = pxTimer;
|
||||
pxTimerStatusArray[ uxTimer ].pcTimerName = pxTimer->pcTimerName;
|
||||
pxTimerStatusArray[ uxTimer ].xTimerPeriodInTicks = pxTimer->xTimerPeriodInTicks;
|
||||
pxTimerStatusArray[ uxTimer ].pvTimerID = pxTimer->pvTimerID;
|
||||
pxTimerStatusArray[ uxTimer ].xIsActive = ( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) != 0U ) ? pdTRUE : pdFALSE;
|
||||
pxTimerStatusArray[ uxTimer ].xAutoReload = ( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0U ) ? pdTRUE : pdFALSE;
|
||||
|
||||
if( pxTimerStatusArray[ uxTimer ].xIsActive != pdFALSE )
|
||||
{
|
||||
pxTimerStatusArray[ uxTimer ].xNextExpiryTime = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pxTimerStatusArray[ uxTimer ].xNextExpiryTime = 0U;
|
||||
}
|
||||
|
||||
uxTimer++;
|
||||
pxTimer = pxTimer->pxNextTimer;
|
||||
}
|
||||
|
||||
uxNumberOfTimers = uxTimer;
|
||||
}
|
||||
}
|
||||
( void ) xTaskResumeAll();
|
||||
}
|
||||
|
||||
traceRETURN_uxTimerGetSystemState( uxNumberOfTimers );
|
||||
|
||||
return uxNumberOfTimers;
|
||||
}
|
||||
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
void vTimerSetTimerNumber( TimerHandle_t xTimer,
|
||||
|
|
@ -1336,6 +1468,13 @@
|
|||
{
|
||||
xTimerQueue = NULL;
|
||||
xTimerTaskHandle = NULL;
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
{
|
||||
pxTimerRegistry = NULL;
|
||||
uxCurrentNumberOfTimers = 0U;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue