- Rework the StaticAllocation.c common demo file to reflect the changes to the static allocation object create functions from the previous check-in.

- Correct various typos in comments.
- Add xTimerGetPeriod() function (feature request).
pull/4/head
Richard Barry 9 years ago
parent 9dda62372c
commit 26d3770fad

@ -407,28 +407,53 @@ const uint32_t ulMaxDivisor = 0xff, ulDivisorShift = 0x08;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )
{
/* 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
stack and to hold its TCB. If these are set to NULL then the buffers will
be allocated dynamically, just as if xTaskCreate() had been called. */
*ppxIdleTaskTCBBuffer = NULL;
*ppxIdleTaskStackBuffer = NULL;
*pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words. NOT in bytes! */
/* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pusIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )
{
/* 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
task as its stack and to hold its TCB. If these are set to NULL then the
buffers will be allocated dynamically, just as if xTaskCreate() had been
called. */
*ppxTimerTaskTCBBuffer = NULL;
*ppxTimerTaskStackBuffer = NULL;
*pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words. NOT in bytes! */
/* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pusTimerTaskStackSize = configMINIMAL_STACK_SIZE;
}

@ -222,28 +222,52 @@ void vApplicationTickHook( void )
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )
{
/* 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
stack and to hold its TCB. If these are set to NULL then the buffers will
be allocated dynamically, just as if xTaskCreate() had been called. */
*ppxIdleTaskTCBBuffer = NULL;
*ppxIdleTaskStackBuffer = NULL;
*pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words. NOT in bytes! */
/* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pusIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )
{
/* 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
task as its stack and to hold its TCB. If these are set to NULL then the
buffers will be allocated dynamically, just as if xTaskCreate() had been
called. */
*ppxTimerTaskTCBBuffer = NULL;
*ppxTimerTaskStackBuffer = NULL;
*pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words. NOT in bytes! */
/* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pusTimerTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/

@ -229,27 +229,51 @@ void vApplicationTickHook( void )
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )
{
/* 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
stack and to hold its TCB. If these are set to NULL then the buffers will
be allocated dynamically, just as if xTaskCreate() had been called. */
*ppxIdleTaskTCBBuffer = NULL;
*ppxIdleTaskStackBuffer = NULL;
*pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words. NOT in bytes! */
/* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pusIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )
{
/* 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
task as its stack and to hold its TCB. If these are set to NULL then the
buffers will be allocated dynamically, just as if xTaskCreate() had been
called. */
*ppxTimerTaskTCBBuffer = NULL;
*ppxTimerTaskStackBuffer = NULL;
*pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words. NOT in bytes! */
/* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pusTimerTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/

@ -234,30 +234,54 @@ void vApplicationTickHook( void )
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )
{
/* 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
stack and to hold its TCB. If these are set to NULL then the buffers will
be allocated dynamically, just as if xTaskCreate() had been called. */
*ppxIdleTaskTCBBuffer = NULL;
*ppxIdleTaskStackBuffer = NULL;
*pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words. NOT in bytes! */
/* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pusIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )
{
/* 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
task as its stack and to hold its TCB. If these are set to NULL then the
buffers will be allocated dynamically, just as if xTaskCreate() had been
called. */
*ppxTimerTaskTCBBuffer = NULL;
*ppxTimerTaskStackBuffer = NULL;
*pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words. NOT in bytes! */
/* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pusTimerTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/

@ -73,6 +73,8 @@
* rather than the normal dynamically allocated memory, and tests objects being
* created and deleted with both statically allocated memory and dynamically
* allocated memory.
*
* See http://www.FreeRTOS.org/Static_Vs_Dynamic_Memory_Allocation.html
*/
/* Scheduler include files. */
@ -130,59 +132,51 @@ static void prvTimerCallback( TimerHandle_t xExpiredTimer );
static void prvStaticallyAllocatedTask( void *pvParameters );
/*
* 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.
* A function that demonstrates and tests the API functions that create and
* delete tasks using both statically and dynamically allocated TCBs and stacks.
*/
static void prvCreateAndDeleteStaticallyAllocatedTasks( void );
/*
* A function that demonstrates and tests the xEventGroupCreateStatic() API
* function by creating and then deleting event groups using both dynamically
* and statically allocated event group structures.
* A function that demonstrates and tests the API functions that create and
* delete event groups using both statically and dynamically allocated RAM.
*/
static void prvCreateAndDeleteStaticallyAllocatedEventGroups( 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.
* A function that demonstrates and tests the API functions that create and
* delete queues using both statically and dynamically allocated RAM.
*/
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.
* A function that demonstrates and tests the API functions that create and
* delete binary semaphores using both statically and dynamically allocated RAM.
*/
static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void );
/*
* A function that demonstrates and tests the xTimerCreateStatic() API macro by
* creating and then deleting software timers with both dynamically and
* statically allocated timer structures.
* A function that demonstrates and tests the API functions that create and
* delete software timers using both statically and dynamically allocated RAM.
*/
static void prvCreateAndDeleteStaticallyAllocatedTimers( void );
/*
* A function that demonstrates and tests the xSemaphoreCreateMutexStatic() API
* macro by creating and then deleting mutexes with both dynamically and
* statically allocated semaphore structures.
* A function that demonstrates and tests the API functions that create and
* delete mutexes using both statically and dynamically allocated RAM.
*/
static void prvCreateAndDeleteStaticallyAllocatedMutexes( void );
/*
* A function that demonstrates and tests the xSemaphoreCreateCountingStatic()
* API macro by creating and then deleting counting semaphores with both
* dynamically and statically allocated semaphore structures.
* A function that demonstrates and tests the API functions that create and
* delete counting semaphores using both statically and dynamically allocated
* RAM.
*/
static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void );
/*
* A function that demonstrates and tests the
* xSemaphoreCreateRecursiveMutexStatic() API macro by creating and then
* deleting recursive mutexes with both dynamically and statically allocated
* semaphore structures.
* A function that demonstrates and tests the API functions that create and
* delete recursive mutexes using both statically and dynamically allocated RAM.
*/
static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void );
@ -250,9 +244,8 @@ static volatile BaseType_t xErrorOccurred = pdFALSE;
void vStartStaticallyAllocatedTasks( void )
{
/* Create a single task, which then repeatedly creates and deletes the
task implemented by prvStaticallyAllocatedTask() at various different
priorities, and both with and without statically allocated TCB and stack. */
/* Create a single task, which then repeatedly creates and deletes the other
RTOS objects using both statically and dynamically allocated RAM. */
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. */
staticCREATOR_TASK_STACK_SIZE, /* Size of the buffer passed in as the stack - in words, not bytes! */
@ -274,16 +267,16 @@ static void prvStaticallyAllocatedCreator( void *pvParameters )
for( ;; )
{
/* Loop, running functions that create and delete the various objects
that can be optionally created using either static or dynamic memory
allocation. */
/* Loop, running functions that create and delete the various RTOS
objects that can be optionally created using either static or dynamic
memory allocation. */
prvCreateAndDeleteStaticallyAllocatedTasks();
prvCreateAndDeleteStaticallyAllocatedQueues();
/* Ensure lower priority tasks get CPU time. */
/* Delay to ensure lower priority tasks get CPU time, and increment the
cycle counter so a 'check' task can determine that this task is still
executing. */
vTaskDelay( prvGetNextDelayTime() );
/* Just to show the check task that this task is still executing. */
uxCycleCounter++;
prvCreateAndDeleteStaticallyAllocatedBinarySemaphores();
@ -304,237 +297,6 @@ static void prvStaticallyAllocatedCreator( void *pvParameters )
}
/*-----------------------------------------------------------*/
static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup )
{
EventBits_t xEventBits;
const EventBits_t xFirstTestBits = ( EventBits_t ) 0xaa, xSecondTestBits = ( EventBits_t ) 0x55;
/* The event group should not have any bits set yet. */
xEventBits = xEventGroupGetBits( xEventGroup );
if( xEventBits != ( EventBits_t ) 0 )
{
xErrorOccurred = pdTRUE;
}
/* Some some bits, then read them back to check they are as expected. */
xEventGroupSetBits( xEventGroup, xFirstTestBits );
xEventBits = xEventGroupGetBits( xEventGroup );
if( xEventBits != xFirstTestBits )
{
xErrorOccurred = pdTRUE;
}
xEventGroupSetBits( xEventGroup, xSecondTestBits );
xEventBits = xEventGroupGetBits( xEventGroup );
if( xEventBits != ( xFirstTestBits | xSecondTestBits ) )
{
xErrorOccurred = pdTRUE;
}
/* Finally try clearing some bits too and check that operation proceeds as
expected. */
xEventGroupClearBits( xEventGroup, xFirstTestBits );
xEventBits = xEventGroupGetBits( xEventGroup );
if( xEventBits != xSecondTestBits )
{
xErrorOccurred = pdTRUE;
}
}
/*-----------------------------------------------------------*/
static void prvSanityCheckCreatedSemaphore( 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( ( ( TickType_t ) ( 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( ( ( TickType_t ) ( 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 prvSanityCheckCreatedQueue( 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 prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore )
{
const BaseType_t xLoops = 5;
BaseType_t x, xReturned;
/* A very basic test that the recursive semaphore behaved like a recursive
semaphore. First the semaphore should not be able to be given, as it has not
yet been taken. */
xReturned = xSemaphoreGiveRecursive( xSemaphore );
if( xReturned != pdFAIL )
{
xErrorOccurred = pdTRUE;
}
/* Now it should be possible to take the mutex a number of times. */
for( x = 0; x < xLoops; x++ )
{
xReturned = xSemaphoreTakeRecursive( xSemaphore, staticDONT_BLOCK );
if( xReturned != pdPASS )
{
xErrorOccurred = pdTRUE;
}
}
/* Should be possible to give the semaphore the same number of times as it
was given in the loop above. */
for( x = 0; x < xLoops; x++ )
{
xReturned = xSemaphoreGiveRecursive( xSemaphore );
if( xReturned != pdPASS )
{
xErrorOccurred = pdTRUE;
}
}
/* No more gives should be possible though. */
xReturned = xSemaphoreGiveRecursive( xSemaphore );
if( xReturned != pdFAIL )
{
xErrorOccurred = pdTRUE;
}
}
/*-----------------------------------------------------------*/
static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void )
{
SemaphoreHandle_t xSemaphore;
@ -552,7 +314,7 @@ a counting semaphore. http://www.freertos.org/RTOS-task-notifications.html */
StaticSemaphore_t xSemaphoreBuffer;
/* Create the semaphore. xSemaphoreCreateCountingStatic() has one more
parameter than the usual xSemaphoreCreateCounting() function. The paraemter
parameter than the usual xSemaphoreCreateCounting() function. The parameter
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
@ -568,6 +330,18 @@ StaticSemaphore_t xSemaphoreBuffer;
/* Delete the semaphore again so the buffers can be reused. */
vSemaphoreDelete( xSemaphore );
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{
/* Now do the same but using dynamically allocated buffers to ensure the
delete functions are working correctly in both the static and dynamic
allocation cases. */
xSemaphore = xSemaphoreCreateCounting( uxMaxCount, 0 );
configASSERT( xSemaphore != NULL );
prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount );
vSemaphoreDelete( xSemaphore );
}
#endif
}
/*-----------------------------------------------------------*/
@ -602,6 +376,18 @@ StaticSemaphore_t xSemaphoreBuffer;
/* Delete the semaphore again so the buffers can be reused. */
vSemaphoreDelete( xSemaphore );
/* Now do the same using dynamically allocated buffers to ensure the delete
functions are working correctly in both the static and dynamic memory
allocation cases. */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{
xSemaphore = xSemaphoreCreateRecursiveMutex();
configASSERT( xSemaphore != NULL );
prvSanityCheckCreatedRecursiveMutex( xSemaphore );
vSemaphoreDelete( xSemaphore );
}
#endif
}
/*-----------------------------------------------------------*/
@ -645,15 +431,35 @@ static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_
/* Delete the queue again so the buffers can be reused. */
vQueueDelete( xQueue );
}
/*-----------------------------------------------------------*/
static void prvCreateAndDeleteStaticallyAllocatedMutexes( void )
{
SemaphoreHandle_t xSemaphore;
BaseType_t xReturned;
/* Now do the same using a dynamically allocated queue to ensure the delete
function is working correctly in both the static and dynamic memory
allocation cases. */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{
xQueue = xQueueCreate( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
sizeof( uint64_t ) ); /* The size of each item. */
/* StaticSemaphore_t is a publicly accessible structure that has the same size
/* The queue handle should equal the static queue structure passed into the
xQueueCreateStatic() function. */
configASSERT( xQueue != NULL );
/* Ensure the queue passes a few sanity checks as a valid queue. */
prvSanityCheckCreatedQueue( xQueue );
/* Delete the queue again so the buffers can be reused. */
vQueueDelete( xQueue );
}
#endif
}
/*-----------------------------------------------------------*/
static void prvCreateAndDeleteStaticallyAllocatedMutexes( void )
{
SemaphoreHandle_t xSemaphore;
BaseType_t xReturned;
/* 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
@ -663,7 +469,7 @@ function calls within this function. */
StaticSemaphore_t xSemaphoreBuffer;
/* Create the semaphore. xSemaphoreCreateMutexStatic() has one more
parameter than the usual xSemaphoreCreateMutex() function. The paraemter
parameter than the usual xSemaphoreCreateMutex() function. The parameter
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
@ -688,6 +494,34 @@ StaticSemaphore_t xSemaphoreBuffer;
/* Delete the semaphore again so the buffers can be reused. */
vSemaphoreDelete( xSemaphore );
/* Now do the same using a dynamically allocated mutex to ensure the delete
function is working correctly in both the static and dynamic allocation
cases. */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{
xSemaphore = xSemaphoreCreateMutex();
/* The semaphore handle should equal the static semaphore structure
passed into the xSemaphoreCreateMutexStatic() function. */
configASSERT( xSemaphore != NULL );
/* Take the mutex so the mutex is in the state expected by the
prvSanityCheckCreatedSemaphore() function. */
xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );
if( xReturned != pdPASS )
{
xErrorOccurred = pdTRUE;
}
/* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
/* Delete the semaphore again so the buffers can be reused. */
vSemaphoreDelete( xSemaphore );
}
#endif
}
/*-----------------------------------------------------------*/
@ -707,7 +541,7 @@ a binary semaphore. http://www.freertos.org/RTOS-task-notifications.html */
StaticSemaphore_t xSemaphoreBuffer;
/* Create the semaphore. xSemaphoreCreateBinaryStatic() has one more
parameter than the usual xSemaphoreCreateBinary() function. The paraemter
parameter than the usual xSemaphoreCreateBinary() function. The parameter
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
@ -724,11 +558,21 @@ StaticSemaphore_t xSemaphoreBuffer;
/* Delete the semaphore again so the buffers can be reused. */
vSemaphoreDelete( xSemaphore );
/* Now do the same using a dynamically allocated semaphore to check the
delete function is working correctly in both the static and dynamic
allocation cases. */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{
xSemaphore = xSemaphoreCreateBinary();
configASSERT( xSemaphore != NULL );
prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
vSemaphoreDelete( xSemaphore );
}
#endif
/* 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. */
still functioning correctly. */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{
vSemaphoreCreateBinary( xSemaphore );
@ -752,7 +596,9 @@ static void prvTimerCallback( TimerHandle_t xExpiredTimer )
UBaseType_t *puxVariableToIncrement;
BaseType_t xReturned;
/* Obtain the address of the variable to increment from the timer ID. */
/* The timer callback just demonstrates it is executing by incrementing a
variable - the address of which is passed into the timer as its ID. Obtain
the address of the variable to increment. */
puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer );
/* Increment the variable to show the timer callback has executed. */
@ -762,7 +608,8 @@ BaseType_t xReturned;
timer. */
if( *puxVariableToIncrement == staticMAX_TIMER_CALLBACK_EXECUTIONS )
{
/* This is called from a timer callback so must not block. */
/* This is called from a timer callback so must not block. See
http://www.FreeRTOS.org/FreeRTOS-timers-xTimerStop.html */
xReturned = xTimerStop( xExpiredTimer, staticDONT_BLOCK );
if( xReturned != pdPASS )
@ -838,6 +685,43 @@ StaticTimer_t xTimerBuffer;
/* Just to show the check task that this task is still executing. */
uxCycleCounter++;
/* Now do the same using a dynamically allocated software timer to ensure
the delete function is working correctly in both the static and dynamic
allocation cases. */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{
xTimer = xTimerCreate( "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, /* The variable incremented by the test is passed into the timer callback using the timer ID. */
prvTimerCallback ); /* The function to execute when the timer expires. */
configASSERT( xTimer != NULL );
uxVariableToIncrement = 0;
xReturned = xTimerStart( xTimer, staticDONT_BLOCK );
if( xReturned != pdPASS )
{
xErrorOccurred = pdTRUE;
}
vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS );
if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS )
{
xErrorOccurred = pdTRUE;
}
xReturned = xTimerDelete( xTimer, staticDONT_BLOCK );
if( xReturned != pdPASS )
{
xErrorOccurred = pdTRUE;
}
}
#endif
}
/*-----------------------------------------------------------*/
@ -871,6 +755,18 @@ StaticEventGroup_t xEventGroupBuffer;
/* Delete the event group again so the buffers can be reused. */
vEventGroupDelete( xEventGroup );
/* Now do the same using a dynamically allocated event group to ensure the
delete function is working correctly in both the static and dynamic
allocation cases. */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{
xEventGroup = xEventGroupCreate();
configASSERT( xEventGroup != NULL );
prvSanityCheckCreatedEventGroup( xEventGroup );
vEventGroupDelete( xEventGroup );
}
#endif
}
/*-----------------------------------------------------------*/
@ -900,11 +796,18 @@ static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
"Static", /* Human readable name for the task. */
configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
NULL, /* Parameter to pass into the task. */
tskIDLE_PRIORITY, /* The priority of the task. */
uxTaskPriorityGet( NULL ) + 1, /* The priority of the task. */
&xCreatedTask, /* Handle of the task being created. */
&( uxStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */
&xTCBBuffer ); /* The variable that will hold that task's TCB. */
/* The created task had a higher priority so should have executed and
suspended itself by now. */
if( eTaskGetState( xCreatedTask ) != eSuspended )
{
xErrorOccurred = pdTRUE;
}
/* Check the task was created correctly, then delete the task. */
configASSERT( xReturned == pdPASS );
if( xReturned != pdPASS )
@ -912,6 +815,33 @@ static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
xErrorOccurred = pdTRUE;
}
vTaskDelete( xCreatedTask );
/* Now do the same using a dynamically allocated task to ensure the delete
function is working correctly in both the static and dynamic allocation
cases. */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{
xReturned = xTaskCreate(
prvStaticallyAllocatedTask, /* Function that implements the task. */
"Static", /* Human readable name for the task. */
configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
NULL, /* Parameter to pass into the task. */
uxTaskPriorityGet( NULL ) + 1, /* The priority of the task. */
&xCreatedTask ); /* Handle of the task being created. */
if( eTaskGetState( xCreatedTask ) != eSuspended )
{
xErrorOccurred = pdTRUE;
}
configASSERT( xReturned == pdPASS );
if( xReturned != pdPASS )
{
xErrorOccurred = pdTRUE;
}
vTaskDelete( xCreatedTask );
}
#endif
}
/*-----------------------------------------------------------*/
@ -919,7 +849,9 @@ static void prvStaticallyAllocatedTask( void *pvParameters )
{
( void ) pvParameters;
/* The created task doesn't do anything - just waits to get deleted. */
/* The created task just suspends itself to wait to get deleted. The task
that creates this task checks this task is in the expected Suspended state
before deleting it. */
vTaskSuspend( NULL );
}
/*-----------------------------------------------------------*/
@ -957,6 +889,237 @@ const TickType_t xTinyDelay = pdMS_TO_TICKS( ( TickType_t ) 2 );
}
/*-----------------------------------------------------------*/
static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup )
{
EventBits_t xEventBits;
const EventBits_t xFirstTestBits = ( EventBits_t ) 0xaa, xSecondTestBits = ( EventBits_t ) 0x55;
/* The event group should not have any bits set yet. */
xEventBits = xEventGroupGetBits( xEventGroup );
if( xEventBits != ( EventBits_t ) 0 )
{
xErrorOccurred = pdTRUE;
}
/* Some some bits, then read them back to check they are as expected. */
xEventGroupSetBits( xEventGroup, xFirstTestBits );
xEventBits = xEventGroupGetBits( xEventGroup );
if( xEventBits != xFirstTestBits )
{
xErrorOccurred = pdTRUE;
}
xEventGroupSetBits( xEventGroup, xSecondTestBits );
xEventBits = xEventGroupGetBits( xEventGroup );
if( xEventBits != ( xFirstTestBits | xSecondTestBits ) )
{
xErrorOccurred = pdTRUE;
}
/* Finally try clearing some bits too and check that operation proceeds as
expected. */
xEventGroupClearBits( xEventGroup, xFirstTestBits );
xEventBits = xEventGroupGetBits( xEventGroup );
if( xEventBits != xSecondTestBits )
{
xErrorOccurred = pdTRUE;
}
}
/*-----------------------------------------------------------*/
static void prvSanityCheckCreatedSemaphore( 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( ( ( TickType_t ) ( 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( ( ( TickType_t ) ( 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 prvSanityCheckCreatedQueue( 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 prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore )
{
const BaseType_t xLoops = 5;
BaseType_t x, xReturned;
/* A very basic test that the recursive semaphore behaved like a recursive
semaphore. First the semaphore should not be able to be given, as it has not
yet been taken. */
xReturned = xSemaphoreGiveRecursive( xSemaphore );
if( xReturned != pdFAIL )
{
xErrorOccurred = pdTRUE;
}
/* Now it should be possible to take the mutex a number of times. */
for( x = 0; x < xLoops; x++ )
{
xReturned = xSemaphoreTakeRecursive( xSemaphore, staticDONT_BLOCK );
if( xReturned != pdPASS )
{
xErrorOccurred = pdTRUE;
}
}
/* Should be possible to give the semaphore the same number of times as it
was given in the loop above. */
for( x = 0; x < xLoops; x++ )
{
xReturned = xSemaphoreGiveRecursive( xSemaphore );
if( xReturned != pdPASS )
{
xErrorOccurred = pdTRUE;
}
}
/* No more gives should be possible though. */
xReturned = xSemaphoreGiveRecursive( xSemaphore );
if( xReturned != pdFAIL )
{
xErrorOccurred = pdTRUE;
}
}
/*-----------------------------------------------------------*/
BaseType_t xAreStaticAllocationTasksStillRunning( void )
{
static UBaseType_t uxLastCycleCounter = 0;

@ -241,35 +241,52 @@ volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )
{
/* The buffers used by the idle task must be static so they are persistent, and
so exist after this function returns. */
/* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* configSUPORT_STATIC_ALLOCATION is set to 1 and
configSUPPORT_DYNAMIC_ALLOCATION is 0, so the application must supply the
buffers that will be used to hold the Idle task data structure and stack. */
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
*pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words. NOT in bytes! */
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pusIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )
{
/* The buffers used by the Timer/Daemon task must be static so they are
persistent, and so exist after this function returns. */
/* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* configSUPPORT_STATIC_ALLOCATION is set to 1,
configSUPPORT_DYNAMIC_ALLOCATION is set to 1, and configUSE_TIMERS is set
to 1, so the application must supply the buffers that will be used to hold
the Timer task data structure and stack. */
/* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
*pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words. NOT in bytes! */
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pusTimerTaskStackSize = configMINIMAL_STACK_SIZE;
}

@ -329,7 +329,7 @@ volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
( void ) ulLine;
( void ) pcFileName;
printf( "ASSERT! Line %d, file %s\r\n", ulLine, pcFileName );
printf( "ASSERT! Line %d, file %s, GetLastError() %d\r\n", ulLine, pcFileName, GetLastError() );
taskENTER_CRITICAL();
{
@ -410,38 +410,51 @@ const HeapRegion_t xHeapRegions[] =
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )
{
/* The buffers used by the idle task must be static so they are persistent, and
so exist after this function returns. */
/* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* 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
stack and to hold its TCB. If these are set to NULL then the buffers will
be allocated dynamically, just as if xTaskCreate() had been called. */
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
*pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words. NOT in bytes! */
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pusIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )
{
/* The buffers used by the Timer/Daemon task must be static so they are
persistent, and so exist after this function returns. The stack buffer is
not declared here, but globally, as it is checked by a test in a different
file. */
/* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
/* configUSE_STATIC_ALLOCATION is set to 1, so the application has the
opportunity to supply the buffers that will be used by the Timer/RTOS daemon
task as its stack and to hold its TCB. If these are set to NULL then the
buffers will be allocated dynamically, just as if xTaskCreate() had been
called. */
/* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
*pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words. NOT in bytes! */
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pusTimerTaskStackSize = configMINIMAL_STACK_SIZE;
}

@ -1616,7 +1616,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION
#endif
/*
* The registry is provided as a means for kernel aware debuggers to
* The queue registry is provided as a means for kernel aware debuggers to
* locate queues, semaphores and mutexes. Call pcQueueGetQueueName() to look
* up and return the name of a queue in the queue registry from the queue's
* handle.

@ -1152,11 +1152,11 @@ typedef QueueHandle_t SemaphoreHandle_t;
/**
* semphr.h
* <pre>TaskHandle_t xSemaphoreGetCount( SemaphoreHandle_t xMutex );</pre>
* <pre>UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xMutex );</pre>
*
* If the semaphore is a counting semaphore then xSemaphoreGetCount() returns
* If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns
* its current count value. If the semaphore is a binary semaphore then
* xSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the
* uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the
* semaphore is not available.
*
*/

Loading…
Cancel
Save