Implement functionality that allows the memory required to create a queue or semaphore to be allocated statically.

Update the standard demo task that tests statically allocated tasks to also test statically allocated queues.
This commit is contained in:
Richard Barry 2016-01-19 13:41:28 +00:00
parent eae4815bf3
commit cf0ed4e2ac
10 changed files with 592 additions and 211 deletions

View file

@ -922,7 +922,7 @@ typedef struct xSTATIC_TCB
eDummy eDummy19;
#endif
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
UBaseType_t uxDummy20;
uint8_t uxDummy20;
#endif
} StaticTCB_t;
@ -964,6 +964,8 @@ typedef struct xSTATIC_QUEUE
} StaticQueue_t;
typedef StaticQueue_t StaticSemaphore_t;
#ifdef __cplusplus
}

View file

@ -170,7 +170,11 @@ typedef void * QueueSetMemberHandle_t;
* \defgroup xQueueCreate xQueueCreate
* \ingroup QueueManagement
*/
#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( uxQueueLength, uxItemSize, queueQUEUE_TYPE_BASE )
#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( uxQueueLength, uxItemSize, NULL, NULL, queueQUEUE_TYPE_BASE )
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
#define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue ) xQueueGenericCreate( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue, queueQUEUE_TYPE_BASE )
#endif
/**
* queue. h
@ -1554,7 +1558,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION
* Generic version of the queue creation function, which is in turn called by
* any queue, semaphore or mutex creation function or macro.
*/
QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
/*
* Queue sets provide a mechanism to allow a task to block (pend) on a read

View file

@ -87,6 +87,10 @@ typedef QueueHandle_t SemaphoreHandle_t;
* semphr. h
* <pre>vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )</pre>
*
* In many usage scenarios it is faster and more memory efficient to use a
* direct to task notification in place of a binary semaphore!
* http://www.freertos.org/RTOS-task-notifications.html
*
* This old vSemaphoreCreateBinary() macro is now deprecated in favour of the
* xSemaphoreCreateBinary() function. Note that binary semaphores created using
* the vSemaphoreCreateBinary() macro are created in a state such that the
@ -128,19 +132,23 @@ typedef QueueHandle_t SemaphoreHandle_t;
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
* \ingroup Semaphores
*/
#define vSemaphoreCreateBinary( xSemaphore ) \
{ \
( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
if( ( xSemaphore ) != NULL ) \
{ \
( void ) xSemaphoreGive( ( xSemaphore ) ); \
} \
#define vSemaphoreCreateBinary( xSemaphore ) \
{ \
( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, NULL, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
if( ( xSemaphore ) != NULL ) \
{ \
( void ) xSemaphoreGive( ( xSemaphore ) ); \
} \
}
/**
* semphr. h
* <pre>SemaphoreHandle_t xSemaphoreCreateBinary( void )</pre>
*
* In many usage scenarios it is faster and more memory efficient to use a
* direct to task notification in place of a binary semaphore!
* http://www.freertos.org/RTOS-task-notifications.html
*
* The old vSemaphoreCreateBinary() macro is now deprecated in favour of this
* xSemaphoreCreateBinary() function. Note that binary semaphores created using
* the vSemaphoreCreateBinary() macro are created in a state such that the
@ -182,7 +190,8 @@ typedef QueueHandle_t SemaphoreHandle_t;
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
* \ingroup Semaphores
*/
#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, NULL, queueQUEUE_TYPE_BINARY_SEMAPHORE )
#define xSemaphoreCreateBinaryStatic( pxStaticQueue ) xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticQueue, queueQUEUE_TYPE_BINARY_SEMAPHORE )
/**
* semphr. h
@ -849,7 +858,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
* semaphore is not available.
*
*/
#define xSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
#endif /* SEMAPHORE_H */

View file

@ -128,12 +128,6 @@ typedef enum
eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */
} eNotifyAction;
/* For data hiding purposes. */
typedef enum
{
eNothing = 0
} eDummy;
/*
* Used internally only.
*/
@ -197,58 +191,6 @@ typedef enum
eNotified
} eNotifyValue;
/*
* FreeRTOS implements a strict data hiding policy, so the real task control
* block (TCB) structure is not accessible to the application code. However, if
* the application writer wants to statically allocate a TCB then the size of
* the TCB needs to be know. The dummy TCB structure below is used for this
* purpose. Its size will allows match the size of the real TCB, no matter what
* the FreeRTOSConfig.h settings.
*/
typedef struct xDUMMY_TCB
{
void *pxDummy1;
#if ( portUSING_MPU_WRAPPERS == 1 )
xMPU_SETTINGS xDummy2;
#endif
ListItem_t xDummy3[ 2 ];
UBaseType_t uxDummy5;
void *pxDummy6;
uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ];
#if ( portSTACK_GROWTH > 0 )
void *pxDummy8;
#endif
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
UBaseType_t uxDummy9;
#endif
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxDummy10[ 2 ];
#endif
#if ( configUSE_MUTEXES == 1 )
UBaseType_t uxDummy12[ 2 ];
#endif
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
void *pxDummy14;
#endif
#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
void pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
#endif
#if ( configGENERATE_RUN_TIME_STATS == 1 )
uint32_t ulDummy16;
#endif
#if ( configUSE_NEWLIB_REENTRANT == 1 )
struct _reent xDummy17;
#endif
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
uint32_t ulDummy18;
eDummy eDummy19;
#endif
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
UBaseType_t uxDummy20;
#endif
} DummyTCB_t;
/**
* Defines the priority used by the idle task. This must not be modified.
*
@ -420,14 +362,14 @@ is used in assert() statements. */
UBaseType_t uxPriority,
TaskHandle_t *pvCreatedTask,
StackType_t *pxStackBuffer,
DummyTCB_t *pxTCBBuffer
StaticTCB_t *pxTCBBuffer
);</pre>
*
* 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
* 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
* using xTaskCreateStatic() then the application writer can optionally provide
* the buffers that will hold the task stack and TCB respectively.
* the buffers that will hold the task stack and TCB respectively.
* xTaskCreateStatic() therefore allows tasks to be created without any dynamic
* memory allocation.
*
@ -435,7 +377,7 @@ is used in assert() statements. */
* must be implemented to never return (i.e. continuous loop).
*
* @param pcName A descriptive name for the task. This is mainly used to
* facilitate debugging. The maximum length of the string is defined by
* facilitate debugging. The maximum length of the string is defined by
* configMAX_TASK_NAME_LEN in FreeRTOSConfig.h.
*
* @param usStackDepth The size of the task stack specified as the number of
@ -453,14 +395,14 @@ is used in assert() statements. */
*
* @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
* 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
* then be used as the task's stack.
*
* @param pxTCBBuffer If pxTCBBuffer is NULL then the TCB (which is the
* structures used internally within FreeRTOS to hold information on the task)
* will be allocated dynamically, just as when xTaskCreate() is used. If
* pxTCBBuffer is not NULL then it must point to a variable of type DummyTCB_T,
* pxTCBBuffer is not NULL then it must point to a variable of type StaticTCB_t,
* which will then be used as the TCB of the task being created.
*
* @return pdPASS if the task was successfully created and added to a ready
@ -476,11 +418,11 @@ is used in assert() statements. */
#define STACK_SIZE 200
// Structure that will hold the TCB of the task being created.
DummyTCB_t xTCB;
StaticTCB_t xTCB;
// Buffer that the task being created will use as its stack.
StackType_t xStack[ STACK_SIZE ];
// Task to be created.
void vTaskCode( void * pvParameters )
{
@ -500,7 +442,7 @@ is used in assert() statements. */
xTaskCreate( vTaskCode, // As per xTaskCreate() parameter.
"NAME", // As per xTaskCreate() parameter.
STACK_SIZE, // As per xTaskCreate() parameter.
&ucParameterToPass, // As per xTaskCreate() parameter.
&ucParameterToPass, // As per xTaskCreate() parameter.
tskIDLE_PRIORITY, // As per xTaskCreate() parameter.
&xHandle, // As per xTaskCreate() parameter.
xStack, // Pointer to the buffer that the task being created will use as its stack.
@ -2153,7 +2095,7 @@ BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGE
* Generic version of the task creation function which is in turn called by the
* 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, DummyTCB_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, StaticTCB_t * const pxTCBBuffer, 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.