From 0549242605e1fbe0160a4bba313df5d108ef9b94 Mon Sep 17 00:00:00 2001 From: rtel Date: Mon, 25 Jan 2016 21:17:47 +0000 Subject: [PATCH] Baseline the Giant Gecko demo, which now has the first pass at a low power tickless implementation. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2409 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../.cproject | 2 +- .../.project | 31 +- .../Source/FreeRTOSConfig.h | 112 +++--- .../Source/Full_Demo/main_full.c | 15 +- .../low_power_tick_management.c | 326 ++++++++++++++++++ .../Source/Low_Power_Demo/main_low_power.c | 31 +- .../Source/main.c | 64 ++-- 7 files changed, 477 insertions(+), 104 deletions(-) create mode 100644 FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management.c diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/.cproject b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/.cproject index e26d77f42..56ac0b4fa 100644 --- a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/.cproject +++ b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/.cproject @@ -83,7 +83,7 @@ - + diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/.project b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/.project index fc794563b..a1f81b665 100644 --- a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/.project +++ b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/.project @@ -70,7 +70,7 @@ - 1453031901581 + 1453621082417 Source/Full_Demo/Standard_Demo_Tasks 5 @@ -79,7 +79,7 @@ - 1453031901586 + 1453621082420 Source/Full_Demo/Standard_Demo_Tasks 5 @@ -88,7 +88,7 @@ - 1453031901590 + 1453621082425 Source/Full_Demo/Standard_Demo_Tasks 5 @@ -97,7 +97,7 @@ - 1453031901594 + 1453621082429 Source/Full_Demo/Standard_Demo_Tasks 5 @@ -106,7 +106,7 @@ - 1453031901598 + 1453621082433 Source/Full_Demo/Standard_Demo_Tasks 5 @@ -115,7 +115,7 @@ - 1453031901602 + 1453621082437 Source/Full_Demo/Standard_Demo_Tasks 5 @@ -124,7 +124,7 @@ - 1453031901606 + 1453621082441 Source/Full_Demo/Standard_Demo_Tasks 5 @@ -133,7 +133,7 @@ - 1453031901610 + 1453621082445 Source/Full_Demo/Standard_Demo_Tasks 5 @@ -142,7 +142,7 @@ - 1453031901614 + 1453621082449 Source/Full_Demo/Standard_Demo_Tasks 5 @@ -151,7 +151,7 @@ - 1453031901618 + 1453621082455 Source/Full_Demo/Standard_Demo_Tasks 5 @@ -160,7 +160,7 @@ - 1453031901623 + 1453621082460 Source/Full_Demo/Standard_Demo_Tasks 5 @@ -168,6 +168,15 @@ 1.0-name-matches-false-false-IntSemTest.c + + 1453621082465 + Source/Full_Demo/Standard_Demo_Tasks + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-StaticAllocation.c + + 0 Source/FreeRTOS_Source/portable/GCC diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/FreeRTOSConfig.h index e1591a0f5..f97b23a72 100644 --- a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/FreeRTOSConfig.h @@ -86,73 +86,103 @@ extern "C" { * See http://www.freertos.org/a00110.html. *----------------------------------------------------------*/ -/* Available options when configUSE_TICKLESS_IDLE set to 1 - * or configUSE_SLEEP_MODE_IN_IDLE set to 1 : - * 1 - EM1, 2 - EM2, 3 - EM3, timer in EM3 is not very accurate*/ -#define configSLEEP_MODE ( 2 ) + +/* Set configCREATE_LOW_POWER_DEMO to one to run the simple blinky demo low power +example, or 1 to run the more comprehensive test and demo application. See +the comments at the top of main.c for more information. */ +#define configCREATE_LOW_POWER_DEMO 1 + +/* Some configuration is dependent on the demo being built. */ +#if( configCREATE_LOW_POWER_DEMO == 1 ) + + /* The slow clock used to generate the tick interrupt in the low power demo + runs at 32768Hz. Ensure the clock is a multiple of the tick rate. */ + #define configTICK_RATE_HZ ( 100 ) + + /* The low power demo uses the tickless idle feature. */ + #define configUSE_TICKLESS_IDLE 1 + + /* Hook function related definitions. */ + #define configUSE_TICK_HOOK ( 0 ) + #define configCHECK_FOR_STACK_OVERFLOW ( 0 ) + #define configUSE_MALLOC_FAILED_HOOK ( 0 ) + #define configUSE_IDLE_HOOK ( 0 ) + +#else + + /* Some of the standard demo test tasks assume a tick rate of 1KHz, even + though that is faster than would normally be warranted by a real + application. */ + #define configTICK_RATE_HZ ( 1000 ) + + /* The full demo always has tasks to run so the tick will never be turned + off. The blinky demo will use the default tickless idle implementation to + turn the tick off. */ + #define configUSE_TICKLESS_IDLE 0 + + /* Hook function related definitions. */ + #define configUSE_TICK_HOOK ( 1 ) + #define configCHECK_FOR_STACK_OVERFLOW ( 1 ) + #define configUSE_MALLOC_FAILED_HOOK ( 1 ) + #define configUSE_IDLE_HOOK ( 1 ) + +#endif /* Main functions*/ #define configUSE_PREEMPTION ( 1 ) -#define configUSE_TICKLESS_IDLE ( 1 ) #define configUSE_PORT_OPTIMISED_TASK_SELECTION ( 1 ) +#define configSUPPORT_STATIC_ALLOCATION ( 1 ) #define configCPU_CLOCK_HZ (( unsigned long ) 14000000) #define configMAX_PRIORITIES ( 6 ) -#define configTICK_RATE_HZ ( 1000 ) -#define configMINIMAL_STACK_SIZE (( unsigned short ) 140) -#define configTOTAL_HEAP_SIZE (( size_t )(40000)) +#define configMINIMAL_STACK_SIZE (( unsigned short ) 140) +#define configTOTAL_HEAP_SIZE (( size_t )(40000)) #define configMAX_TASK_NAME_LEN ( 10 ) -#define configUSE_TRACE_FACILITY ( 0 ) +#define configUSE_TRACE_FACILITY ( 0 ) #define configUSE_16_BIT_TICKS ( 0 ) -#define configIDLE_SHOULD_YIELD ( 0 ) -#define configUSE_MUTEXES ( 1 ) -#define configUSE_RECURSIVE_MUTEXES ( 1 ) -#define configUSE_COUNTING_SEMAPHORES ( 1 ) -#define configUSE_ALTERNATIVE_API ( 0 )/* Deprecated! */ -#define configQUEUE_REGISTRY_SIZE ( 10 ) -#define configUSE_QUEUE_SETS ( 0 ) - -/* Hook function related definitions. */ -#define configUSE_TICK_HOOK ( 1 ) -#define configCHECK_FOR_STACK_OVERFLOW ( 2 ) -#define configUSE_MALLOC_FAILED_HOOK ( 1 ) -#define configUSE_IDLE_HOOK ( 1 ) +#define configIDLE_SHOULD_YIELD ( 0 ) +#define configUSE_MUTEXES ( 1 ) +#define configUSE_RECURSIVE_MUTEXES ( 1 ) +#define configUSE_COUNTING_SEMAPHORES ( 1 ) +#define configUSE_ALTERNATIVE_API ( 0 )/* Deprecated! */ +#define configQUEUE_REGISTRY_SIZE ( 10 ) +#define configUSE_QUEUE_SETS ( 0 ) /* Run time stats gathering related definitions. */ -#define configGENERATE_RUN_TIME_STATS ( 0 ) +#define configGENERATE_RUN_TIME_STATS ( 0 ) /* Co-routine related definitions. */ -#define configUSE_CO_ROUTINES ( 0 ) -#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) +#define configUSE_CO_ROUTINES ( 0 ) +#define configMAX_CO_ROUTINE_PRIORITIES ( 1 ) /* Software timer related definitions. */ -#define configUSE_TIMERS ( 1 ) -#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) /* Highest priority */ -#define configTIMER_QUEUE_LENGTH ( 10 ) -#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE ) +#define configUSE_TIMERS ( 1 ) +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) /* Highest priority */ +#define configTIMER_QUEUE_LENGTH ( 10 ) +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE ) /* Interrupt nesting behaviour configuration. */ -#define configKERNEL_INTERRUPT_PRIORITY ( 255 ) -#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 191 ) /* equivalent to 0xa0, or priority 5. */ +#define configKERNEL_INTERRUPT_PRIORITY ( 255 ) +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 191 ) /* equivalent to 0xa0, or priority 5. */ /* Optional functions - most linkers will remove unused functions anyway. */ -#define INCLUDE_vTaskPrioritySet ( 1 ) -#define INCLUDE_uxTaskPriorityGet ( 1 ) -#define INCLUDE_vTaskDelete ( 1 ) -#define INCLUDE_vTaskSuspend ( 1 ) +#define INCLUDE_vTaskPrioritySet ( 1 ) +#define INCLUDE_uxTaskPriorityGet ( 1 ) +#define INCLUDE_vTaskDelete ( 1 ) +#define INCLUDE_vTaskSuspend ( 1 ) #define INCLUDE_xResumeFromISR ( 1 ) -#define INCLUDE_vTaskDelayUntil ( 1 ) +#define INCLUDE_vTaskDelayUntil ( 1 ) #define INCLUDE_vTaskDelay ( 1 ) #define INCLUDE_xTaskGetSchedulerState ( 1 ) -#define INCLUDE_xTaskGetCurrentTaskHandle ( 1 ) -#define INCLUDE_uxTaskGetStackHighWaterMark ( 0 ) +#define INCLUDE_xTaskGetCurrentTaskHandle ( 1 ) +#define INCLUDE_uxTaskGetStackHighWaterMark ( 0 ) #define INCLUDE_xTaskGetIdleTaskHandle ( 0 ) #define INCLUDE_xTimerGetTimerDaemonTaskHandle ( 0 ) -#define INCLUDE_pcTaskGetTaskName ( 0 ) -#define INCLUDE_eTaskGetState ( 1 ) +#define INCLUDE_pcTaskGetTaskName ( 0 ) +#define INCLUDE_eTaskGetState ( 1 ) #define INCLUDE_xTimerPendFunctionCall ( 1 ) /* Stop if an assertion fails. */ -#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } +#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Full_Demo/main_full.c b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Full_Demo/main_full.c index 2c5172584..cb8552289 100644 --- a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Full_Demo/main_full.c +++ b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Full_Demo/main_full.c @@ -70,10 +70,10 @@ /****************************************************************************** * NOTE 1: This project provides two demo applications. A simple blinky style * project that demonstrates the tickless low power features of FreeRTOS, and a - * more comprehensive test and demo application. The mainCREATE_LOW_POWER_DEMO - * setting in main.c is used to select between the two. See the notes on using - * mainCREATE_LOW_POWER_DEMO in main.c. This file implements the comprehensive - * test and demo version. + * more comprehensive test and demo application. The configCREATE_LOW_POWER_DEMO + * setting in FreeRTOSConifg.h is used to select between the two. See the notes + * on using conifgCREATE_LOW_POWER_DEMO in main.c. This file implements the + * comprehensive test and demo version. * * NOTE 2: This file only contains the source code that is specific to the * full demo. Generic functions, such FreeRTOS hook functions, and functions @@ -133,6 +133,7 @@ #include "EventGroupsDemo.h" #include "TaskNotify.h" #include "IntSemTest.h" +#include "StaticAllocation.h" /* Priorities for the demo application tasks. */ #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL ) @@ -227,6 +228,7 @@ void main_full( void ) vStartEventGroupTasks(); vStartTaskNotifyTask(); vStartInterruptSemaphoreTasks(); + vStartStaticallyAllocatedTasks(); /* Create the register check tasks, as described at the top of this file */ xTaskCreate( prvRegTestTaskEntry1, "Reg1", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_1_PARAMETER, tskIDLE_PRIORITY, NULL ); @@ -291,6 +293,11 @@ unsigned long ulErrorFound = pdFALSE; ulErrorFound = 1UL << 2UL; } + if( xAreStaticAllocationTasksStillRunning() != pdPASS ) + { + ulErrorFound = 1UL << 3UL; + } + if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) { ulErrorFound = 1UL << 4UL; diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management.c b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management.c new file mode 100644 index 000000000..fda6e0eac --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management.c @@ -0,0 +1,326 @@ +/* + FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* Standard includes. */ +#include "limits.h" + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* SiLabs library includes. */ +#include "em_cmu.h" +#include "em_burtc.h" +#include "em_rmu.h" +#include "em_int.h" +#include "sleep.h" + +/* This file contains functions that will override the default implementations +in the RTOS port layer. Therefore only build this file if the low power demo +is being built. */ +#if( configCREATE_LOW_POWER_DEMO == 1 ) + +#define mainTIMER_FREQUENCY_HZ ( 2000UL ) + +/* + * The low power demo does not use the SysTick, so override the + * vPortSetupTickInterrupt() function with an implementation that configures + * a low power clock source. NOTE: This function name must not be changed as + * it is called from the RTOS portable layer. + */ +void vPortSetupTimerInterrupt( void ); + +/* Override the default definition of vPortSuppressTicksAndSleep() that is + * weakly defined in the FreeRTOS Cortex-M port layer with a version that + * manages the BURTC clock, as the tick is generated from the low power BURTC + * and not the SysTick as would normally be the case on a Cortex-M. + */ +void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + +/*-----------------------------------------------------------*/ + +/* Calculate how many clock increments make up a single tick period. */ +static const uint32_t ulReloadValueForOneTick = ( mainTIMER_FREQUENCY_HZ / configTICK_RATE_HZ ); + +/* Calculate the maximum number of ticks that can be suppressed when using the +high resolution clock and low resolution clock respectively. */ +static uint32_t xMaximumPossibleSuppressedTicks = 0; + +/* Flag set from the tick interrupt to allow the sleep processing to know if +sleep mode was exited because of an timer interrupt or a different interrupt. */ +static volatile uint32_t ulTickFlag = pdFALSE; + +/* As the clock is only 2KHz, it is likely a value of 1 will be too much, so +use zero - but leave the value here to assist porting to different clock +speeds. */ +static const uint32_t ulStoppedTimerCompensation = 0UL; + +/*-----------------------------------------------------------*/ + +void vPortSetupTimerInterrupt( void ) +{ +BURTC_Init_TypeDef xBURTCInitStruct = BURTC_INIT_DEFAULT; + + xMaximumPossibleSuppressedTicks = ULONG_MAX / ulReloadValueForOneTick; + + /* Ensure LE modules are accessible. */ + CMU_ClockEnable( cmuClock_CORELE, true ); + + /* Enable access to BURTC registers. */ + RMU_ResetControl( rmuResetBU, false ); + + /* Generate the tick interrupt from BURTC. */ + xBURTCInitStruct.mode = burtcModeEM3; /* Operational in EM3. */ + xBURTCInitStruct.clkSel = burtcClkSelULFRCO;/* ULFRCO clock. */ + xBURTCInitStruct.clkDiv = burtcClkDiv_1; /* 2kHz ULFRCO clock. */ + xBURTCInitStruct.compare0Top = true; /* Wrap on COMP0. */ + BURTC_IntDisable( BURTC_IF_COMP0 ); + BURTC_Init( &xBURTCInitStruct ); + + /* The tick interrupt must be set to the lowest possible. */ + NVIC_SetPriority( BURTC_IRQn, configKERNEL_INTERRUPT_PRIORITY ); + NVIC_ClearPendingIRQ( BURTC_IRQn ); + NVIC_EnableIRQ( BURTC_IRQn ); + BURTC_CompareSet( 0, ulReloadValueForOneTick ); + BURTC_IntClear( BURTC_IF_COMP0 ); + BURTC_IntEnable( BURTC_IF_COMP0 ); + BURTC_CounterReset(); +} +/*-----------------------------------------------------------*/ + +void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) +{ +uint32_t ulReloadValue, ulCompleteTickPeriods, ulCurrentCount; +eSleepModeStatus eSleepAction; +TickType_t xModifiableIdleTime; + + /* THIS FUNCTION IS CALLED WITH THE SCHEDULER SUSPENDED. */ + + /* Make sure the BURTC reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Calculate the reload value required to wait xExpectedIdleTime tick + periods. */ + ulReloadValue = ulReloadValueForOneTick * xExpectedIdleTime; + if( ulReloadValue > ulStoppedTimerCompensation ) + { + /* Compensate for the fact that the BURTC is going to be stopped + momentarily. */ + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Stop the BURTC momentarily. The time the BURTC is stopped for is + accounted for as best it can be, but using the tickless mode will inevitably + result in some tiny drift of the time maintained by the kernel with respect + to calendar time. The count is latched before stopping the timer as + stopping the timer appears to clear the count. */ + ulCurrentCount = BURTC_CounterGet(); + BURTC_Enable( false ); + + /* Enter a critical section but don't use the taskENTER_CRITICAL() method as + that will mask interrupts that should exit sleep mode. */ + INT_Disable(); + + /* The tick flag is set to false before sleeping. If it is true when sleep + mode is exited then sleep mode was probably exited because the tick was + suppressed for the entire xExpectedIdleTime period. */ + ulTickFlag = pdFALSE; + + /* If a context switch is pending then abandon the low power entry as the + context switch might have been pended by an external interrupt that requires + processing. */ + eSleepAction = eTaskConfirmSleepModeStatus(); + if( eSleepAction == eAbortSleep ) + { + /* Restart tick and count up to whatever was left of the current time + slice. */ + BURTC_CompareSet( 0, ulReloadValueForOneTick - ulCurrentCount ); + BURTC_Enable( true ); + + /* Re-enable interrupts - see comments above the cpsid instruction() + above. */ + INT_Enable(); + } + else + { + /* Adjust the reload value to take into account that the current time + slice is already partially complete. */ + ulReloadValue -= ulCurrentCount; + BURTC_CompareSet( 0, ulReloadValue ); + + /* Restart the BURTC. */ + BURTC_Enable( true ); + + /* Allow the application to define some pre-sleep processing. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + + /* xExpectedIdleTime being set to 0 by configPRE_SLEEP_PROCESSING() + means the application defined code has already executed the WAIT + instruction. */ + if( xModifiableIdleTime > 0 ) + { + __asm volatile( "dsb" ); + SLEEP_Sleep(); + __asm volatile( "isb" ); + } + + /* Allow the application to define some post sleep processing. */ + configPOST_SLEEP_PROCESSING( xModifiableIdleTime ); + + /* Stop BURTC. Again, the time the SysTick is stopped for is accounted + for as best it can be, but using the tickless mode will inevitably + result in some tiny drift of the time maintained by the kernel with + respect to calendar time. The count value is latched before stopping + the timer as stopping the timer appears to clear the count. */ + ulCurrentCount = BURTC_CounterGet(); + BURTC_Enable( false ); + + /* Re-enable interrupts - see comments above the cpsid instruction() + above. */ + INT_Enable(); + + if( ulTickFlag != pdFALSE ) + { + /* The tick interrupt has already executed, although because this + function is called with the scheduler suspended the actual tick + processing will not occur until after this function has exited. + Reset the reload value with whatever remains of this tick period. */ + ulReloadValue = ulReloadValueForOneTick - ulCurrentCount; + BURTC_CompareSet( 0, ulReloadValue ); + + /* The tick interrupt handler will already have pended the tick + processing in the kernel. As the pending tick will be processed as + soon as this function exits, the tick value maintained by the tick + is stepped forward by one less than the time spent sleeping. The + actual stepping of the tick appears later in this function. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. How + many complete tick periods passed while the processor was + sleeping? */ + ulCompleteTickPeriods = ulCurrentCount / ulReloadValueForOneTick; + + /* The reload value is set to whatever fraction of a single tick + period remains. */ + ulReloadValue = ulCurrentCount - ( ulCompleteTickPeriods * ulReloadValueForOneTick ); + if( ulReloadValue == 0 ) + { + /* There is no fraction remaining. */ + ulReloadValue = ulReloadValueForOneTick; + ulCompleteTickPeriods++; + } + + BURTC_CompareSet( 0, ulReloadValue ); + } + + /* Restart the BURTC so it runs up to the alarm value. The alarm value + will get set to the value required to generate exactly one tick period + the next time the BURTC interrupt executes. */ + BURTC_Enable( true ); + + /* Wind the tick forward by the number of tick periods that the CPU + remained in a low power state. */ + vTaskStepTick( ulCompleteTickPeriods ); + } +} +/*-----------------------------------------------------------*/ + +void BURTC_IRQHandler(void) +{ + if( ulTickFlag == pdFALSE ) + { + /* Set BURTC interrupt to one system tick period*/ + BURTC_Enable( false ); + BURTC_CompareSet( 0, ulReloadValueForOneTick ); + ulTickFlag = pdTRUE; + BURTC_Enable( true ); + } + + BURTC_IntClear( _RTC_IFC_MASK ); + + /* Critical section which protect incrementing the tick*/ + ( void ) portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( xTaskIncrementTick() != pdFALSE ) + { + /* Pend a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); +} + +#endif /* ( configCREATE_LOW_POWER_DEMO == 1 ) */ + diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/main_low_power.c b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/main_low_power.c index f39f9b8e4..fe4824d8c 100644 --- a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/main_low_power.c +++ b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/main_low_power.c @@ -69,10 +69,10 @@ /****************************************************************************** * NOTE 1: This project provides two demo applications. A simple blinky demo - * that demonstrates tickless low power operation, and a more comprehensive test - * and demo application. The mainCREATE_LOW_POWER_DEMO setting in main.c is - * used to select between the two. See the notes on using - * mainCREATE_LOW_POWER_DEMO in main.c. This file implements the low power + * that demonstrates tickless low power operation, and a more comprehensive + * test and demo application. The configCREATE_LOW_POWER_DEMO setting in + * FreeRTOSConfig.h is used to select between the two. See the notes on using + * configCREATE_LOW_POWER_DEMO in main.c. This file implements the low power * version. * * NOTE 2: This file only contains the source code that is specific to the @@ -83,26 +83,7 @@ * main_low_power() creates one queue, and two tasks. It then starts the * scheduler. * - * The Queue Send Task: - * The queue send task is implemented by the prvQueueSendTask() function in - * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly - * block for 200 milliseconds, before sending the value 100 to the queue that - * was created within main_low_power(). Once the value is sent, the task loops - * back around to block for another 200 milliseconds...and so on. - * - * The Queue Receive Task: - * The queue receive task is implemented by the prvQueueReceiveTask() function - * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly - * blocks on attempts to read data from the queue that was created within - * main_low_power(). When data is received, the task checks the value of the - * data, and if the value equals the expected 100, toggles an LED. The 'block - * time' parameter passed to the queue receive function specifies that the - * task should be held in the Blocked state indefinitely to wait for data to - * be available on the queue. The queue receive task will only leave the - * Blocked state when the queue send task writes to the queue. As the queue - * send task writes to the queue every 200 milliseconds, the queue receive - * task leaves the Blocked state every 200 milliseconds, and therefore toggles - * the LED every 200 milliseconds. + * TBD */ #warning Description of demo in comments above is not correct. @@ -121,7 +102,7 @@ /* The rate at which data is sent to the queue. The 200ms value is converted to ticks using the portTICK_PERIOD_MS constant. */ -#define mainQUEUE_SEND_FREQUENCY_MS pdMS_TO_TICKS( 500 ) +#define mainQUEUE_SEND_FREQUENCY_MS pdMS_TO_TICKS( 1000 ) /* The number of items the queue can hold. This is 1 as the receive task will remove items as they are added, meaning the send task should always find diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/main.c b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/main.c index 1f0371876..8bd4c4576 100644 --- a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/main.c +++ b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/main.c @@ -69,11 +69,11 @@ /****************************************************************************** * This project provides two demo applications. A simple blinky style project - * that demonstrates tickless low power functionality, and a more comprehensive - * test and demo application. The mainCREATE_LOW_POWER_DEMO setting (defined in - * this file) is used to select between the two. The simply blinky low power - * demo is implemented and described in main_low_power.c. The more - * comprehensive test and demo application is implemented and described in + * that demonstrates low power tickless functionality, and a more comprehensive + * test and demo application. The configCREATE_LOW_POWER_DEMO setting, which is + * defined in FreeRTOSConfig.h, is used to select between the two. The simply + * blinky low power demo is implemented and described in main_low_power.c. The + * more comprehensive test and demo application is implemented and described in * main_full.c. * * This file implements the code that is not demo specific, including the @@ -85,8 +85,6 @@ * */ -#warning FreeRTOSConfig.h needs formatting. - /* FreeRTOS includes. */ #include "FreeRTOS.h" #include "task.h" @@ -109,14 +107,14 @@ run the more comprehensive test and demo application. */ static void prvSetupHardware( void ); /* - * main_low_power() is used when mainCREATE_LOW_POWER_DEMO is set to 1. - * main_full() is used when mainCREATE_LOW_POWER_DEMO is set to 0. + * main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1. + * main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0. */ -#if mainCREATE_LOW_POWER_DEMO == 1 +#if( configCREATE_LOW_POWER_DEMO == 1 ) extern void main_low_power( void ); #else extern void main_full( void ); -#endif /* #if mainCREATE_LOW_POWER_DEMO == 1 */ +#endif /* #if configCREATE_LOW_POWER_DEMO == 1 */ /* Prototypes for the standard FreeRTOS callback/hook functions implemented within this file. */ @@ -134,7 +132,7 @@ int main( void ) /* The mainCREATE_LOW_POWER_DEMO setting is described at the top of this file. */ - #if( mainCREATE_LOW_POWER_DEMO == 1 ) + #if( configCREATE_LOW_POWER_DEMO == 1 ) { main_low_power(); } @@ -144,10 +142,7 @@ int main( void ) } #endif - /* Start FreeRTOS Scheduler */ - vTaskStartScheduler(); - - /* Cannot get here. */ + /* Should not get here. */ return 0; } /*-----------------------------------------------------------*/ @@ -160,11 +155,7 @@ static void prvSetupHardware( void ) SLEEP_Init( NULL, NULL ); BSP_LedsInit(); - #if (configSLEEP_MODE < 3) - { - SLEEP_SleepBlockBegin((SLEEP_EnergyMode_t)(configSLEEP_MODE+1)); - } - #endif +//_RB_ SLEEP_SleepBlockBegin( ( SLEEP_EnergyMode_t ) ( configSLEEP_MODE+1 ) ); } /*-----------------------------------------------------------*/ @@ -216,12 +207,41 @@ volatile size_t xFreeHeapSpace; void vApplicationTickHook( void ) { /* The full demo includes tests that run from the tick hook. */ - #if( mainCREATE_LOW_POWER_DEMO == 0 ) + #if( configCREATE_LOW_POWER_DEMO == 0 ) { extern void vFullDemoTickHook( void ); + /* Some of the tests and demo tasks executed by the full demo include + interaction from an interrupt - for which the tick interrupt is used + via the tick hook function. */ vFullDemoTickHook(); } #endif } +/*-----------------------------------------------------------*/ + +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! */ +} +/*-----------------------------------------------------------*/ + +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! */ +} +/*-----------------------------------------------------------*/ -- 2.39.5