]> git.sur5r.net Git - freertos/commitdiff
- Rework the StaticAllocation.c common demo file to reflect the changes to the static...
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 29 Mar 2016 11:08:42 +0000 (11:08 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 29 Mar 2016 11:08:42 +0000 (11:08 +0000)
- Correct various typos in comments.
- Add xTimerGetPeriod() function (feature request).

git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2431 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelHooks.h
FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c
FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c
FreeRTOS/Demo/CORTEX_EFM32_Giant_Gecko_Simplicity_Studio/main.c
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/main.c
FreeRTOS/Demo/CORTEX_M4F_CEC1302_Keil/main.c
FreeRTOS/Demo/Common/Minimal/StaticAllocation.c
FreeRTOS/Demo/WIN32-MSVC-Static-Allocation-Only/main.c
FreeRTOS/Demo/WIN32-MSVC/main.c
FreeRTOS/Source/include/queue.h
FreeRTOS/Source/include/semphr.h

index 7b94a106f520c33003b8bd8ad3e0c6bae4a7ce31..03145b8e6abaf18da4616cfe894f9b67771587a1 100644 (file)
 #undef trcKERNEL_HOOKS_TASK_RESUME\r
 #define trcKERNEL_HOOKS_TASK_RESUME(SERVICE, pxTCB) \\r
        vTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB));\r
-       \r
+\r
 #undef trcKERNEL_HOOKS_TIMER_EVENT\r
 #define trcKERNEL_HOOKS_TIMER_EVENT(SERVICE, pxTimer) \\r
        vTraceStoreKernelCall(SERVICE, TRACE_CLASS_TIMER, TRACE_GET_TIMER_NUMBER(pxTimer));\r
index 38251c40e7aea7773b34ef34a47fb381a7f5064f..722e553419ca0263133db21ea3ed7f9af92613bb 100644 (file)
@@ -5,30 +5,30 @@
  * trcKernelPort.c\r
  *\r
  * Kernel-specific functionality for FreeRTOS, used by the recorder library.\r
- * \r
+ *\r
  * Terms of Use\r
  * This software is copyright Percepio AB. The recorder library is free for\r
  * use together with Percepio products. You may distribute the recorder library\r
  * in its original form, including modifications in trcHardwarePort.c/.h\r
  * given that these modification are clearly marked as your own modifications\r
- * and documented in the initial comment section of these source files. \r
- * This software is the intellectual property of Percepio AB and may not be \r
- * sold or in other ways commercially redistributed without explicit written \r
+ * and documented in the initial comment section of these source files.\r
+ * This software is the intellectual property of Percepio AB and may not be\r
+ * sold or in other ways commercially redistributed without explicit written\r
  * permission by Percepio AB.\r
  *\r
- * Disclaimer \r
- * The trace tool and recorder library is being delivered to you AS IS and \r
- * Percepio AB makes no warranty as to its use or performance. Percepio AB does \r
- * not and cannot warrant the performance or results you may obtain by using the \r
- * software or documentation. Percepio AB make no warranties, express or \r
- * implied, as to noninfringement of third party rights, merchantability, or \r
- * fitness for any particular purpose. In no event will Percepio AB, its \r
- * technology partners, or distributors be liable to you for any consequential, \r
- * incidental or special damages, including any lost profits or lost savings, \r
- * even if a representative of Percepio AB has been advised of the possibility \r
- * of such damages, or for any claim by any third party. Some jurisdictions do \r
- * not allow the exclusion or limitation of incidental, consequential or special \r
- * damages, or the exclusion of implied warranties or limitations on how long an \r
+ * Disclaimer\r
+ * The trace tool and recorder library is being delivered to you AS IS and\r
+ * Percepio AB makes no warranty as to its use or performance. Percepio AB does\r
+ * not and cannot warrant the performance or results you may obtain by using the\r
+ * software or documentation. Percepio AB make no warranties, express or\r
+ * implied, as to noninfringement of third party rights, merchantability, or\r
+ * fitness for any particular purpose. In no event will Percepio AB, its\r
+ * technology partners, or distributors be liable to you for any consequential,\r
+ * incidental or special damages, including any lost profits or lost savings,\r
+ * even if a representative of Percepio AB has been advised of the possibility\r
+ * of such damages, or for any claim by any third party. Some jurisdictions do\r
+ * not allow the exclusion or limitation of incidental, consequential or special\r
+ * damages, or the exclusion of implied warranties or limitations on how long an\r
  * implied warranty may last, so the above limitations may not apply to you.\r
  *\r
  * Tabs are used for indent in this file (1 tab = 4 spaces)\r
@@ -45,7 +45,7 @@
 \r
 #include "task.h"\r
 \r
-/* For classes implemented as FreeRTOS Queues: \r
+/* For classes implemented as FreeRTOS Queues:\r
 This translates queue.type to the corresponding trace object class. */\r
 traceObjectClass TraceObjectClassTable[5] = {\r
        TRACE_CLASS_QUEUE,\r
@@ -119,14 +119,14 @@ void vTraceInitObjectPropertyTable()
        RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[3] = NTask;\r
        RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[4] = NISR;\r
        RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[5] = NTimer;\r
-       RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[6] = NEventGroup;  \r
+       RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[6] = NEventGroup;\r
        RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[0] = NameLenQueue;\r
        RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[1] = NameLenSemaphore;\r
        RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[2] = NameLenMutex;\r
        RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[3] = NameLenTask;\r
        RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[4] = NameLenISR;\r
        RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[5] = NameLenTimer;\r
-       RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[6] = NameLenEventGroup; \r
+       RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[6] = NameLenEventGroup;\r
        RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[0] = PropertyTableSizeQueue;\r
        RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[1] = PropertyTableSizeSemaphore;\r
        RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[2] = PropertyTableSizeMutex;\r
@@ -163,7 +163,7 @@ void vTraceInitObjectHandleStack()
        objectHandleStacks.highestIndexOfClass[5] = NQueue + NSemaphore + NMutex + NTask + NISR + NTimer - 1;\r
        objectHandleStacks.highestIndexOfClass[6] = NQueue + NSemaphore + NMutex + NTask + NISR + NTimer + NEventGroup - 1;\r
 }\r
-       \r
+\r
 /* Returns the "Not enough handles" error message for this object class */\r
 const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass)\r
 {\r
@@ -182,7 +182,7 @@ const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass)
        case TRACE_CLASS_TIMER:\r
                return "Not enough TIMER handles - increase NTimer in trcConfig.h";\r
        case TRACE_CLASS_EVENTGROUP:\r
-               return "Not enough EVENTGROUP handles - increase NEventGroup in trcConfig.h";           \r
+               return "Not enough EVENTGROUP handles - increase NEventGroup in trcConfig.h";\r
        default:\r
                return "pszTraceGetErrorHandles: Invalid objectclass!";\r
        }\r
