- 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).
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelHooks.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelHooks.h
index 7b94a10..03145b8 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelHooks.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelHooks.h
@@ -187,7 +187,7 @@
#undef trcKERNEL_HOOKS_TASK_RESUME
#define trcKERNEL_HOOKS_TASK_RESUME(SERVICE, pxTCB) \
vTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));
-
+
#undef trcKERNEL_HOOKS_TIMER_EVENT
#define trcKERNEL_HOOKS_TIMER_EVENT(SERVICE, pxTimer) \
vTraceStoreKernelCall(SERVICE, TRACE_CLASS_TIMER, TRACE_GET_TIMER_NUMBER(pxTimer));
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c
index 38251c4..722e553 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c
@@ -5,30 +5,30 @@
* trcKernelPort.c
*
* Kernel-specific functionality for FreeRTOS, used by the recorder library.
- *
+ *
* Terms of Use
* This software is copyright Percepio AB. The recorder library is free for
* use together with Percepio products. You may distribute the recorder library
* in its original form, including modifications in trcHardwarePort.c/.h
* given that these modification are clearly marked as your own modifications
- * and documented in the initial comment section of these source files.
- * This software is the intellectual property of Percepio AB and may not be
- * sold or in other ways commercially redistributed without explicit written
+ * and documented in the initial comment section of these source files.
+ * This software is the intellectual property of Percepio AB and may not be
+ * sold or in other ways commercially redistributed without explicit written
* permission by Percepio AB.
*
- * Disclaimer
- * The trace tool and recorder library is being delivered to you AS IS and
- * Percepio AB makes no warranty as to its use or performance. Percepio AB does
- * not and cannot warrant the performance or results you may obtain by using the
- * software or documentation. Percepio AB make no warranties, express or
- * implied, as to noninfringement of third party rights, merchantability, or
- * fitness for any particular purpose. In no event will Percepio AB, its
- * technology partners, or distributors be liable to you for any consequential,
- * incidental or special damages, including any lost profits or lost savings,
- * even if a representative of Percepio AB has been advised of the possibility
- * of such damages, or for any claim by any third party. Some jurisdictions do
- * not allow the exclusion or limitation of incidental, consequential or special
- * damages, or the exclusion of implied warranties or limitations on how long an
+ * Disclaimer
+ * The trace tool and recorder library is being delivered to you AS IS and
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does
+ * not and cannot warrant the performance or results you may obtain by using the
+ * software or documentation. Percepio AB make no warranties, express or
+ * implied, as to noninfringement of third party rights, merchantability, or
+ * fitness for any particular purpose. In no event will Percepio AB, its
+ * technology partners, or distributors be liable to you for any consequential,
+ * incidental or special damages, including any lost profits or lost savings,
+ * even if a representative of Percepio AB has been advised of the possibility
+ * of such damages, or for any claim by any third party. Some jurisdictions do
+ * not allow the exclusion or limitation of incidental, consequential or special
+ * damages, or the exclusion of implied warranties or limitations on how long an
* implied warranty may last, so the above limitations may not apply to you.
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
@@ -45,7 +45,7 @@
#include "task.h"
-/* For classes implemented as FreeRTOS Queues:
+/* For classes implemented as FreeRTOS Queues:
This translates queue.type to the corresponding trace object class. */
traceObjectClass TraceObjectClassTable[5] = {
TRACE_CLASS_QUEUE,
@@ -119,14 +119,14 @@
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[3] = NTask;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[4] = NISR;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[5] = NTimer;
- RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[6] = NEventGroup;
+ RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[6] = NEventGroup;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[0] = NameLenQueue;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[1] = NameLenSemaphore;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[2] = NameLenMutex;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[3] = NameLenTask;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[4] = NameLenISR;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[5] = NameLenTimer;
- RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[6] = NameLenEventGroup;
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[6] = NameLenEventGroup;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[0] = PropertyTableSizeQueue;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[1] = PropertyTableSizeSemaphore;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[2] = PropertyTableSizeMutex;
@@ -163,7 +163,7 @@
objectHandleStacks.highestIndexOfClass[5] = NQueue + NSemaphore + NMutex + NTask + NISR + NTimer - 1;
objectHandleStacks.highestIndexOfClass[6] = NQueue + NSemaphore + NMutex + NTask + NISR + NTimer + NEventGroup - 1;
}
-
+
/* Returns the "Not enough handles" error message for this object class */
const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass)
{
@@ -182,7 +182,7 @@
case TRACE_CLASS_TIMER:
return "Not enough TIMER handles - increase NTimer in trcConfig.h";
case TRACE_CLASS_EVENTGROUP:
- return "Not enough EVENTGROUP handles - increase NEventGroup in trcConfig.h";
+ return "Not enough EVENTGROUP handles - increase NEventGroup in trcConfig.h";
default:
return "pszTraceGetErrorHandles: Invalid objectclass!";
}
@@ -193,7 +193,7 @@
{
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "prvTraceIsObjectExcluded: objectclass >= TRACE_NCLASSES", 1);
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "uiTraceIsObjectExcluded: Invalid value for handle", 1);
-
+
switch(objectclass)
{
case TRACE_CLASS_TASK:
@@ -205,13 +205,13 @@
case TRACE_CLASS_QUEUE:
return TRACE_GET_QUEUE_FLAG_ISEXCLUDED(handle);
case TRACE_CLASS_TIMER:
- return TRACE_GET_TIMER_FLAG_ISEXCLUDED(handle);
+ return TRACE_GET_TIMER_FLAG_ISEXCLUDED(handle);
case TRACE_CLASS_EVENTGROUP:
- return TRACE_GET_EVENTGROUP_FLAG_ISEXCLUDED(handle);
+ return TRACE_GET_EVENTGROUP_FLAG_ISEXCLUDED(handle);
}
-
+
vTraceError("Invalid object class ID in uiTraceIsObjectExcluded!");
-
+
/* Must never reach */
return 1;
}
diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c
index b533712..0092d9e 100644
--- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c
+++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c
@@ -407,28 +407,53 @@
}
/*-----------------------------------------------------------*/
+/* 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;
}
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Giant_Gecko_Simplicity_Studio/main.c b/FreeRTOS/Demo/CORTEX_EFM32_Giant_Gecko_Simplicity_Studio/main.c
index 1eb40c1..1bef000 100644
--- a/FreeRTOS/Demo/CORTEX_EFM32_Giant_Gecko_Simplicity_Studio/main.c
+++ b/FreeRTOS/Demo/CORTEX_EFM32_Giant_Gecko_Simplicity_Studio/main.c
@@ -222,28 +222,52 @@
}
/*-----------------------------------------------------------*/
+/* 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;
}
-/*-----------------------------------------------------------*/
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/main.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/main.c
index de94bcb..369099a 100644
--- a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/main.c
+++ b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/main.c
@@ -229,27 +229,51 @@
}
/*-----------------------------------------------------------*/
+/* 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;
}
-/*-----------------------------------------------------------*/
diff --git a/FreeRTOS/Demo/CORTEX_M4F_CEC1302_Keil/main.c b/FreeRTOS/Demo/CORTEX_M4F_CEC1302_Keil/main.c
index 18db411..8211556 100644
--- a/FreeRTOS/Demo/CORTEX_M4F_CEC1302_Keil/main.c
+++ b/FreeRTOS/Demo/CORTEX_M4F_CEC1302_Keil/main.c
@@ -234,30 +234,54 @@
}
/*-----------------------------------------------------------*/
+/* 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;
}
-/*-----------------------------------------------------------*/
diff --git a/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c b/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c
index 1433476..4b4232b 100644
--- a/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c
+++ b/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c
@@ -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 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 @@
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 @@
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,6 +297,598 @@
}
/*-----------------------------------------------------------*/
+static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void )
+{
+SemaphoreHandle_t xSemaphore;
+const UBaseType_t uxMaxCount = ( UBaseType_t ) 10;
+
+/* StaticSemaphore_t is a publicly accessible structure that has the same size
+and alignment requirements as the real semaphore structure. It is provided as a
+mechanism for applications to know the size of the semaphore (which is dependent
+on the architecture and configuration file settings) without breaking the strict
+data hiding policy by exposing the real semaphore internals. This
+StaticSemaphore_t variable is passed into the xSemaphoreCreateCountingStatic()
+function calls within this function. NOTE: In most usage scenarios now it is
+faster and more memory efficient to use a direct to task notification instead of
+a 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 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
+ when xSemaphoreCreateCounting() is called. */
+ xSemaphore = xSemaphoreCreateCountingStatic( uxMaxCount, 0, &xSemaphoreBuffer );
+
+ /* The semaphore handle should equal the static semaphore structure passed
+ into the xSemaphoreCreateBinaryStatic() function. */
+ configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
+
+ /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
+ prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount );
+
+ /* 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
+}
+/*-----------------------------------------------------------*/
+
+static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void )
+{
+SemaphoreHandle_t xSemaphore;
+
+/* StaticSemaphore_t is a publicly accessible structure that has the same size
+and alignment requirements as the real semaphore structure. It is provided as a
+mechanism for applications to know the size of the semaphore (which is dependent
+on the architecture and configuration file settings) without breaking the strict
+data hiding policy by exposing the real semaphore internals. This
+StaticSemaphore_t variable is passed into the
+xSemaphoreCreateRecursiveMutexStatic() function calls within this function. */
+StaticSemaphore_t xSemaphoreBuffer;
+
+ /* Create the semaphore. xSemaphoreCreateRecursiveMutexStatic() has one
+ more parameter than the usual xSemaphoreCreateRecursiveMutex() 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 when xSemaphoreCreateRecursiveMutex() is called. */
+ xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xSemaphoreBuffer );
+
+ /* The semaphore handle should equal the static semaphore structure passed
+ into the xSemaphoreCreateBinaryStatic() function. */
+ configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
+
+ /* Ensure the semaphore passes a few sanity checks as a valid
+ recursive semaphore. */
+ prvSanityCheckCreatedRecursiveMutex( xSemaphore );
+
+ /* 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
+}
+/*-----------------------------------------------------------*/
+
+static void prvCreateAndDeleteStaticallyAllocatedQueues( void )
+{
+QueueHandle_t xQueue;
+
+/* StaticQueue_t is a publicly accessible structure that has the same size and
+alignment requirements as the real queue structure. It is provided as a
+mechanism for applications to know the size of the queue (which is dependent on
+the architecture and configuration file settings) without breaking the strict
+data hiding policy by exposing the real queue internals. This StaticQueue_t
+variable is passed into the xQueueCreateStatic() function calls within this
+function. */
+static StaticQueue_t xStaticQueue;
+
+/* The queue storage area must be large enough to hold the maximum number of
+items it is possible for the queue to hold at any one time, which equals the
+queue length (in items, not bytes) multiplied by the size of each item. In this
+case the queue will hold staticQUEUE_LENGTH_IN_ITEMS 64-bit items. See
+http://www.freertos.org/Embedded-RTOS-Queues.html */
+static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_t ) ];
+
+ /* Create the queue. xQueueCreateStatic() has two more parameters than the
+ usual xQueueCreate() function. The first new 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 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. */
+ &xStaticQueue ); /* The static queue structure that will hold the state of the queue. */
+
+ /* The queue handle should equal the static queue structure passed into the
+ xQueueCreateStatic() function. */
+ configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue );
+
+ /* Ensure the queue passes a few sanity checks as a valid queue. */
+ prvSanityCheckCreatedQueue( xQueue );
+
+ /* Delete the queue again so the buffers can be reused. */
+ vQueueDelete( xQueue );
+
+ /* 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. */
+
+ /* 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
+data hiding policy by exposing the real semaphore internals. This
+StaticSemaphore_t variable is passed into the xSemaphoreCreateMutexStatic()
+function calls within this function. */
+StaticSemaphore_t xSemaphoreBuffer;
+
+ /* Create the semaphore. xSemaphoreCreateMutexStatic() has one more
+ 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
+ when xSemaphoreCreateMutex() is called. */
+ xSemaphore = xSemaphoreCreateMutexStatic( &xSemaphoreBuffer );
+
+ /* The semaphore handle should equal the static semaphore structure passed
+ into the xSemaphoreCreateMutexStatic() function. */
+ configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
+
+ /* 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 );
+
+ /* 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
+}
+/*-----------------------------------------------------------*/
+
+static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void )
+{
+SemaphoreHandle_t xSemaphore;
+
+/* StaticSemaphore_t is a publicly accessible structure that has the same size
+and alignment requirements as the real semaphore structure. It is provided as a
+mechanism for applications to know the size of the semaphore (which is dependent
+on the architecture and configuration file settings) without breaking the strict
+data hiding policy by exposing the real semaphore internals. This
+StaticSemaphore_t variable is passed into the xSemaphoreCreateBinaryStatic()
+function calls within this function. NOTE: In most usage scenarios now it is
+faster and more memory efficient to use a direct to task notification instead of
+a binary semaphore. http://www.freertos.org/RTOS-task-notifications.html */
+StaticSemaphore_t xSemaphoreBuffer;
+
+ /* Create the semaphore. xSemaphoreCreateBinaryStatic() has one more
+ 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
+ when xSemaphoreCreateBinary() is called. */
+ xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer );
+
+ /* The semaphore handle should equal the static semaphore structure passed
+ into the xSemaphoreCreateBinaryStatic() function. */
+ configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
+
+ /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
+ prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
+
+ /* 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. */
+ #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+ {
+ vSemaphoreCreateBinary( xSemaphore );
+
+ /* The macro starts with the binary semaphore available, but the test
+ function expects it to be unavailable. */
+ if( xSemaphoreTake( xSemaphore, staticDONT_BLOCK ) == pdFAIL )
+ {
+ xErrorOccurred = pdTRUE;
+ }
+
+ prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
+ vSemaphoreDelete( xSemaphore );
+ }
+ #endif
+}
+/*-----------------------------------------------------------*/
+
+static void prvTimerCallback( TimerHandle_t xExpiredTimer )
+{
+UBaseType_t *puxVariableToIncrement;
+BaseType_t xReturned;
+
+ /* 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. */
+ ( *puxVariableToIncrement )++;
+
+ /* If this callback has executed the required number of times, stop the
+ timer. */
+ if( *puxVariableToIncrement == staticMAX_TIMER_CALLBACK_EXECUTIONS )
+ {
+ /* 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 )
+ {
+ xErrorOccurred = pdTRUE;
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvCreateAndDeleteStaticallyAllocatedTimers( void )
+{
+TimerHandle_t xTimer;
+UBaseType_t uxVariableToIncrement;
+const TickType_t xTimerPeriod = pdMS_TO_TICKS( 20 );
+BaseType_t xReturned;
+
+/* StaticTimer_t is a publicly accessible structure that has the same size
+and alignment requirements as the real timer structure. It is provided as a
+mechanism for applications to know the size of the timer structure (which is
+dependent on the architecture and configuration file settings) without breaking
+the strict data hiding policy by exposing the real timer internals. This
+StaticTimer_t variable is passed into the xTimerCreateStatic() function calls
+within this function. */
+StaticTimer_t xTimerBuffer;
+
+ /* Create the software time. xTimerCreateStatic() has an extra parameter
+ than the normal xTimerCreate() API function. The parameter is a pointer to
+ the StaticTimer_t structure that will hold the software timer structure. If
+ the parameter is passed as NULL then the structure will be allocated
+ dynamically, just as if xTimerCreate() had been called. */
+ xTimer = xTimerCreateStatic( "T1", /* Text name for the task. Helps debugging only. Not used by FreeRTOS. */
+ xTimerPeriod, /* The period of the timer in ticks. */
+ pdTRUE, /* This is an auto-reload timer. */
+ ( void * ) &uxVariableToIncrement, /* 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. */
+ &xTimerBuffer ); /* The buffer that will hold the software timer structure. */
+
+ /* The timer handle should equal the static timer structure passed into the
+ xTimerCreateStatic() function. */
+ configASSERT( xTimer == ( TimerHandle_t ) &xTimerBuffer );
+
+ /* Set the variable to 0, wait for a few timer periods to expire, then check
+ the timer callback has incremented the variable to the expected value. */
+ uxVariableToIncrement = 0;
+
+ /* This is a low priority so a block time should not be needed. */
+ xReturned = xTimerStart( xTimer, staticDONT_BLOCK );
+
+ if( xReturned != pdPASS )
+ {
+ xErrorOccurred = pdTRUE;
+ }
+
+ vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS );
+
+ /* By now the timer should have expired staticMAX_TIMER_CALLBACK_EXECUTIONS
+ times, and then stopped itself. */
+ if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS )
+ {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* Finished with the timer, delete it. */
+ xReturned = xTimerDelete( xTimer, staticDONT_BLOCK );
+
+ /* Again, as this is a low priority task it is expected that the timer
+ command will have been sent even without a block time being used. */
+ if( xReturned != pdPASS )
+ {
+ xErrorOccurred = pdTRUE;
+ }
+
+ /* 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
+}
+/*-----------------------------------------------------------*/
+
+static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void )
+{
+EventGroupHandle_t xEventGroup;
+
+/* StaticEventGroup_t is a publicly accessible structure that has the same size
+and alignment requirements as the real event group structure. It is provided as
+a mechanism for applications to know the size of the event group (which is
+dependent on the architecture and configuration file settings) without breaking
+the strict data hiding policy by exposing the real event group internals. This
+StaticEventGroup_t variable is passed into the xSemaphoreCreateEventGroupStatic()
+function calls within this function. */
+StaticEventGroup_t xEventGroupBuffer;
+
+ /* Create the event group. xEventGroupCreateStatic() has an extra parameter
+ than the normal xEventGroupCreate() API function. The parameter is a
+ pointer to the StaticEventGroup_t structure that will hold the event group
+ structure. If the parameter is passed as NULL then the structure will be
+ allocated dynamically, just as if xEventGroupCreate() had been called. */
+ xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
+
+ /* The event group handle should equal the static event group structure
+ passed into the xEventGroupCreateStatic() function. */
+ configASSERT( xEventGroup == ( EventGroupHandle_t ) &xEventGroupBuffer );
+
+ /* 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 );
+
+ /* 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
+}
+/*-----------------------------------------------------------*/
+
+static void prvCreateAndDeleteStaticallyAllocatedTasks( void )
+{
+TaskHandle_t xCreatedTask;
+BaseType_t xReturned;
+
+/* The variable that will hold the TCB of tasks created by this function. See
+the comments above the declaration of the xCreatorTaskTCBBuffer variable for
+more information. */
+StaticTask_t xTCBBuffer;
+
+/* This buffer that will be used as the stack of tasks created by this function.
+See the comments above the declaration of the uxCreatorTaskStackBuffer[] array
+above for more information. */
+static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
+
+ /* Create the task. xTaskCreateStatic() has two more parameters than
+ 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 both pointers are
+ passed as NULL then the respective object will be allocated dynamically as
+ if xTaskCreate() had been called. */
+ 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. */
+ 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 )
+ {
+ 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
+}
+/*-----------------------------------------------------------*/
+
+static void prvStaticallyAllocatedTask( void *pvParameters )
+{
+ ( void ) pvParameters;
+
+ /* 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 );
+}
+/*-----------------------------------------------------------*/
+
+static UBaseType_t prvRand( void )
+{
+const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
+
+ /* Utility function to generate a pseudo random number. */
+ ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
+ return( ( ulNextRand >> 16UL ) & 0x7fffUL );
+}
+/*-----------------------------------------------------------*/
+
+static TickType_t prvGetNextDelayTime( void )
+{
+TickType_t xNextDelay;
+const TickType_t xMaxDelay = pdMS_TO_TICKS( ( TickType_t ) 150 );
+const TickType_t xMinDelay = pdMS_TO_TICKS( ( TickType_t ) 75 );
+const TickType_t xTinyDelay = pdMS_TO_TICKS( ( TickType_t ) 2 );
+
+ /* Generate the next delay time. This is kept within a narrow band so as
+ not to disturb the timing of other tests - but does add in some pseudo
+ randomisation into the tests. */
+ do
+ {
+ xNextDelay = prvRand() % xMaxDelay;
+
+ /* Just in case this loop is executed lots of times. */
+ vTaskDelay( xTinyDelay );
+
+ } while ( xNextDelay < xMinDelay );
+
+ return xNextDelay;
+}
+/*-----------------------------------------------------------*/
+
static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup )
{
EventBits_t xEventBits;
@@ -535,428 +1120,6 @@
}
/*-----------------------------------------------------------*/
-static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void )
-{
-SemaphoreHandle_t xSemaphore;
-const UBaseType_t uxMaxCount = ( UBaseType_t ) 10;
-
-/* StaticSemaphore_t is a publicly accessible structure that has the same size
-and alignment requirements as the real semaphore structure. It is provided as a
-mechanism for applications to know the size of the semaphore (which is dependent
-on the architecture and configuration file settings) without breaking the strict
-data hiding policy by exposing the real semaphore internals. This
-StaticSemaphore_t variable is passed into the xSemaphoreCreateCountingStatic()
-function calls within this function. NOTE: In most usage scenarios now it is
-faster and more memory efficient to use a direct to task notification instead of
-a 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
- is a pointer to the pre-allocated StaticSemaphore_t structure, which will
- hold information on the semaphore in an anonymous way. If the pointer is
- passed as NULL then the structure will be allocated dynamically, just as
- when xSemaphoreCreateCounting() is called. */
- xSemaphore = xSemaphoreCreateCountingStatic( uxMaxCount, 0, &xSemaphoreBuffer );
-
- /* The semaphore handle should equal the static semaphore structure passed
- into the xSemaphoreCreateBinaryStatic() function. */
- configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
-
- /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
- prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount );
-
- /* Delete the semaphore again so the buffers can be reused. */
- vSemaphoreDelete( xSemaphore );
-}
-/*-----------------------------------------------------------*/
-
-static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void )
-{
-SemaphoreHandle_t xSemaphore;
-
-/* StaticSemaphore_t is a publicly accessible structure that has the same size
-and alignment requirements as the real semaphore structure. It is provided as a
-mechanism for applications to know the size of the semaphore (which is dependent
-on the architecture and configuration file settings) without breaking the strict
-data hiding policy by exposing the real semaphore internals. This
-StaticSemaphore_t variable is passed into the
-xSemaphoreCreateRecursiveMutexStatic() function calls within this function. */
-StaticSemaphore_t xSemaphoreBuffer;
-
- /* Create the semaphore. xSemaphoreCreateRecursiveMutexStatic() has one
- more parameter than the usual xSemaphoreCreateRecursiveMutex() 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 when xSemaphoreCreateRecursiveMutex() is called. */
- xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xSemaphoreBuffer );
-
- /* The semaphore handle should equal the static semaphore structure passed
- into the xSemaphoreCreateBinaryStatic() function. */
- configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
-
- /* Ensure the semaphore passes a few sanity checks as a valid
- recursive semaphore. */
- prvSanityCheckCreatedRecursiveMutex( xSemaphore );
-
- /* Delete the semaphore again so the buffers can be reused. */
- vSemaphoreDelete( xSemaphore );
-}
-/*-----------------------------------------------------------*/
-
-static void prvCreateAndDeleteStaticallyAllocatedQueues( void )
-{
-QueueHandle_t xQueue;
-
-/* StaticQueue_t is a publicly accessible structure that has the same size and
-alignment requirements as the real queue structure. It is provided as a
-mechanism for applications to know the size of the queue (which is dependent on
-the architecture and configuration file settings) without breaking the strict
-data hiding policy by exposing the real queue internals. This StaticQueue_t
-variable is passed into the xQueueCreateStatic() function calls within this
-function. */
-static StaticQueue_t xStaticQueue;
-
-/* The queue storage area must be large enough to hold the maximum number of
-items it is possible for the queue to hold at any one time, which equals the
-queue length (in items, not bytes) multiplied by the size of each item. In this
-case the queue will hold staticQUEUE_LENGTH_IN_ITEMS 64-bit items. See
-http://www.freertos.org/Embedded-RTOS-Queues.html */
-static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_t ) ];
-
- /* Create the queue. xQueueCreateStatic() has two more parameters than the
- usual xQueueCreate() function. The first new 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 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. */
- &xStaticQueue ); /* The static queue structure that will hold the state of the queue. */
-
- /* The queue handle should equal the static queue structure passed into the
- xQueueCreateStatic() function. */
- configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue );
-
- /* Ensure the queue passes a few sanity checks as a valid queue. */
- prvSanityCheckCreatedQueue( xQueue );
-
- /* Delete the queue again so the buffers can be reused. */
- vQueueDelete( xQueue );
-}
-/*-----------------------------------------------------------*/
-
-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
-data hiding policy by exposing the real semaphore internals. This
-StaticSemaphore_t variable is passed into the xSemaphoreCreateMutexStatic()
-function calls within this function. */
-StaticSemaphore_t xSemaphoreBuffer;
-
- /* Create the semaphore. xSemaphoreCreateMutexStatic() has one more
- parameter than the usual xSemaphoreCreateMutex() function. The paraemter
- is a pointer to the pre-allocated StaticSemaphore_t structure, which will
- hold information on the semaphore in an anonymous way. If the pointer is
- passed as NULL then the structure will be allocated dynamically, just as
- when xSemaphoreCreateMutex() is called. */
- xSemaphore = xSemaphoreCreateMutexStatic( &xSemaphoreBuffer );
-
- /* The semaphore handle should equal the static semaphore structure passed
- into the xSemaphoreCreateMutexStatic() function. */
- configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
-
- /* 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 );
-}
-/*-----------------------------------------------------------*/
-
-static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void )
-{
-SemaphoreHandle_t xSemaphore;
-
-/* StaticSemaphore_t is a publicly accessible structure that has the same size
-and alignment requirements as the real semaphore structure. It is provided as a
-mechanism for applications to know the size of the semaphore (which is dependent
-on the architecture and configuration file settings) without breaking the strict
-data hiding policy by exposing the real semaphore internals. This
-StaticSemaphore_t variable is passed into the xSemaphoreCreateBinaryStatic()
-function calls within this function. NOTE: In most usage scenarios now it is
-faster and more memory efficient to use a direct to task notification instead of
-a binary semaphore. http://www.freertos.org/RTOS-task-notifications.html */
-StaticSemaphore_t xSemaphoreBuffer;
-
- /* Create the semaphore. xSemaphoreCreateBinaryStatic() has one more
- parameter than the usual xSemaphoreCreateBinary() function. The paraemter
- is a pointer to the pre-allocated StaticSemaphore_t structure, which will
- hold information on the semaphore in an anonymous way. If the pointer is
- passed as NULL then the structure will be allocated dynamically, just as
- when xSemaphoreCreateBinary() is called. */
- xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer );
-
- /* The semaphore handle should equal the static semaphore structure passed
- into the xSemaphoreCreateBinaryStatic() function. */
- configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
-
- /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
- 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. */
- #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
- {
- vSemaphoreCreateBinary( xSemaphore );
-
- /* The macro starts with the binary semaphore available, but the test
- function expects it to be unavailable. */
- if( xSemaphoreTake( xSemaphore, staticDONT_BLOCK ) == pdFAIL )
- {
- xErrorOccurred = pdTRUE;
- }
-
- prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
- vSemaphoreDelete( xSemaphore );
- }
- #endif
-}
-/*-----------------------------------------------------------*/
-
-static void prvTimerCallback( TimerHandle_t xExpiredTimer )
-{
-UBaseType_t *puxVariableToIncrement;
-BaseType_t xReturned;
-
- /* Obtain the address of the variable to increment from the timer ID. */
- puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer );
-
- /* Increment the variable to show the timer callback has executed. */
- ( *puxVariableToIncrement )++;
-
- /* If this callback has executed the required number of times, stop the
- timer. */
- if( *puxVariableToIncrement == staticMAX_TIMER_CALLBACK_EXECUTIONS )
- {
- /* This is called from a timer callback so must not block. */
- xReturned = xTimerStop( xExpiredTimer, staticDONT_BLOCK );
-
- if( xReturned != pdPASS )
- {
- xErrorOccurred = pdTRUE;
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvCreateAndDeleteStaticallyAllocatedTimers( void )
-{
-TimerHandle_t xTimer;
-UBaseType_t uxVariableToIncrement;
-const TickType_t xTimerPeriod = pdMS_TO_TICKS( 20 );
-BaseType_t xReturned;
-
-/* StaticTimer_t is a publicly accessible structure that has the same size
-and alignment requirements as the real timer structure. It is provided as a
-mechanism for applications to know the size of the timer structure (which is
-dependent on the architecture and configuration file settings) without breaking
-the strict data hiding policy by exposing the real timer internals. This
-StaticTimer_t variable is passed into the xTimerCreateStatic() function calls
-within this function. */
-StaticTimer_t xTimerBuffer;
-
- /* Create the software time. xTimerCreateStatic() has an extra parameter
- than the normal xTimerCreate() API function. The parameter is a pointer to
- the StaticTimer_t structure that will hold the software timer structure. If
- the parameter is passed as NULL then the structure will be allocated
- dynamically, just as if xTimerCreate() had been called. */
- xTimer = xTimerCreateStatic( "T1", /* Text name for the task. Helps debugging only. Not used by FreeRTOS. */
- xTimerPeriod, /* The period of the timer in ticks. */
- pdTRUE, /* This is an auto-reload timer. */
- ( void * ) &uxVariableToIncrement, /* 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. */
- &xTimerBuffer ); /* The buffer that will hold the software timer structure. */
-
- /* The timer handle should equal the static timer structure passed into the
- xTimerCreateStatic() function. */
- configASSERT( xTimer == ( TimerHandle_t ) &xTimerBuffer );
-
- /* Set the variable to 0, wait for a few timer periods to expire, then check
- the timer callback has incremented the variable to the expected value. */
- uxVariableToIncrement = 0;
-
- /* This is a low priority so a block time should not be needed. */
- xReturned = xTimerStart( xTimer, staticDONT_BLOCK );
-
- if( xReturned != pdPASS )
- {
- xErrorOccurred = pdTRUE;
- }
-
- vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS );
-
- /* By now the timer should have expired staticMAX_TIMER_CALLBACK_EXECUTIONS
- times, and then stopped itself. */
- if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS )
- {
- xErrorOccurred = pdTRUE;
- }
-
- /* Finished with the timer, delete it. */
- xReturned = xTimerDelete( xTimer, staticDONT_BLOCK );
-
- /* Again, as this is a low priority task it is expected that the timer
- command will have been sent even without a block time being used. */
- if( xReturned != pdPASS )
- {
- xErrorOccurred = pdTRUE;
- }
-
- /* Just to show the check task that this task is still executing. */
- uxCycleCounter++;
-}
-/*-----------------------------------------------------------*/
-
-static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void )
-{
-EventGroupHandle_t xEventGroup;
-
-/* StaticEventGroup_t is a publicly accessible structure that has the same size
-and alignment requirements as the real event group structure. It is provided as
-a mechanism for applications to know the size of the event group (which is
-dependent on the architecture and configuration file settings) without breaking
-the strict data hiding policy by exposing the real event group internals. This
-StaticEventGroup_t variable is passed into the xSemaphoreCreateEventGroupStatic()
-function calls within this function. */
-StaticEventGroup_t xEventGroupBuffer;
-
- /* Create the event group. xEventGroupCreateStatic() has an extra parameter
- than the normal xEventGroupCreate() API function. The parameter is a
- pointer to the StaticEventGroup_t structure that will hold the event group
- structure. If the parameter is passed as NULL then the structure will be
- allocated dynamically, just as if xEventGroupCreate() had been called. */
- xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
-
- /* The event group handle should equal the static event group structure
- passed into the xEventGroupCreateStatic() function. */
- configASSERT( xEventGroup == ( EventGroupHandle_t ) &xEventGroupBuffer );
-
- /* 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 );
-}
-/*-----------------------------------------------------------*/
-
-static void prvCreateAndDeleteStaticallyAllocatedTasks( void )
-{
-TaskHandle_t xCreatedTask;
-BaseType_t xReturned;
-
-/* The variable that will hold the TCB of tasks created by this function. See
-the comments above the declaration of the xCreatorTaskTCBBuffer variable for
-more information. */
-StaticTask_t xTCBBuffer;
-
-/* This buffer that will be used as the stack of tasks created by this function.
-See the comments above the declaration of the uxCreatorTaskStackBuffer[] array
-above for more information. */
-static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
-
- /* Create the task. xTaskCreateStatic() has two more parameters than
- 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 both pointers are
- passed as NULL then the respective object will be allocated dynamically as
- if xTaskCreate() had been called. */
- 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. */
- tskIDLE_PRIORITY, /* 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. */
-
- /* Check the task was created correctly, then delete the task. */
- configASSERT( xReturned == pdPASS );
- if( xReturned != pdPASS )
- {
- xErrorOccurred = pdTRUE;
- }
- vTaskDelete( xCreatedTask );
-}
-/*-----------------------------------------------------------*/
-
-static void prvStaticallyAllocatedTask( void *pvParameters )
-{
- ( void ) pvParameters;
-
- /* The created task doesn't do anything - just waits to get deleted. */
- vTaskSuspend( NULL );
-}
-/*-----------------------------------------------------------*/
-
-static UBaseType_t prvRand( void )
-{
-const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
-
- /* Utility function to generate a pseudo random number. */
- ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
- return( ( ulNextRand >> 16UL ) & 0x7fffUL );
-}
-/*-----------------------------------------------------------*/
-
-static TickType_t prvGetNextDelayTime( void )
-{
-TickType_t xNextDelay;
-const TickType_t xMaxDelay = pdMS_TO_TICKS( ( TickType_t ) 150 );
-const TickType_t xMinDelay = pdMS_TO_TICKS( ( TickType_t ) 75 );
-const TickType_t xTinyDelay = pdMS_TO_TICKS( ( TickType_t ) 2 );
-
- /* Generate the next delay time. This is kept within a narrow band so as
- not to disturb the timing of other tests - but does add in some pseudo
- randomisation into the tests. */
- do
- {
- xNextDelay = prvRand() % xMaxDelay;
-
- /* Just in case this loop is executed lots of times. */
- vTaskDelay( xTinyDelay );
-
- } while ( xNextDelay < xMinDelay );
-
- return xNextDelay;
-}
-/*-----------------------------------------------------------*/
-
BaseType_t xAreStaticAllocationTasksStillRunning( void )
{
static UBaseType_t uxLastCycleCounter = 0;
diff --git a/FreeRTOS/Demo/WIN32-MSVC-Static-Allocation-Only/main.c b/FreeRTOS/Demo/WIN32-MSVC-Static-Allocation-Only/main.c
index c3a7d1b..a14fa41 100644
--- a/FreeRTOS/Demo/WIN32-MSVC-Static-Allocation-Only/main.c
+++ b/FreeRTOS/Demo/WIN32-MSVC-Static-Allocation-Only/main.c
@@ -241,35 +241,52 @@
}
/*-----------------------------------------------------------*/
+/* 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;
}
diff --git a/FreeRTOS/Demo/WIN32-MSVC/main.c b/FreeRTOS/Demo/WIN32-MSVC/main.c
index 00f67d4..8b3fdf0 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/main.c
+++ b/FreeRTOS/Demo/WIN32-MSVC/main.c
@@ -329,7 +329,7 @@
( 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 @@
}
/*-----------------------------------------------------------*/
+/* 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;
}
diff --git a/FreeRTOS/Source/include/queue.h b/FreeRTOS/Source/include/queue.h
index a3e5522..4ff7aa8 100644
--- a/FreeRTOS/Source/include/queue.h
+++ b/FreeRTOS/Source/include/queue.h
@@ -1616,7 +1616,7 @@
#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.
diff --git a/FreeRTOS/Source/include/semphr.h b/FreeRTOS/Source/include/semphr.h
index 29a0f98..eff0bfd 100644
--- a/FreeRTOS/Source/include/semphr.h
+++ b/FreeRTOS/Source/include/semphr.h
@@ -1152,11 +1152,11 @@
/**
* 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.
*
*/