mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Ensure the code builds when configSUPPORT_STATIC_ALLOCATION is 0.
Continue to document the new static allocation functions.
This commit is contained in:
parent
f82953554d
commit
8ef7849199
|
@ -278,6 +278,8 @@ const TickType_t xRegulatorOffIdleTime = 30;
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
above. */
|
above. */
|
||||||
__asm volatile ( "cpsie i" );
|
__asm volatile ( "cpsie i" );
|
||||||
|
__asm volatile ( "dsb" );
|
||||||
|
__asm volatile ( "isb" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -151,14 +151,18 @@ EventGroup_t *pxEventBits;
|
||||||
pxEventBits->uxEventBits = 0;
|
pxEventBits->uxEventBits = 0;
|
||||||
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||||
|
|
||||||
if( pxStaticEventGroup == NULL )
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
{
|
{
|
||||||
pxEventBits->ucStaticallyAllocated = pdFALSE;
|
if( pxStaticEventGroup == NULL )
|
||||||
}
|
{
|
||||||
else
|
pxEventBits->ucStaticallyAllocated = pdFALSE;
|
||||||
{
|
}
|
||||||
pxEventBits->ucStaticallyAllocated = pdTRUE;
|
else
|
||||||
|
{
|
||||||
|
pxEventBits->ucStaticallyAllocated = pdTRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
traceEVENT_GROUP_CREATE( pxEventBits );
|
traceEVENT_GROUP_CREATE( pxEventBits );
|
||||||
}
|
}
|
||||||
|
@ -605,10 +609,18 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only free the memory if it was allocated dynamically. */
|
/* Only free the memory if it was allocated dynamically. */
|
||||||
if( pxEventBits->ucStaticallyAllocated == pdFALSE )
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
if( pxEventBits->ucStaticallyAllocated == pdFALSE )
|
||||||
|
{
|
||||||
|
vPortFree( pxEventBits );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
vPortFree( pxEventBits );
|
vPortFree( pxEventBits );
|
||||||
}
|
}
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
}
|
}
|
||||||
( void ) xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,8 +123,19 @@ typedef void * QueueSetMemberHandle_t;
|
||||||
);
|
);
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Creates a new queue instance. This allocates the storage required by the
|
* Creates a new queue instance, and returns a handle by which the new queue
|
||||||
* new queue and returns a handle for the queue.
|
* can be referenced.
|
||||||
|
*
|
||||||
|
* Internally, within the FreeRTOS implementation, queue's use two blocks of
|
||||||
|
* memory. The first block is used to hold the queue's data structures. The
|
||||||
|
* second block is used to hold items placed into the queue. If a queue is
|
||||||
|
* created using xQueueCreate() then both blocks of memory are automatically
|
||||||
|
* dynamically allocated inside the xQueueCreate() function. (see
|
||||||
|
* http://www.freertos.org/a00111.html). If a queue is created using
|
||||||
|
* xQueueCreateStatic() then the application writer can instead optionally
|
||||||
|
* provide the memory that will get used by the queue. xQueueCreateStatic()
|
||||||
|
* therefore allows a queue to be created without using any dynamic memory
|
||||||
|
* allocation.
|
||||||
*
|
*
|
||||||
* @param uxQueueLength The maximum number of items that the queue can contain.
|
* @param uxQueueLength The maximum number of items that the queue can contain.
|
||||||
*
|
*
|
||||||
|
@ -172,8 +183,95 @@ typedef void * QueueSetMemberHandle_t;
|
||||||
*/
|
*/
|
||||||
#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( uxQueueLength, uxItemSize, NULL, NULL, queueQUEUE_TYPE_BASE )
|
#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( uxQueueLength, uxItemSize, NULL, NULL, queueQUEUE_TYPE_BASE )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* queue. h
|
||||||
|
* <pre>
|
||||||
|
QueueHandle_t xQueueCreateStatic(
|
||||||
|
UBaseType_t uxQueueLength,
|
||||||
|
UBaseType_t uxItemSize,
|
||||||
|
uint8_t *pucQueueStorageBuffer,
|
||||||
|
StaticQueue_t *pxQueueBuffer
|
||||||
|
);
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* Creates a new queue instance, and returns a handle by which the new queue
|
||||||
|
* can be referenced.
|
||||||
|
*
|
||||||
|
* Internally, within the FreeRTOS implementation, queue's use two blocks of
|
||||||
|
* memory. The first block is used to hold the queue's data structures. The
|
||||||
|
* second block is used to hold items placed into the queue. If a queue is
|
||||||
|
* created using xQueueCreate() then both blocks of memory are automatically
|
||||||
|
* dynamically allocated inside the xQueueCreate() function. (see
|
||||||
|
* http://www.freertos.org/a00111.html). If a queue is created using
|
||||||
|
* xQueueCreateStatic() then the application writer can instead optionally
|
||||||
|
* provide the memory that will get used by the queue. xQueueCreateStatic()
|
||||||
|
* therefore allows a queue to be created without using any dynamic memory
|
||||||
|
* allocation.
|
||||||
|
*
|
||||||
|
* @param uxQueueLength The maximum number of items that the queue can contain.
|
||||||
|
*
|
||||||
|
* @param uxItemSize The number of bytes each item in the queue will require.
|
||||||
|
* Items are queued by copy, not by reference, so this is the number of bytes
|
||||||
|
* that will be copied for each posted item. Each item on the queue must be
|
||||||
|
* the same size.
|
||||||
|
*
|
||||||
|
* @param pucQueueStorageBuffer If pucQueueStorageBuffer is NULL then the memory
|
||||||
|
* used to hold items stored in the queue will be allocated dynamically, just as
|
||||||
|
* when a queue is created using xQueueCreate(). If pxQueueStorageBuffer is not
|
||||||
|
* NULL then it must point to a uint8_t array that is at least large enough to
|
||||||
|
* hold the maximum number of items that can be in the queue at any one time -
|
||||||
|
* which is ( uxQueueLength * uxItemsSize ) bytes.
|
||||||
|
*
|
||||||
|
* @param pxQueueBuffer If pxQueueBuffer is NULL then the memory required to
|
||||||
|
* hold the queue's data structures will be allocated dynamically, just as when
|
||||||
|
* a queue is created using xQueueCreate(). If pxQueueBuffer is not NULL then
|
||||||
|
* it must point to a variable of type StaticQueue_t, which will then be used to
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
struct AMessage
|
||||||
|
{
|
||||||
|
char ucMessageID;
|
||||||
|
char ucData[ 20 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define QUEUE_LENGTH 10
|
||||||
|
#define ITEM_SIZE sizeof( uint32_t )
|
||||||
|
|
||||||
|
// xQueueBuffer will hold the queue structure.
|
||||||
|
StaticQueue_t xQueueBuffer;
|
||||||
|
|
||||||
|
// ucQueueStorage will hold the items posted to the queue. Must be at least
|
||||||
|
// [(queue length) * ( queue item size)] bytes long.
|
||||||
|
uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ];
|
||||||
|
|
||||||
|
void vATask( void *pvParameters )
|
||||||
|
{
|
||||||
|
QueueHandle_t xQueue1;
|
||||||
|
|
||||||
|
// Create a queue capable of containing 10 uint32_t values.
|
||||||
|
xQueue1 = xQueueCreate( QUEUE_LENGTH, // The number of items the queue can hold.
|
||||||
|
ITEM_SIZE // The size of each item in the queue
|
||||||
|
&( ucQueueStorage[ 0 ] ), // The buffer that will hold the items in the queue.
|
||||||
|
&xQueueBuffer ); // The buffer that will hold the queue structure.
|
||||||
|
|
||||||
|
// The queue is guaranteed to be created successfully as no dynamic memory
|
||||||
|
// allocation was used. Therefore xQueue1 is now a handle to a valid queue.
|
||||||
|
|
||||||
|
// ... Rest of task code.
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xQueueCreate xQueueCreate
|
||||||
|
* \ingroup QueueManagement
|
||||||
|
*/
|
||||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
#define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue ) xQueueGenericCreate( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue, queueQUEUE_TYPE_BASE )
|
#define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) )
|
||||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -283,6 +283,20 @@ is used in assert() statements. */
|
||||||
*
|
*
|
||||||
* Create a new task and add it to the list of tasks that are ready to run.
|
* Create a new task and add it to the list of tasks that are ready to run.
|
||||||
*
|
*
|
||||||
|
* Internally, within the FreeRTOS implementation, tasks's use two blocks of
|
||||||
|
* memory. The first block is used to hold the tasks's data structures. The
|
||||||
|
* second block is used by the task as its stack. If a task is created using
|
||||||
|
* xTaskCreate() then both blocks of memory are automatically dynamically
|
||||||
|
* allocated inside the xTaskCreate() function. (see
|
||||||
|
* http://www.freertos.org/a00111.html). If a task is created using
|
||||||
|
* xTaskCreateStatic() then the application writer can instead optionally
|
||||||
|
* provide the memory that will get used by the task. xTaskCreateStatic()
|
||||||
|
* therefore allows a task to be created without using any dynamic memory
|
||||||
|
* allocation.
|
||||||
|
*
|
||||||
|
* See xTaskCreateStatic() for a version that does not use any dynamic memory
|
||||||
|
* allocation.
|
||||||
|
*
|
||||||
* xTaskCreate() can only be used to create a task that has unrestricted
|
* xTaskCreate() can only be used to create a task that has unrestricted
|
||||||
* access to the entire microcontroller memory map. Systems that include MPU
|
* access to the entire microcontroller memory map. Systems that include MPU
|
||||||
* support can alternatively create an MPU constrained task using
|
* support can alternatively create an MPU constrained task using
|
||||||
|
@ -362,16 +376,21 @@ is used in assert() statements. */
|
||||||
UBaseType_t uxPriority,
|
UBaseType_t uxPriority,
|
||||||
TaskHandle_t *pvCreatedTask,
|
TaskHandle_t *pvCreatedTask,
|
||||||
StackType_t *pxStackBuffer,
|
StackType_t *pxStackBuffer,
|
||||||
StaticTask_t *pxTCBBuffer
|
StaticTask_t *pxTaskBuffer
|
||||||
);</pre>
|
);</pre>
|
||||||
*
|
*
|
||||||
* Create a new task and add it to the list of tasks that are ready to run.
|
* Create a new task and add it to the list of tasks that are ready to run.
|
||||||
* If a task is created using xTaskCreate() then the stack and task control
|
*
|
||||||
* block (TCB) used by the task are allocated dynamically. If a task is created
|
* Internally, within the FreeRTOS implementation, tasks's use two blocks of
|
||||||
* using xTaskCreateStatic() then the application writer can optionally provide
|
* memory. The first block is used to hold the tasks's data structures. The
|
||||||
* the buffers that will hold the task stack and TCB respectively.
|
* second block is used by the task as its stack. If a task is created using
|
||||||
* xTaskCreateStatic() therefore allows tasks to be created without any dynamic
|
* xTaskCreate() then both blocks of memory are automatically dynamically
|
||||||
* memory allocation.
|
* allocated inside the xTaskCreate() function. (see
|
||||||
|
* http://www.freertos.org/a00111.html). If a task is created using
|
||||||
|
* xTaskCreateStatic() then the application writer can instead optionally
|
||||||
|
* provide the memory that will get used by the task. xTaskCreateStatic()
|
||||||
|
* therefore allows a task to be created without using any dynamic memory
|
||||||
|
* allocation.
|
||||||
*
|
*
|
||||||
* @param pvTaskCode Pointer to the task entry function. Tasks
|
* @param pvTaskCode Pointer to the task entry function. Tasks
|
||||||
* must be implemented to never return (i.e. continuous loop).
|
* must be implemented to never return (i.e. continuous loop).
|
||||||
|
@ -395,15 +414,17 @@ is used in assert() statements. */
|
||||||
*
|
*
|
||||||
* @param pxStackBuffer If pxStackBuffer is NULL then the stack used by the
|
* @param pxStackBuffer If pxStackBuffer is NULL then the stack used by the
|
||||||
* task will be allocated dynamically, just as if the task was created using
|
* task will be allocated dynamically, just as if the task was created using
|
||||||
* xTaskCreate(). if pxStackBuffer is not NULL then it must point to a
|
* xTaskCreate(). If pxStackBuffer is not NULL then it must point to a
|
||||||
* StackType_t array that has at least usStackDepth indexes - the array will
|
* StackType_t array that has at least usStackDepth indexes - the array will
|
||||||
* then be used as the task's stack.
|
* then be used as the task's stack, removing the need for the stack to be
|
||||||
|
* allocated dynamically.
|
||||||
*
|
*
|
||||||
* @param pxTCBBuffer If pxTCBBuffer is NULL then the TCB (which is the
|
* @param pxTaskBuffer If pxTaskBuffer is NULL then the memory used to hold the
|
||||||
* structures used internally within FreeRTOS to hold information on the task)
|
* task's data structures will be allocated dynamically, just as when a task is
|
||||||
* will be allocated dynamically, just as when xTaskCreate() is used. If
|
* created using xTaskCreate(). If pxTaskBuffer is not NULL then it must point
|
||||||
* pxTCBBuffer is not NULL then it must point to a variable of type StaticTask_t,
|
* to a variable of type StaticTask_t, which will then be used to hold the
|
||||||
* which will then be used as the TCB of the task being created.
|
* 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
|
* @return pdPASS if the task was successfully created and added to a ready
|
||||||
* list, otherwise an error code defined in the file projdefs.h
|
* list, otherwise an error code defined in the file projdefs.h
|
||||||
|
@ -418,7 +439,7 @@ is used in assert() statements. */
|
||||||
#define STACK_SIZE 200
|
#define STACK_SIZE 200
|
||||||
|
|
||||||
// Structure that will hold the TCB of the task being created.
|
// Structure that will hold the TCB of the task being created.
|
||||||
StaticTask_t xTCB;
|
StaticTask_t xTaskBuffer;
|
||||||
|
|
||||||
// Buffer that the task being created will use as its stack.
|
// Buffer that the task being created will use as its stack.
|
||||||
StackType_t xStack[ STACK_SIZE ];
|
StackType_t xStack[ STACK_SIZE ];
|
||||||
|
@ -446,14 +467,14 @@ is used in assert() statements. */
|
||||||
tskIDLE_PRIORITY, // As per xTaskCreate() parameter.
|
tskIDLE_PRIORITY, // As per xTaskCreate() parameter.
|
||||||
&xHandle, // As per xTaskCreate() parameter.
|
&xHandle, // As per xTaskCreate() parameter.
|
||||||
xStack, // Pointer to the buffer that the task being created will use as its stack.
|
xStack, // Pointer to the buffer that the task being created will use as its stack.
|
||||||
&xTCB ); // Pointer to a structure in which the TCB of the task being created will be stored.
|
&xTaskBuffer ); // Pointer to a StaticTask_t structure for use as the memory require by the task.
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
* \defgroup xTaskCreateStatic xTaskCreateStatic
|
* \defgroup xTaskCreateStatic xTaskCreateStatic
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
#define xTaskCreateStatic( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, puxStackBuffer, pxDummyTCB ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( puxStackBuffer ), ( pxDummyTCB ), ( NULL ) )
|
#define xTaskCreateStatic( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, puxStackBuffer, pxTaskBuffer ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( puxStackBuffer ), ( pxTaskBuffer ), ( NULL ) )
|
||||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2095,7 +2116,7 @@ BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGE
|
||||||
* Generic version of the task creation function which is in turn called by the
|
* Generic version of the task creation function which is in turn called by the
|
||||||
* xTaskCreate() and xTaskCreateRestricted() macros.
|
* xTaskCreate() and xTaskCreateRestricted() macros.
|
||||||
*/
|
*/
|
||||||
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, StaticTask_t * const pxTCBBuffer, const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer, const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the uxTCBNumber assigned to the task referenced by the xTask parameter.
|
* Get the uxTCBNumber assigned to the task referenced by the xTask parameter.
|
||||||
|
|
|
@ -135,9 +135,18 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
||||||
* void * pvTimerID,
|
* void * pvTimerID,
|
||||||
* TimerCallbackFunction_t pxCallbackFunction );
|
* TimerCallbackFunction_t pxCallbackFunction );
|
||||||
*
|
*
|
||||||
* Creates a new software timer instance. This allocates the storage required
|
* Creates a new software timer instance, and returns a handle by which the
|
||||||
* by the new timer, initialises the new timers internal state, and returns a
|
* created software timer can be referenced.
|
||||||
* handle by which the new timer can be referenced.
|
*
|
||||||
|
* Internally, within the FreeRTOS implementation, software timer's use a block
|
||||||
|
* of memory, in which the timer data structure is stored. If a software timer
|
||||||
|
* is created using xTimerCreate() then the required memory is automatically
|
||||||
|
* dynamically allocated inside the xTimerCreate() function. (see
|
||||||
|
* 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.
|
||||||
*
|
*
|
||||||
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
||||||
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
||||||
|
@ -259,8 +268,136 @@ typedef void (*PendedFunction_t)( void *, uint32_t );
|
||||||
*/
|
*/
|
||||||
#define xTimerCreate( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction ) xTimerGenericCreate( ( pcTimerName ), ( xTimerPeriodInTicks ), ( uxAutoReload ), ( pvTimerID ), ( pxCallbackFunction ), NULL )
|
#define xTimerCreate( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction ) xTimerGenericCreate( ( pcTimerName ), ( xTimerPeriodInTicks ), ( uxAutoReload ), ( pvTimerID ), ( pxCallbackFunction ), NULL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TimerHandle_t xTimerCreateStatic(const char * const pcTimerName,
|
||||||
|
* TickType_t xTimerPeriodInTicks,
|
||||||
|
* UBaseType_t uxAutoReload,
|
||||||
|
* void * pvTimerID,
|
||||||
|
* TimerCallbackFunction_t pxCallbackFunction,
|
||||||
|
* StaticTimer_t *pxTimerBuffer );
|
||||||
|
*
|
||||||
|
* Creates a new software timer instance, and returns a handle by which the
|
||||||
|
* created software timer can be referenced.
|
||||||
|
*
|
||||||
|
* Internally, within the FreeRTOS implementation, software timer's use a block
|
||||||
|
* of memory, in which the timer data structure is stored. If a software timer
|
||||||
|
* is created using xTimerCreate() then the required memory is automatically
|
||||||
|
* dynamically allocated inside the xTimerCreate() function. (see
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
||||||
|
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
||||||
|
* xTimerChangePeriodFromISR() API functions can all be used to transition a
|
||||||
|
* timer into the active state.
|
||||||
|
*
|
||||||
|
* @param pcTimerName A text name that is assigned to the timer. This is done
|
||||||
|
* purely to assist debugging. The kernel itself only ever references a timer
|
||||||
|
* by its handle, and never by its name.
|
||||||
|
*
|
||||||
|
* @param xTimerPeriodInTicks The timer period. The time is defined in tick
|
||||||
|
* periods so the constant portTICK_PERIOD_MS can be used to convert a time that
|
||||||
|
* has been specified in milliseconds. For example, if the timer must expire
|
||||||
|
* after 100 ticks, then xTimerPeriodInTicks should be set to 100.
|
||||||
|
* Alternatively, if the timer must expire after 500ms, then xPeriod can be set
|
||||||
|
* to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or
|
||||||
|
* equal to 1000.
|
||||||
|
*
|
||||||
|
* @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will
|
||||||
|
* expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter.
|
||||||
|
* If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
|
||||||
|
* enter the dormant state after it expires.
|
||||||
|
*
|
||||||
|
* @param pvTimerID An identifier that is assigned to the timer being created.
|
||||||
|
* Typically this would be used in the timer callback function to identify which
|
||||||
|
* timer expired when the same callback function is assigned to more than one
|
||||||
|
* timer.
|
||||||
|
*
|
||||||
|
* @param pxCallbackFunction The function to call when the timer expires.
|
||||||
|
* Callback functions must have the prototype defined by TimerCallbackFunction_t,
|
||||||
|
* which is "void vCallbackFunction( TimerHandle_t xTimer );".
|
||||||
|
*
|
||||||
|
* @param pxTimerBuffer If pxTimerBuffer is NULL then the memory required to
|
||||||
|
* hold the software timer's data structure will be allocated dynamically, just
|
||||||
|
* as when a software timer is created using xTimerCreate(). If pxTimerBuffer
|
||||||
|
* is not NULL then it must point to a variable of type StaticTimer_t, which
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
* @verbatim
|
||||||
|
*
|
||||||
|
* // The buffer used to hold the software timer's data structure.
|
||||||
|
* static StaticTimer_t xTimerBuffer;
|
||||||
|
*
|
||||||
|
* // A variable that will be incremented by the software timer's callback
|
||||||
|
* // function.
|
||||||
|
* UBaseType_t uxVariableToIncrement = 0;
|
||||||
|
*
|
||||||
|
* // A software timer callback function that increments a variable passed to
|
||||||
|
* // it when the software timer was created. After the 5th increment the
|
||||||
|
* // callback function stops the software timer.
|
||||||
|
* static void prvTimerCallback( TimerHandle_t xExpiredTimer )
|
||||||
|
* {
|
||||||
|
* UBaseType_t *puxVariableToIncrement;
|
||||||
|
* BaseType_t xReturned;
|
||||||
|
*
|
||||||
|
* // Obtain the address of the variable to increment from the timer ID.
|
||||||
|
* puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer );
|
||||||
|
*
|
||||||
|
* // Increment the variable to show the timer callback has executed.
|
||||||
|
* ( *puxVariableToIncrement )++;
|
||||||
|
*
|
||||||
|
* // If this callback has executed the required number of times, stop the
|
||||||
|
* // timer.
|
||||||
|
* if( *puxVariableToIncrement == 5 )
|
||||||
|
* {
|
||||||
|
* // This is called from a timer callback so must not block.
|
||||||
|
* xTimerStop( xExpiredTimer, staticDONT_BLOCK );
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* void main( void )
|
||||||
|
* {
|
||||||
|
* // Create the software time. xTimerCreateStatic() has an extra parameter
|
||||||
|
* // than the normal xTimerCreate() API function. The parameter is a pointer
|
||||||
|
* // to the StaticTimer_t structure that will hold the software timer
|
||||||
|
* // structure. If the parameter is passed as NULL then the structure will be
|
||||||
|
* // allocated dynamically, just as if xTimerCreate() had been called.
|
||||||
|
* xTimer = xTimerCreateStatic( "T1", // Text name for the task. Helps debugging only. Not used by FreeRTOS.
|
||||||
|
* xTimerPeriod, // The period of the timer in ticks.
|
||||||
|
* pdTRUE, // This is an auto-reload timer.
|
||||||
|
* ( void * ) &uxVariableToIncrement, // A variable incremented by the software timer's callback function
|
||||||
|
* prvTimerCallback, // The function to execute when the timer expires.
|
||||||
|
* &xTimerBuffer ); // The buffer that will hold the software timer structure.
|
||||||
|
*
|
||||||
|
* // The scheduler has not started yet so a block time is not used.
|
||||||
|
* xReturned = xTimerStart( xTimer, 0 );
|
||||||
|
*
|
||||||
|
* // ...
|
||||||
|
* // Create tasks here.
|
||||||
|
* // ...
|
||||||
|
*
|
||||||
|
* // Starting the scheduler will start the timers running as they have already
|
||||||
|
* // been set into the active state.
|
||||||
|
* xTaskStartScheduler();
|
||||||
|
*
|
||||||
|
* // Should not reach here.
|
||||||
|
* for( ;; );
|
||||||
|
* }
|
||||||
|
* @endverbatim
|
||||||
|
*/
|
||||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
#define xTimerCreateStatic( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxStaticTimer ) xTimerGenericCreate( ( pcTimerName ), ( xTimerPeriodInTicks ), ( uxAutoReload ), ( pvTimerID ), ( pxCallbackFunction ), pxStaticTimer )
|
#define xTimerCreateStatic( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxTimerBuffer ) xTimerGenericCreate( ( pcTimerName ), ( xTimerPeriodInTicks ), ( uxAutoReload ), ( pvTimerID ), ( pxCallbackFunction ), ( pxTimerBuffer ) )
|
||||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1140,7 +1277,7 @@ const char * pcTimerGetTimerName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*
|
||||||
*/
|
*/
|
||||||
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
|
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
|
||||||
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
TimerHandle_t xTimerGenericCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxStaticTimer ) 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;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -554,7 +554,7 @@ static void prvResetNextTaskUnblockTime( void );
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, StaticTask_t * const pxTCBBuffer, const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer, const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
TCB_t * pxNewTCB;
|
TCB_t * pxNewTCB;
|
||||||
|
@ -565,7 +565,7 @@ StackType_t *pxTopOfStack;
|
||||||
|
|
||||||
/* Allocate the memory required by the TCB and stack for the new task,
|
/* Allocate the memory required by the TCB and stack for the new task,
|
||||||
checking that the allocation was successful. */
|
checking that the allocation was successful. */
|
||||||
pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer, ( TCB_t* ) pxTCBBuffer ); /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
|
pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer, ( TCB_t* ) pxTaskBuffer ); /*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( pxNewTCB != NULL )
|
if( pxNewTCB != NULL )
|
||||||
{
|
{
|
||||||
|
@ -3145,7 +3145,7 @@ static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer, TCB_t * const pxTCBBuffer )
|
static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer, TCB_t * const pxTaskBuffer )
|
||||||
{
|
{
|
||||||
TCB_t *pxNewTCB;
|
TCB_t *pxNewTCB;
|
||||||
|
|
||||||
|
@ -3166,7 +3166,7 @@ TCB_t *pxNewTCB;
|
||||||
{
|
{
|
||||||
/* Allocate space for the TCB. Where the memory comes from depends on
|
/* Allocate space for the TCB. Where the memory comes from depends on
|
||||||
the implementation of the port malloc function. */
|
the implementation of the port malloc function. */
|
||||||
pxNewTCB = ( TCB_t * ) pvPortMallocAligned( sizeof( TCB_t ), pxTCBBuffer );
|
pxNewTCB = ( TCB_t * ) pvPortMallocAligned( sizeof( TCB_t ), pxTaskBuffer );
|
||||||
|
|
||||||
if( pxNewTCB != NULL )
|
if( pxNewTCB != NULL )
|
||||||
{
|
{
|
||||||
|
@ -3179,7 +3179,7 @@ TCB_t *pxNewTCB;
|
||||||
{
|
{
|
||||||
/* Could not allocate the stack. Delete the allocated TCB - if
|
/* Could not allocate the stack. Delete the allocated TCB - if
|
||||||
it was allocated dynamically. */
|
it was allocated dynamically. */
|
||||||
if( pxTCBBuffer == NULL )
|
if( pxTaskBuffer == NULL )
|
||||||
{
|
{
|
||||||
vPortFree( pxNewTCB );
|
vPortFree( pxNewTCB );
|
||||||
}
|
}
|
||||||
|
@ -3197,7 +3197,7 @@ TCB_t *pxNewTCB;
|
||||||
if( pxStack != NULL )
|
if( pxStack != NULL )
|
||||||
{
|
{
|
||||||
/* Allocate space for the TCB. */
|
/* Allocate space for the TCB. */
|
||||||
pxNewTCB = ( TCB_t * ) pvPortMallocAligned( sizeof( TCB_t ), pxTCBBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some paths. */
|
pxNewTCB = ( TCB_t * ) pvPortMallocAligned( sizeof( TCB_t ), pxTaskBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some paths. */
|
||||||
|
|
||||||
if( pxNewTCB != NULL )
|
if( pxNewTCB != NULL )
|
||||||
{
|
{
|
||||||
|
@ -3250,7 +3250,7 @@ TCB_t *pxNewTCB;
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pxTCBBuffer != NULL )
|
if( pxTaskBuffer != NULL )
|
||||||
{
|
{
|
||||||
/* The application provided its own TCB. Note the fact so no
|
/* The application provided its own TCB. Note the fact so no
|
||||||
attempt is made to delete the TCB if the task is deleted. */
|
attempt is made to delete the TCB if the task is deleted. */
|
||||||
|
|
|
@ -298,7 +298,7 @@ uint16_t usTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
TimerHandle_t xTimerGenericCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxStaticTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
TimerHandle_t xTimerGenericCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
{
|
{
|
||||||
Timer_t *pxNewTimer;
|
Timer_t *pxNewTimer;
|
||||||
|
|
||||||
|
@ -321,13 +321,13 @@ Timer_t *pxNewTimer;
|
||||||
{
|
{
|
||||||
/* If the user passed in a statically allocated timer structure then use
|
/* If the user passed in a statically allocated timer structure then use
|
||||||
it, otherwise allocate the structure dynamically. */
|
it, otherwise allocate the structure dynamically. */
|
||||||
if( pxStaticTimer == NULL )
|
if( pxTimerBuffer == NULL )
|
||||||
{
|
{
|
||||||
pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) );
|
pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pxNewTimer = ( Timer_t * ) pxStaticTimer;
|
pxNewTimer = ( Timer_t * ) pxTimerBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pxNewTimer != NULL )
|
if( pxNewTimer != NULL )
|
||||||
|
@ -345,14 +345,18 @@ Timer_t *pxNewTimer;
|
||||||
pxNewTimer->pxCallbackFunction = pxCallbackFunction;
|
pxNewTimer->pxCallbackFunction = pxCallbackFunction;
|
||||||
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
|
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
|
||||||
|
|
||||||
if( pxStaticTimer == NULL )
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
{
|
{
|
||||||
pxNewTimer->ucStaticallyAllocated = pdFALSE;
|
if( pxTimerBuffer == NULL )
|
||||||
}
|
{
|
||||||
else
|
pxNewTimer->ucStaticallyAllocated = pdFALSE;
|
||||||
{
|
}
|
||||||
pxNewTimer->ucStaticallyAllocated = pdTRUE;
|
else
|
||||||
|
{
|
||||||
|
pxNewTimer->ucStaticallyAllocated = pdTRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
traceTIMER_CREATE( pxNewTimer );
|
traceTIMER_CREATE( pxNewTimer );
|
||||||
}
|
}
|
||||||
|
@ -763,14 +767,22 @@ TickType_t xTimeNow;
|
||||||
/* The timer has already been removed from the active list,
|
/* The timer has already been removed from the active list,
|
||||||
just free up the memory if the memory was dynamically
|
just free up the memory if the memory was dynamically
|
||||||
allocated. */
|
allocated. */
|
||||||
if( pxTimer->ucStaticallyAllocated == pdFALSE )
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
if( pxTimer->ucStaticallyAllocated == pdFALSE )
|
||||||
|
{
|
||||||
|
vPortFree( pxTimer );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
vPortFree( pxTimer );
|
vPortFree( pxTimer );
|
||||||
}
|
}
|
||||||
else
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
{
|
|
||||||
mtCOVERAGE_TEST_MARKER();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
|
|
Loading…
Reference in a new issue