@@ -193,7 +193,7 @@ uint8_t uiTraceIsObjectExcluded(traceObjectClass objectclass, objectHandleType h
 {\r
        TRACE_ASSERT(objectclass < TRACE_NCLASSES, "prvTraceIsObjectExcluded: objectclass >= TRACE_NCLASSES", 1);\r
        TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "uiTraceIsObjectExcluded: Invalid value for handle", 1);\r
-       \r
+\r
        switch(objectclass)\r
        {\r
        case TRACE_CLASS_TASK:\r
@@ -205,13 +205,13 @@ uint8_t uiTraceIsObjectExcluded(traceObjectClass objectclass, objectHandleType h
        case TRACE_CLASS_QUEUE:\r
                return TRACE_GET_QUEUE_FLAG_ISEXCLUDED(handle);\r
        case TRACE_CLASS_TIMER:\r
-               return TRACE_GET_TIMER_FLAG_ISEXCLUDED(handle);         \r
+               return TRACE_GET_TIMER_FLAG_ISEXCLUDED(handle);\r
        case TRACE_CLASS_EVENTGROUP:\r
-               return TRACE_GET_EVENTGROUP_FLAG_ISEXCLUDED(handle);                            \r
+               return TRACE_GET_EVENTGROUP_FLAG_ISEXCLUDED(handle);\r
        }\r
-       \r
+\r
        vTraceError("Invalid object class ID in uiTraceIsObjectExcluded!");\r
-       \r
+\r
        /* Must never reach */\r
        return 1;\r
 }\r
index b533712c1ecb622c9a83871ea4e6c0ab0697edc2..0092d9e6b5a1751a543c0077cdcfeac06dd91afa 100644 (file)
@@ -407,28 +407,53 @@ const uint32_t ulMaxDivisor = 0xff, ulDivisorShift = 0x08;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an\r
+implementation of vApplicationGetIdleTaskMemory() to provide the memory that is\r
+used by the Idle task. */\r
 void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )\r
 {\r
-       /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the\r
-       opportunity to supply the buffers that will be used by the Idle task as its\r
-       stack and to hold its TCB.  If these are set to NULL then the buffers will\r
-       be allocated dynamically, just as if xTaskCreate() had been called. */\r
-       *ppxIdleTaskTCBBuffer = NULL;\r
-       *ppxIdleTaskStackBuffer = NULL;\r
-       *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words.  NOT in bytes! */\r
+/* If the buffers to be provided to the Idle task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
+static StaticTask_t xIdleTaskTCB;\r
+static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];\r
+\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Idle task's\r
+       state will be stored. */\r
+       *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Idle task's stack. */\r
+       *ppxIdleTaskStackBuffer = uxIdleTaskStack;\r
+\r
+       /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the\r
+application must provide an implementation of vApplicationGetTimerTaskMemory()\r
+to provide the memory that is used by the Timer service task. */\r
 void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )\r
 {\r
-       /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the\r
-       opportunity to supply the buffers that will be used by the Timer/RTOS daemon\r
-       task as its     stack and to hold its TCB.  If these are set to NULL then the\r
-       buffers will be allocated dynamically, just as if xTaskCreate() had been\r
-       called. */\r
-       *ppxTimerTaskTCBBuffer = NULL;\r
-       *ppxTimerTaskStackBuffer = NULL;\r
-       *pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words.  NOT in bytes! */\r
+/* If the buffers to be provided to the Timer task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
+static StaticTask_t xTimerTaskTCB;\r
+static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];\r
+\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Timer\r
+       task's state will be stored. */\r
+       *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Timer task's stack. */\r
+       *ppxTimerTaskStackBuffer = uxTimerTaskStack;\r
+\r
+       /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pusTimerTaskStackSize = configMINIMAL_STACK_SIZE;\r
 }\r
 \r
 \r
index 1eb40c1ffe72f09c64215f69e1a9d9e8e02d62fa..1bef000bf5fdd0e2cc3c6118298fb30426ce21de 100644 (file)
@@ -222,28 +222,52 @@ void vApplicationTickHook( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an\r
+implementation of vApplicationGetIdleTaskMemory() to provide the memory that is\r
+used by the Idle task. */\r
 void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )\r
 {\r
-       /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the\r
-       opportunity to supply the buffers that will be used by the Idle task as its\r
-       stack and to hold its TCB.  If these are set to NULL then the buffers will\r
-       be allocated dynamically, just as if xTaskCreate() had been called. */\r
-       *ppxIdleTaskTCBBuffer = NULL;\r
-       *ppxIdleTaskStackBuffer = NULL;\r
-       *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words.  NOT in bytes! */\r
+/* If the buffers to be provided to the Idle task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
+static StaticTask_t xIdleTaskTCB;\r
+static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];\r
+\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Idle task's\r
+       state will be stored. */\r
+       *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Idle task's stack. */\r
+       *ppxIdleTaskStackBuffer = uxIdleTaskStack;\r
+\r
+       /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the\r
+application must provide an implementation of vApplicationGetTimerTaskMemory()\r
+to provide the memory that is used by the Timer service task. */\r
 void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )\r
 {\r
-       /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the\r
-       opportunity to supply the buffers that will be used by the Timer/RTOS daemon\r
-       task as its     stack and to hold its TCB.  If these are set to NULL then the\r
-       buffers will be allocated dynamically, just as if xTaskCreate() had been\r
-       called. */\r
-       *ppxTimerTaskTCBBuffer = NULL;\r
-       *ppxTimerTaskStackBuffer = NULL;\r
-       *pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words.  NOT in bytes! */\r
+/* If the buffers to be provided to the Timer task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
+static StaticTask_t xTimerTaskTCB;\r
+static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];\r
+\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Timer\r
+       task's state will be stored. */\r
+       *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Timer task's stack. */\r
+       *ppxTimerTaskStackBuffer = uxTimerTaskStack;\r
+\r
+       /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pusTimerTaskStackSize = configMINIMAL_STACK_SIZE;\r
 }\r
-/*-----------------------------------------------------------*/\r
 \r
index de94bcb9f0e2054d9302598ab1128e712bae4a0a..369099a1c5f3925024fcd057bff5866f42ec37f0 100644 (file)
@@ -229,27 +229,51 @@ void vApplicationTickHook( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an\r
+implementation of vApplicationGetIdleTaskMemory() to provide the memory that is\r
+used by the Idle task. */\r
 void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )\r
 {\r
-       /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the\r
-       opportunity to supply the buffers that will be used by the Idle task as its\r
-       stack and to hold its TCB.  If these are set to NULL then the buffers will\r
-       be allocated dynamically, just as if xTaskCreate() had been called. */\r
-       *ppxIdleTaskTCBBuffer = NULL;\r
-       *ppxIdleTaskStackBuffer = NULL;\r
-       *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words.  NOT in bytes! */\r
+/* If the buffers to be provided to the Idle task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
+static StaticTask_t xIdleTaskTCB;\r
+static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];\r
+\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Idle task's\r
+       state will be stored. */\r
+       *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Idle task's stack. */\r
+       *ppxIdleTaskStackBuffer = uxIdleTaskStack;\r
+\r
+       /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the\r
+application must provide an implementation of vApplicationGetTimerTaskMemory()\r
+to provide the memory that is used by the Timer service task. */\r
 void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )\r
 {\r
-       /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the\r
-       opportunity to supply the buffers that will be used by the Timer/RTOS daemon\r
-       task as its     stack and to hold its TCB.  If these are set to NULL then the\r
-       buffers will be allocated dynamically, just as if xTaskCreate() had been\r
-       called. */\r
-       *ppxTimerTaskTCBBuffer = NULL;\r
-       *ppxTimerTaskStackBuffer = NULL;\r
-       *pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words.  NOT in bytes! */\r
+/* If the buffers to be provided to the Timer task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
+static StaticTask_t xTimerTaskTCB;\r
+static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];\r
+\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Timer\r
+       task's state will be stored. */\r
+       *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Timer task's stack. */\r
+       *ppxTimerTaskStackBuffer = uxTimerTaskStack;\r
+\r
+       /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pusTimerTaskStackSize = configMINIMAL_STACK_SIZE;\r
 }\r
-/*-----------------------------------------------------------*/\r
index 18db411340a19fffda1c8052c57701dad352e9cc..82115564d8dbaa1c2dea2fa06c4ea2fc001ccc2b 100644 (file)
@@ -234,30 +234,54 @@ void vApplicationTickHook( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an\r
+implementation of vApplicationGetIdleTaskMemory() to provide the memory that is\r
+used by the Idle task. */\r
 void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )\r
 {\r
-       /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the\r
-       opportunity to supply the buffers that will be used by the Idle task as its\r
-       stack and to hold its TCB.  If these are set to NULL then the buffers will\r
-       be allocated dynamically, just as if xTaskCreate() had been called. */\r
-       *ppxIdleTaskTCBBuffer = NULL;\r
-       *ppxIdleTaskStackBuffer = NULL;\r
-       *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words.  NOT in bytes! */\r
+/* If the buffers to be provided to the Idle task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
+static StaticTask_t xIdleTaskTCB;\r
+static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];\r
+\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Idle task's\r
+       state will be stored. */\r
+       *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Idle task's stack. */\r
+       *ppxIdleTaskStackBuffer = uxIdleTaskStack;\r
+\r
+       /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the\r
+application must provide an implementation of vApplicationGetTimerTaskMemory()\r
+to provide the memory that is used by the Timer service task. */\r
 void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )\r
 {\r
-       /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the\r
-       opportunity to supply the buffers that will be used by the Timer/RTOS daemon\r
-       task as its     stack and to hold its TCB.  If these are set to NULL then the\r
-       buffers will be allocated dynamically, just as if xTaskCreate() had been\r
-       called. */\r
-       *ppxTimerTaskTCBBuffer = NULL;\r
-       *ppxTimerTaskStackBuffer = NULL;\r
-       *pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words.  NOT in bytes! */\r
+/* If the buffers to be provided to the Timer task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
+static StaticTask_t xTimerTaskTCB;\r
+static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];\r
+\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Timer\r
+       task's state will be stored. */\r
+       *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Timer task's stack. */\r
+       *ppxTimerTaskStackBuffer = uxTimerTaskStack;\r
+\r
+       /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pusTimerTaskStackSize = configMINIMAL_STACK_SIZE;\r
 }\r
-/*-----------------------------------------------------------*/\r
 \r
 \r
 \r
index 1433476f2c94f5c75b1caa09cbf561c001a88bc8..4b4232b55dcfe788547d09a7bfac297b006f26a4 100644 (file)
@@ -73,6 +73,8 @@
  * rather than the normal dynamically allocated memory, and tests objects being\r
  * created and deleted with both statically allocated memory and dynamically\r
  * allocated memory.\r
+ *\r
+ * See http://www.FreeRTOS.org/Static_Vs_Dynamic_Memory_Allocation.html\r
  */\r
 \r
 /* Scheduler include files. */\r
@@ -130,59 +132,51 @@ static void prvTimerCallback( TimerHandle_t xExpiredTimer );
 static void prvStaticallyAllocatedTask( void *pvParameters );\r
 \r
 /*\r
- * A function that demonstrates and tests the xTaskCreateStatic() API function\r
- * by creating and then deleting tasks with both dynamically and statically\r
- * allocated TCBs and stacks.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete tasks using both statically and dynamically allocated TCBs and stacks.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedTasks( void );\r
 \r
 /*\r
- * A function that demonstrates and tests the xEventGroupCreateStatic() API\r
- * function by creating and then deleting event groups using both dynamically\r
- * and statically allocated event group structures.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete event groups using both statically and dynamically allocated RAM.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void );\r
 \r
 /*\r
- * A function that demonstrates and tests the xQueueCreateStatic() API function\r
- * by creating and then deleting queues with both dynamically and statically\r
- * allocated queue structures and queue storage areas.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete queues using both statically and dynamically allocated RAM.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedQueues( void );\r
 \r
 /*\r
- * A function that demonstrates and tests the xSemaphoreCreateBinaryStatic() API\r
- * macro by creating and then deleting binary semaphores with both dynamically\r
- * and statically allocated semaphore structures.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete binary semaphores using both statically and dynamically allocated RAM.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void );\r
 \r
 /*\r
- * A function that demonstrates and tests the xTimerCreateStatic() API macro by\r
- * creating and then deleting software timers with both dynamically and\r
- * statically allocated timer structures.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete software timers using both statically and dynamically allocated RAM.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedTimers( void );\r
 \r
 /*\r
- * A function that demonstrates and tests the xSemaphoreCreateMutexStatic() API\r
- * macro by creating and then deleting mutexes with both dynamically and\r
- * statically allocated semaphore structures.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete mutexes using both statically and dynamically allocated RAM.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedMutexes( void );\r
 \r
 /*\r
- * A function that demonstrates and tests the xSemaphoreCreateCountingStatic()\r
- * API macro by creating and then deleting counting semaphores with both\r
- * dynamically and statically allocated semaphore structures.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete counting semaphores using both statically and dynamically allocated\r
+ * RAM.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void );\r
 \r
 /*\r
- * A function that demonstrates and tests the\r
- * xSemaphoreCreateRecursiveMutexStatic() API macro by creating and then\r
- * deleting recursive mutexes with both dynamically and statically allocated\r
- * semaphore structures.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete recursive mutexes using both statically and dynamically allocated RAM.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void );\r
 \r
@@ -250,9 +244,8 @@ static volatile BaseType_t xErrorOccurred = pdFALSE;
 \r
 void vStartStaticallyAllocatedTasks( void  )\r
 {\r
-       /* Create a single task, which then repeatedly creates and deletes the\r
-       task implemented by prvStaticallyAllocatedTask() at various different\r
-       priorities, and both with and without statically allocated TCB and stack. */\r
+       /* Create a single task, which then repeatedly creates and deletes the other\r
+       RTOS objects using both statically and dynamically allocated RAM. */\r
        xTaskCreateStatic( prvStaticallyAllocatedCreator,               /* The function that implements the task being created. */\r
                                           "StatCreate",                                                /* Text name for the task - not used by the RTOS, its just to assist debugging. */\r
                                           staticCREATOR_TASK_STACK_SIZE,               /* Size of the buffer passed in as the stack - in words, not bytes! */\r
@@ -274,16 +267,16 @@ static void prvStaticallyAllocatedCreator( void *pvParameters )
 \r
        for( ;; )\r
        {\r
-               /* Loop, running functions that create and delete the various objects\r
-               that can be optionally created using either static or dynamic memory\r
-               allocation. */\r
+               /* Loop, running functions that create and delete the various RTOS\r
+               objects that can be optionally created using either static or dynamic\r
+               memory allocation. */\r
                prvCreateAndDeleteStaticallyAllocatedTasks();\r
                prvCreateAndDeleteStaticallyAllocatedQueues();\r
 \r
-               /* Ensure lower priority tasks get CPU time. */\r
+               /* Delay to ensure lower priority tasks get CPU time, and increment the\r
+               cycle counter so a 'check' task can determine that this task is still\r
+               executing. */\r
                vTaskDelay( prvGetNextDelayTime() );\r
-\r
-               /* Just to show the check task that this task is still executing. */\r
                uxCycleCounter++;\r
 \r
                prvCreateAndDeleteStaticallyAllocatedBinarySemaphores();\r
@@ -304,237 +297,6 @@ static void prvStaticallyAllocatedCreator( void *pvParameters )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup )\r
-{\r
-EventBits_t xEventBits;\r
-const EventBits_t xFirstTestBits = ( EventBits_t ) 0xaa, xSecondTestBits = ( EventBits_t ) 0x55;\r
-\r
-       /* The event group should not have any bits set yet. */\r
-       xEventBits = xEventGroupGetBits( xEventGroup );\r
-\r
-       if( xEventBits != ( EventBits_t ) 0 )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       /* Some some bits, then read them back to check they are as expected. */\r
-       xEventGroupSetBits( xEventGroup, xFirstTestBits );\r
-\r
-       xEventBits = xEventGroupGetBits( xEventGroup );\r
-\r
-       if( xEventBits != xFirstTestBits )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       xEventGroupSetBits( xEventGroup, xSecondTestBits );\r
-\r
-       xEventBits = xEventGroupGetBits( xEventGroup );\r
-\r
-       if( xEventBits != ( xFirstTestBits | xSecondTestBits ) )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       /* Finally try clearing some bits too and check that operation proceeds as\r
-       expected. */\r
-       xEventGroupClearBits( xEventGroup, xFirstTestBits );\r
-\r
-       xEventBits = xEventGroupGetBits( xEventGroup );\r
-\r
-       if( xEventBits != xSecondTestBits )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvSanityCheckCreatedSemaphore( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount )\r
-{\r
-BaseType_t xReturned;\r
-UBaseType_t x;\r
-const TickType_t xShortBlockTime = pdMS_TO_TICKS( 10 );\r
-TickType_t xTickCount;\r
-\r
-       /* The binary semaphore should start 'empty', so a call to xSemaphoreTake()\r
-       should fail. */\r
-       xTickCount = xTaskGetTickCount();\r
-       xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );\r
-\r
-       if( ( ( TickType_t ) ( xTaskGetTickCount() - xTickCount ) ) < xShortBlockTime )\r
-       {\r
-               /* Did not block on the semaphore as long as expected. */\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       if( xReturned != pdFAIL )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       /* Should be possible to 'give' the semaphore up to a maximum of uxMaxCount\r
-       times. */\r
-       for( x = 0; x < uxMaxCount; x++ )\r
-       {\r
-               xReturned = xSemaphoreGive( xSemaphore );\r
-\r
-               if( xReturned == pdFAIL )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-       }\r
-\r
-       /* Giving the semaphore again should fail, as it is 'full'. */\r
-       xReturned = xSemaphoreGive( xSemaphore );\r
-\r
-       if( xReturned != pdFAIL )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       configASSERT( uxSemaphoreGetCount( xSemaphore ) == uxMaxCount );\r
-\r
-       /* Should now be possible to 'take' the semaphore up to a maximum of\r
-       uxMaxCount times without blocking. */\r
-       for( x = 0; x < uxMaxCount; x++ )\r
-       {\r
-               xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );\r
-\r
-               if( xReturned == pdFAIL )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-       }\r
-\r
-       /* Back to the starting condition, where the semaphore should not be\r
-       available. */\r
-       xTickCount = xTaskGetTickCount();\r
-       xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );\r
-\r
-       if( ( ( TickType_t ) ( xTaskGetTickCount() - xTickCount ) ) < xShortBlockTime )\r
-       {\r
-               /* Did not block on the semaphore as long as expected. */\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       if( xReturned != pdFAIL )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvSanityCheckCreatedQueue( QueueHandle_t xQueue )\r
-{\r
-uint64_t ull, ullRead;\r
-BaseType_t xReturned, xLoop;\r
-\r
-       /* This test is done twice to ensure the queue storage area wraps. */\r
-       for( xLoop = 0; xLoop < 2; xLoop++ )\r
-       {\r
-               /* A very basic test that the queue can be written to and read from as\r
-               expected.  First the queue should be empty. */\r
-               xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );\r
-               if( xReturned != errQUEUE_EMPTY )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-\r
-               /* Now it should be possible to write to the queue staticQUEUE_LENGTH_IN_ITEMS\r
-               times. */\r
-               for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )\r
-               {\r
-                       xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );\r
-                       if( xReturned != pdPASS )\r
-                       {\r
-                               xErrorOccurred = pdTRUE;\r
-                       }\r
-               }\r
-\r
-               /* Should not now be possible to write to the queue again. */\r
-               xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );\r
-               if( xReturned != errQUEUE_FULL )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-\r
-               /* Now read back from the queue to ensure the data read back matches that\r
-               written. */\r
-               for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )\r
-               {\r
-                       xReturned = xQueueReceive( xQueue, &ullRead, staticDONT_BLOCK );\r
-\r
-                       if( xReturned != pdPASS )\r
-                       {\r
-                               xErrorOccurred = pdTRUE;\r
-                       }\r
-\r
-                       if( ullRead != ull )\r
-                       {\r
-                               xErrorOccurred = pdTRUE;\r
-                       }\r
-               }\r
-\r
-               /* The queue should be empty again. */\r
-               xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );\r
-               if( xReturned != errQUEUE_EMPTY )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore )\r
-{\r
-const BaseType_t xLoops = 5;\r
-BaseType_t x, xReturned;\r
-\r
-       /* A very basic test that the recursive semaphore behaved like a recursive\r
-       semaphore. First the semaphore should not be able to be given, as it has not\r
-       yet been taken. */\r
-       xReturned = xSemaphoreGiveRecursive( xSemaphore );\r
-\r
-       if( xReturned != pdFAIL )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       /* Now it should be possible to take the mutex a number of times. */\r
-       for( x = 0; x < xLoops; x++ )\r
-       {\r
-               xReturned = xSemaphoreTakeRecursive( xSemaphore, staticDONT_BLOCK );\r
-\r
-               if( xReturned != pdPASS )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-       }\r
-\r
-       /* Should be possible to give the semaphore the same number of times as it\r
-       was given in the loop above. */\r
-       for( x = 0; x < xLoops; x++ )\r
-       {\r
-               xReturned = xSemaphoreGiveRecursive( xSemaphore );\r
-\r
-               if( xReturned != pdPASS )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-       }\r
-\r
-       /* No more gives should be possible though. */\r
-       xReturned = xSemaphoreGiveRecursive( xSemaphore );\r
-\r
-       if( xReturned != pdFAIL )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
 static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void )\r
 {\r
 SemaphoreHandle_t xSemaphore;\r
@@ -552,7 +314,7 @@ a counting semaphore.  http://www.freertos.org/RTOS-task-notifications.html */
 StaticSemaphore_t xSemaphoreBuffer;\r
 \r
        /* Create the semaphore.  xSemaphoreCreateCountingStatic() has one more\r
-       parameter than the usual xSemaphoreCreateCounting() function.  The paraemter\r
+       parameter than the usual xSemaphoreCreateCounting() function.  The parameter\r
        is a pointer to the pre-allocated StaticSemaphore_t structure, which will\r
        hold information on the semaphore in an anonymous way.  If the pointer is\r
        passed as NULL then the structure will be allocated dynamically, just as\r
@@ -568,6 +330,18 @@ StaticSemaphore_t xSemaphoreBuffer;
 \r
        /* Delete the semaphore again so the buffers can be reused. */\r
        vSemaphoreDelete( xSemaphore );\r
+\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               /* Now do the same but using dynamically allocated buffers to ensure the\r
+               delete functions are working correctly in both the static and dynamic\r
+               allocation cases. */\r
+               xSemaphore = xSemaphoreCreateCounting( uxMaxCount, 0 );\r
+               configASSERT( xSemaphore != NULL );\r
+               prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount );\r
+               vSemaphoreDelete( xSemaphore );\r
+       }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -602,6 +376,18 @@ StaticSemaphore_t xSemaphoreBuffer;
 \r
        /* Delete the semaphore again so the buffers can be reused. */\r
        vSemaphoreDelete( xSemaphore );\r
+\r
+       /* Now do the same using dynamically allocated buffers to ensure the delete\r
+       functions are working correctly in both the static and dynamic memory\r
+       allocation cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               xSemaphore = xSemaphoreCreateRecursiveMutex();\r
+               configASSERT( xSemaphore != NULL );\r
+               prvSanityCheckCreatedRecursiveMutex( xSemaphore );\r
+               vSemaphoreDelete( xSemaphore );\r
+       }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -645,6 +431,26 @@ static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_
 \r
        /* Delete the queue again so the buffers can be reused. */\r
        vQueueDelete( xQueue );\r
+\r
+       /* Now do the same using a dynamically allocated queue to ensure the delete\r
+       function is working correctly in both the static and dynamic memory\r
+       allocation cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               xQueue = xQueueCreate( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */\r
+                                                          sizeof( uint64_t ) );                /* The size of each item. */\r
+\r
+               /* The queue handle should equal the static queue structure passed into the\r
+               xQueueCreateStatic() function. */\r
+               configASSERT( xQueue != NULL );\r
+\r
+               /* Ensure the queue passes a few sanity checks as a valid queue. */\r
+               prvSanityCheckCreatedQueue( xQueue );\r
+\r
+               /* Delete the queue again so the buffers can be reused. */\r
+               vQueueDelete( xQueue );\r
+       }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -663,7 +469,7 @@ function calls within this function. */
 StaticSemaphore_t xSemaphoreBuffer;\r
 \r
        /* Create the semaphore.  xSemaphoreCreateMutexStatic() has one more\r
-       parameter than the usual xSemaphoreCreateMutex() function.  The paraemter\r
+       parameter than the usual xSemaphoreCreateMutex() function.  The parameter\r
        is a pointer to the pre-allocated StaticSemaphore_t structure, which will\r
        hold information on the semaphore in an anonymous way.  If the pointer is\r
        passed as NULL then the structure will be allocated dynamically, just as\r
@@ -688,11 +494,39 @@ StaticSemaphore_t xSemaphoreBuffer;
 \r
        /* Delete the semaphore again so the buffers can be reused. */\r
        vSemaphoreDelete( xSemaphore );\r
-}\r
-/*-----------------------------------------------------------*/\r
 \r
-static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void )\r
-{\r
+       /* Now do the same using a dynamically allocated mutex to ensure the delete\r
+       function is working correctly in both the static and dynamic allocation\r
+       cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               xSemaphore = xSemaphoreCreateMutex();\r
+\r
+               /* The semaphore handle should equal the static semaphore structure\r
+               passed into the xSemaphoreCreateMutexStatic() function. */\r
+               configASSERT( xSemaphore != NULL );\r
+\r
+               /* Take the mutex so the mutex is in the state expected by the\r
+               prvSanityCheckCreatedSemaphore() function. */\r
+               xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );\r
+\r
+               if( xReturned != pdPASS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */\r
+               prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
+\r
+               /* Delete the semaphore again so the buffers can be reused. */\r
+               vSemaphoreDelete( xSemaphore );\r
+       }\r
+       #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void )\r
+{\r
 SemaphoreHandle_t xSemaphore;\r
 \r
 /* StaticSemaphore_t is a publicly accessible structure that has the same size\r
@@ -707,7 +541,7 @@ a binary semaphore.  http://www.freertos.org/RTOS-task-notifications.html */
 StaticSemaphore_t xSemaphoreBuffer;\r
 \r
        /* Create the semaphore.  xSemaphoreCreateBinaryStatic() has one more\r
-       parameter than the usual xSemaphoreCreateBinary() function.  The paraemter\r
+       parameter than the usual xSemaphoreCreateBinary() function.  The parameter\r
        is a pointer to the pre-allocated StaticSemaphore_t structure, which will\r
        hold information on the semaphore in an anonymous way.  If the pointer is\r
        passed as NULL then the structure will be allocated dynamically, just as\r
@@ -724,11 +558,21 @@ StaticSemaphore_t xSemaphoreBuffer;
        /* Delete the semaphore again so the buffers can be reused. */\r
        vSemaphoreDelete( xSemaphore );\r
 \r
+       /* Now do the same using a dynamically allocated semaphore to check the\r
+       delete function is working correctly in both the static and dynamic\r
+       allocation cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               xSemaphore = xSemaphoreCreateBinary();\r
+               configASSERT( xSemaphore != NULL );\r
+               prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
+               vSemaphoreDelete( xSemaphore );\r
+       }\r
+       #endif\r
 \r
        /* There isn't a static version of the old and deprecated\r
        vSemaphoreCreateBinary() macro (because its deprecated!), but check it is\r
-       still functioning correctly when configSUPPORT_STATIC_ALLOCATION is set to\r
-       1. */\r
+       still functioning correctly. */\r
        #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
        {\r
                vSemaphoreCreateBinary( xSemaphore );\r
@@ -752,7 +596,9 @@ static void prvTimerCallback( TimerHandle_t xExpiredTimer )
 UBaseType_t *puxVariableToIncrement;\r
 BaseType_t xReturned;\r
 \r
-       /* Obtain the address of the variable to increment from the timer ID. */\r
+       /* The timer callback just demonstrates it is executing by incrementing a\r
+       variable - the address of which is passed into the timer as its ID.  Obtain\r
+       the address of the variable to increment. */\r
        puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer );\r
 \r
        /* Increment the variable to show the timer callback has executed. */\r
@@ -762,7 +608,8 @@ BaseType_t xReturned;
        timer. */\r
        if( *puxVariableToIncrement == staticMAX_TIMER_CALLBACK_EXECUTIONS )\r
        {\r
-               /* This is called from a timer callback so must not block. */\r
+               /* This is called from a timer callback so must not block.  See\r
+               http://www.FreeRTOS.org/FreeRTOS-timers-xTimerStop.html */\r
                xReturned = xTimerStop( xExpiredTimer, staticDONT_BLOCK );\r
 \r
                if( xReturned != pdPASS )\r
@@ -838,6 +685,43 @@ StaticTimer_t xTimerBuffer;
 \r
        /* Just to show the check task that this task is still executing. */\r
        uxCycleCounter++;\r
+\r
+       /* Now do the same using a dynamically allocated software timer to ensure\r
+       the delete function is working correctly in both the static and dynamic\r
+       allocation cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               xTimer = xTimerCreate( "T1",                                                            /* Text name for the task.  Helps debugging only.  Not used by FreeRTOS. */\r
+                                                           xTimerPeriod,                                               /* The period of the timer in ticks. */\r
+                                                               pdTRUE,                                                         /* This is an auto-reload timer. */\r
+                                                               ( void * ) &uxVariableToIncrement,      /* The variable incremented by the test is passed into the timer callback using the timer ID. */\r
+                                                               prvTimerCallback );                                     /* The function to execute when the timer expires. */\r
+\r
+               configASSERT( xTimer != NULL );\r
+\r
+               uxVariableToIncrement = 0;\r
+               xReturned = xTimerStart( xTimer, staticDONT_BLOCK );\r
+\r
+               if( xReturned != pdPASS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS );\r
+\r
+               if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               xReturned = xTimerDelete( xTimer, staticDONT_BLOCK );\r
+\r
+               if( xReturned != pdPASS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+       }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -871,6 +755,18 @@ StaticEventGroup_t xEventGroupBuffer;
 \r
        /* Delete the event group again so the buffers can be reused. */\r
        vEventGroupDelete( xEventGroup );\r
+\r
+       /* Now do the same using a dynamically allocated event group to ensure the\r
+       delete function is working correctly in both the static and dynamic\r
+       allocation cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               xEventGroup = xEventGroupCreate();\r
+               configASSERT( xEventGroup != NULL );\r
+               prvSanityCheckCreatedEventGroup( xEventGroup );\r
+               vEventGroupDelete( xEventGroup );\r
+       }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -896,14 +792,21 @@ static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
        passed as NULL then the respective object will be allocated dynamically as\r
        if xTaskCreate() had been called. */\r
        xReturned = xTaskCreateStatic(\r
-                                               prvStaticallyAllocatedTask, /* Function that implements the task. */\r
-                                               "Static",                                       /* Human readable name for the task. */\r
-                                               configMINIMAL_STACK_SIZE,       /* Task's stack size, in words (not bytes!). */\r
-                                               NULL,                                           /* Parameter to pass into the task. */\r
-                                               tskIDLE_PRIORITY,                       /* The priority of the task. */\r
-                                               &xCreatedTask,                          /* Handle of the task being created. */\r
-                                               &( uxStackBuffer[ 0 ] ),        /* The buffer to use as the task's stack. */\r
-                                               &xTCBBuffer );                          /* The variable that will hold that task's TCB. */\r
+                                               prvStaticallyAllocatedTask,     /* Function that implements the task. */\r
+                                               "Static",                                               /* Human readable name for the task. */\r
+                                               configMINIMAL_STACK_SIZE,               /* Task's stack size, in words (not bytes!). */\r
+                                               NULL,                                                   /* Parameter to pass into the task. */\r
+                                               uxTaskPriorityGet( NULL ) + 1,  /* The priority of the task. */\r
+                                               &xCreatedTask,                                  /* Handle of the task being created. */\r
+                                               &( uxStackBuffer[ 0 ] ),                /* The buffer to use as the task's stack. */\r
+                                               &xTCBBuffer );                                  /* The variable that will hold that task's TCB. */\r
+\r
+       /* The created task had a higher priority so should have executed and\r
+       suspended itself by now. */\r
+       if( eTaskGetState( xCreatedTask ) != eSuspended )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
 \r
        /* Check the task was created correctly, then delete the task. */\r
        configASSERT( xReturned == pdPASS );\r
@@ -912,6 +815,33 @@ static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
                xErrorOccurred = pdTRUE;\r
        }\r
        vTaskDelete( xCreatedTask );\r
