Add vTaskGetTaskInfo() function that allows a TaskStatus_t structure to be returned for an individual task (previously information could only be obtained for all the tasks at once).
Add a member to the TaskStatus_t structure that is used to return the base address of the stack used by the task being queried. Add xTaskGetTaskHandle() that allows the handle of a task to be looked up from the task's text name. Continue to document the macros that allow RTOS objects to be created using statically allocated memory. Introduced vApplicationDaemonTaskStartupHook(), which allows initialisation that that needs to be executed after the scheduler has been started to be executed from the RTOS daemon task. Call prvResetNextTaskUnblockTime() in xTaskResumeAll() if a task is moved from the pending ready list - this can prevent an unnecessary wake from sleep mode if a task is unblocked by an interrupt while in a low power tickless state.
This commit is contained in:
@ -0,0 +1,5 @@
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,2
|
||||
[InternetShortcut]
|
||||
URL=http://www.freertos.org/labs
|
||||
IDList=
|
@ -86,6 +86,7 @@
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_IDLE_HOOK 1
|
||||
#define configUSE_TICK_HOOK 1
|
||||
#define configUSE_DAEMON_TASK_STARTUP_HOOK 1
|
||||
#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 50 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the win32 thread. */
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 24 * 1024 ) )
|
||||
@ -145,6 +146,7 @@ functions anyway. */
|
||||
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||
#define INCLUDE_pcTaskGetTaskName 1
|
||||
#define INCLUDE_xTaskGetTaskHandle 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xSemaphoreGetMutexHolder 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
|
@ -154,8 +154,8 @@ void vApplicationMallocFailedHook( void );
|
||||
void vApplicationIdleHook( void );
|
||||
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
|
||||
void vApplicationTickHook( void );
|
||||
void vApplicationGetIdleTaskMemory( DummyTCB_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize );
|
||||
void vApplicationGetTimerTaskMemory( DummyTCB_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize );
|
||||
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize );
|
||||
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize );
|
||||
|
||||
/*
|
||||
* Writes trace data to a disk file when the trace recording is stopped.
|
||||
@ -163,6 +163,15 @@ void vApplicationGetTimerTaskMemory( DummyTCB_t **ppxTimerTaskTCBBuffer, StackTy
|
||||
*/
|
||||
static void prvSaveTraceFile( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* When configSUPPORT_STATIC_ALLOCATION is set to 1 the application writer can
|
||||
use a callback function to optionally provide the memory required by the idle
|
||||
and timer tasks. This is the stack that will be used by the timer task. It is
|
||||
declared here, as a global, so it can be checked by a test that is implemented
|
||||
in a different file. */
|
||||
StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
|
||||
|
||||
/* The user trace event posted to the trace recording on each tick interrupt.
|
||||
Note: This project runs under Windows, and Windows will not be executing the
|
||||
RTOS threads continuously. Therefore tick events will not appear with a regular
|
||||
@ -299,6 +308,15 @@ void vApplicationTickHook( void )
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationDaemonTaskStartupHook( void )
|
||||
{
|
||||
/* This function will be called once only, when the daemon task starts to
|
||||
execute (sometimes called the timer task). This is useful if the
|
||||
application includes initialisation code that would benefit from executing
|
||||
after the scheduler has been started. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vAssertCalled( unsigned long ulLine, const char * const pcFileName )
|
||||
{
|
||||
static portBASE_TYPE xPrinted = pdFALSE;
|
||||
@ -392,11 +410,11 @@ const HeapRegion_t xHeapRegions[] =
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationGetIdleTaskMemory( DummyTCB_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )
|
||||
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )
|
||||
{
|
||||
/* The buffers used by the idle task must be static so they are persistent, and
|
||||
so exist after this function returns. */
|
||||
static DummyTCB_t xIdleTaskTCB;
|
||||
static StaticTask_t xIdleTaskTCB;
|
||||
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
|
||||
|
||||
/* configUSE_STATIC_ALLOCATION is set to 1, so the application has the
|
||||
@ -409,12 +427,13 @@ static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationGetTimerTaskMemory( DummyTCB_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )
|
||||
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )
|
||||
{
|
||||
/* The buffers used by the Timer/Daemon task must be static so they are
|
||||
persistent, and so exist after this function returns. */
|
||||
static DummyTCB_t xTimerTaskTCB;
|
||||
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
|
||||
persistent, and so exist after this function returns. The stack buffer is
|
||||
not declared here, but globally, as it is checked by a test in a different
|
||||
file. */
|
||||
static StaticTask_t xTimerTaskTCB;
|
||||
|
||||
/* configUSE_STATIC_ALLOCATION is set to 1, so the application has the
|
||||
opportunity to supply the buffers that will be used by the Timer/RTOS daemon
|
||||
|
@ -215,7 +215,12 @@ int main_full( void )
|
||||
vStartInterruptSemaphoreTasks();
|
||||
vStartQueueSetPollingTask();
|
||||
xTaskCreate( prvDemoQueueSpaceFunctions, "QSpace", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
{
|
||||
vStartStaticallyAllocatedTasks();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if( configUSE_PREEMPTION != 0 )
|
||||
{
|
||||
@ -339,10 +344,13 @@ const TickType_t xCycleFrequency = pdMS_TO_TICKS( 2500UL );
|
||||
{
|
||||
pcStatusMessage = "Error: Queue set polling";
|
||||
}
|
||||
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
else if( xAreStaticAllocationTasksStillRunning() != pdPASS )
|
||||
{
|
||||
pcStatusMessage = "Error: Static allocation";
|
||||
}
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
/* This is the only task that uses stdout so its ok to call printf()
|
||||
directly. */
|
||||
@ -396,6 +404,16 @@ void *pvAllocated;
|
||||
that has tasks blocked on it. */
|
||||
if( xMutexToDelete != NULL )
|
||||
{
|
||||
/* For test purposes, add the mutex to the registry, then remove it
|
||||
again, before it is deleted - checking its name is as expected before
|
||||
and after the assertion into the registry and its removal from the
|
||||
registry. */
|
||||
configASSERT( pcQueueGetQueueName( xMutexToDelete ) == NULL );
|
||||
vQueueAddToRegistry( xMutexToDelete, "Test_Mutex" );
|
||||
configASSERT( strcmp( pcQueueGetQueueName( xMutexToDelete ), "Test_Mutex" ) == 0 );
|
||||
vQueueUnregisterQueue( xMutexToDelete );
|
||||
configASSERT( pcQueueGetQueueName( xMutexToDelete ) == NULL );
|
||||
|
||||
vSemaphoreDelete( xMutexToDelete );
|
||||
xMutexToDelete = NULL;
|
||||
}
|
||||
@ -482,6 +500,8 @@ TaskHandle_t xIdleTaskHandle, xTimerTaskHandle;
|
||||
char *pcTaskName;
|
||||
static portBASE_TYPE xPerformedOneShotTests = pdFALSE;
|
||||
TaskHandle_t xTestTask;
|
||||
TaskStatus_t xTaskInfo;
|
||||
extern StackType_t uxTimerTaskStack[];
|
||||
|
||||
/* Demonstrate the use of the xTimerGetTimerDaemonTaskHandle() and
|
||||
xTaskGetIdleTaskHandle() functions. Also try using the function that sets
|
||||
@ -496,6 +516,18 @@ TaskHandle_t xTestTask;
|
||||
pcStatusMessage = "Error: Returned idle task handle was incorrect";
|
||||
}
|
||||
|
||||
/* Check the same handle is obtained using the idle task's name. First try
|
||||
with the wrong name, then the right name. */
|
||||
if( xTaskGetTaskHandle( "Idle" ) == xIdleTaskHandle )
|
||||
{
|
||||
pcStatusMessage = "Error: Returned handle for name Idle was incorrect";
|
||||
}
|
||||
|
||||
if( xTaskGetTaskHandle( "IDLE" ) != xIdleTaskHandle )
|
||||
{
|
||||
pcStatusMessage = "Error: Returned handle for name Idle was incorrect";
|
||||
}
|
||||
|
||||
/* Check the timer task handle was returned correctly. */
|
||||
pcTaskName = pcTaskGetTaskName( xTimerTaskHandle );
|
||||
if( strcmp( pcTaskName, "Tmr Svc" ) != 0 )
|
||||
@ -503,6 +535,11 @@ TaskHandle_t xTestTask;
|
||||
pcStatusMessage = "Error: Returned timer task handle was incorrect";
|
||||
}
|
||||
|
||||
if( xTaskGetTaskHandle( "Tmr Svc" ) != xTimerTaskHandle )
|
||||
{
|
||||
pcStatusMessage = "Error: Returned handle for name Tmr Svc was incorrect";
|
||||
}
|
||||
|
||||
/* This task is running, make sure it's state is returned as running. */
|
||||
if( eTaskStateGet( xIdleTaskHandle ) != eRunning )
|
||||
{
|
||||
@ -515,6 +552,22 @@ TaskHandle_t xTestTask;
|
||||
pcStatusMessage = "Error: Returned timer task state was incorrect";
|
||||
}
|
||||
|
||||
/* Also with the vTaskGetTaskInfo() function. */
|
||||
vTaskGetTaskInfo( xTimerTaskHandle, /* The task being queried. */
|
||||
&xTaskInfo, /* The structure into which information on the task will be written. */
|
||||
pdTRUE, /* Include the task's high watermark in the structure. */
|
||||
eInvalid ); /* Include the task state in the structure. */
|
||||
|
||||
/* Check the information returned by vTaskGetTaskInfo() is as expected. */
|
||||
if( ( xTaskInfo.eCurrentState != eBlocked ) ||
|
||||
( strcmp( xTaskInfo.pcTaskName, "Tmr Svc" ) != 0 ) ||
|
||||
( xTaskInfo.uxCurrentPriority != configTIMER_TASK_PRIORITY ) ||
|
||||
( xTaskInfo.pxStackBase != uxTimerTaskStack ) ||
|
||||
( xTaskInfo.xHandle != xTimerTaskHandle ) )
|
||||
{
|
||||
pcStatusMessage = "Error: vTaskGetTaskInfo() returned incorrect information about the timer task";
|
||||
}
|
||||
|
||||
/* Other tests that should only be performed once follow. The test task
|
||||
is not created on each iteration because to do so would cause the death
|
||||
task to report an error (too many tasks running). */
|
||||
|
@ -171,6 +171,10 @@ extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK
|
||||
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_xTaskGetIdleTaskHandle
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
#endif
|
||||
@ -191,6 +195,10 @@ extern "C" {
|
||||
#define INCLUDE_pcTaskGetTaskName 0
|
||||
#endif
|
||||
|
||||
#ifndef INCLUDE_xTaskGetTaskHandle
|
||||
#define INCLUDE_xTaskGetTaskHandle 0
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_APPLICATION_TASK_TAG
|
||||
#define configUSE_APPLICATION_TASK_TAG 0
|
||||
#endif
|
||||
|
@ -229,9 +229,13 @@ typedef void * QueueSetMemberHandle_t;
|
||||
* hold the queue's data structure, removing the need for the memory to be
|
||||
* allocated dynamically.
|
||||
*
|
||||
* @return If the queue is successfully create then a handle to the newly
|
||||
* created queue is returned. If the queue cannot be created then 0 is
|
||||
* returned.
|
||||
* @return If neither pucQueueStorageBuffer or pxQueueBuffer are NULL, then the
|
||||
* function will not attempt any dynamic memory allocation, and a handle to the
|
||||
* created queue will always be returned. If pucQueueStorageBuffer or
|
||||
* pxQueueBuffer is NULL then the function will attempt to dynamically allocate
|
||||
* one of both buffers. In this case, if the allocation succeeds then a handle
|
||||
* to the created queue will be returned, and if one of the the allocation fails
|
||||
* NULL will be returned.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
@ -267,7 +271,7 @@ typedef void * QueueSetMemberHandle_t;
|
||||
// ... Rest of task code.
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xQueueCreate xQueueCreate
|
||||
* \defgroup xQueueCreateStatic xQueueCreateStatic
|
||||
* \ingroup QueueManagement
|
||||
*/
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
@ -1649,7 +1653,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION
|
||||
* returned.
|
||||
*/
|
||||
#if( configQUEUE_REGISTRY_SIZE > 0 )
|
||||
const char *pcQueueGetQueueName( QueueHandle_t xQueue );
|
||||
const char *pcQueueGetQueueName( QueueHandle_t xQueue ); /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -115,7 +115,8 @@ typedef enum
|
||||
eReady, /* The task being queried is in a read or pending ready list. */
|
||||
eBlocked, /* The task being queried is in the Blocked state. */
|
||||
eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */
|
||||
eDeleted /* The task being queried has been deleted, but its TCB has not yet been freed. */
|
||||
eDeleted, /* The task being queried has been deleted, but its TCB has not yet been freed. */
|
||||
eInvalid /* Used as an 'invalid state' value. */
|
||||
} eTaskState;
|
||||
|
||||
/* Actions that can be performed when vTaskNotify() is called. */
|
||||
@ -172,6 +173,7 @@ typedef struct xTASK_STATUS
|
||||
UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */
|
||||
UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */
|
||||
uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */
|
||||
StackType_t *pxStackBase; /* Points to the lowest address of the task's stack area. */
|
||||
uint16_t usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */
|
||||
} TaskStatus_t;
|
||||
|
||||
@ -426,8 +428,12 @@ is used in assert() statements. */
|
||||
* task's data structures, removing the need for the memory to be allocated
|
||||
* dynamically.
|
||||
*
|
||||
* @return pdPASS if the task was successfully created and added to a ready
|
||||
* list, otherwise an error code defined in the file projdefs.h
|
||||
* @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the function
|
||||
* will not attempt any dynamic memory allocation, and pdPASS will always be
|
||||
* returned. If pxStackBuffer or pxTaskBuffer is NULL then the function will
|
||||
* attempt to dynamically allocate one of both buffers. In this case, if the
|
||||
* allocation succeeds then pdPASS will be returned, and if the allocation fails
|
||||
* then an error code defined in projdefs.h is returned.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
@ -819,6 +825,62 @@ UBaseType_t uxTaskPriorityGetFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
*/
|
||||
eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>void vTaskGetTaskInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState );</pre>
|
||||
*
|
||||
* configUSE_TRACE_FACILITY must be defined as 1 for this function to be
|
||||
* available. See the configuration section for more information.
|
||||
*
|
||||
* Populates a TaskStatus_t structure with information about a task.
|
||||
*
|
||||
* @param xTask Handle of the task being queried. If xTask is NULL then
|
||||
* information will be returned about the calling task.
|
||||
*
|
||||
* @param pxTaskStatus A pointer to the TaskStatus_t structure that will be
|
||||
* filled with information about the task referenced by the handle passed using
|
||||
* the xTask parameter.
|
||||
*
|
||||
* @xGetFreeStackSpace The TaskStatus_t structure contains a member to report
|
||||
* the stack high water mark of the task being queried. Calculating the stack
|
||||
* high water mark takes a relatively long time, and can make the system
|
||||
* temporarily unresponsive - so the xGetFreeStackSpace parameter is provided to
|
||||
* allow the high water mark checking to be skipped. The high watermark value
|
||||
* will only be written to the TaskStatus_t structure if xGetFreeStackSpace is
|
||||
* not set to pdFALSE;
|
||||
*
|
||||
* @param eState The TaskStatus_t structure contains a member to report the
|
||||
* state of the task being queried. Obtaining the task state is not as fast as
|
||||
* a simple assignment - so the eState parameter is provided to allow the state
|
||||
* information to be omitted from the TaskStatus_t structure. To obtain state
|
||||
* information then set eState to eInvalid - otherwise the value passed in
|
||||
* eState will be reported as the task state in the TaskStatus_t structure.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
void vAFunction( void )
|
||||
{
|
||||
TaskHandle_t xHandle;
|
||||
TaskStatus_t xTaskDetails;
|
||||
|
||||
// Obtain the handle of a task from its name.
|
||||
xHandle = xTaskGetTaskHandle( "Task_Name" );
|
||||
|
||||
// Check the handle is not NULL.
|
||||
configASSERT( xHandle );
|
||||
|
||||
// Use the handle to obtain further information about the task.
|
||||
vTaskGetTaskInfo( xHandle,
|
||||
&xTaskDetails,
|
||||
pdTRUE, // Include the high water mark in xTaskDetails.
|
||||
eInvalid ); // Include the task state in xTaskDetails.
|
||||
}
|
||||
</pre>
|
||||
* \defgroup vTaskGetTaskInfo vTaskGetTaskInfo
|
||||
* \ingroup TaskCtrl
|
||||
*/
|
||||
void vTaskGetTaskInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState );
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <pre>void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );</pre>
|
||||
@ -1243,6 +1305,22 @@ UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION;
|
||||
*/
|
||||
char *pcTaskGetTaskName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
|
||||
/**
|
||||
* task. h
|
||||
* <PRE>TaskHandle_t xTaskGetTaskHandle( const char *pcNameToQuery );</PRE>
|
||||
*
|
||||
* NOTE: This function takes a relatively long time to complete and should be
|
||||
* used sparingly.
|
||||
*
|
||||
* @return The handle of the task that has the human readable name pcNameToQuery.
|
||||
* NULL is returned if no matching name is found. INCLUDE_xTaskGetTaskHandle
|
||||
* must be set to 1 in FreeRTOSConfig.h for pcTaskGetTaskHandle() to be available.
|
||||
*
|
||||
* \defgroup pcTaskGetTaskHandle pcTaskGetTaskHandle
|
||||
* \ingroup TaskUtils
|
||||
*/
|
||||
TaskHandle_t xTaskGetTaskHandle( const char *pcNameToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
|
||||
/**
|
||||
* task.h
|
||||
* <PRE>UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );</PRE>
|
||||
|
@ -145,8 +145,8 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
||||
* http://www.freertos.org/a00111.html). If a software timer is created using
|
||||
* xTimerCreateStatic() then the application writer can instead optionally
|
||||
* provide the memory that will get used by the software timer.
|
||||
* xTimerCreateStatic() therefore allows a software to be created without using
|
||||
* any dynamic memory allocation.
|
||||
* xTimerCreateStatic() therefore allows a software timer to be created without
|
||||
* using any dynamic memory allocation.
|
||||
*
|
||||
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
||||
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
||||
@ -327,10 +327,12 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
||||
* will be then be used to hold the software timer's data structures, removing
|
||||
* the need for the memory to be allocated dynamically.
|
||||
*
|
||||
* @return If the timer is successfully created then a handle to the newly
|
||||
* created timer is returned. If the timer cannot be created (because either
|
||||
* there is insufficient FreeRTOS heap remaining to allocate the timer
|
||||
* structures, or the timer period was set to 0) then NULL is returned.
|
||||
* @return If pxTimerBuffer is not NULL then the function will not attempt
|
||||
* any dynamic memory allocation, and a handle to the created timer will always
|
||||
* be returned. If pxTimerBuffer is NULL then the function will attempt to
|
||||
* dynamically allocate the memory required to hold the timer's data structures.
|
||||
* In this case, if the allocation succeeds then a handle to the created timer
|
||||
* will be returned, and if the allocation fails NULL will be returned.
|
||||
*
|
||||
* Example usage:
|
||||
* @verbatim
|
||||
@ -1277,7 +1279,7 @@ const char * pcTimerGetTimerName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*
|
||||
*/
|
||||
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
|
||||
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
TimerHandle_t xTimerGenericCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION;
|
||||
TimerHandle_t xTimerGenericCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -274,7 +274,6 @@ uint16_t usTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
||||
}
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
|
||||
#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
|
||||
{
|
||||
/* Create the timer task, storing its handle in xTimerTaskHandle so
|
||||
@ -327,7 +326,7 @@ Timer_t *pxNewTimer;
|
||||
}
|
||||
else
|
||||
{
|
||||
pxNewTimer = ( Timer_t * ) pxTimerBuffer;
|
||||
pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
|
||||
}
|
||||
|
||||
if( pxNewTimer != NULL )
|
||||
@ -429,7 +428,7 @@ DaemonTaskMessage_t xMessage;
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
const char * pcTimerGetTimerName( TimerHandle_t xTimer )
|
||||
const char * pcTimerGetTimerName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
{
|
||||
Timer_t *pxTimer = ( Timer_t * ) xTimer;
|
||||
|
||||
@ -486,6 +485,18 @@ BaseType_t xListWasEmpty;
|
||||
/* Just to avoid compiler warnings. */
|
||||
( void ) pvParameters;
|
||||
|
||||
#if( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 )
|
||||
{
|
||||
extern void vApplicationDaemonTaskStartupHook( void );
|
||||
|
||||
/* Allow the application writer to execute some code in the context of
|
||||
this task at the point the task starts executing. This is useful if the
|
||||
application includes initialisation code that would benefit from
|
||||
executing after the scheduler has been started. */
|
||||
vApplicationDaemonTaskStartupHook();
|
||||
}
|
||||
#endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Query the timers list to see if it contains any timers, and if so,
|
||||
@ -769,7 +780,7 @@ TickType_t xTimeNow;
|
||||
allocated. */
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
{
|
||||
if( pxTimer->ucStaticallyAllocated == pdFALSE )
|
||||
if( pxTimer->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
|
||||
{
|
||||
vPortFree( pxTimer );
|
||||
}
|
||||
|
Reference in New Issue
Block a user