mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Update EFM32 demos to include an option to use the RTC as the clock source when using low power tickless mode.
This commit is contained in:
parent
c4dd17eeb5
commit
556de14a1d
|
@ -53,7 +53,7 @@
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Source/SilLabs_Code/kits/EFM32GG_STK3700/config}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Source/SilLabs_Code/kits/EFM32GG_STK3700/config}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Source/SilLabs_Code/Device/SiliconLabs/EFM32GG/Include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Source/SilLabs_Code/Device/SiliconLabs/EFM32GG/Include}""/>
|
||||||
</option>
|
</option>
|
||||||
<option id="gnu.c.compiler.option.preprocessor.undef.symbol.1550566013" name="Undefined symbols (-U)" superClass="gnu.c.compiler.option.preprocessor.undef.symbol" valueType="undefDefinedSymbols"/>
|
<option id="gnu.c.compiler.option.preprocessor.undef.symbol.1550566013" name="Undefined symbols (-U)" superClass="gnu.c.compiler.option.preprocessor.undef.symbol"/>
|
||||||
<inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.733848972" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
<inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.733848972" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||||
</tool>
|
</tool>
|
||||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base.1840601111" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base">
|
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base.1840601111" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base">
|
||||||
|
@ -103,6 +103,9 @@
|
||||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.1920617400" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>
|
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.1920617400" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||||
</toolChain>
|
</toolChain>
|
||||||
</folderInfo>
|
</folderInfo>
|
||||||
|
<fileInfo id="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.8.3.20131129.566130702" name="low_power_tick_management_BURTC.c" rcbsApplicability="disable" resourcePath="Source/Low_Power_Demo/low_power_tick_management_BURTC.c" toolsToInvoke="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1299820402.669016646">
|
||||||
|
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1299820402.669016646" name="GNU ARM C Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1299820402"/>
|
||||||
|
</fileInfo>
|
||||||
<sourceEntries>
|
<sourceEntries>
|
||||||
<entry excluding="Source/FreeRTOS_Source/portable/GCC/ARM_CM4F|Source/SilLabs_Code/kits/EFM32WG_STK3800|Source/SilLabs_Code/Device/SiliconLabs/EFM32GG/Source|Source/SilLabs_Code/Device/SiliconLabs/EFM32WG|Source/SilLabs_Code/CMSIS/efm32wg|CMSIS/efm32wg|Source/SilLabs_Code/kits/bsp/bsp_dk_3201.c|Source/SilLabs_Code/kits/bsp/bsp_dk_3200.c|Source/SilLabs_Code/kits/bsp/bsp_dk_leds.c|Source/RTT|Source/SilLabs_Code/kits/bsp/bsp_dk_mcuboard.c|Source/SilLabs_Code/kits/bsp/bsp_bcc.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
<entry excluding="Source/FreeRTOS_Source/portable/GCC/ARM_CM4F|Source/SilLabs_Code/kits/EFM32WG_STK3800|Source/SilLabs_Code/Device/SiliconLabs/EFM32GG/Source|Source/SilLabs_Code/Device/SiliconLabs/EFM32WG|Source/SilLabs_Code/CMSIS/efm32wg|CMSIS/efm32wg|Source/SilLabs_Code/kits/bsp/bsp_dk_3201.c|Source/SilLabs_Code/kits/bsp/bsp_dk_3200.c|Source/SilLabs_Code/kits/bsp/bsp_dk_leds.c|Source/RTT|Source/SilLabs_Code/kits/bsp/bsp_dk_mcuboard.c|Source/SilLabs_Code/kits/bsp/bsp_bcc.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||||
</sourceEntries>
|
</sourceEntries>
|
||||||
|
|
|
@ -87,28 +87,24 @@ extern "C" {
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Set configCREATE_LOW_POWER_DEMO to one to run the simple blinky demo low power
|
/* Set configCREATE_LOW_POWER_DEMO as follows:
|
||||||
example, or 1 to run the more comprehensive test and demo application. See
|
*
|
||||||
the comments at the top of main.c for more information. */
|
* 0: Build the full test and demo application.
|
||||||
#define configCREATE_LOW_POWER_DEMO 1
|
* 1: Build the simple blinky tickless low power demo, generating the tick
|
||||||
|
* interrupt from the BURTC. EM3 will be entered, but use of the ULFRCO
|
||||||
|
* clock means timing will be inaccurate.
|
||||||
|
* 2: Build the simple blinky tickless low power demo, generating the tick from
|
||||||
|
* the RTC. EM2 will be entered. The LXFO clock is used, which is more
|
||||||
|
* accurate than the ULFRCO clock.
|
||||||
|
* See the comments at the top of main.c, main_full.c and main_low_power.c for
|
||||||
|
* more information.
|
||||||
|
*/
|
||||||
|
#define configCREATE_LOW_POWER_DEMO 2
|
||||||
|
|
||||||
/* Some configuration is dependent on the demo being built. */
|
/* Some configuration is dependent on the demo being built. */
|
||||||
#if( configCREATE_LOW_POWER_DEMO == 1 )
|
#if( configCREATE_LOW_POWER_DEMO == 0 )
|
||||||
|
|
||||||
/* The slow clock used to generate the tick interrupt in the low power demo
|
/* Tickless mode is not used. */
|
||||||
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
|
/* 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
|
though that is faster than would normally be warranted by a real
|
||||||
|
@ -124,7 +120,49 @@ the comments at the top of main.c for more information. */
|
||||||
#define configUSE_TICK_HOOK ( 1 )
|
#define configUSE_TICK_HOOK ( 1 )
|
||||||
#define configCHECK_FOR_STACK_OVERFLOW ( 1 )
|
#define configCHECK_FOR_STACK_OVERFLOW ( 1 )
|
||||||
#define configUSE_MALLOC_FAILED_HOOK ( 1 )
|
#define configUSE_MALLOC_FAILED_HOOK ( 1 )
|
||||||
#define configUSE_IDLE_HOOK ( 1 )
|
#define configUSE_IDLE_HOOK ( 1 )
|
||||||
|
|
||||||
|
#define configENERGY_MODE ( sleepEM3 )
|
||||||
|
|
||||||
|
#elif( configCREATE_LOW_POWER_DEMO == 1 )
|
||||||
|
|
||||||
|
/* Tickless idle mode, generating RTOS tick interrupts from the BURTC, fed
|
||||||
|
by the [inaccurate] ULFRCO clock. */
|
||||||
|
|
||||||
|
/* The slow clock used to generate the tick interrupt in the low power demo
|
||||||
|
runs at 2KHz. Ensure the tick rate is a multiple of the clock. */
|
||||||
|
#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 )
|
||||||
|
|
||||||
|
#define configENERGY_MODE ( sleepEM4 )
|
||||||
|
|
||||||
|
#elif( configCREATE_LOW_POWER_DEMO == 2 )
|
||||||
|
|
||||||
|
/* Tickless idle mode, generating RTOS tick interrupts from the RTC, fed
|
||||||
|
by the LXFO clock. */
|
||||||
|
|
||||||
|
/* The slow clock used to generate the tick interrupt in the low power demo
|
||||||
|
runs at 32768/8=4096Hz. Ensure the tick rate is a multiple of the clock. */
|
||||||
|
#define configTICK_RATE_HZ ( 128 )
|
||||||
|
|
||||||
|
/* 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 )
|
||||||
|
|
||||||
|
#define configENERGY_MODE ( sleepEM3 )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -71,8 +71,9 @@
|
||||||
* NOTE 1: This project provides two demo applications. A simple blinky style
|
* NOTE 1: This project provides two demo applications. A simple blinky style
|
||||||
* project that demonstrates the tickless low power features of FreeRTOS, and a
|
* project that demonstrates the tickless low power features of FreeRTOS, and a
|
||||||
* more comprehensive test and demo application. The configCREATE_LOW_POWER_DEMO
|
* 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
|
* setting in FreeRTOSConifg.h is used to select between the two, and to select
|
||||||
* on using conifgCREATE_LOW_POWER_DEMO in main.c. This file implements the
|
* the clock used when tickless mode is used. See the notes on using
|
||||||
|
* conifgCREATE_LOW_POWER_DEMO in main.c. This file implements the
|
||||||
* comprehensive test and demo version.
|
* comprehensive test and demo version.
|
||||||
*
|
*
|
||||||
* NOTE 2: This file only contains the source code that is specific to the
|
* NOTE 2: This file only contains the source code that is specific to the
|
||||||
|
|
|
@ -83,7 +83,9 @@
|
||||||
#include "em_int.h"
|
#include "em_int.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
|
||||||
/* This file contains functions that will override the default implementations
|
/* SEE THE COMMENTS ABOVE THE DEFINITION OF configCREATE_LOW_POWER_DEMO IN
|
||||||
|
FreeRTOSConfig.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
|
in the RTOS port layer. Therefore only build this file if the low power demo
|
||||||
is being built. */
|
is being built. */
|
||||||
#if( configCREATE_LOW_POWER_DEMO == 1 )
|
#if( configCREATE_LOW_POWER_DEMO == 1 )
|
||||||
|
@ -98,7 +100,8 @@ is being built. */
|
||||||
*/
|
*/
|
||||||
void vPortSetupTimerInterrupt( void );
|
void vPortSetupTimerInterrupt( void );
|
||||||
|
|
||||||
/* Override the default definition of vPortSuppressTicksAndSleep() that is
|
/*
|
||||||
|
* Override the default definition of vPortSuppressTicksAndSleep() that is
|
||||||
* weakly defined in the FreeRTOS Cortex-M port layer with a version that
|
* 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
|
* 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.
|
* and not the SysTick as would normally be the case on a Cortex-M.
|
||||||
|
@ -110,12 +113,11 @@ void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
/* Calculate how many clock increments make up a single tick period. */
|
/* Calculate how many clock increments make up a single tick period. */
|
||||||
static const uint32_t ulReloadValueForOneTick = ( mainTIMER_FREQUENCY_HZ / configTICK_RATE_HZ );
|
static const uint32_t ulReloadValueForOneTick = ( mainTIMER_FREQUENCY_HZ / configTICK_RATE_HZ );
|
||||||
|
|
||||||
/* Calculate the maximum number of ticks that can be suppressed when using the
|
/* Will hold the maximum number of ticks that can be suppressed. */
|
||||||
high resolution clock and low resolution clock respectively. */
|
|
||||||
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||||
|
|
||||||
/* Flag set from the tick interrupt to allow the sleep processing to know if
|
/* 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. */
|
sleep mode was exited because of a timer interrupt or a different interrupt. */
|
||||||
static volatile uint32_t ulTickFlag = pdFALSE;
|
static volatile uint32_t ulTickFlag = pdFALSE;
|
||||||
|
|
||||||
/* As the clock is only 2KHz, it is likely a value of 1 will be too much, so
|
/* As the clock is only 2KHz, it is likely a value of 1 will be too much, so
|
||||||
|
@ -129,6 +131,8 @@ void vPortSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
BURTC_Init_TypeDef xBURTCInitStruct = BURTC_INIT_DEFAULT;
|
BURTC_Init_TypeDef xBURTCInitStruct = BURTC_INIT_DEFAULT;
|
||||||
|
|
||||||
|
/* Configure the BURTC to generate the RTOS tick interrupt. */
|
||||||
|
|
||||||
xMaximumPossibleSuppressedTicks = ULONG_MAX / ulReloadValueForOneTick;
|
xMaximumPossibleSuppressedTicks = ULONG_MAX / ulReloadValueForOneTick;
|
||||||
|
|
||||||
/* Ensure LE modules are accessible. */
|
/* Ensure LE modules are accessible. */
|
||||||
|
@ -145,7 +149,7 @@ BURTC_Init_TypeDef xBURTCInitStruct = BURTC_INIT_DEFAULT;
|
||||||
BURTC_IntDisable( BURTC_IF_COMP0 );
|
BURTC_IntDisable( BURTC_IF_COMP0 );
|
||||||
BURTC_Init( &xBURTCInitStruct );
|
BURTC_Init( &xBURTCInitStruct );
|
||||||
|
|
||||||
/* The tick interrupt must be set to the lowest possible. */
|
/* The tick interrupt must be set to the lowest priority possible. */
|
||||||
NVIC_SetPriority( BURTC_IRQn, configKERNEL_INTERRUPT_PRIORITY );
|
NVIC_SetPriority( BURTC_IRQn, configKERNEL_INTERRUPT_PRIORITY );
|
||||||
NVIC_ClearPendingIRQ( BURTC_IRQn );
|
NVIC_ClearPendingIRQ( BURTC_IRQn );
|
||||||
NVIC_EnableIRQ( BURTC_IRQn );
|
NVIC_EnableIRQ( BURTC_IRQn );
|
||||||
|
@ -299,11 +303,11 @@ TickType_t xModifiableIdleTime;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void BURTC_IRQHandler(void)
|
void BURTC_IRQHandler( void )
|
||||||
{
|
{
|
||||||
if( ulTickFlag == pdFALSE )
|
if( ulTickFlag == pdFALSE )
|
||||||
{
|
{
|
||||||
/* Set BURTC interrupt to one system tick period*/
|
/* Set BURTC interrupt to one RTOS tick period. */
|
||||||
BURTC_Enable( false );
|
BURTC_Enable( false );
|
||||||
BURTC_CompareSet( 0, ulReloadValueForOneTick );
|
BURTC_CompareSet( 0, ulReloadValueForOneTick );
|
||||||
ulTickFlag = pdTRUE;
|
ulTickFlag = pdTRUE;
|
|
@ -0,0 +1,341 @@
|
||||||
|
/*
|
||||||
|
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!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* SiLabs library includes. */
|
||||||
|
#include "em_cmu.h"
|
||||||
|
#include "em_rtc.h"
|
||||||
|
#include "em_rmu.h"
|
||||||
|
#include "em_int.h"
|
||||||
|
#include "sleep.h"
|
||||||
|
|
||||||
|
/* SEE THE COMMENTS ABOVE THE DEFINITION OF configCREATE_LOW_POWER_DEMO IN
|
||||||
|
FreeRTOSConfig.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 == 2 )
|
||||||
|
|
||||||
|
#define mainTIMER_FREQUENCY_HZ ( 4096UL ) /* 32768 clock divided by 8. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 RTC clock, as the tick is generated from the low power RTC
|
||||||
|
* 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 );
|
||||||
|
|
||||||
|
/* Will hold the maximum number of ticks that can be suppressed. */
|
||||||
|
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 a timer interrupt or a different interrupt. */
|
||||||
|
static volatile uint32_t ulTickFlag = pdFALSE;
|
||||||
|
|
||||||
|
/* As the clock is only 32KHz, it is likely a value of 1 will be enough. */
|
||||||
|
static const uint32_t ulStoppedTimerCompensation = 0UL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
RTC_Init_TypeDef xRTCInitStruct;
|
||||||
|
const uint32_t ulMAX24BitValue = 0xffffffUL;
|
||||||
|
|
||||||
|
xMaximumPossibleSuppressedTicks = ulMAX24BitValue / ulReloadValueForOneTick;
|
||||||
|
|
||||||
|
/* Configure the RTC to generate the RTOS tick interrupt. */
|
||||||
|
|
||||||
|
/* LXFO setup. For rev D use 70% boost */
|
||||||
|
CMU->CTRL = ( CMU->CTRL & ~_CMU_CTRL_LFXOBOOST_MASK ) | CMU_CTRL_LFXOBOOST_70PCENT;
|
||||||
|
#if defined( EMU_AUXCTRL_REDLFXOBOOST )
|
||||||
|
EMU->AUXCTRL = (EMU->AUXCTRL & ~_EMU_AUXCTRL_REDLFXOBOOST_MASK) | EMU_AUXCTRL_REDLFXOBOOST;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Ensure LE modules are accessible. */
|
||||||
|
CMU_ClockEnable( cmuClock_CORELE, true );
|
||||||
|
|
||||||
|
/* Use LFXO. */
|
||||||
|
CMU_ClockSelectSet( cmuClock_LFA, cmuSelect_LFXO );
|
||||||
|
|
||||||
|
/* Use 8x divider to reduce energy. */
|
||||||
|
CMU_ClockDivSet( cmuClock_RTC, cmuClkDiv_8 );
|
||||||
|
|
||||||
|
/* Enable clock to the RTC module. */
|
||||||
|
CMU_ClockEnable( cmuClock_RTC, true );
|
||||||
|
xRTCInitStruct.enable = false;
|
||||||
|
xRTCInitStruct.debugRun = false;
|
||||||
|
xRTCInitStruct.comp0Top = true;
|
||||||
|
RTC_Init( &xRTCInitStruct );
|
||||||
|
|
||||||
|
/* Disable RTC0 interrupt. */
|
||||||
|
RTC_IntDisable( RTC_IFC_COMP0 );
|
||||||
|
|
||||||
|
/* The tick interrupt must be set to the lowest priority possible. */
|
||||||
|
NVIC_SetPriority( RTC_IRQn, configKERNEL_INTERRUPT_PRIORITY );
|
||||||
|
NVIC_ClearPendingIRQ( RTC_IRQn );
|
||||||
|
NVIC_EnableIRQ( RTC_IRQn );
|
||||||
|
RTC_CompareSet( 0, ulReloadValueForOneTick );
|
||||||
|
RTC_IntClear( RTC_IFC_COMP0 );
|
||||||
|
RTC_IntEnable( RTC_IF_COMP0 );
|
||||||
|
RTC_Enable( true );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
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 RTC 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 RTC is going to be stopped
|
||||||
|
momentarily. */
|
||||||
|
ulReloadValue -= ulStoppedTimerCompensation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stop the RTC momentarily. The time the RTC 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 = RTC_CounterGet();
|
||||||
|
RTC_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();
|
||||||
|
__asm volatile( "dsb" );
|
||||||
|
__asm volatile( "isb" );
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
RTC_CompareSet( 0, ulReloadValueForOneTick - ulCurrentCount );
|
||||||
|
RTC_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;
|
||||||
|
RTC_CompareSet( 0, ulReloadValue );
|
||||||
|
|
||||||
|
/* Restart the RTC. */
|
||||||
|
RTC_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 RTC. 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 = RTC_CounterGet();
|
||||||
|
RTC_Enable( false );
|
||||||
|
|
||||||
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
|
above. */
|
||||||
|
INT_Enable();
|
||||||
|
__asm volatile( "dsb" );
|
||||||
|
__asm volatile( "isb" );
|
||||||
|
|
||||||
|
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;
|
||||||
|
RTC_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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTC_CompareSet( 0, ulReloadValue );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restart the RTC 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 RTC interrupt executes. */
|
||||||
|
RTC_Enable( true );
|
||||||
|
|
||||||
|
/* Wind the tick forward by the number of tick periods that the CPU
|
||||||
|
remained in a low power state. */
|
||||||
|
vTaskStepTick( ulCompleteTickPeriods );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void RTC_IRQHandler( void )
|
||||||
|
{
|
||||||
|
if( ulTickFlag == pdFALSE )
|
||||||
|
{
|
||||||
|
/* Set RTC interrupt to one RTOS tick period. */
|
||||||
|
RTC_Enable( false );
|
||||||
|
RTC_CompareSet( 0, ulReloadValueForOneTick );
|
||||||
|
ulTickFlag = pdTRUE;
|
||||||
|
RTC_Enable( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
RTC_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 ) */
|
||||||
|
|
|
@ -71,9 +71,10 @@
|
||||||
* NOTE 1: This project provides two demo applications. A simple blinky demo
|
* NOTE 1: This project provides two demo applications. A simple blinky demo
|
||||||
* that demonstrates tickless low power operation, and a more comprehensive
|
* that demonstrates tickless low power operation, and a more comprehensive
|
||||||
* test and demo application. The configCREATE_LOW_POWER_DEMO setting in
|
* 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
|
* FreeRTOSConfig.h is used to select between the two, and to select the clock
|
||||||
* configCREATE_LOW_POWER_DEMO in main.c. This file implements the low power
|
* used when tickless low power operation is demonstrated. See the notes on
|
||||||
* version.
|
* 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
|
* NOTE 2: This file only contains the source code that is specific to the
|
||||||
* low power demo. Generic functions, such FreeRTOS hook functions, and
|
* low power demo. Generic functions, such FreeRTOS hook functions, and
|
||||||
|
@ -211,7 +212,7 @@ const TickType_t xShortDelay = pdMS_TO_TICKS( 10 );
|
||||||
if( ulReceivedValue == ulExpectedValue )
|
if( ulReceivedValue == ulExpectedValue )
|
||||||
{
|
{
|
||||||
/* Turn the LED on for a brief time only so it doens't distort the
|
/* Turn the LED on for a brief time only so it doens't distort the
|
||||||
enerty reading. */
|
energy reading. */
|
||||||
BSP_LedSet( mainTASK_LED );
|
BSP_LedSet( mainTASK_LED );
|
||||||
vTaskDelay( xShortDelay );
|
vTaskDelay( xShortDelay );
|
||||||
BSP_LedClear( mainTASK_LED );
|
BSP_LedClear( mainTASK_LED );
|
||||||
|
|
|
@ -71,10 +71,12 @@
|
||||||
* This project provides two demo applications. A simple blinky style project
|
* This project provides two demo applications. A simple blinky style project
|
||||||
* that demonstrates low power tickless functionality, and a more comprehensive
|
* that demonstrates low power tickless functionality, and a more comprehensive
|
||||||
* test and demo application. The configCREATE_LOW_POWER_DEMO setting, which is
|
* 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
|
* defined in FreeRTOSConfig.h, is used to select between the two, and to select
|
||||||
* blinky low power demo is implemented and described in main_low_power.c. The
|
* the clock used when demonstrating tickless functionality.
|
||||||
* more comprehensive test and demo application is implemented and described in
|
*
|
||||||
* main_full.c.
|
* 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
|
* This file implements the code that is not demo specific, including the
|
||||||
* hardware setup and standard FreeRTOS hook functions.
|
* hardware setup and standard FreeRTOS hook functions.
|
||||||
|
@ -85,6 +87,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#warning Check the tick suppression routine in the case where the system unblocks before an entire tick period has expired.
|
||||||
|
|
||||||
/* FreeRTOS includes. */
|
/* FreeRTOS includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
@ -132,7 +136,7 @@ int main( void )
|
||||||
|
|
||||||
/* The mainCREATE_LOW_POWER_DEMO setting is described at the top
|
/* The mainCREATE_LOW_POWER_DEMO setting is described at the top
|
||||||
of this file. */
|
of this file. */
|
||||||
#if( configCREATE_LOW_POWER_DEMO == 1 )
|
#if( configCREATE_LOW_POWER_DEMO != 0 )
|
||||||
{
|
{
|
||||||
main_low_power();
|
main_low_power();
|
||||||
}
|
}
|
||||||
|
@ -154,6 +158,8 @@ static void prvSetupHardware( void )
|
||||||
BSP_TraceProfilerSetup();
|
BSP_TraceProfilerSetup();
|
||||||
SLEEP_Init( NULL, NULL );
|
SLEEP_Init( NULL, NULL );
|
||||||
BSP_LedsInit();
|
BSP_LedsInit();
|
||||||
|
|
||||||
|
SLEEP_SleepBlockBegin( configENERGY_MODE );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue