diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelHooks.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcKernelHooks.h index 7b94a106f..03145b8e6 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 38251c40e..722e55341 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 @@ void vTraceInitObjectPropertyTable() 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 @@ void vTraceInitObjectHandleStack() 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 @@ const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass) 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 @@ uint8_t uiTraceIsObjectExcluded(traceObjectClass objectclass, objectHandleType h { 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 @@ uint8_t uiTraceIsObjectExcluded(traceObjectClass objectclass, objectHandleType h 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 b533712c1..0092d9e6b 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 @@ const uint32_t ulMaxDivisor = 0xff, ulDivisorShift = 0x08; } /*-----------------------------------------------------------*/ +/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an +implementation of vApplicationGetIdleTaskMemory() to provide the memory that is +used by the Idle task. */ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize ) { - /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the - opportunity to supply the buffers that will be used by the Idle task as its - stack and to hold its TCB. If these are set to NULL then the buffers will - be allocated dynamically, just as if xTaskCreate() had been called. */ - *ppxIdleTaskTCBBuffer = NULL; - *ppxIdleTaskStackBuffer = NULL; - *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words. NOT in bytes! */ +/* If the buffers to be provided to the Idle task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ +static StaticTask_t xIdleTaskTCB; +static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; } /*-----------------------------------------------------------*/ +/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the +application must provide an implementation of vApplicationGetTimerTaskMemory() +to provide the memory that is used by the Timer service task. */ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize ) { - /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the - opportunity to supply the buffers that will be used by the Timer/RTOS daemon - task as its stack and to hold its TCB. If these are set to NULL then the - buffers will be allocated dynamically, just as if xTaskCreate() had been - called. */ - *ppxTimerTaskTCBBuffer = NULL; - *ppxTimerTaskStackBuffer = NULL; - *pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words. NOT in bytes! */ +/* If the buffers to be provided to the Timer task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ +static StaticTask_t xTimerTaskTCB; +static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pusTimerTaskStackSize = configMINIMAL_STACK_SIZE; } 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 1eb40c1ff..1bef000bf 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 @@ void vApplicationTickHook( void ) } /*-----------------------------------------------------------*/ +/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an +implementation of vApplicationGetIdleTaskMemory() to provide the memory that is +used by the Idle task. */ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize ) { - /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the - opportunity to supply the buffers that will be used by the Idle task as its - stack and to hold its TCB. If these are set to NULL then the buffers will - be allocated dynamically, just as if xTaskCreate() had been called. */ - *ppxIdleTaskTCBBuffer = NULL; - *ppxIdleTaskStackBuffer = NULL; - *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words. NOT in bytes! */ +/* If the buffers to be provided to the Idle task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ +static StaticTask_t xIdleTaskTCB; +static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; } /*-----------------------------------------------------------*/ +/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the +application must provide an implementation of vApplicationGetTimerTaskMemory() +to provide the memory that is used by the Timer service task. */ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize ) { - /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the - opportunity to supply the buffers that will be used by the Timer/RTOS daemon - task as its stack and to hold its TCB. If these are set to NULL then the - buffers will be allocated dynamically, just as if xTaskCreate() had been - called. */ - *ppxTimerTaskTCBBuffer = NULL; - *ppxTimerTaskStackBuffer = NULL; - *pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words. NOT in bytes! */ -} -/*-----------------------------------------------------------*/ +/* If the buffers to be provided to the Timer task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ +static StaticTask_t xTimerTaskTCB; +static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pusTimerTaskStackSize = configMINIMAL_STACK_SIZE; +} 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 de94bcb9f..369099a1c 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 @@ void vApplicationTickHook( void ) } /*-----------------------------------------------------------*/ +/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an +implementation of vApplicationGetIdleTaskMemory() to provide the memory that is +used by the Idle task. */ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize ) { - /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the - opportunity to supply the buffers that will be used by the Idle task as its - stack and to hold its TCB. If these are set to NULL then the buffers will - be allocated dynamically, just as if xTaskCreate() had been called. */ - *ppxIdleTaskTCBBuffer = NULL; - *ppxIdleTaskStackBuffer = NULL; - *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words. NOT in bytes! */ +/* If the buffers to be provided to the Idle task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ +static StaticTask_t xIdleTaskTCB; +static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; } /*-----------------------------------------------------------*/ +/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the +application must provide an implementation of vApplicationGetTimerTaskMemory() +to provide the memory that is used by the Timer service task. */ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize ) { - /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the - opportunity to supply the buffers that will be used by the Timer/RTOS daemon - task as its stack and to hold its TCB. If these are set to NULL then the - buffers will be allocated dynamically, just as if xTaskCreate() had been - called. */ - *ppxTimerTaskTCBBuffer = NULL; - *ppxTimerTaskStackBuffer = NULL; - *pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words. NOT in bytes! */ +/* If the buffers to be provided to the Timer task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ +static StaticTask_t xTimerTaskTCB; +static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pusTimerTaskStackSize = configMINIMAL_STACK_SIZE; } -/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/CORTEX_M4F_CEC1302_Keil/main.c b/FreeRTOS/Demo/CORTEX_M4F_CEC1302_Keil/main.c index 18db41134..82115564d 100644 --- a/FreeRTOS/Demo/CORTEX_M4F_CEC1302_Keil/main.c +++ b/FreeRTOS/Demo/CORTEX_M4F_CEC1302_Keil/main.c @@ -234,30 +234,54 @@ void vApplicationTickHook( void ) } /*-----------------------------------------------------------*/ +/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an +implementation of vApplicationGetIdleTaskMemory() to provide the memory that is +used by the Idle task. */ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize ) { - /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the - opportunity to supply the buffers that will be used by the Idle task as its - stack and to hold its TCB. If these are set to NULL then the buffers will - be allocated dynamically, just as if xTaskCreate() had been called. */ - *ppxIdleTaskTCBBuffer = NULL; - *ppxIdleTaskStackBuffer = NULL; - *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words. NOT in bytes! */ +/* If the buffers to be provided to the Idle task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ +static StaticTask_t xIdleTaskTCB; +static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; } /*-----------------------------------------------------------*/ +/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the +application must provide an implementation of vApplicationGetTimerTaskMemory() +to provide the memory that is used by the Timer service task. */ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize ) { - /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the - opportunity to supply the buffers that will be used by the Timer/RTOS daemon - task as its stack and to hold its TCB. If these are set to NULL then the - buffers will be allocated dynamically, just as if xTaskCreate() had been - called. */ - *ppxTimerTaskTCBBuffer = NULL; - *ppxTimerTaskStackBuffer = NULL; - *pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words. NOT in bytes! */ +/* If the buffers to be provided to the Timer task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ +static StaticTask_t xTimerTaskTCB; +static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pusTimerTaskStackSize = configMINIMAL_STACK_SIZE; } -/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c b/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c index 1433476f2..4b4232b55 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 prvTimerCallback( TimerHandle_t xExpiredTimer ); static void prvStaticallyAllocatedTask( void *pvParameters ); /* - * A function that demonstrates and tests the xTaskCreateStatic() API function - * by creating and then deleting tasks with both dynamically and statically - * allocated TCBs and stacks. + * A function that demonstrates and tests the API functions that create and + * delete tasks using both statically and dynamically allocated TCBs and stacks. */ static void prvCreateAndDeleteStaticallyAllocatedTasks( void ); /* - * A function that demonstrates and tests the xEventGroupCreateStatic() API - * function by creating and then deleting event groups using both dynamically - * and statically allocated event group structures. + * A function that demonstrates and tests the API functions that create and + * delete event groups using both statically and dynamically allocated RAM. */ static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void ); /* - * A function that demonstrates and tests the xQueueCreateStatic() API function - * by creating and then deleting queues with both dynamically and statically - * allocated queue structures and queue storage areas. + * A function that demonstrates and tests the API functions that create and + * delete queues using both statically and dynamically allocated RAM. */ static void prvCreateAndDeleteStaticallyAllocatedQueues( void ); /* - * A function that demonstrates and tests the xSemaphoreCreateBinaryStatic() API - * macro by creating and then deleting binary semaphores with both dynamically - * and statically allocated semaphore structures. + * A function that demonstrates and tests the API functions that create and + * delete binary semaphores using both statically and dynamically allocated RAM. */ static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void ); /* - * A function that demonstrates and tests the xTimerCreateStatic() API macro by - * creating and then deleting software timers with both dynamically and - * statically allocated timer structures. + * A function that demonstrates and tests the API functions that create and + * delete software timers using both statically and dynamically allocated RAM. */ static void prvCreateAndDeleteStaticallyAllocatedTimers( void ); /* - * A function that demonstrates and tests the xSemaphoreCreateMutexStatic() API - * macro by creating and then deleting mutexes with both dynamically and - * statically allocated semaphore structures. + * A function that demonstrates and tests the API functions that create and + * delete mutexes using both statically and dynamically allocated RAM. */ static void prvCreateAndDeleteStaticallyAllocatedMutexes( void ); /* - * A function that demonstrates and tests the xSemaphoreCreateCountingStatic() - * API macro by creating and then deleting counting semaphores with both - * dynamically and statically allocated semaphore structures. + * A function that demonstrates and tests the API functions that create and + * delete counting semaphores using both statically and dynamically allocated + * RAM. */ static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void ); /* - * A function that demonstrates and tests the - * xSemaphoreCreateRecursiveMutexStatic() API macro by creating and then - * deleting recursive mutexes with both dynamically and statically allocated - * semaphore structures. + * A function that demonstrates and tests the API functions that create and + * delete recursive mutexes using both statically and dynamically allocated RAM. */ static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void ); @@ -250,9 +244,8 @@ static volatile BaseType_t xErrorOccurred = pdFALSE; void vStartStaticallyAllocatedTasks( void ) { - /* Create a single task, which then repeatedly creates and deletes the - task implemented by prvStaticallyAllocatedTask() at various different - priorities, and both with and without statically allocated TCB and stack. */ + /* Create a single task, which then repeatedly creates and deletes the other + RTOS objects using both statically and dynamically allocated RAM. */ xTaskCreateStatic( prvStaticallyAllocatedCreator, /* The function that implements the task being created. */ "StatCreate", /* Text name for the task - not used by the RTOS, its just to assist debugging. */ staticCREATOR_TASK_STACK_SIZE, /* Size of the buffer passed in as the stack - in words, not bytes! */ @@ -274,16 +267,16 @@ static void prvStaticallyAllocatedCreator( void *pvParameters ) for( ;; ) { - /* Loop, running functions that create and delete the various objects - that can be optionally created using either static or dynamic memory - allocation. */ + /* Loop, running functions that create and delete the various RTOS + objects that can be optionally created using either static or dynamic + memory allocation. */ prvCreateAndDeleteStaticallyAllocatedTasks(); prvCreateAndDeleteStaticallyAllocatedQueues(); - /* Ensure lower priority tasks get CPU time. */ + /* Delay to ensure lower priority tasks get CPU time, and increment the + cycle counter so a 'check' task can determine that this task is still + executing. */ vTaskDelay( prvGetNextDelayTime() ); - - /* Just to show the check task that this task is still executing. */ uxCycleCounter++; prvCreateAndDeleteStaticallyAllocatedBinarySemaphores(); @@ -304,6 +297,598 @@ static void prvStaticallyAllocatedCreator( void *pvParameters ) } /*-----------------------------------------------------------*/ +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 @@ BaseType_t x, xReturned; } /*-----------------------------------------------------------*/ -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 c3a7d1be3..a14fa4165 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 @@ volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0; } /*-----------------------------------------------------------*/ +/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an +implementation of vApplicationGetIdleTaskMemory() to provide the memory that is +used by the Idle task. */ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize ) { -/* The buffers used by the idle task must be static so they are persistent, and -so exist after this function returns. */ +/* If the buffers to be provided to the Idle task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ static StaticTask_t xIdleTaskTCB; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; - /* configSUPORT_STATIC_ALLOCATION is set to 1 and - configSUPPORT_DYNAMIC_ALLOCATION is 0, so the application must supply the - buffers that will be used to hold the Idle task data structure and stack. */ + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ *ppxIdleTaskStackBuffer = uxIdleTaskStack; - *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words. NOT in bytes! */ + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; } /*-----------------------------------------------------------*/ +/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the +application must provide an implementation of vApplicationGetTimerTaskMemory() +to provide the memory that is used by the Timer service task. */ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize ) { -/* The buffers used by the Timer/Daemon task must be static so they are -persistent, and so exist after this function returns. */ +/* If the buffers to be provided to the Timer task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ static StaticTask_t xTimerTaskTCB; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; - /* configSUPPORT_STATIC_ALLOCATION is set to 1, - configSUPPORT_DYNAMIC_ALLOCATION is set to 1, and configUSE_TIMERS is set - to 1, so the application must supply the buffers that will be used to hold - the Timer task data structure and stack. */ + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ *ppxTimerTaskStackBuffer = uxTimerTaskStack; - *pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words. NOT in bytes! */ + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pusTimerTaskStackSize = configMINIMAL_STACK_SIZE; } diff --git a/FreeRTOS/Demo/WIN32-MSVC/main.c b/FreeRTOS/Demo/WIN32-MSVC/main.c index 00f67d459..8b3fdf00b 100644 --- a/FreeRTOS/Demo/WIN32-MSVC/main.c +++ b/FreeRTOS/Demo/WIN32-MSVC/main.c @@ -329,7 +329,7 @@ volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0; ( void ) ulLine; ( void ) pcFileName; - printf( "ASSERT! Line %d, file %s\r\n", ulLine, pcFileName ); + printf( "ASSERT! Line %d, file %s, GetLastError() %d\r\n", ulLine, pcFileName, GetLastError() ); taskENTER_CRITICAL(); { @@ -410,38 +410,51 @@ const HeapRegion_t xHeapRegions[] = } /*-----------------------------------------------------------*/ +/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an +implementation of vApplicationGetIdleTaskMemory() to provide the memory that is +used by the Idle task. */ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize ) { -/* The buffers used by the idle task must be static so they are persistent, and -so exist after this function returns. */ +/* If the buffers to be provided to the Idle task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ static StaticTask_t xIdleTaskTCB; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; - /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the - opportunity to supply the buffers that will be used by the Idle task as its - stack and to hold its TCB. If these are set to NULL then the buffers will - be allocated dynamically, just as if xTaskCreate() had been called. */ + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ *ppxIdleTaskStackBuffer = uxIdleTaskStack; - *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words. NOT in bytes! */ + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; } /*-----------------------------------------------------------*/ +/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the +application must provide an implementation of vApplicationGetTimerTaskMemory() +to provide the memory that is used by the Timer service task. */ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize ) { -/* The buffers used by the Timer/Daemon task must be static so they are -persistent, and so exist after this function returns. The stack buffer is -not declared here, but globally, as it is checked by a test in a different -file. */ +/* If the buffers to be provided to the Timer task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ static StaticTask_t xTimerTaskTCB; - /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the - opportunity to supply the buffers that will be used by the Timer/RTOS daemon - task as its stack and to hold its TCB. If these are set to NULL then the - buffers will be allocated dynamically, just as if xTaskCreate() had been - called. */ + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ *ppxTimerTaskStackBuffer = uxTimerTaskStack; - *pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words. NOT in bytes! */ + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pusTimerTaskStackSize = configMINIMAL_STACK_SIZE; } diff --git a/FreeRTOS/Source/include/queue.h b/FreeRTOS/Source/include/queue.h index a3e55221f..4ff7aa8d5 100644 --- a/FreeRTOS/Source/include/queue.h +++ b/FreeRTOS/Source/include/queue.h @@ -1616,7 +1616,7 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION #endif /* - * The registry is provided as a means for kernel aware debuggers to + * The queue registry is provided as a means for kernel aware debuggers to * locate queues, semaphores and mutexes. Call pcQueueGetQueueName() to look * up and return the name of a queue in the queue registry from the queue's * handle. diff --git a/FreeRTOS/Source/include/semphr.h b/FreeRTOS/Source/include/semphr.h index 29a0f98f5..eff0bfd30 100644 --- a/FreeRTOS/Source/include/semphr.h +++ b/FreeRTOS/Source/include/semphr.h @@ -1152,11 +1152,11 @@ typedef QueueHandle_t SemaphoreHandle_t; /** * semphr.h - *
TaskHandle_t xSemaphoreGetCount( SemaphoreHandle_t xMutex );
+ *
UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xMutex );
* - * 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. * */