+\r
+       /* Now do the same using a dynamically allocated task to ensure the delete\r
+       function is working correctly in both the static and dynamic allocation\r
+       cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               xReturned = xTaskCreate(\r
+                                                                       prvStaticallyAllocatedTask,             /* Function that implements the task. */\r
+                                                                       "Static",                                               /* Human readable name for the task. */\r
+                                                                       configMINIMAL_STACK_SIZE,               /* Task's stack size, in words (not bytes!). */\r
+                                                                       NULL,                                                   /* Parameter to pass into the task. */\r
+                                                                       uxTaskPriorityGet( NULL ) + 1,  /* The priority of the task. */\r
+                                                                       &xCreatedTask );                                /* Handle of the task being created. */\r
+\r
+               if( eTaskGetState( xCreatedTask ) != eSuspended )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               configASSERT( xReturned == pdPASS );\r
+               if( xReturned != pdPASS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+               vTaskDelete( xCreatedTask );\r
+       }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -919,7 +849,9 @@ static void prvStaticallyAllocatedTask( void *pvParameters )
 {\r
        ( void ) pvParameters;\r
 \r
-       /* The created task doesn't do anything - just waits to get deleted. */\r
+       /* The created task just suspends itself to wait to get deleted.  The task\r
+       that creates this task checks this task is in the expected Suspended state\r
+       before deleting it. */\r
        vTaskSuspend( NULL );\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -957,6 +889,237 @@ const TickType_t xTinyDelay = pdMS_TO_TICKS( ( TickType_t ) 2 );
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup )\r
+{\r
+EventBits_t xEventBits;\r
+const EventBits_t xFirstTestBits = ( EventBits_t ) 0xaa, xSecondTestBits = ( EventBits_t ) 0x55;\r
+\r
+       /* The event group should not have any bits set yet. */\r
+       xEventBits = xEventGroupGetBits( xEventGroup );\r
+\r
+       if( xEventBits != ( EventBits_t ) 0 )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       /* Some some bits, then read them back to check they are as expected. */\r
+       xEventGroupSetBits( xEventGroup, xFirstTestBits );\r
+\r
+       xEventBits = xEventGroupGetBits( xEventGroup );\r
+\r
+       if( xEventBits != xFirstTestBits )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       xEventGroupSetBits( xEventGroup, xSecondTestBits );\r
+\r
+       xEventBits = xEventGroupGetBits( xEventGroup );\r
+\r
+       if( xEventBits != ( xFirstTestBits | xSecondTestBits ) )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       /* Finally try clearing some bits too and check that operation proceeds as\r
+       expected. */\r
+       xEventGroupClearBits( xEventGroup, xFirstTestBits );\r
+\r
+       xEventBits = xEventGroupGetBits( xEventGroup );\r
+\r
+       if( xEventBits != xSecondTestBits )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSanityCheckCreatedSemaphore( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount )\r
+{\r
+BaseType_t xReturned;\r
+UBaseType_t x;\r
+const TickType_t xShortBlockTime = pdMS_TO_TICKS( 10 );\r
+TickType_t xTickCount;\r
+\r
+       /* The binary semaphore should start 'empty', so a call to xSemaphoreTake()\r
+       should fail. */\r
+       xTickCount = xTaskGetTickCount();\r
+       xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );\r
+\r
+       if( ( ( TickType_t ) ( xTaskGetTickCount() - xTickCount ) ) < xShortBlockTime )\r
+       {\r
+               /* Did not block on the semaphore as long as expected. */\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       if( xReturned != pdFAIL )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       /* Should be possible to 'give' the semaphore up to a maximum of uxMaxCount\r
+       times. */\r
+       for( x = 0; x < uxMaxCount; x++ )\r
+       {\r
+               xReturned = xSemaphoreGive( xSemaphore );\r
+\r
+               if( xReturned == pdFAIL )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+       }\r
+\r
+       /* Giving the semaphore again should fail, as it is 'full'. */\r
+       xReturned = xSemaphoreGive( xSemaphore );\r
+\r
+       if( xReturned != pdFAIL )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       configASSERT( uxSemaphoreGetCount( xSemaphore ) == uxMaxCount );\r
+\r
+       /* Should now be possible to 'take' the semaphore up to a maximum of\r
+       uxMaxCount times without blocking. */\r
+       for( x = 0; x < uxMaxCount; x++ )\r
+       {\r
+               xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );\r
+\r
+               if( xReturned == pdFAIL )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+       }\r
+\r
+       /* Back to the starting condition, where the semaphore should not be\r
+       available. */\r
+       xTickCount = xTaskGetTickCount();\r
+       xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );\r
+\r
+       if( ( ( TickType_t ) ( xTaskGetTickCount() - xTickCount ) ) < xShortBlockTime )\r
+       {\r
+               /* Did not block on the semaphore as long as expected. */\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       if( xReturned != pdFAIL )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSanityCheckCreatedQueue( QueueHandle_t xQueue )\r
+{\r
+uint64_t ull, ullRead;\r
+BaseType_t xReturned, xLoop;\r
+\r
+       /* This test is done twice to ensure the queue storage area wraps. */\r
+       for( xLoop = 0; xLoop < 2; xLoop++ )\r
+       {\r
+               /* A very basic test that the queue can be written to and read from as\r
+               expected.  First the queue should be empty. */\r
+               xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );\r
+               if( xReturned != errQUEUE_EMPTY )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               /* Now it should be possible to write to the queue staticQUEUE_LENGTH_IN_ITEMS\r
+               times. */\r
+               for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )\r
+               {\r
+                       xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );\r
+                       if( xReturned != pdPASS )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               /* Should not now be possible to write to the queue again. */\r
+               xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );\r
+               if( xReturned != errQUEUE_FULL )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               /* Now read back from the queue to ensure the data read back matches that\r
+               written. */\r
+               for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )\r
+               {\r
+                       xReturned = xQueueReceive( xQueue, &ullRead, staticDONT_BLOCK );\r
+\r
+                       if( xReturned != pdPASS )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       if( ullRead != ull )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               /* The queue should be empty again. */\r
+               xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );\r
+               if( xReturned != errQUEUE_EMPTY )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore )\r
+{\r
+const BaseType_t xLoops = 5;\r
+BaseType_t x, xReturned;\r
+\r
+       /* A very basic test that the recursive semaphore behaved like a recursive\r
+       semaphore. First the semaphore should not be able to be given, as it has not\r
+       yet been taken. */\r
+       xReturned = xSemaphoreGiveRecursive( xSemaphore );\r
+\r
+       if( xReturned != pdFAIL )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       /* Now it should be possible to take the mutex a number of times. */\r
+       for( x = 0; x < xLoops; x++ )\r
+       {\r
+               xReturned = xSemaphoreTakeRecursive( xSemaphore, staticDONT_BLOCK );\r
+\r
+               if( xReturned != pdPASS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+       }\r
+\r
+       /* Should be possible to give the semaphore the same number of times as it\r
+       was given in the loop above. */\r
+       for( x = 0; x < xLoops; x++ )\r
+       {\r
+               xReturned = xSemaphoreGiveRecursive( xSemaphore );\r
+\r
+               if( xReturned != pdPASS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+       }\r
+\r
+       /* No more gives should be possible though. */\r
+       xReturned = xSemaphoreGiveRecursive( xSemaphore );\r
+\r
+       if( xReturned != pdFAIL )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 BaseType_t xAreStaticAllocationTasksStillRunning( void )\r
 {\r
 static UBaseType_t uxLastCycleCounter = 0;\r
index c3a7d1be3f84ef89ca45a73a4a4e5732a49f42ba..a14fa4165164e7f7a67114d438f642c4a6b2057d 100644 (file)
@@ -241,35 +241,52 @@ volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an\r
+implementation of vApplicationGetIdleTaskMemory() to provide the memory that is\r
+used by the Idle task. */\r
 void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )\r
 {\r
-/* The buffers used by the idle task must be static so they are persistent, and\r
-so exist after this function returns. */\r
+/* If the buffers to be provided to the Idle task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
 static StaticTask_t xIdleTaskTCB;\r
 static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];\r
 \r
-       /* configSUPORT_STATIC_ALLOCATION is set to 1 and\r
-       configSUPPORT_DYNAMIC_ALLOCATION is 0, so the application must supply the\r
-       buffers that will be used to hold the Idle task data structure and stack. */\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Idle task's\r
+       state will be stored. */\r
        *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Idle task's stack. */\r
        *ppxIdleTaskStackBuffer = uxIdleTaskStack;\r
-       *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words.  NOT in bytes! */\r
+\r
+       /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the\r
+application must provide an implementation of vApplicationGetTimerTaskMemory()\r
+to provide the memory that is used by the Timer service task. */\r
 void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )\r
 {\r
-/* The buffers used by the Timer/Daemon task must be static so they are\r
-persistent, and so exist after this function returns. */\r
+/* If the buffers to be provided to the Timer task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
 static StaticTask_t xTimerTaskTCB;\r
 static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];\r
 \r
-       /* configSUPPORT_STATIC_ALLOCATION is set to 1,\r
-       configSUPPORT_DYNAMIC_ALLOCATION is set to 1, and configUSE_TIMERS is set\r
-       to 1, so the application must supply the buffers that will be used to hold\r
-       the Timer task data structure and stack. */\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Timer\r
+       task's state will be stored. */\r
        *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Timer task's stack. */\r
        *ppxTimerTaskStackBuffer = uxTimerTaskStack;\r
-       *pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words.  NOT in bytes! */\r
+\r
+       /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pusTimerTaskStackSize = configMINIMAL_STACK_SIZE;\r
 }\r
 \r
index 00f67d45960a2044a7f84d7ab77017c24fefef7c..8b3fdf00b6d093da93a47529963fd10fb0c44a11 100644 (file)
@@ -329,7 +329,7 @@ volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
        ( void ) ulLine;\r
        ( void ) pcFileName;\r
 \r
-       printf( "ASSERT! Line %d, file %s\r\n", ulLine, pcFileName );\r
+       printf( "ASSERT! Line %d, file %s, GetLastError() %d\r\n", ulLine, pcFileName, GetLastError() );\r
 \r
        taskENTER_CRITICAL();\r
        {\r
@@ -410,38 +410,51 @@ const HeapRegion_t xHeapRegions[] =
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an\r
+implementation of vApplicationGetIdleTaskMemory() to provide the memory that is\r
+used by the Idle task. */\r
 void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )\r
 {\r
-/* The buffers used by the idle task must be static so they are persistent, and\r
-so exist after this function returns. */\r
+/* If the buffers to be provided to the Idle task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
 static StaticTask_t xIdleTaskTCB;\r
 static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];\r
 \r
-       /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the\r
-       opportunity to supply the buffers that will be used by the Idle task as its\r
-       stack and to hold its TCB.  If these are set to NULL then the buffers will\r
-       be allocated dynamically, just as if xTaskCreate() had been called. */\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Idle task's\r
+       state will be stored. */\r
        *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Idle task's stack. */\r
        *ppxIdleTaskStackBuffer = uxIdleTaskStack;\r
-       *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words.  NOT in bytes! */\r
+\r
+       /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the\r
+application must provide an implementation of vApplicationGetTimerTaskMemory()\r
+to provide the memory that is used by the Timer service task. */\r
 void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )\r
 {\r
-/* The buffers used by the Timer/Daemon task must be static so they are\r
-persistent, and so exist after this function returns.  The stack buffer is\r
-not declared here, but globally, as it is checked by a test in a different\r
-file. */\r
+/* If the buffers to be provided to the Timer task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
 static StaticTask_t xTimerTaskTCB;\r
 \r
-       /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the\r
-       opportunity to supply the buffers that will be used by the Timer/RTOS daemon\r
-       task as its     stack and to hold its TCB.  If these are set to NULL then the\r
-       buffers will be allocated dynamically, just as if xTaskCreate() had been\r
-       called. */\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Timer\r
+       task's state will be stored. */\r
        *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Timer task's stack. */\r
        *ppxTimerTaskStackBuffer = uxTimerTaskStack;\r
-       *pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words.  NOT in bytes! */\r
+\r
+       /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pusTimerTaskStackSize = configMINIMAL_STACK_SIZE;\r
 }\r
 \r
index a3e55221f83d8cd260527a3272e03e83e58e302a..4ff7aa8d5aaa9bc5106d73f038809d7d75090e63 100644 (file)
@@ -1616,7 +1616,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION
 #endif\r
 \r
 /*\r
- * The registry is provided as a means for kernel aware debuggers to\r
+ * The queue registry is provided as a means for kernel aware debuggers to\r
  * locate queues, semaphores and mutexes.  Call pcQueueGetQueueName() to look\r
  * up and return the name of a queue in the queue registry from the queue's\r
  * handle.\r
index 29a0f98f5ea9224c6ec04aec815703baf7032ae4..eff0bfd306259e7905b55cf6b8db28c87d79416b 100644 (file)
@@ -1152,11 +1152,11 @@ typedef QueueHandle_t SemaphoreHandle_t;
 \r
 /**\r
  * semphr.h\r
- * <pre>TaskHandle_t xSemaphoreGetCount( SemaphoreHandle_t xMutex );</pre>\r
+ * <pre>UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xMutex );</pre>\r
  *\r
- * If the semaphore is a counting semaphore then xSemaphoreGetCount() returns\r
+ * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns\r
  * its current count value.  If the semaphore is a binary semaphore then\r
- * xSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the\r
+ * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the\r
  * semaphore is not available.\r
  *\r
  */\r