mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
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:
parent
eae4815bf3
commit
cf0ed4e2ac
|
@ -405,7 +405,7 @@ const uint32_t ulMaxDivisor = 0xff, ulDivisorShift = 0x08;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vApplicationGetIdleTaskMemory( DummyTCB_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )
|
void vApplicationGetIdleTaskMemory( StaticTCB_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )
|
||||||
{
|
{
|
||||||
/* configUSE_STATIC_ALLOCATION is set to 1, so the application has the
|
/* configUSE_STATIC_ALLOCATION is set to 1, so the application has the
|
||||||
opportunity to supply the buffers that will be used by the Idle task as its
|
opportunity to supply the buffers that will be used by the Idle task as its
|
||||||
|
@ -417,7 +417,7 @@ void vApplicationGetIdleTaskMemory( DummyTCB_t **ppxIdleTaskTCBBuffer, StackType
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vApplicationGetTimerTaskMemory( DummyTCB_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )
|
void vApplicationGetTimerTaskMemory( StaticTCB_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )
|
||||||
{
|
{
|
||||||
/* configUSE_STATIC_ALLOCATION is set to 1, so the application has the
|
/* 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
|
opportunity to supply the buffers that will be used by the Timer/RTOS daemon
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
[{000214A0-0000-0000-C000-000000000046}]
|
||||||
|
Prop3=19,2
|
||||||
|
[InternetShortcut]
|
||||||
|
URL=http://www.freertos.org/Atmel_SAMV7_Cortex-M7_RTOS_Demo.html
|
||||||
|
IDList=
|
|
@ -72,7 +72,10 @@
|
||||||
* In this case, there was difficulty generating interrupts from TC1, so only
|
* In this case, there was difficulty generating interrupts from TC1, so only
|
||||||
* TC0 is used. Nested interrupts are instead generated by manually pending the
|
* TC0 is used. Nested interrupts are instead generated by manually pending the
|
||||||
* TC1 interrupt from inside the TC0 interrupt handler. This means TC1 must be
|
* TC1 interrupt from inside the TC0 interrupt handler. This means TC1 must be
|
||||||
* assigned an interrupt priority above TC0.
|
* assigned an interrupt priority above TC0. [Note this arrangement does not
|
||||||
|
* really fulfil the purpose of the test as the nesting always occurs at the
|
||||||
|
* same point in the code, whereas the test is designed to test nesting
|
||||||
|
* occurring within the queue API functions]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
|
|
|
@ -70,12 +70,11 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Demonstrates how to create FreeRTOS objects using pre-allocated memory,
|
* Demonstrates how to create FreeRTOS objects using pre-allocated memory,
|
||||||
* rather than the normal dynamically allocated memory. Currently only tasks
|
* rather than the normal dynamically allocated memory.
|
||||||
* are being allocated statically.
|
|
||||||
*
|
*
|
||||||
* Two buffers are required by a task - one that is used by the task as its
|
* Two buffers are required by a task - one that is used by the task as its
|
||||||
* stack, and one that holds the task's control block (TCB).
|
* stack, and one that holds the task's control block (TCB).
|
||||||
* prvStaticallyAllocatedTaskCreator() creates and deletes tasks with all
|
* prvStaticallyAllocatedCreator() creates and deletes tasks with all
|
||||||
* possible combinations of statically allocated and dynamically allocated
|
* possible combinations of statically allocated and dynamically allocated
|
||||||
* stacks and TCBs.
|
* stacks and TCBs.
|
||||||
*/
|
*/
|
||||||
|
@ -83,6 +82,8 @@
|
||||||
/* Scheduler include files. */
|
/* Scheduler include files. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
/* Demo program include files. */
|
/* Demo program include files. */
|
||||||
#include "StaticAllocation.h"
|
#include "StaticAllocation.h"
|
||||||
|
@ -90,26 +91,60 @@
|
||||||
/* Exclude the entire file if configSUPPORT_STATIC_ALLOCATION is 0. */
|
/* Exclude the entire file if configSUPPORT_STATIC_ALLOCATION is 0. */
|
||||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
|
||||||
|
/* The priority at which the task that performs the tests is created. */
|
||||||
#define staticTASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
#define staticTASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||||
|
|
||||||
|
/* The length of the queue, in items, not bytes, used in the queue static
|
||||||
|
allocation tests. */
|
||||||
|
#define staticQUEUE_LENGTH_IN_ITEMS ( 5 )
|
||||||
|
|
||||||
|
/* A block time of 0 simply means "don't block". */
|
||||||
|
#define staticDONT_BLOCK ( ( TickType_t ) 0 )
|
||||||
|
|
||||||
|
/* Binary semaphores have a maximum count of 1. */
|
||||||
|
#define staticBINARY_SEMAPHORE_MAX_COUNT ( 1 )
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A task that is created multiple times, using both statically and dynamically
|
* A task that is created and deleted multiple times, using both statically and
|
||||||
* allocated stack and TCB.
|
* dynamically allocated stack and TCB.
|
||||||
*/
|
*/
|
||||||
static void prvStaticallyAllocatedTask( void *pvParameters );
|
static void prvStaticallyAllocatedTask( void *pvParameters );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The task that creates and deletes the prvStaticallyAllocatedTask() task,
|
* The task that repeatedly creates and deletes statically allocated tasks, and
|
||||||
* using various priorities, and sometimes with statically and sometimes
|
* other RTOS objects.
|
||||||
* dynamically allocated stack and TCB.
|
|
||||||
*/
|
*/
|
||||||
static void prvStaticallyAllocatedTaskCreator( void *pvParameters );
|
static void prvStaticallyAllocatedCreator( void *pvParameters );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility function to create pseudo random numbers.
|
* Utility function to create pseudo random numbers.
|
||||||
*/
|
*/
|
||||||
static UBaseType_t prvRand( void );
|
static UBaseType_t prvRand( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A function that demonstrates and tests the xTaskCreateStatic() API function
|
||||||
|
* by creating and then deleting tasks with both dynamically and statically
|
||||||
|
* allocated TCBs and stacks.
|
||||||
|
*/
|
||||||
|
static void prvCreateAndDeleteStaticallyAllocatedTasks( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A function that demonstrates and tests the xQueueCreateStatic() API function
|
||||||
|
* by creating and then deleting queues with both dynamically and statically
|
||||||
|
* allocated queue structures and queue storage areas.
|
||||||
|
*/
|
||||||
|
static void prvCreateAndDeleteStaticallyAllocatedQueues( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A function that demonstrates and tests the xSemaphoreCreateBinaryStatic() API
|
||||||
|
* macro by creating and then deleting binary semaphores with both dynamically
|
||||||
|
* and statically allocated semaphore structures.
|
||||||
|
*/
|
||||||
|
static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The task that creates and deletes other tasks has to delay occasionally to
|
* The task that creates and deletes other tasks has to delay occasionally to
|
||||||
* ensure lower priority tasks are not starved of processing time. A pseudo
|
* ensure lower priority tasks are not starved of processing time. A pseudo
|
||||||
|
@ -118,21 +153,32 @@ static UBaseType_t prvRand( void );
|
||||||
*/
|
*/
|
||||||
static TickType_t prvGetNextDelayTime( void );
|
static TickType_t prvGetNextDelayTime( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks the basic operation of a queue after it has been created.
|
||||||
|
*/
|
||||||
|
static void prvCheckQueueFunction( QueueHandle_t xQueue );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks the basic operation of a binary semaphore after it has been created.
|
||||||
|
*/
|
||||||
|
static void prvCheckSemaphoreFunction( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* DummyTCB_t is a publicly accessible structure that has the same size and
|
/* StaticTCB_t is a publicly accessible structure that has the same size and
|
||||||
alignment requirements as the real TCB structure. It is provided as a mechanism
|
alignment requirements as the real TCB structure. It is provided as a mechanism
|
||||||
for applications to know the size of the TCB (which is dependent on the
|
for applications to know the size of the TCB (which is dependent on the
|
||||||
architecture and configuration file settings) without breaking the strict data
|
architecture and configuration file settings) without breaking the strict data
|
||||||
hiding policy by exposing the real TCB. This DummyTCB_t variable is passed into
|
hiding policy by exposing the real TCB. This StaticTCB_t variable is passed
|
||||||
the xTaskCreateStatic() function, and will hold the task's TCB. */
|
into the xTaskCreateStatic() function that creates the
|
||||||
static DummyTCB_t xTCBBuffer;
|
prvStaticallyAllocatedCreator() task, and will hold the TCB of the created
|
||||||
|
tasks. */
|
||||||
|
static StaticTCB_t xCreatorTaskTCBBuffer;
|
||||||
|
|
||||||
/* This is the stack that will be used by the task. The alignment requirements
|
/* This is the stack that will be used by the prvStaticallyAllocatedCreator()
|
||||||
for the stack depend on the architecture, and the method of forcing an alignment
|
task, which is itself created using statically allocated buffers (so without any
|
||||||
is dependent on the compiler, but any bad alignment is corrected inside the
|
dynamic memory allocation). */
|
||||||
FreeRTOS code. */
|
static StackType_t uxCreatorTaskStackBuffer[ configMINIMAL_STACK_SIZE ];
|
||||||
static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
|
|
||||||
|
|
||||||
/* Used by the pseudo random number generating function. */
|
/* Used by the pseudo random number generating function. */
|
||||||
static uint32_t ulNextRand = 0;
|
static uint32_t ulNextRand = 0;
|
||||||
|
@ -141,6 +187,9 @@ static uint32_t ulNextRand = 0;
|
||||||
stalled. */
|
stalled. */
|
||||||
static volatile UBaseType_t uxCycleCounter = 0;
|
static volatile UBaseType_t uxCycleCounter = 0;
|
||||||
|
|
||||||
|
/* A variable that gets set to pdTRUE if an error is detected. */
|
||||||
|
static BaseType_t xErrorOccurred = pdFALSE;
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vStartStaticallyAllocatedTasks( void )
|
void vStartStaticallyAllocatedTasks( void )
|
||||||
|
@ -148,27 +197,347 @@ void vStartStaticallyAllocatedTasks( void )
|
||||||
/* Create a single task, which then repeatedly creates and deletes the
|
/* Create a single task, which then repeatedly creates and deletes the
|
||||||
task implemented by prvStaticallyAllocatedTask() at various different
|
task implemented by prvStaticallyAllocatedTask() at various different
|
||||||
priorities, and both with and without statically allocated TCB and stack. */
|
priorities, and both with and without statically allocated TCB and stack. */
|
||||||
xTaskCreate( prvStaticallyAllocatedTaskCreator, "StatCreate", configMINIMAL_STACK_SIZE, NULL, staticTASK_PRIORITY, NULL );
|
xTaskCreateStatic( prvStaticallyAllocatedCreator, /* The function that implements the task being created. */
|
||||||
|
"StatCreate", /* Text name for the task - not used by the RTOS, its just to assist debugging. */
|
||||||
|
configMINIMAL_STACK_SIZE, /* Size of the buffer passed in as the stack - in words, not bytes! */
|
||||||
|
NULL, /* Parameter passed into the task - not used in this case. */
|
||||||
|
staticTASK_PRIORITY, /* Priority of the task. */
|
||||||
|
NULL, /* Handle of the task being created, not used in this case. */
|
||||||
|
&( uxCreatorTaskStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */
|
||||||
|
&xCreatorTaskTCBBuffer ); /* The variable that will hold the task's TCB. */
|
||||||
|
|
||||||
/* Pseudo seed the random number generator. */
|
/* Pseudo seed the random number generator. */
|
||||||
ulNextRand = ( uint32_t ) prvRand;
|
ulNextRand = ( uint32_t ) prvRand;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvStaticallyAllocatedTaskCreator( void *pvParameters )
|
static void prvStaticallyAllocatedCreator( void *pvParameters )
|
||||||
{
|
{
|
||||||
TaskHandle_t xCreatedTask;
|
|
||||||
BaseType_t xReturned;
|
|
||||||
|
|
||||||
/* Avoid compiler warnings. */
|
/* Avoid compiler warnings. */
|
||||||
( void ) pvParameters;
|
( void ) pvParameters;
|
||||||
|
|
||||||
for( ;; )
|
for( ;; )
|
||||||
{
|
{
|
||||||
|
prvCreateAndDeleteStaticallyAllocatedTasks();
|
||||||
|
prvCreateAndDeleteStaticallyAllocatedQueues();
|
||||||
|
prvCreateAndDeleteStaticallyAllocatedBinarySemaphores();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckSemaphoreFunction( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount )
|
||||||
|
{
|
||||||
|
BaseType_t xReturned;
|
||||||
|
UBaseType_t x;
|
||||||
|
const TickType_t xShortBlockTime = pdMS_TO_TICKS( 10 );
|
||||||
|
TickType_t xTickCount;
|
||||||
|
|
||||||
|
/* The binary semaphore should start 'empty', so a call to xSemaphoreTake()
|
||||||
|
should fail. */
|
||||||
|
xTickCount = xTaskGetTickCount();
|
||||||
|
xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );
|
||||||
|
|
||||||
|
if( ( xTaskGetTickCount() - xTickCount) < xShortBlockTime )
|
||||||
|
{
|
||||||
|
/* Did not block on the semaphore as long as expected. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xReturned != pdFAIL )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should be possible to 'give' the semaphore up to a maximum of uxMaxCount
|
||||||
|
times. */
|
||||||
|
for( x = 0; x < uxMaxCount; x++ )
|
||||||
|
{
|
||||||
|
xReturned = xSemaphoreGive( xSemaphore );
|
||||||
|
|
||||||
|
if( xReturned == pdFAIL )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Giving the semaphore again should fail, as it is 'full'. */
|
||||||
|
xReturned = xSemaphoreGive( xSemaphore );
|
||||||
|
|
||||||
|
if( xReturned != pdFAIL )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
configASSERT( uxSemaphoreGetCount( xSemaphore ) == uxMaxCount );
|
||||||
|
|
||||||
|
/* Should now be possible to 'take' the semaphore up to a maximum of
|
||||||
|
uxMaxCount times without blocking. */
|
||||||
|
for( x = 0; x < uxMaxCount; x++ )
|
||||||
|
{
|
||||||
|
xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );
|
||||||
|
|
||||||
|
if( xReturned == pdFAIL )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Back to the starting condition, where the semaphore should not be
|
||||||
|
available. */
|
||||||
|
xTickCount = xTaskGetTickCount();
|
||||||
|
xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );
|
||||||
|
|
||||||
|
if( ( xTaskGetTickCount() - xTickCount) < xShortBlockTime )
|
||||||
|
{
|
||||||
|
/* Did not block on the semaphore as long as expected. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xReturned != pdFAIL )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckQueueFunction( QueueHandle_t xQueue )
|
||||||
|
{
|
||||||
|
uint64_t ull, ullRead;
|
||||||
|
BaseType_t xReturned, xLoop;
|
||||||
|
|
||||||
|
/* This test is done twice to ensure the queue storage area wraps. */
|
||||||
|
for( xLoop = 0; xLoop < 2; xLoop++ )
|
||||||
|
{
|
||||||
|
/* A very basic test that the queue can be written to and read from as
|
||||||
|
expected. First the queue should be empty. */
|
||||||
|
xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );
|
||||||
|
if( xReturned != errQUEUE_EMPTY )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now it should be possible to write to the queue staticQUEUE_LENGTH_IN_ITEMS
|
||||||
|
times. */
|
||||||
|
for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )
|
||||||
|
{
|
||||||
|
xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );
|
||||||
|
if( xReturned != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should not now be possible to write to the queue again. */
|
||||||
|
xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );
|
||||||
|
if( xReturned != errQUEUE_FULL )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now read back from the queue to ensure the data read back matches that
|
||||||
|
written. */
|
||||||
|
for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )
|
||||||
|
{
|
||||||
|
xReturned = xQueueReceive( xQueue, &ullRead, staticDONT_BLOCK );
|
||||||
|
|
||||||
|
if( xReturned != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ullRead != ull )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The queue should be empty again. */
|
||||||
|
xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );
|
||||||
|
if( xReturned != errQUEUE_EMPTY )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCreateAndDeleteStaticallyAllocatedQueues( void )
|
||||||
|
{
|
||||||
|
QueueHandle_t xQueue;
|
||||||
|
|
||||||
|
/* StaticQueue_t is a publicly accessible structure that has the same size and
|
||||||
|
alignment requirements as the real queue structure. It is provided as a
|
||||||
|
mechanism for applications to know the size of the queue (which is dependent on
|
||||||
|
the architecture and configuration file settings) without breaking the strict
|
||||||
|
data hiding policy by exposing the real queue internals. This StaticQueue_t
|
||||||
|
variable is passed into the xQueueCreateStatic() function calls within this
|
||||||
|
function. */
|
||||||
|
static StaticQueue_t xStaticQueue;
|
||||||
|
|
||||||
|
/* The queue storage area must be large enough to hold the maximum number of
|
||||||
|
items it is possible for the queue to hold at any one time, which equals the
|
||||||
|
queue length (in items, not bytes) multiplied by the size of each item. In this
|
||||||
|
case the queue will hold staticQUEUE_LENGTH_IN_ITEMS 64-bit items. See
|
||||||
|
http://www.freertos.org/Embedded-RTOS-Queues.html */
|
||||||
|
static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_t ) ];
|
||||||
|
|
||||||
|
/* Create the queue. xQueueCreateStatic() has two more parameters than the
|
||||||
|
usual xQueueCreate() function. The first new paraemter is a pointer to the
|
||||||
|
pre-allocated queue storage area. The second new parameter is a pointer to
|
||||||
|
the StaticQueue_t structure that will hold the queue state information in
|
||||||
|
an anonymous way. If either pointer is passed as NULL then the respective
|
||||||
|
data will be allocated dynamically as if xQueueCreate() had been called. */
|
||||||
|
xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
|
||||||
|
sizeof( uint64_t ), /* The size of each item. */
|
||||||
|
ucQueueStorageArea, /* The buffer used to hold items within the queue. */
|
||||||
|
&xStaticQueue ); /* The static queue structure that will hold the state of the queue. */
|
||||||
|
|
||||||
|
/* The queue handle should equal the static queue structure passed into the
|
||||||
|
xQueueCreateStatic() function. */
|
||||||
|
configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue );
|
||||||
|
|
||||||
|
/* Ensure the queue passes a few sanity checks as a valid queue. */
|
||||||
|
prvCheckQueueFunction( xQueue );
|
||||||
|
|
||||||
|
/* Delete the queue again so the buffers can be reused. */
|
||||||
|
vQueueDelete( xQueue );
|
||||||
|
|
||||||
|
|
||||||
|
/* The queue created above had a statically allocated queue storage area and
|
||||||
|
queue structure. Repeat the above with three more times - with different
|
||||||
|
combinations of static and dynamic allocation. */
|
||||||
|
|
||||||
|
xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
|
||||||
|
sizeof( uint64_t ), /* The size of each item. */
|
||||||
|
NULL, /* Allocate the buffer used to hold items within the queue dynamically. */
|
||||||
|
&xStaticQueue ); /* The static queue structure that will hold the state of the queue. */
|
||||||
|
|
||||||
|
configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue );
|
||||||
|
prvCheckQueueFunction( xQueue );
|
||||||
|
vQueueDelete( xQueue );
|
||||||
|
|
||||||
|
/* Ensure lower priority tasks get CPU time. */
|
||||||
|
vTaskDelay( prvGetNextDelayTime() );
|
||||||
|
|
||||||
|
/* Just to show the check task that this task is still executing. */
|
||||||
|
uxCycleCounter++;
|
||||||
|
|
||||||
|
xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
|
||||||
|
sizeof( uint64_t ), /* The size of each item. */
|
||||||
|
ucQueueStorageArea, /* The buffer used to hold items within the queue. */
|
||||||
|
NULL ); /* The queue structure is allocated dynamically. */
|
||||||
|
|
||||||
|
prvCheckQueueFunction( xQueue );
|
||||||
|
vQueueDelete( xQueue );
|
||||||
|
|
||||||
|
xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
|
||||||
|
sizeof( uint64_t ), /* The size of each item. */
|
||||||
|
NULL, /* Allocate the buffer used to hold items within the queue dynamically. */
|
||||||
|
NULL ); /* The queue structure is allocated dynamically. */
|
||||||
|
|
||||||
|
prvCheckQueueFunction( xQueue );
|
||||||
|
vQueueDelete( xQueue );
|
||||||
|
|
||||||
|
/* Ensure lower priority tasks get CPU time. */
|
||||||
|
vTaskDelay( prvGetNextDelayTime() );
|
||||||
|
|
||||||
|
/* Just to show the check task that this task is still executing. */
|
||||||
|
uxCycleCounter++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void )
|
||||||
|
{
|
||||||
|
SemaphoreHandle_t xSemaphore;
|
||||||
|
|
||||||
|
/* StaticSemaphore_t is a publicly accessible structure that has the same size
|
||||||
|
and alignment requirements as the real semaphore structure. It is provided as a
|
||||||
|
mechanism for applications to know the size of the semaphore (which is dependent
|
||||||
|
on the architecture and configuration file settings) without breaking the strict
|
||||||
|
data hiding policy by exposing the real semaphore internals. This
|
||||||
|
StaticSemaphore_t variable is passed into the xSemaphoreCreateBinary() function
|
||||||
|
calls within this function. NOTE: In most usage scenarios now it is faster and
|
||||||
|
more memory efficient to use a direct to task notification instead of a binary
|
||||||
|
semaphore. http://www.freertos.org/RTOS-task-notifications.html */
|
||||||
|
static StaticSemaphore_t xSemaphoreBuffer; /* Static so it doesn't use too much stack space. */
|
||||||
|
|
||||||
|
/* Create the semaphore. xSemaphoreCreateBinaryStatic() has one more
|
||||||
|
parameter than the usual xSemaphoreCreateBinary() function. The paraemter
|
||||||
|
is a pointer to the pre-allocated StaticSemaphore_t structure, which will
|
||||||
|
hold information on the semaphore in an anonymous way. If the pointer is
|
||||||
|
passed as NULL then the structure will be allocated dynamically, just as
|
||||||
|
when xSemaphoreCreateBinary() is called. */
|
||||||
|
xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer );
|
||||||
|
|
||||||
|
/* The semaphore handle should equal the static semaphore structure passed
|
||||||
|
into the xSemaphoreCreateBinaryStatic() function. */
|
||||||
|
configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
|
||||||
|
|
||||||
|
/* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
|
||||||
|
prvCheckSemaphoreFunction( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
|
||||||
|
|
||||||
|
/* Delete the semaphore again so the buffers can be reused. */
|
||||||
|
vSemaphoreDelete( xSemaphore );
|
||||||
|
|
||||||
|
|
||||||
|
/* The semaphore created above had a statically allocated semaphore
|
||||||
|
structure. Repeat the above using NULL as the xSemaphoreCreateBinaryStatic()
|
||||||
|
parameter so the queue structure is instead allocated dynamically. */
|
||||||
|
xSemaphore = xSemaphoreCreateBinaryStatic( NULL );
|
||||||
|
|
||||||
|
/* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
|
||||||
|
prvCheckSemaphoreFunction( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
|
||||||
|
|
||||||
|
/* Delete the semaphore again so the buffers can be reused. */
|
||||||
|
vSemaphoreDelete( xSemaphore );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* There isn't a static version of the old and deprecated
|
||||||
|
vSemaphoreCreateBinary() macro (because its deprecated!), but check it is
|
||||||
|
still functioning correctly when configSUPPORT_STATIC_ALLOCATION is set to
|
||||||
|
1. */
|
||||||
|
vSemaphoreCreateBinary( xSemaphore );
|
||||||
|
|
||||||
|
/* The macro starts with the binary semaphore available, but the test
|
||||||
|
function expects it to be unavailable. */
|
||||||
|
if( xSemaphoreTake( xSemaphore, staticDONT_BLOCK ) == pdFAIL )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
prvCheckSemaphoreFunction( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
|
||||||
|
vSemaphoreDelete( xSemaphore );
|
||||||
|
|
||||||
|
/* Ensure lower priority tasks get CPU time. */
|
||||||
|
vTaskDelay( prvGetNextDelayTime() );
|
||||||
|
|
||||||
|
/* Just to show the check task that this task is still executing. */
|
||||||
|
uxCycleCounter++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCreateAndDeleteStaticallyAllocatedTasks( void )
|
||||||
|
{
|
||||||
|
TaskHandle_t xCreatedTask;
|
||||||
|
BaseType_t xReturned;
|
||||||
|
|
||||||
|
/* The variable that will hold the TCB of tasks created by this function. See
|
||||||
|
the comments above the declaration of the xCreatorTaskTCBBuffer variable for
|
||||||
|
more information. */
|
||||||
|
static StaticTCB_t xTCBBuffer; /* Static so it does not use too much stack space. */
|
||||||
|
|
||||||
|
/* This buffer that will be used as the stack of tasks created by this function.
|
||||||
|
See the comments above the declaration of the uxCreatorTaskStackBuffer[] array
|
||||||
|
above for more information. */
|
||||||
|
static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
|
||||||
|
|
||||||
/* Create the task. xTaskCreateStatic() has two more parameters than
|
/* Create the task. xTaskCreateStatic() has two more parameters than
|
||||||
the usual xTaskCreate() function. The first new parameter is a pointer to
|
the usual xTaskCreate() function. The first new parameter is a pointer to
|
||||||
the pre-allocated stack. The second new parameter is a pointer to the
|
the pre-allocated stack. The second new parameter is a pointer to the
|
||||||
DummyTCB_t structure that will hold the task's TCB. If either pointer is
|
StaticTCB_t structure that will hold the task's TCB. If either pointer is
|
||||||
passed as NULL then the respective object will be allocated dynamically as
|
passed as NULL then the respective object will be allocated dynamically as
|
||||||
if xTaskCreate() had been called. */
|
if xTaskCreate() had been called. */
|
||||||
xReturned = xTaskCreateStatic(
|
xReturned = xTaskCreateStatic(
|
||||||
|
@ -183,7 +552,10 @@ BaseType_t xReturned;
|
||||||
|
|
||||||
/* Check the task was created correctly, then delete the task. */
|
/* Check the task was created correctly, then delete the task. */
|
||||||
configASSERT( xReturned == pdPASS );
|
configASSERT( xReturned == pdPASS );
|
||||||
( void ) xReturned; /* In case configASSERT() is not defined. */
|
if( xReturned != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
vTaskDelete( xCreatedTask );
|
vTaskDelete( xCreatedTask );
|
||||||
|
|
||||||
/* Ensure lower priority tasks get CPU time. */
|
/* Ensure lower priority tasks get CPU time. */
|
||||||
|
@ -202,7 +574,10 @@ BaseType_t xReturned;
|
||||||
&xTCBBuffer ); /* The variable that will hold that task's TCB. */
|
&xTCBBuffer ); /* The variable that will hold that task's TCB. */
|
||||||
|
|
||||||
configASSERT( xReturned == pdPASS );
|
configASSERT( xReturned == pdPASS );
|
||||||
( void ) xReturned; /* In case configASSERT() is not defined. */
|
if( xReturned != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
vTaskDelete( xCreatedTask );
|
vTaskDelete( xCreatedTask );
|
||||||
|
|
||||||
/* Just to show the check task that this task is still executing. */
|
/* Just to show the check task that this task is still executing. */
|
||||||
|
@ -222,7 +597,10 @@ BaseType_t xReturned;
|
||||||
NULL ); /* This time dynamically allocate the TCB. */
|
NULL ); /* This time dynamically allocate the TCB. */
|
||||||
|
|
||||||
configASSERT( xReturned == pdPASS );
|
configASSERT( xReturned == pdPASS );
|
||||||
( void ) xReturned; /* In case configASSERT() is not defined. */
|
if( xReturned != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
vTaskDelete( xCreatedTask );
|
vTaskDelete( xCreatedTask );
|
||||||
|
|
||||||
/* Ensure lower priority tasks get CPU time. */
|
/* Ensure lower priority tasks get CPU time. */
|
||||||
|
@ -239,7 +617,10 @@ BaseType_t xReturned;
|
||||||
NULL ); /* This time dynamically allocate the stack and TCB. */
|
NULL ); /* This time dynamically allocate the stack and TCB. */
|
||||||
|
|
||||||
configASSERT( xReturned == pdPASS );
|
configASSERT( xReturned == pdPASS );
|
||||||
( void ) xReturned; /* In case configASSERT() is not defined. */
|
if( xReturned != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
vTaskDelete( xCreatedTask );
|
vTaskDelete( xCreatedTask );
|
||||||
|
|
||||||
/* Ensure lower priority tasks get CPU time. */
|
/* Ensure lower priority tasks get CPU time. */
|
||||||
|
@ -247,7 +628,6 @@ BaseType_t xReturned;
|
||||||
|
|
||||||
/* Just to show the check task that this task is still executing. */
|
/* Just to show the check task that this task is still executing. */
|
||||||
uxCycleCounter++;
|
uxCycleCounter++;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -299,13 +679,21 @@ static UBaseType_t uxLastCycleCounter = 0;
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
if( uxCycleCounter == uxLastCycleCounter )
|
if( uxCycleCounter == uxLastCycleCounter )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uxLastCycleCounter = uxCycleCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xErrorOccurred != pdFALSE )
|
||||||
{
|
{
|
||||||
xReturn = pdFAIL;
|
xReturn = pdFAIL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xReturn = pdPASS;
|
xReturn = pdPASS;
|
||||||
uxLastCycleCounter = uxCycleCounter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
|
|
|
@ -193,7 +193,7 @@ UBaseType_t ux;
|
||||||
/* We should be able to 'take' the semaphore countMAX_COUNT_VALUE times. */
|
/* We should be able to 'take' the semaphore countMAX_COUNT_VALUE times. */
|
||||||
for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )
|
for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )
|
||||||
{
|
{
|
||||||
configASSERT( xSemaphoreGetCount( xSemaphore ) == ( countMAX_COUNT_VALUE - ux ) );
|
configASSERT( uxSemaphoreGetCount( xSemaphore ) == ( countMAX_COUNT_VALUE - ux ) );
|
||||||
|
|
||||||
if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) != pdPASS )
|
if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) != pdPASS )
|
||||||
{
|
{
|
||||||
|
@ -210,7 +210,7 @@ UBaseType_t ux;
|
||||||
|
|
||||||
/* If the semaphore count is zero then we should not be able to 'take'
|
/* If the semaphore count is zero then we should not be able to 'take'
|
||||||
the semaphore. */
|
the semaphore. */
|
||||||
configASSERT( xSemaphoreGetCount( xSemaphore ) == 0 );
|
configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 );
|
||||||
if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS )
|
if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS )
|
||||||
{
|
{
|
||||||
xErrorDetected = pdTRUE;
|
xErrorDetected = pdTRUE;
|
||||||
|
@ -232,7 +232,7 @@ UBaseType_t ux;
|
||||||
/* We should be able to 'give' the semaphore countMAX_COUNT_VALUE times. */
|
/* We should be able to 'give' the semaphore countMAX_COUNT_VALUE times. */
|
||||||
for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )
|
for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )
|
||||||
{
|
{
|
||||||
configASSERT( xSemaphoreGetCount( xSemaphore ) == ux );
|
configASSERT( uxSemaphoreGetCount( xSemaphore ) == ux );
|
||||||
|
|
||||||
if( xSemaphoreGive( xSemaphore ) != pdPASS )
|
if( xSemaphoreGive( xSemaphore ) != pdPASS )
|
||||||
{
|
{
|
||||||
|
|
|
@ -922,7 +922,7 @@ typedef struct xSTATIC_TCB
|
||||||
eDummy eDummy19;
|
eDummy eDummy19;
|
||||||
#endif
|
#endif
|
||||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
UBaseType_t uxDummy20;
|
uint8_t uxDummy20;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} StaticTCB_t;
|
} StaticTCB_t;
|
||||||
|
@ -964,6 +964,8 @@ typedef struct xSTATIC_QUEUE
|
||||||
|
|
||||||
} StaticQueue_t;
|
} StaticQueue_t;
|
||||||
|
|
||||||
|
typedef StaticQueue_t StaticSemaphore_t;
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,11 @@ typedef void * QueueSetMemberHandle_t;
|
||||||
* \defgroup xQueueCreate xQueueCreate
|
* \defgroup xQueueCreate xQueueCreate
|
||||||
* \ingroup QueueManagement
|
* \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
|
* 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
|
* Generic version of the queue creation function, which is in turn called by
|
||||||
* any queue, semaphore or mutex creation function or macro.
|
* 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
|
* Queue sets provide a mechanism to allow a task to block (pend) on a read
|
||||||
|
|
|
@ -87,6 +87,10 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* <pre>vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )</pre>
|
* <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
|
* This old vSemaphoreCreateBinary() macro is now deprecated in favour of the
|
||||||
* xSemaphoreCreateBinary() function. Note that binary semaphores created using
|
* xSemaphoreCreateBinary() function. Note that binary semaphores created using
|
||||||
* the vSemaphoreCreateBinary() macro are created in a state such that the
|
* the vSemaphoreCreateBinary() macro are created in a state such that the
|
||||||
|
@ -130,7 +134,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
*/
|
*/
|
||||||
#define vSemaphoreCreateBinary( xSemaphore ) \
|
#define vSemaphoreCreateBinary( xSemaphore ) \
|
||||||
{ \
|
{ \
|
||||||
( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
|
( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, NULL, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
|
||||||
if( ( xSemaphore ) != NULL ) \
|
if( ( xSemaphore ) != NULL ) \
|
||||||
{ \
|
{ \
|
||||||
( void ) xSemaphoreGive( ( xSemaphore ) ); \
|
( void ) xSemaphoreGive( ( xSemaphore ) ); \
|
||||||
|
@ -141,6 +145,10 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* <pre>SemaphoreHandle_t xSemaphoreCreateBinary( void )</pre>
|
* <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
|
* The old vSemaphoreCreateBinary() macro is now deprecated in favour of this
|
||||||
* xSemaphoreCreateBinary() function. Note that binary semaphores created using
|
* xSemaphoreCreateBinary() function. Note that binary semaphores created using
|
||||||
* the vSemaphoreCreateBinary() macro are created in a state such that the
|
* the vSemaphoreCreateBinary() macro are created in a state such that the
|
||||||
|
@ -182,7 +190,8 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
|
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
|
||||||
* \ingroup Semaphores
|
* \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
|
* semphr. h
|
||||||
|
@ -849,7 +858,7 @@ typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
* semaphore is not available.
|
* semaphore is not available.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define xSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
|
#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
|
||||||
|
|
||||||
#endif /* SEMAPHORE_H */
|
#endif /* SEMAPHORE_H */
|
||||||
|
|
||||||
|
|
|
@ -128,12 +128,6 @@ typedef enum
|
||||||
eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */
|
eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */
|
||||||
} eNotifyAction;
|
} eNotifyAction;
|
||||||
|
|
||||||
/* For data hiding purposes. */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
eNothing = 0
|
|
||||||
} eDummy;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used internally only.
|
* Used internally only.
|
||||||
*/
|
*/
|
||||||
|
@ -197,58 +191,6 @@ typedef enum
|
||||||
eNotified
|
eNotified
|
||||||
} eNotifyValue;
|
} 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.
|
* Defines the priority used by the idle task. This must not be modified.
|
||||||
*
|
*
|
||||||
|
@ -420,7 +362,7 @@ is used in assert() statements. */
|
||||||
UBaseType_t uxPriority,
|
UBaseType_t uxPriority,
|
||||||
TaskHandle_t *pvCreatedTask,
|
TaskHandle_t *pvCreatedTask,
|
||||||
StackType_t *pxStackBuffer,
|
StackType_t *pxStackBuffer,
|
||||||
DummyTCB_t *pxTCBBuffer
|
StaticTCB_t *pxTCBBuffer
|
||||||
);</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.
|
||||||
|
@ -460,7 +402,7 @@ is used in assert() statements. */
|
||||||
* @param pxTCBBuffer If pxTCBBuffer is NULL then the TCB (which is the
|
* @param pxTCBBuffer If pxTCBBuffer is NULL then the TCB (which is the
|
||||||
* structures used internally within FreeRTOS to hold information on the task)
|
* structures used internally within FreeRTOS to hold information on the task)
|
||||||
* will be allocated dynamically, just as when xTaskCreate() is used. If
|
* 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.
|
* 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
|
* @return pdPASS if the task was successfully created and added to a ready
|
||||||
|
@ -476,7 +418,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.
|
||||||
DummyTCB_t xTCB;
|
StaticTCB_t xTCB;
|
||||||
|
|
||||||
// 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 ];
|
||||||
|
@ -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
|
* 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, 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.
|
* Get the uxTCBNumber assigned to the task referenced by the xTask parameter.
|
||||||
|
|
|
@ -239,6 +239,17 @@ static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvIte
|
||||||
*/
|
*/
|
||||||
static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION;
|
static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A queue requires two blocks of memory; a structure to hold the queue state
|
||||||
|
* and a storage area to hold the items in the queue. The memory is assigned
|
||||||
|
* by prvAllocateQueueMemory(). If ppucQueueStorage is NULL then the queue
|
||||||
|
* storage will allocated dynamically, otherwise the buffer passed in
|
||||||
|
* ppucQueueStorage will be used. If pxStaticQueue is NULL then the queue
|
||||||
|
* structure will be allocated dynamically, otherwise the buffer pointed to by
|
||||||
|
* pxStaticQueue will be used.
|
||||||
|
*/
|
||||||
|
static Queue_t *prvAllocateQueueMemory( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t **ppucQueueStorage, StaticQueue_t *pxStaticQueue );
|
||||||
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
/*
|
/*
|
||||||
* Checks to see if a queue is a member of a queue set, and if so, notifies
|
* Checks to see if a queue is a member of a queue set, and if so, notifies
|
||||||
|
@ -331,8 +342,8 @@ size_t xQueueSizeInBytes;
|
||||||
#if( ( configASSERT_DEFINED == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
#if( ( configASSERT_DEFINED == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||||
{
|
{
|
||||||
/* Sanity check that the size of the structure used to declare a
|
/* Sanity check that the size of the structure used to declare a
|
||||||
variable of type DummyQueue_t or DummySemaphore_t equals the size of the
|
variable of type StaticQueue_t or StaticSemaphore_t equals the size of
|
||||||
real queue and semaphore structures. */
|
the real queue and semaphore structures. */
|
||||||
volatile size_t xSize = sizeof( StaticQueue_t );
|
volatile size_t xSize = sizeof( StaticQueue_t );
|
||||||
configASSERT( xSize == sizeof( Queue_t ) );
|
configASSERT( xSize == sizeof( Queue_t ) );
|
||||||
}
|
}
|
||||||
|
@ -345,9 +356,9 @@ size_t xQueueSizeInBytes;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The queue is one byte longer than asked for to make wrap checking
|
/* Allocate enough space to hold the maximum number of items that can be
|
||||||
easier/faster. */
|
in the queue at any time. */
|
||||||
xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
|
xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#if( configSUPPORT_STATIC_ALLOCATION == 0 )
|
#if( configSUPPORT_STATIC_ALLOCATION == 0 )
|
||||||
|
@ -399,8 +410,17 @@ size_t xQueueSizeInBytes;
|
||||||
{
|
{
|
||||||
vPortFree( ( void * ) pxNewQueue );
|
vPortFree( ( void * ) pxNewQueue );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
pxNewQueue = NULL;
|
pxNewQueue = NULL;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1860,6 +1880,10 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||||
freed. */
|
freed. */
|
||||||
vPortFree( pxQueue->pcHead );
|
vPortFree( pxQueue->pcHead );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
if( ( pxQueue->ucStaticAllocationFlags & queueSTATICALLY_ALLOCATED_QUEUE_STRUCT ) == 0 )
|
if( ( pxQueue->ucStaticAllocationFlags & queueSTATICALLY_ALLOCATED_QUEUE_STRUCT ) == 0 )
|
||||||
{
|
{
|
||||||
|
@ -1867,6 +1891,10 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||||
free. */
|
free. */
|
||||||
vPortFree( pxQueue );
|
vPortFree( pxQueue );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue