mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-01 08:54:14 -04:00
Notes:
+ The MPU port is not supported in this revision number. + The documentation for the static allocation functions in the header files has not yet been updated for this revision. Kernel updates: + Simplify the static allocation of objects implementation. + Introduce configSUPPORT_DYNAMIC_ALLOCATION in addition to the existing configSUPPORT_STATIC_ALLOCATION so FreeRTOS can be built without providing a heap at all. Demo application updates: + Update the demos to take into account the new configSUPPORT_DYNAMIC_ALLOCATION constant. + Add an MSVC demo that only uses static allocation, and does not include a FreeRTOS heap. + Update the MSVC project to use both configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION. + Update the MingW project to use only configSUPPORT_DYNAMIC_ALLOCATION.
This commit is contained in:
parent
283bc18d23
commit
6568ba6eb0
50 changed files with 2350 additions and 3914 deletions
|
@ -398,13 +398,23 @@ uint32_t ulReturn;
|
|||
static void prvTestAbortingEventGroupWait( void )
|
||||
{
|
||||
TickType_t xTimeAtStart;
|
||||
static StaticEventGroup_t xEventGroupBuffer;
|
||||
EventGroupHandle_t xEventGroup;
|
||||
EventBits_t xBitsToWaitFor = ( EventBits_t ) 0x01, xReturn;
|
||||
|
||||
/* Create the event group. Statically allocated memory is used so the
|
||||
creation cannot fail. */
|
||||
xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
{
|
||||
static StaticEventGroup_t xEventGroupBuffer;
|
||||
|
||||
/* Create the event group. Statically allocated memory is used so the
|
||||
creation cannot fail. */
|
||||
xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
|
||||
}
|
||||
#else
|
||||
{
|
||||
xEventGroup = xEventGroupCreate();
|
||||
configASSERT( xEventGroup );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Note the time before the delay so the length of the delay is known. */
|
||||
xTimeAtStart = xTaskGetTickCount();
|
||||
|
@ -449,14 +459,25 @@ static void prvTestAbortingQueueSend( void )
|
|||
{
|
||||
TickType_t xTimeAtStart;
|
||||
BaseType_t xReturn;
|
||||
static StaticQueue_t xQueueBuffer;
|
||||
static uint8_t ucQueueStorage[ sizeof( uint8_t ) ], ucItemToQueue;
|
||||
const UBaseType_t xQueueLength = ( UBaseType_t ) 1;
|
||||
QueueHandle_t xQueue;
|
||||
uint8_t ucItemToQueue;
|
||||
|
||||
/* Create the queue. Statically allocated memory is used so the
|
||||
creation cannot fail. */
|
||||
xQueue = xQueueCreateStatic( xQueueLength, sizeof( uint8_t ), ucQueueStorage, &xQueueBuffer );
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
{
|
||||
static StaticQueue_t xQueueBuffer;
|
||||
static uint8_t ucQueueStorage[ sizeof( uint8_t ) ];
|
||||
|
||||
/* Create the queue. Statically allocated memory is used so the
|
||||
creation cannot fail. */
|
||||
xQueue = xQueueCreateStatic( xQueueLength, sizeof( uint8_t ), ucQueueStorage, &xQueueBuffer );
|
||||
}
|
||||
#else
|
||||
{
|
||||
xQueue = xQueueCreate( xQueueLength, sizeof( uint8_t ) );
|
||||
configASSERT( xQueue );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This function tests aborting when in the blocked state waiting to send,
|
||||
so the queue must be full. There is only one space in the queue. */
|
||||
|
@ -509,12 +530,21 @@ static void prvTestAbortingSemaphoreTake( void )
|
|||
{
|
||||
TickType_t xTimeAtStart;
|
||||
BaseType_t xReturn;
|
||||
static StaticSemaphore_t xSemaphoreBuffer;
|
||||
SemaphoreHandle_t xSemaphore;
|
||||
|
||||
/* Create the semaphore. Statically allocated memory is used so the
|
||||
creation cannot fail. */
|
||||
xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer );
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
{
|
||||
static StaticSemaphore_t xSemaphoreBuffer;
|
||||
|
||||
/* Create the semaphore. Statically allocated memory is used so the
|
||||
creation cannot fail. */
|
||||
xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer );
|
||||
}
|
||||
#else
|
||||
{
|
||||
xSemaphore = xSemaphoreCreateBinary();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Note the time before the delay so the length of the delay is known. */
|
||||
xTimeAtStart = xTaskGetTickCount();
|
||||
|
|
|
@ -104,6 +104,10 @@
|
|||
#define blckqSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||
#define blckqNUM_TASK_SETS ( 3 )
|
||||
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
|
||||
#error This example cannot be used if dynamic allocation is not allowed.
|
||||
#endif
|
||||
|
||||
/* Structure used to pass parameters to the blocking queue tasks. */
|
||||
typedef struct BLOCKING_QUEUE_PARAMETERS
|
||||
{
|
||||
|
|
|
@ -154,36 +154,42 @@ SemaphoreHandle_t xMutex;
|
|||
prvSendFrontAndBackTest demo. */
|
||||
xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( uint32_t ) );
|
||||
|
||||
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
|
||||
in use. The queue registry is provided as a means for kernel aware
|
||||
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( xQueue, "Gen_Queue_Test" );
|
||||
if( xQueue != NULL )
|
||||
{
|
||||
/* vQueueAddToRegistry() adds the queue to the queue registry, if one
|
||||
is in use. The queue registry is provided as a means for kernel aware
|
||||
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( xQueue, "Gen_Queue_Test" );
|
||||
|
||||
/* Create the demo task and pass it the queue just created. We are
|
||||
passing the queue handle by value so it does not matter that it is
|
||||
declared on the stack here. */
|
||||
xTaskCreate( prvSendFrontAndBackTest, "GenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL );
|
||||
/* Create the demo task and pass it the queue just created. We are
|
||||
passing the queue handle by value so it does not matter that it is
|
||||
declared on the stack here. */
|
||||
xTaskCreate( prvSendFrontAndBackTest, "GenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL );
|
||||
}
|
||||
|
||||
/* Create the mutex used by the prvMutexTest task. */
|
||||
xMutex = xSemaphoreCreateMutex();
|
||||
|
||||
/* vQueueAddToRegistry() adds the mutex to the registry, if one is
|
||||
in use. The registry is provided as a means for kernel aware
|
||||
debuggers to locate mutexes and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( ( QueueHandle_t ) xMutex, "Gen_Queue_Mutex" );
|
||||
if( xMutex != NULL )
|
||||
{
|
||||
/* vQueueAddToRegistry() adds the mutex to the registry, if one is
|
||||
in use. The registry is provided as a means for kernel aware
|
||||
debuggers to locate mutexes and has no purpose if a kernel aware
|
||||
debugger is not being used. The call to vQueueAddToRegistry() will be
|
||||
removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not
|
||||
defined or is defined to be less than 1. */
|
||||
vQueueAddToRegistry( ( QueueHandle_t ) xMutex, "Gen_Queue_Mutex" );
|
||||
|
||||
/* Create the mutex demo tasks and pass it the mutex just created. We are
|
||||
passing the mutex handle by value so it does not matter that it is declared
|
||||
on the stack here. */
|
||||
xTaskCreate( prvLowPriorityMutexTask, "MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );
|
||||
xTaskCreate( prvMediumPriorityMutexTask, "MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );
|
||||
xTaskCreate( prvHighPriorityMutexTask, "MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask );
|
||||
/* Create the mutex demo tasks and pass it the mutex just created. We
|
||||
are passing the mutex handle by value so it does not matter that it is
|
||||
declared on the stack here. */
|
||||
xTaskCreate( prvLowPriorityMutexTask, "MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );
|
||||
xTaskCreate( prvMediumPriorityMutexTask, "MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );
|
||||
xTaskCreate( prvHighPriorityMutexTask, "MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -134,17 +134,20 @@ static QueueHandle_t xPolledQueue;
|
|||
/* Create the queue used by the producer and consumer. */
|
||||
xPolledQueue = xQueueCreate( pollqQUEUE_SIZE, ( UBaseType_t ) sizeof( uint16_t ) );
|
||||
|
||||
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
|
||||
in use. The queue registry is provided as a means for kernel aware
|
||||
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( xPolledQueue, "Poll_Test_Queue" );
|
||||
if( xPolledQueue != NULL )
|
||||
{
|
||||
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
|
||||
in use. The queue registry is provided as a means for kernel aware
|
||||
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( xPolledQueue, "Poll_Test_Queue" );
|
||||
|
||||
/* Spawn the producer and consumer. */
|
||||
xTaskCreate( vPolledQueueConsumer, "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL );
|
||||
xTaskCreate( vPolledQueueProducer, "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL );
|
||||
/* Spawn the producer and consumer. */
|
||||
xTaskCreate( vPolledQueueConsumer, "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL );
|
||||
xTaskCreate( vPolledQueueProducer, "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -127,21 +127,24 @@ QueueHandle_t xQueue;
|
|||
/* Create the queue that we are going to use for the test/demo. */
|
||||
xQueue = xQueueCreate( qpeekQUEUE_LENGTH, sizeof( uint32_t ) );
|
||||
|
||||
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
|
||||
in use. The queue registry is provided as a means for kernel aware
|
||||
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( xQueue, "QPeek_Test_Queue" );
|
||||
if( xQueue != NULL )
|
||||
{
|
||||
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
|
||||
in use. The queue registry is provided as a means for kernel aware
|
||||
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( xQueue, "QPeek_Test_Queue" );
|
||||
|
||||
/* Create the demo tasks and pass it the queue just created. We are
|
||||
passing the queue handle by value so it does not matter that it is declared
|
||||
on the stack here. */
|
||||
xTaskCreate( prvLowPriorityPeekTask, "PeekL", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekLOW_PRIORITY, NULL );
|
||||
xTaskCreate( prvMediumPriorityPeekTask, "PeekM", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekMEDIUM_PRIORITY, &xMediumPriorityTask );
|
||||
xTaskCreate( prvHighPriorityPeekTask, "PeekH1", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGH_PRIORITY, &xHighPriorityTask );
|
||||
xTaskCreate( prvHighestPriorityPeekTask, "PeekH2", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGHEST_PRIORITY, &xHighestPriorityTask );
|
||||
/* Create the demo tasks and pass it the queue just created. We are
|
||||
passing the queue handle by value so it does not matter that it is declared
|
||||
on the stack here. */
|
||||
xTaskCreate( prvLowPriorityPeekTask, "PeekL", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekLOW_PRIORITY, NULL );
|
||||
xTaskCreate( prvMediumPriorityPeekTask, "PeekM", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekMEDIUM_PRIORITY, &xMediumPriorityTask );
|
||||
xTaskCreate( prvHighPriorityPeekTask, "PeekH1", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGH_PRIORITY, &xHighPriorityTask );
|
||||
xTaskCreate( prvHighestPriorityPeekTask, "PeekH2", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGHEST_PRIORITY, &xHighestPriorityTask );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -234,14 +234,18 @@ void vStartQueueSetTasks( void )
|
|||
{
|
||||
/* Create the tasks. */
|
||||
xTaskCreate( prvQueueSetSendingTask, "SetTx", configMINIMAL_STACK_SIZE, NULL, queuesetMEDIUM_PRIORITY, &xQueueSetSendingTask );
|
||||
xTaskCreate( prvQueueSetReceivingTask, "SetRx", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, queuesetMEDIUM_PRIORITY, &xQueueSetReceivingTask );
|
||||
|
||||
/* It is important that the sending task does not attempt to write to a
|
||||
queue before the queue has been created. It is therefore placed into the
|
||||
suspended state before the scheduler has started. It is resumed by the
|
||||
receiving task after the receiving task has created the queues and added the
|
||||
queues to the queue set. */
|
||||
vTaskSuspend( xQueueSetSendingTask );
|
||||
if( xQueueSetSendingTask != NULL )
|
||||
{
|
||||
xTaskCreate( prvQueueSetReceivingTask, "SetRx", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, queuesetMEDIUM_PRIORITY, &xQueueSetReceivingTask );
|
||||
|
||||
/* It is important that the sending task does not attempt to write to a
|
||||
queue before the queue has been created. It is therefore placed into
|
||||
the suspended state before the scheduler has started. It is resumed by
|
||||
the receiving task after the receiving task has created the queues and
|
||||
added the queues to the queue set. */
|
||||
vTaskSuspend( xQueueSetSendingTask );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -130,10 +130,14 @@ void vStartQueueSetPollingTask( void )
|
|||
the set. */
|
||||
xQueue = xQueueCreate( setpollQUEUE_LENGTH, sizeof( uint32_t ) );
|
||||
xQueueSet = xQueueCreateSet( setpollQUEUE_LENGTH );
|
||||
xQueueAddToSet( xQueue, xQueueSet );
|
||||
|
||||
/* Create the task. */
|
||||
xTaskCreate( prvQueueSetReceivingTask, "SetPoll", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
if( ( xQueue != NULL ) && ( xQueueSet != NULL ) )
|
||||
{
|
||||
xQueueAddToSet( xQueue, xQueueSet );
|
||||
|
||||
/* Create the task. */
|
||||
xTaskCreate( prvQueueSetReceivingTask, "SetPoll", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -279,10 +279,25 @@ static void prvStaticallyAllocatedCreator( void *pvParameters )
|
|||
allocation. */
|
||||
prvCreateAndDeleteStaticallyAllocatedTasks();
|
||||
prvCreateAndDeleteStaticallyAllocatedQueues();
|
||||
|
||||
/* Ensure lower priority tasks get CPU time. */
|
||||
vTaskDelay( prvGetNextDelayTime() );
|
||||
|
||||
/* Just to show the check task that this task is still executing. */
|
||||
uxCycleCounter++;
|
||||
|
||||
prvCreateAndDeleteStaticallyAllocatedBinarySemaphores();
|
||||
prvCreateAndDeleteStaticallyAllocatedCountingSemaphores();
|
||||
|
||||
vTaskDelay( prvGetNextDelayTime() );
|
||||
uxCycleCounter++;
|
||||
|
||||
prvCreateAndDeleteStaticallyAllocatedMutexes();
|
||||
prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes();
|
||||
|
||||
vTaskDelay( prvGetNextDelayTime() );
|
||||
uxCycleCounter++;
|
||||
|
||||
prvCreateAndDeleteStaticallyAllocatedEventGroups();
|
||||
prvCreateAndDeleteStaticallyAllocatedTimers();
|
||||
}
|
||||
|
@ -553,25 +568,6 @@ StaticSemaphore_t xSemaphoreBuffer;
|
|||
|
||||
/* 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 third
|
||||
xSemaphoreCreateCountingStatic() parameter so the semaphore structure is
|
||||
instead allocated dynamically. */
|
||||
xSemaphore = xSemaphoreCreateCountingStatic( uxMaxCount, 0, NULL );
|
||||
|
||||
/* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
|
||||
prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount );
|
||||
|
||||
/* Delete the semaphore again so the buffers can be reused. */
|
||||
vSemaphoreDelete( xSemaphore );
|
||||
|
||||
/* Ensure lower priority tasks get CPU time. */
|
||||
vTaskDelay( prvGetNextDelayTime() );
|
||||
|
||||
/* Just to show the check task that this task is still executing. */
|
||||
uxCycleCounter++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -606,25 +602,6 @@ StaticSemaphore_t xSemaphoreBuffer;
|
|||
|
||||
/* 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
|
||||
xSemaphoreCreateRecursiveMutexStatic() parameter so the semaphore structure
|
||||
is instead allocated dynamically. */
|
||||
xSemaphore = xSemaphoreCreateRecursiveMutexStatic( NULL );
|
||||
|
||||
/* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
|
||||
prvSanityCheckCreatedRecursiveMutex( xSemaphore );
|
||||
|
||||
/* Delete the semaphore again so the buffers can be reused. */
|
||||
vSemaphoreDelete( xSemaphore );
|
||||
|
||||
/* Ensure lower priority tasks get CPU time. */
|
||||
vTaskDelay( prvGetNextDelayTime() );
|
||||
|
||||
/* Just to show the check task that this task is still executing. */
|
||||
uxCycleCounter++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -649,11 +626,11 @@ 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
|
||||
usual xQueueCreate() function. The first new parameter 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. */
|
||||
an anonymous way. If the two pointers are passed as NULL then the 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. */
|
||||
|
@ -668,48 +645,6 @@ static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_
|
|||
|
||||
/* 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 );
|
||||
prvSanityCheckCreatedQueue( 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. */
|
||||
|
||||
prvSanityCheckCreatedQueue( 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. */
|
||||
|
||||
prvSanityCheckCreatedQueue( 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++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -753,33 +688,6 @@ StaticSemaphore_t xSemaphoreBuffer;
|
|||
|
||||
/* 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 xSemaphoreCreateMutexStatic()
|
||||
parameter so the semaphore structure is instead allocated dynamically. */
|
||||
xSemaphore = xSemaphoreCreateMutexStatic( 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 );
|
||||
|
||||
/* Ensure lower priority tasks get CPU time. */
|
||||
vTaskDelay( prvGetNextDelayTime() );
|
||||
|
||||
/* Just to show the check task that this task is still executing. */
|
||||
uxCycleCounter++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -817,40 +725,25 @@ StaticSemaphore_t xSemaphoreBuffer;
|
|||
vSemaphoreDelete( xSemaphore );
|
||||
|
||||
|
||||
/* The semaphore created above had a statically allocated semaphore
|
||||
structure. Repeat the above using NULL as the xSemaphoreCreateBinaryStatic()
|
||||
parameter so the semaphore structure is instead allocated dynamically. */
|
||||
xSemaphore = xSemaphoreCreateBinaryStatic( NULL );
|
||||
|
||||
/* 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 );
|
||||
|
||||
|
||||
|
||||
/* 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 )
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
{
|
||||
xErrorOccurred = pdTRUE;
|
||||
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;
|
||||
}
|
||||
|
||||
prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
|
||||
vSemaphoreDelete( xSemaphore );
|
||||
}
|
||||
|
||||
prvSanityCheckCreatedSemaphore( 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++;
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -945,43 +838,6 @@ StaticTimer_t xTimerBuffer;
|
|||
|
||||
/* Just to show the check task that this task is still executing. */
|
||||
uxCycleCounter++;
|
||||
|
||||
/* The software timer created above had a statically allocated timer
|
||||
structure. Repeat the above using NULL as the xTimerCreateStatic()
|
||||
parameter so the timer structure is instead allocated dynamically. */
|
||||
xTimer = xTimerCreateStatic( "T1", /* Text name for the task. Helps debugging only. Not used by FreeRTOS. */
|
||||
xTimerPeriod, /* The period of the timer in ticks. */
|
||||
pdTRUE, /* This is an auto-reload timer. */
|
||||
( void * ) &uxVariableToIncrement, /* 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. */
|
||||
NULL ); /* A buffer is not passed this time, so the timer should be allocated dynamically. */
|
||||
uxVariableToIncrement = 0;
|
||||
xReturned = xTimerStart( xTimer, staticDONT_BLOCK );
|
||||
|
||||
if( xReturned != pdPASS )
|
||||
{
|
||||
xErrorOccurred = pdTRUE;
|
||||
}
|
||||
|
||||
vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS );
|
||||
|
||||
/* Just to show the check task that this task is still executing. */
|
||||
uxCycleCounter++;
|
||||
|
||||
if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS )
|
||||
{
|
||||
xErrorOccurred = pdTRUE;
|
||||
}
|
||||
|
||||
xReturned = xTimerDelete( xTimer, staticDONT_BLOCK );
|
||||
|
||||
if( xReturned != pdPASS )
|
||||
{
|
||||
xErrorOccurred = pdTRUE;
|
||||
}
|
||||
|
||||
/* Just to show the check task that this task is still executing. */
|
||||
uxCycleCounter++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -1015,25 +871,6 @@ StaticEventGroup_t xEventGroupBuffer;
|
|||
|
||||
/* Delete the event group again so the buffers can be reused. */
|
||||
vEventGroupDelete( xEventGroup );
|
||||
|
||||
|
||||
/* The event group created above had a statically allocated event group
|
||||
structure. Repeat the above using NULL as the xEventGroupCreateStatic()
|
||||
parameter so the event group structure is instead allocated dynamically. */
|
||||
xEventGroup = xEventGroupCreateStatic( NULL );
|
||||
|
||||
/* Ensure the event group passes a few sanity checks as a valid event
|
||||
group. */
|
||||
prvSanityCheckCreatedEventGroup( xEventGroup );
|
||||
|
||||
/* Delete the event group again so the buffers can be reused. */
|
||||
vEventGroupDelete( xEventGroup );
|
||||
|
||||
/* Ensure lower priority tasks get CPU time. */
|
||||
vTaskDelay( prvGetNextDelayTime() );
|
||||
|
||||
/* Just to show the check task that this task is still executing. */
|
||||
uxCycleCounter++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -1055,7 +892,7 @@ static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
|
|||
/* Create the task. xTaskCreateStatic() has two more parameters than
|
||||
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
|
||||
StaticTask_t structure that will hold the task's TCB. If either pointer is
|
||||
StaticTask_t structure that will hold the task's TCB. If both pointers are
|
||||
passed as NULL then the respective object will be allocated dynamically as
|
||||
if xTaskCreate() had been called. */
|
||||
xReturned = xTaskCreateStatic(
|
||||
|
@ -1075,77 +912,6 @@ static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
|
|||
xErrorOccurred = pdTRUE;
|
||||
}
|
||||
vTaskDelete( xCreatedTask );
|
||||
|
||||
/* Ensure lower priority tasks get CPU time. */
|
||||
vTaskDelay( prvGetNextDelayTime() );
|
||||
|
||||
/* Create and delete the task a few times again - testing both static and
|
||||
dynamic allocation for the stack and TCB. */
|
||||
xReturned = xTaskCreateStatic(
|
||||
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. */
|
||||
staticTASK_PRIORITY + 1, /* The priority of the task. */
|
||||
&xCreatedTask, /* Handle of the task being created. */
|
||||
NULL, /* This time, dynamically allocate the stack. */
|
||||
&xTCBBuffer ); /* The variable that will hold that task's TCB. */
|
||||
|
||||
configASSERT( xReturned == pdPASS );
|
||||
if( xReturned != pdPASS )
|
||||
{
|
||||
xErrorOccurred = pdTRUE;
|
||||
}
|
||||
vTaskDelete( xCreatedTask );
|
||||
|
||||
/* Just to show the check task that this task is still executing. */
|
||||
uxCycleCounter++;
|
||||
|
||||
/* Ensure lower priority tasks get CPU time. */
|
||||
vTaskDelay( prvGetNextDelayTime() );
|
||||
|
||||
xReturned = xTaskCreateStatic(
|
||||
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. */
|
||||
staticTASK_PRIORITY - 1, /* The priority of the task. */
|
||||
&xCreatedTask, /* Handle of the task being created. */
|
||||
&( uxStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */
|
||||
NULL ); /* This time dynamically allocate the TCB. */
|
||||
|
||||
configASSERT( xReturned == pdPASS );
|
||||
if( xReturned != pdPASS )
|
||||
{
|
||||
xErrorOccurred = pdTRUE;
|
||||
}
|
||||
vTaskDelete( xCreatedTask );
|
||||
|
||||
/* Ensure lower priority tasks get CPU time. */
|
||||
vTaskDelay( prvGetNextDelayTime() );
|
||||
|
||||
xReturned = xTaskCreateStatic(
|
||||
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. */
|
||||
staticTASK_PRIORITY, /* The priority of the task. */
|
||||
&xCreatedTask, /* Handle of the task being created. */
|
||||
NULL, /* This time dynamically allocate the stack and TCB. */
|
||||
NULL ); /* This time dynamically allocate the stack and TCB. */
|
||||
|
||||
configASSERT( xReturned == pdPASS );
|
||||
if( xReturned != pdPASS )
|
||||
{
|
||||
xErrorOccurred = pdTRUE;
|
||||
}
|
||||
vTaskDelete( xCreatedTask );
|
||||
|
||||
/* Ensure lower priority tasks get CPU time. */
|
||||
vTaskDelay( prvGetNextDelayTime() );
|
||||
|
||||
/* Just to show the check task that this task is still executing. */
|
||||
uxCycleCounter++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -285,18 +285,16 @@ TickType_t xTimer;
|
|||
|
||||
for( xTimer = 0; xTimer < configTIMER_QUEUE_LENGTH; xTimer++ )
|
||||
{
|
||||
/* As the timer queue is not yet full, it should be possible to both create
|
||||
and start a timer. These timers are being started before the scheduler has
|
||||
been started, so their block times should get set to zero within the timer
|
||||
API itself. */
|
||||
/* As the timer queue is not yet full, it should be possible to both
|
||||
create and start a timer. These timers are being started before the
|
||||
scheduler has been started, so their block times should get set to zero
|
||||
within the timer API itself. */
|
||||
xAutoReloadTimers[ xTimer ] = xTimerCreate( "FR Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */
|
||||
( ( xTimer + ( TickType_t ) 1 ) * xBasePeriod ),/* The period for the timer. The plus 1 ensures a period of zero is not specified. */
|
||||
pdTRUE, /* Auto-reload is set to true. */
|
||||
( void * ) xTimer, /* An identifier for the timer as all the auto reload timers use the same callback. */
|
||||
prvAutoReloadTimerCallback ); /* The callback to be called when the timer expires. */
|
||||
|
||||
configASSERT( strcmp( pcTimerGetTimerName( xAutoReloadTimers[ xTimer ] ), "FR Timer" ) == 0 );
|
||||
|
||||
if( xAutoReloadTimers[ xTimer ] == NULL )
|
||||
{
|
||||
xTestStatus = pdFAIL;
|
||||
|
@ -304,6 +302,8 @@ TickType_t xTimer;
|
|||
}
|
||||
else
|
||||
{
|
||||
configASSERT( strcmp( pcTimerGetTimerName( xAutoReloadTimers[ xTimer ] ), "FR Timer" ) == 0 );
|
||||
|
||||
/* The scheduler has not yet started, so the block period of
|
||||
portMAX_DELAY should just get set to zero in xTimerStart(). Also,
|
||||
the timer queue is not yet full so xTimerStart() should return
|
||||
|
@ -402,7 +402,7 @@ UBaseType_t uxOriginalPriority;
|
|||
in the Blocked state. */
|
||||
uxOriginalPriority = uxTaskPriorityGet( NULL );
|
||||
vTaskPrioritySet( NULL, ( configMAX_PRIORITIES - 1 ) );
|
||||
|
||||
|
||||
/* Delaying for configTIMER_QUEUE_LENGTH * xBasePeriod ticks should allow
|
||||
all the auto reload timers to expire at least once. */
|
||||
xBlockPeriod = ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod;
|
||||
|
|
|
@ -134,19 +134,22 @@ static volatile UBaseType_t xRunIndicator;
|
|||
void vCreateBlockTimeTasks( void )
|
||||
{
|
||||
/* Create the queue on which the two tasks block. */
|
||||
xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( BaseType_t ) );
|
||||
xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( BaseType_t ) );
|
||||
|
||||
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
|
||||
in use. The queue registry is provided as a means for kernel aware
|
||||
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( xTestQueue, "Block_Time_Queue" );
|
||||
if( xTestQueue != NULL )
|
||||
{
|
||||
/* vQueueAddToRegistry() adds the queue to the queue registry, if one
|
||||
is in use. The queue registry is provided as a means for kernel aware
|
||||
debuggers to locate queues and has no purpose if a kernel aware
|
||||
debugger is not being used. The call to vQueueAddToRegistry() will be
|
||||
removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not
|
||||
defined or is defined to be less than 1. */
|
||||
vQueueAddToRegistry( xTestQueue, "Block_Time_Queue" );
|
||||
|
||||
/* Create the two test tasks. */
|
||||
xTaskCreate( vPrimaryBlockTimeTestTask, "BTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL );
|
||||
xTaskCreate( vSecondaryBlockTimeTestTask, "BTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary );
|
||||
/* Create the two test tasks. */
|
||||
xTaskCreate( vPrimaryBlockTimeTestTask, "BTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL );
|
||||
xTaskCreate( vSecondaryBlockTimeTestTask, "BTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -159,19 +159,18 @@ void vStartCountingSemaphoreTasks( void )
|
|||
xParameters[ 1 ].uxExpectedStartCount = 0;
|
||||
xParameters[ 1 ].uxLoopCounter = 0;
|
||||
|
||||
/* vQueueAddToRegistry() adds the semaphore to the registry, if one is
|
||||
in use. The registry is provided as a means for kernel aware
|
||||
debuggers to locate semaphores and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( ( QueueHandle_t ) xParameters[ 0 ].xSemaphore, "Counting_Sem_1" );
|
||||
vQueueAddToRegistry( ( QueueHandle_t ) xParameters[ 1 ].xSemaphore, "Counting_Sem_2" );
|
||||
|
||||
|
||||
/* Were the semaphores created? */
|
||||
if( ( xParameters[ 0 ].xSemaphore != NULL ) || ( xParameters[ 1 ].xSemaphore != NULL ) )
|
||||
{
|
||||
/* vQueueAddToRegistry() adds the semaphore to the registry, if one is
|
||||
in use. The registry is provided as a means for kernel aware
|
||||
debuggers to locate semaphores and has no purpose if a kernel aware
|
||||
debugger is not being used. The call to vQueueAddToRegistry() will be
|
||||
removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not
|
||||
defined or is defined to be less than 1. */
|
||||
vQueueAddToRegistry( ( QueueHandle_t ) xParameters[ 0 ].xSemaphore, "Counting_Sem_1" );
|
||||
vQueueAddToRegistry( ( QueueHandle_t ) xParameters[ 1 ].xSemaphore, "Counting_Sem_2" );
|
||||
|
||||
/* Create the demo tasks, passing in the semaphore to use as the parameter. */
|
||||
xTaskCreate( prvCountingSemaphoreTask, "CNT1", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 0 ] ), tskIDLE_PRIORITY, NULL );
|
||||
xTaskCreate( prvCountingSemaphoreTask, "CNT2", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 1 ] ), tskIDLE_PRIORITY, NULL );
|
||||
|
|
|
@ -129,14 +129,7 @@ TaskHandle_t xCreatedTask;
|
|||
|
||||
void vCreateSuicidalTasks( UBaseType_t uxPriority )
|
||||
{
|
||||
UBaseType_t *puxPriority;
|
||||
|
||||
/* Create the Creator tasks - passing in as a parameter the priority at which
|
||||
the suicidal tasks should be created. */
|
||||
puxPriority = ( UBaseType_t * ) pvPortMalloc( sizeof( UBaseType_t ) );
|
||||
*puxPriority = uxPriority;
|
||||
|
||||
xTaskCreate( vCreateTasks, "CREATOR", deathSTACK_SIZE, ( void * ) puxPriority, uxPriority, NULL );
|
||||
xTaskCreate( vCreateTasks, "CREATOR", deathSTACK_SIZE, ( void * ) NULL, uxPriority, NULL );
|
||||
|
||||
/* Record the number of tasks that are running now so we know if any of the
|
||||
suicidal tasks have failed to be killed. */
|
||||
|
@ -206,8 +199,10 @@ static portTASK_FUNCTION( vCreateTasks, pvParameters )
|
|||
const TickType_t xDelay = pdMS_TO_TICKS( ( TickType_t ) 1000 );
|
||||
UBaseType_t uxPriority;
|
||||
|
||||
uxPriority = *( UBaseType_t * ) pvParameters;
|
||||
vPortFree( pvParameters );
|
||||
/* Remove compiler warning about unused parameter. */
|
||||
( void ) pvParameters;
|
||||
|
||||
uxPriority = uxTaskPriorityGet( NULL );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
|
|
|
@ -189,19 +189,22 @@ void vStartDynamicPriorityTasks( void )
|
|||
{
|
||||
xSuspendedTestQueue = xQueueCreate( priSUSPENDED_QUEUE_LENGTH, sizeof( uint32_t ) );
|
||||
|
||||
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
|
||||
in use. The queue registry is provided as a means for kernel aware
|
||||
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( xSuspendedTestQueue, "Suspended_Test_Queue" );
|
||||
if( xSuspendedTestQueue != NULL )
|
||||
{
|
||||
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
|
||||
in use. The queue registry is provided as a means for kernel aware
|
||||
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( xSuspendedTestQueue, "Suspended_Test_Queue" );
|
||||
|
||||
xTaskCreate( vContinuousIncrementTask, "CNT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinuousIncrementHandle );
|
||||
xTaskCreate( vLimitedIncrementTask, "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle );
|
||||
xTaskCreate( vCounterControlTask, "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
xTaskCreate( vQueueSendWhenSuspendedTask, "SUSP_TX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
xTaskCreate( vQueueReceiveWhenSuspendedTask, "SUSP_RX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
xTaskCreate( vContinuousIncrementTask, "CNT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinuousIncrementHandle );
|
||||
xTaskCreate( vLimitedIncrementTask, "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle );
|
||||
xTaskCreate( vCounterControlTask, "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
xTaskCreate( vQueueSendWhenSuspendedTask, "SUSP_TX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
xTaskCreate( vQueueReceiveWhenSuspendedTask, "SUSP_RX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -151,20 +151,19 @@ void vStartRecursiveMutexTasks( void )
|
|||
|
||||
xMutex = xSemaphoreCreateRecursiveMutex();
|
||||
|
||||
/* vQueueAddToRegistry() adds the mutex to the registry, if one is
|
||||
in use. The registry is provided as a means for kernel aware
|
||||
debuggers to locate mutex and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( ( QueueHandle_t ) xMutex, "Recursive_Mutex" );
|
||||
|
||||
|
||||
if( xMutex != NULL )
|
||||
{
|
||||
/* vQueueAddToRegistry() adds the mutex to the registry, if one is
|
||||
in use. The registry is provided as a means for kernel aware
|
||||
debuggers to locate mutex and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( ( QueueHandle_t ) xMutex, "Recursive_Mutex" );
|
||||
|
||||
xTaskCreate( prvRecursiveMutexControllingTask, "Rec1", configMINIMAL_STACK_SIZE, NULL, recmuCONTROLLING_TASK_PRIORITY, &xControllingTaskHandle );
|
||||
xTaskCreate( prvRecursiveMutexBlockingTask, "Rec2", configMINIMAL_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle );
|
||||
xTaskCreate( prvRecursiveMutexPollingTask, "Rec3", configMINIMAL_STACK_SIZE, NULL, recmuPOLLING_TASK_PRIORITY, NULL );
|
||||
xTaskCreate( prvRecursiveMutexBlockingTask, "Rec2", configMINIMAL_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle );
|
||||
xTaskCreate( prvRecursiveMutexPollingTask, "Rec3", configMINIMAL_STACK_SIZE, NULL, recmuPOLLING_TASK_PRIORITY, NULL );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
@ -68,24 +68,24 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Creates two sets of two tasks. The tasks within a set share a variable, access
|
||||
* Creates two sets of two tasks. The tasks within a set share a variable, access
|
||||
* to which is guarded by a semaphore.
|
||||
*
|
||||
* Each task starts by attempting to obtain the semaphore. On obtaining a
|
||||
* semaphore a task checks to ensure that the guarded variable has an expected
|
||||
* value. It then clears the variable to zero before counting it back up to the
|
||||
* expected value in increments of 1. After each increment the variable is checked
|
||||
* to ensure it contains the value to which it was just set. When the starting
|
||||
* value is again reached the task releases the semaphore giving the other task in
|
||||
* the set a chance to do exactly the same thing. The starting value is high
|
||||
*
|
||||
* Each task starts by attempting to obtain the semaphore. On obtaining a
|
||||
* semaphore a task checks to ensure that the guarded variable has an expected
|
||||
* value. It then clears the variable to zero before counting it back up to the
|
||||
* expected value in increments of 1. After each increment the variable is checked
|
||||
* to ensure it contains the value to which it was just set. When the starting
|
||||
* value is again reached the task releases the semaphore giving the other task in
|
||||
* the set a chance to do exactly the same thing. The starting value is high
|
||||
* enough to ensure that a tick is likely to occur during the incrementing loop.
|
||||
*
|
||||
* An error is flagged if at any time during the process a shared variable is
|
||||
* found to have a value other than that expected. Such an occurrence would
|
||||
* suggest an error in the mutual exclusion mechanism by which access to the
|
||||
* An error is flagged if at any time during the process a shared variable is
|
||||
* found to have a value other than that expected. Such an occurrence would
|
||||
* suggest an error in the mutual exclusion mechanism by which access to the
|
||||
* variable is restricted.
|
||||
*
|
||||
* The first set of two tasks poll their semaphore. The second set use blocking
|
||||
* The first set of two tasks poll their semaphore. The second set use blocking
|
||||
* calls.
|
||||
*
|
||||
*/
|
||||
|
@ -139,11 +139,12 @@ const TickType_t xBlockTime = ( TickType_t ) 100;
|
|||
if( pxFirstSemaphoreParameters != NULL )
|
||||
{
|
||||
/* Create the semaphore used by the first two tasks. */
|
||||
pxFirstSemaphoreParameters->xSemaphore = xSemaphoreCreateBinary();
|
||||
xSemaphoreGive( pxFirstSemaphoreParameters->xSemaphore );
|
||||
pxFirstSemaphoreParameters->xSemaphore = xSemaphoreCreateBinary();
|
||||
|
||||
if( pxFirstSemaphoreParameters->xSemaphore != NULL )
|
||||
{
|
||||
xSemaphoreGive( pxFirstSemaphoreParameters->xSemaphore );
|
||||
|
||||
/* Create the variable which is to be shared by the first two tasks. */
|
||||
pxFirstSemaphoreParameters->pulSharedVariable = ( uint32_t * ) pvPortMalloc( sizeof( uint32_t ) );
|
||||
|
||||
|
@ -156,36 +157,44 @@ const TickType_t xBlockTime = ( TickType_t ) 100;
|
|||
/* Spawn the first two tasks. As they poll they operate at the idle priority. */
|
||||
xTaskCreate( prvSemaphoreTest, "PolSEM1", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL );
|
||||
xTaskCreate( prvSemaphoreTest, "PolSEM2", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL );
|
||||
|
||||
/* vQueueAddToRegistry() adds the semaphore to the registry, if one
|
||||
is in use. The registry is provided as a means for kernel aware
|
||||
debuggers to locate semaphores and has no purpose if a kernel aware
|
||||
debugger is not being used. The call to vQueueAddToRegistry() will
|
||||
be removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not
|
||||
defined or is defined to be less than 1. */
|
||||
vQueueAddToRegistry( ( QueueHandle_t ) pxFirstSemaphoreParameters->xSemaphore, "Counting_Sem_1" );
|
||||
}
|
||||
}
|
||||
|
||||
/* Do exactly the same to create the second set of tasks, only this time
|
||||
/* Do exactly the same to create the second set of tasks, only this time
|
||||
provide a block time for the semaphore calls. */
|
||||
pxSecondSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) );
|
||||
if( pxSecondSemaphoreParameters != NULL )
|
||||
{
|
||||
pxSecondSemaphoreParameters->xSemaphore = xSemaphoreCreateBinary();
|
||||
xSemaphoreGive( pxSecondSemaphoreParameters->xSemaphore );
|
||||
pxSecondSemaphoreParameters->xSemaphore = xSemaphoreCreateBinary();
|
||||
|
||||
if( pxSecondSemaphoreParameters->xSemaphore != NULL )
|
||||
{
|
||||
xSemaphoreGive( pxSecondSemaphoreParameters->xSemaphore );
|
||||
|
||||
pxSecondSemaphoreParameters->pulSharedVariable = ( uint32_t * ) pvPortMalloc( sizeof( uint32_t ) );
|
||||
*( pxSecondSemaphoreParameters->pulSharedVariable ) = semtstBLOCKING_EXPECTED_VALUE;
|
||||
pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_PERIOD_MS;
|
||||
|
||||
xTaskCreate( prvSemaphoreTest, "BlkSEM1", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL );
|
||||
xTaskCreate( prvSemaphoreTest, "BlkSEM2", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL );
|
||||
|
||||
/* vQueueAddToRegistry() adds the semaphore to the registry, if one
|
||||
is in use. The registry is provided as a means for kernel aware
|
||||
debuggers to locate semaphores and has no purpose if a kernel aware
|
||||
debugger is not being used. The call to vQueueAddToRegistry() will
|
||||
be removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not
|
||||
defined or is defined to be less than 1. */
|
||||
vQueueAddToRegistry( ( QueueHandle_t ) pxSecondSemaphoreParameters->xSemaphore, "Counting_Sem_2" );
|
||||
}
|
||||
}
|
||||
|
||||
/* vQueueAddToRegistry() adds the semaphore to the registry, if one is
|
||||
in use. The registry is provided as a means for kernel aware
|
||||
debuggers to locate semaphores and has no purpose if a kernel aware debugger
|
||||
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||
defined to be less than 1. */
|
||||
vQueueAddToRegistry( ( QueueHandle_t ) pxFirstSemaphoreParameters->xSemaphore, "Counting_Sem_1" );
|
||||
vQueueAddToRegistry( ( QueueHandle_t ) pxSecondSemaphoreParameters->xSemaphore, "Counting_Sem_2" );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -196,14 +205,14 @@ volatile uint32_t *pulSharedVariable, ulExpectedValue;
|
|||
uint32_t ulCounter;
|
||||
short sError = pdFALSE, sCheckVariableToUse;
|
||||
|
||||
/* See which check variable to use. sNextCheckVariable is not semaphore
|
||||
/* See which check variable to use. sNextCheckVariable is not semaphore
|
||||
protected! */
|
||||
portENTER_CRITICAL();
|
||||
sCheckVariableToUse = sNextCheckVariable;
|
||||
sNextCheckVariable++;
|
||||
portEXIT_CRITICAL();
|
||||
|
||||
/* A structure is passed in as the parameter. This contains the shared
|
||||
/* A structure is passed in as the parameter. This contains the shared
|
||||
variable being guarded. */
|
||||
pxParameters = ( xSemaphoreParameters * ) pvParameters;
|
||||
pulSharedVariable = pxParameters->pulSharedVariable;
|
||||
|
@ -231,7 +240,7 @@ short sError = pdFALSE, sCheckVariableToUse;
|
|||
{
|
||||
sError = pdTRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Clear the variable, then count it back up to the expected value
|
||||
before releasing the semaphore. Would expect a context switch or
|
||||
two during this time. */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue