mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-06-06 12:29:03 -04:00
Test the RTC and BURTC tickless implementations on the Gecko parts, and make correct as appropriate.
Replace some references to the older portTICK_RATE_MS macro with the newer pdMS_TO_TICKS() macro in the standard demo files.
This commit is contained in:
parent
556de14a1d
commit
732778a971
|
@ -103,9 +103,6 @@
|
||||||
<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>
|
||||||
|
|
|
@ -99,7 +99,7 @@ extern "C" {
|
||||||
* See the comments at the top of main.c, main_full.c and main_low_power.c for
|
* See the comments at the top of main.c, main_full.c and main_low_power.c for
|
||||||
* more information.
|
* more information.
|
||||||
*/
|
*/
|
||||||
#define configCREATE_LOW_POWER_DEMO 2
|
#define configCREATE_LOW_POWER_DEMO 1
|
||||||
|
|
||||||
/* Some configuration is dependent on the demo being built. */
|
/* Some configuration is dependent on the demo being built. */
|
||||||
#if( configCREATE_LOW_POWER_DEMO == 0 )
|
#if( configCREATE_LOW_POWER_DEMO == 0 )
|
||||||
|
@ -142,7 +142,7 @@ extern "C" {
|
||||||
#define configUSE_MALLOC_FAILED_HOOK ( 0 )
|
#define configUSE_MALLOC_FAILED_HOOK ( 0 )
|
||||||
#define configUSE_IDLE_HOOK ( 0 )
|
#define configUSE_IDLE_HOOK ( 0 )
|
||||||
|
|
||||||
#define configENERGY_MODE ( sleepEM4 )
|
#define configENERGY_MODE ( sleepEM3 )
|
||||||
|
|
||||||
#elif( configCREATE_LOW_POWER_DEMO == 2 )
|
#elif( configCREATE_LOW_POWER_DEMO == 2 )
|
||||||
|
|
||||||
|
@ -198,9 +198,31 @@ extern "C" {
|
||||||
#define configTIMER_QUEUE_LENGTH ( 10 )
|
#define configTIMER_QUEUE_LENGTH ( 10 )
|
||||||
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE )
|
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE )
|
||||||
|
|
||||||
/* Interrupt nesting behaviour configuration. */
|
/* Cortex-M specific definitions. */
|
||||||
#define configKERNEL_INTERRUPT_PRIORITY ( 255 )
|
#ifdef __NVIC_PRIO_BITS
|
||||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 191 ) /* equivalent to 0xa0, or priority 5. */
|
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
|
||||||
|
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||||
|
#else
|
||||||
|
#define configPRIO_BITS 3 /* 7 priority levels */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The lowest interrupt priority that can be used in a call to a "set priority"
|
||||||
|
function. */
|
||||||
|
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x07
|
||||||
|
|
||||||
|
/* The highest interrupt priority that can be used by any interrupt service
|
||||||
|
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
|
||||||
|
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
|
||||||
|
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
|
||||||
|
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 0x05
|
||||||
|
|
||||||
|
/* Interrupt priorities used by the kernel port layer itself. These are generic
|
||||||
|
to all Cortex-M ports, and do not rely on any particular library functions. */
|
||||||
|
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||||
|
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
|
||||||
|
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||||
|
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||||
|
|
||||||
|
|
||||||
/* Optional functions - most linkers will remove unused functions anyway. */
|
/* Optional functions - most linkers will remove unused functions anyway. */
|
||||||
#define INCLUDE_vTaskPrioritySet ( 1 )
|
#define INCLUDE_vTaskPrioritySet ( 1 )
|
||||||
|
|
|
@ -150,7 +150,7 @@ BURTC_Init_TypeDef xBURTCInitStruct = BURTC_INIT_DEFAULT;
|
||||||
BURTC_Init( &xBURTCInitStruct );
|
BURTC_Init( &xBURTCInitStruct );
|
||||||
|
|
||||||
/* The tick interrupt must be set to the lowest priority possible. */
|
/* The tick interrupt must be set to the lowest priority possible. */
|
||||||
NVIC_SetPriority( BURTC_IRQn, configKERNEL_INTERRUPT_PRIORITY );
|
NVIC_SetPriority( BURTC_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY );
|
||||||
NVIC_ClearPendingIRQ( BURTC_IRQn );
|
NVIC_ClearPendingIRQ( BURTC_IRQn );
|
||||||
NVIC_EnableIRQ( BURTC_IRQn );
|
NVIC_EnableIRQ( BURTC_IRQn );
|
||||||
BURTC_CompareSet( 0, ulReloadValueForOneTick );
|
BURTC_CompareSet( 0, ulReloadValueForOneTick );
|
||||||
|
@ -162,7 +162,7 @@ BURTC_Init_TypeDef xBURTCInitStruct = BURTC_INIT_DEFAULT;
|
||||||
|
|
||||||
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCurrentCount;
|
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCountBeforeSleep, ulCountAfterSleep;
|
||||||
eSleepModeStatus eSleepAction;
|
eSleepModeStatus eSleepAction;
|
||||||
TickType_t xModifiableIdleTime;
|
TickType_t xModifiableIdleTime;
|
||||||
|
|
||||||
|
@ -189,12 +189,20 @@ TickType_t xModifiableIdleTime;
|
||||||
result in some tiny drift of the time maintained by the kernel with respect
|
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
|
to calendar time. The count is latched before stopping the timer as
|
||||||
stopping the timer appears to clear the count. */
|
stopping the timer appears to clear the count. */
|
||||||
ulCurrentCount = BURTC_CounterGet();
|
ulCountBeforeSleep = BURTC_CounterGet();
|
||||||
BURTC_Enable( false );
|
BURTC_Enable( false );
|
||||||
|
|
||||||
|
/* If this function is re-entered before one complete tick period then the
|
||||||
|
reload value might be to take into account a partial tick, but just reading
|
||||||
|
the count assumes it is counting up to a full ticks worth - so add in the
|
||||||
|
different if any. */
|
||||||
|
ulCountBeforeSleep += ( ulReloadValueForOneTick - BURTC_CompareGet( 0 ) );
|
||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL() method as
|
/* Enter a critical section but don't use the taskENTER_CRITICAL() method as
|
||||||
that will mask interrupts that should exit sleep mode. */
|
that will mask interrupts that should exit sleep mode. */
|
||||||
INT_Disable();
|
INT_Disable();
|
||||||
|
__asm volatile( "dsb" );
|
||||||
|
__asm volatile( "isb" );
|
||||||
|
|
||||||
/* The tick flag is set to false before sleeping. If it is true when sleep
|
/* 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
|
mode is exited then sleep mode was probably exited because the tick was
|
||||||
|
@ -209,7 +217,7 @@ TickType_t xModifiableIdleTime;
|
||||||
{
|
{
|
||||||
/* Restart tick and count up to whatever was left of the current time
|
/* Restart tick and count up to whatever was left of the current time
|
||||||
slice. */
|
slice. */
|
||||||
BURTC_CompareSet( 0, ulReloadValueForOneTick - ulCurrentCount );
|
BURTC_CompareSet( 0, ( ulReloadValueForOneTick - ulCountBeforeSleep ) + ulStoppedTimerCompensation );
|
||||||
BURTC_Enable( true );
|
BURTC_Enable( true );
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
|
@ -220,7 +228,7 @@ TickType_t xModifiableIdleTime;
|
||||||
{
|
{
|
||||||
/* Adjust the reload value to take into account that the current time
|
/* Adjust the reload value to take into account that the current time
|
||||||
slice is already partially complete. */
|
slice is already partially complete. */
|
||||||
ulReloadValue -= ulCurrentCount;
|
ulReloadValue -= ulCountBeforeSleep;
|
||||||
BURTC_CompareSet( 0, ulReloadValue );
|
BURTC_CompareSet( 0, ulReloadValue );
|
||||||
|
|
||||||
/* Restart the BURTC. */
|
/* Restart the BURTC. */
|
||||||
|
@ -248,12 +256,14 @@ TickType_t xModifiableIdleTime;
|
||||||
result in some tiny drift of the time maintained by the kernel with
|
result in some tiny drift of the time maintained by the kernel with
|
||||||
respect to calendar time. The count value is latched before stopping
|
respect to calendar time. The count value is latched before stopping
|
||||||
the timer as stopping the timer appears to clear the count. */
|
the timer as stopping the timer appears to clear the count. */
|
||||||
ulCurrentCount = BURTC_CounterGet();
|
ulCountAfterSleep = BURTC_CounterGet();
|
||||||
BURTC_Enable( false );
|
BURTC_Enable( false );
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
above. */
|
above. */
|
||||||
INT_Enable();
|
INT_Enable();
|
||||||
|
__asm volatile( "dsb" );
|
||||||
|
__asm volatile( "isb" );
|
||||||
|
|
||||||
if( ulTickFlag != pdFALSE )
|
if( ulTickFlag != pdFALSE )
|
||||||
{
|
{
|
||||||
|
@ -261,7 +271,7 @@ TickType_t xModifiableIdleTime;
|
||||||
function is called with the scheduler suspended the actual tick
|
function is called with the scheduler suspended the actual tick
|
||||||
processing will not occur until after this function has exited.
|
processing will not occur until after this function has exited.
|
||||||
Reset the reload value with whatever remains of this tick period. */
|
Reset the reload value with whatever remains of this tick period. */
|
||||||
ulReloadValue = ulReloadValueForOneTick - ulCurrentCount;
|
ulReloadValue = ulReloadValueForOneTick - ulCountAfterSleep;
|
||||||
BURTC_CompareSet( 0, ulReloadValue );
|
BURTC_CompareSet( 0, ulReloadValue );
|
||||||
|
|
||||||
/* The tick interrupt handler will already have pended the tick
|
/* The tick interrupt handler will already have pended the tick
|
||||||
|
@ -275,12 +285,17 @@ TickType_t xModifiableIdleTime;
|
||||||
{
|
{
|
||||||
/* Something other than the tick interrupt ended the sleep. How
|
/* Something other than the tick interrupt ended the sleep. How
|
||||||
many complete tick periods passed while the processor was
|
many complete tick periods passed while the processor was
|
||||||
sleeping? */
|
sleeping? Add back in the adjustment that was made to the reload
|
||||||
ulCompleteTickPeriods = ulCurrentCount / ulReloadValueForOneTick;
|
value to account for the fact that a time slice was part way through
|
||||||
|
when this function was called. */
|
||||||
|
ulCountAfterSleep += ulCountBeforeSleep;
|
||||||
|
ulCompleteTickPeriods = ulCountAfterSleep / ulReloadValueForOneTick;
|
||||||
|
|
||||||
/* The reload value is set to whatever fraction of a single tick
|
/* The reload value is set to whatever fraction of a single tick
|
||||||
period remains. */
|
period remains. */
|
||||||
ulReloadValue = ulCurrentCount - ( ulCompleteTickPeriods * ulReloadValueForOneTick );
|
ulCountAfterSleep -= ( ulCompleteTickPeriods * ulReloadValueForOneTick );
|
||||||
|
ulReloadValue = ulReloadValueForOneTick - ulCountAfterSleep;
|
||||||
|
|
||||||
if( ulReloadValue == 0 )
|
if( ulReloadValue == 0 )
|
||||||
{
|
{
|
||||||
/* There is no fraction remaining. */
|
/* There is no fraction remaining. */
|
||||||
|
@ -305,12 +320,13 @@ TickType_t xModifiableIdleTime;
|
||||||
|
|
||||||
void BURTC_IRQHandler( void )
|
void BURTC_IRQHandler( void )
|
||||||
{
|
{
|
||||||
if( ulTickFlag == pdFALSE )
|
ulTickFlag = pdTRUE;
|
||||||
|
|
||||||
|
if( RTC_CompareGet( 0 ) != ulReloadValueForOneTick )
|
||||||
{
|
{
|
||||||
/* Set BURTC interrupt to one RTOS tick period. */
|
/* Set RTC interrupt to one RTOS tick period. */
|
||||||
BURTC_Enable( false );
|
BURTC_Enable( false );
|
||||||
BURTC_CompareSet( 0, ulReloadValueForOneTick );
|
BURTC_CompareSet( 0, ulReloadValueForOneTick );
|
||||||
ulTickFlag = pdTRUE;
|
|
||||||
BURTC_Enable( true );
|
BURTC_Enable( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,10 +74,13 @@
|
||||||
/* SiLabs library includes. */
|
/* SiLabs library includes. */
|
||||||
#include "em_cmu.h"
|
#include "em_cmu.h"
|
||||||
#include "em_rtc.h"
|
#include "em_rtc.h"
|
||||||
|
#include "em_burtc.h"
|
||||||
#include "em_rmu.h"
|
#include "em_rmu.h"
|
||||||
#include "em_int.h"
|
#include "em_int.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
|
||||||
|
#define lpINCLUDE_TEST_TIMER 1
|
||||||
|
|
||||||
/* SEE THE COMMENTS ABOVE THE DEFINITION OF configCREATE_LOW_POWER_DEMO IN
|
/* SEE THE COMMENTS ABOVE THE DEFINITION OF configCREATE_LOW_POWER_DEMO IN
|
||||||
FreeRTOSConfig.h
|
FreeRTOSConfig.h
|
||||||
This file contains functions that will override the default implementations
|
This file contains functions that will override the default implementations
|
||||||
|
@ -103,6 +106,14 @@ void vPortSetupTimerInterrupt( void );
|
||||||
*/
|
*/
|
||||||
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
|
|
||||||
|
/* If lpINCLUDE_TEST_TIMER is defined then the BURTC is used to generate
|
||||||
|
interrupts that will wake the processor prior to the expected idle time
|
||||||
|
completing. The timer interval can be altered to test different
|
||||||
|
scenarios. */
|
||||||
|
#if( lpINCLUDE_TEST_TIMER == 1 )
|
||||||
|
static void prvSetupTestTimer( void );
|
||||||
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Calculate how many clock increments make up a single tick period. */
|
/* Calculate how many clock increments make up a single tick period. */
|
||||||
|
@ -155,19 +166,27 @@ const uint32_t ulMAX24BitValue = 0xffffffUL;
|
||||||
RTC_IntDisable( RTC_IFC_COMP0 );
|
RTC_IntDisable( RTC_IFC_COMP0 );
|
||||||
|
|
||||||
/* The tick interrupt must be set to the lowest priority possible. */
|
/* The tick interrupt must be set to the lowest priority possible. */
|
||||||
NVIC_SetPriority( RTC_IRQn, configKERNEL_INTERRUPT_PRIORITY );
|
NVIC_SetPriority( RTC_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY );
|
||||||
NVIC_ClearPendingIRQ( RTC_IRQn );
|
NVIC_ClearPendingIRQ( RTC_IRQn );
|
||||||
NVIC_EnableIRQ( RTC_IRQn );
|
NVIC_EnableIRQ( RTC_IRQn );
|
||||||
RTC_CompareSet( 0, ulReloadValueForOneTick );
|
RTC_CompareSet( 0, ulReloadValueForOneTick );
|
||||||
RTC_IntClear( RTC_IFC_COMP0 );
|
RTC_IntClear( RTC_IFC_COMP0 );
|
||||||
RTC_IntEnable( RTC_IF_COMP0 );
|
RTC_IntEnable( RTC_IF_COMP0 );
|
||||||
RTC_Enable( true );
|
RTC_Enable( true );
|
||||||
|
|
||||||
|
/* If lpINCLUDE_TEST_TIMER is defined then the BURTC is used to generate
|
||||||
|
interrupts that will wake the processor prior to the expected idle time
|
||||||
|
completing. The timer interval can be altered to test different
|
||||||
|
scenarios. */
|
||||||
|
#if( lpINCLUDE_TEST_TIMER == 1 )
|
||||||
|
prvSetupTestTimer();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||||
{
|
{
|
||||||
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCurrentCount;
|
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCountBeforeSleep, ulCountAfterSleep;
|
||||||
eSleepModeStatus eSleepAction;
|
eSleepModeStatus eSleepAction;
|
||||||
TickType_t xModifiableIdleTime;
|
TickType_t xModifiableIdleTime;
|
||||||
|
|
||||||
|
@ -194,9 +213,15 @@ TickType_t xModifiableIdleTime;
|
||||||
in some tiny drift of the time maintained by the kernel with respect to
|
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
|
calendar time. The count is latched before stopping the timer as stopping
|
||||||
the timer appears to clear the count. */
|
the timer appears to clear the count. */
|
||||||
ulCurrentCount = RTC_CounterGet();
|
ulCountBeforeSleep = RTC_CounterGet();
|
||||||
RTC_Enable( false );
|
RTC_Enable( false );
|
||||||
|
|
||||||
|
/* If this function is re-entered before one complete tick period then the
|
||||||
|
reload value might be to take into account a partial tick, but just reading
|
||||||
|
the count assumes it is counting up to a full ticks worth - so add in the
|
||||||
|
different if any. */
|
||||||
|
ulCountBeforeSleep += ( ulReloadValueForOneTick - RTC_CompareGet( 0 ) );
|
||||||
|
|
||||||
/* Enter a critical section but don't use the taskENTER_CRITICAL() method as
|
/* Enter a critical section but don't use the taskENTER_CRITICAL() method as
|
||||||
that will mask interrupts that should exit sleep mode. */
|
that will mask interrupts that should exit sleep mode. */
|
||||||
INT_Disable();
|
INT_Disable();
|
||||||
|
@ -216,7 +241,7 @@ TickType_t xModifiableIdleTime;
|
||||||
{
|
{
|
||||||
/* Restart tick and count up to whatever was left of the current time
|
/* Restart tick and count up to whatever was left of the current time
|
||||||
slice. */
|
slice. */
|
||||||
RTC_CompareSet( 0, ulReloadValueForOneTick - ulCurrentCount );
|
RTC_CompareSet( 0, ( ulReloadValueForOneTick - ulCountBeforeSleep ) + ulStoppedTimerCompensation );
|
||||||
RTC_Enable( true );
|
RTC_Enable( true );
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
|
@ -227,7 +252,7 @@ TickType_t xModifiableIdleTime;
|
||||||
{
|
{
|
||||||
/* Adjust the reload value to take into account that the current time
|
/* Adjust the reload value to take into account that the current time
|
||||||
slice is already partially complete. */
|
slice is already partially complete. */
|
||||||
ulReloadValue -= ulCurrentCount;
|
ulReloadValue -= ulCountBeforeSleep;
|
||||||
RTC_CompareSet( 0, ulReloadValue );
|
RTC_CompareSet( 0, ulReloadValue );
|
||||||
|
|
||||||
/* Restart the RTC. */
|
/* Restart the RTC. */
|
||||||
|
@ -255,7 +280,7 @@ TickType_t xModifiableIdleTime;
|
||||||
result in some tiny drift of the time maintained by the kernel with
|
result in some tiny drift of the time maintained by the kernel with
|
||||||
respect to calendar time. The count value is latched before stopping
|
respect to calendar time. The count value is latched before stopping
|
||||||
the timer as stopping the timer appears to clear the count. */
|
the timer as stopping the timer appears to clear the count. */
|
||||||
ulCurrentCount = RTC_CounterGet();
|
ulCountAfterSleep = RTC_CounterGet();
|
||||||
RTC_Enable( false );
|
RTC_Enable( false );
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
|
@ -270,7 +295,7 @@ TickType_t xModifiableIdleTime;
|
||||||
function is called with the scheduler suspended the actual tick
|
function is called with the scheduler suspended the actual tick
|
||||||
processing will not occur until after this function has exited.
|
processing will not occur until after this function has exited.
|
||||||
Reset the reload value with whatever remains of this tick period. */
|
Reset the reload value with whatever remains of this tick period. */
|
||||||
ulReloadValue = ulReloadValueForOneTick - ulCurrentCount;
|
ulReloadValue = ulReloadValueForOneTick - ulCountAfterSleep;
|
||||||
RTC_CompareSet( 0, ulReloadValue );
|
RTC_CompareSet( 0, ulReloadValue );
|
||||||
|
|
||||||
/* The tick interrupt handler will already have pended the tick
|
/* The tick interrupt handler will already have pended the tick
|
||||||
|
@ -284,12 +309,17 @@ TickType_t xModifiableIdleTime;
|
||||||
{
|
{
|
||||||
/* Something other than the tick interrupt ended the sleep. How
|
/* Something other than the tick interrupt ended the sleep. How
|
||||||
many complete tick periods passed while the processor was
|
many complete tick periods passed while the processor was
|
||||||
sleeping? */
|
sleeping? Add back in the adjustment that was made to the reload
|
||||||
ulCompleteTickPeriods = ulCurrentCount / ulReloadValueForOneTick;
|
value to account for the fact that a time slice was part way through
|
||||||
|
when this function was called. */
|
||||||
|
ulCountAfterSleep += ulCountBeforeSleep;
|
||||||
|
ulCompleteTickPeriods = ulCountAfterSleep / ulReloadValueForOneTick;
|
||||||
|
|
||||||
/* The reload value is set to whatever fraction of a single tick
|
/* The reload value is set to whatever fraction of a single tick
|
||||||
period remains. */
|
period remains. */
|
||||||
ulReloadValue = ulCurrentCount - ( ulCompleteTickPeriods * ulReloadValueForOneTick );
|
ulCountAfterSleep -= ( ulCompleteTickPeriods * ulReloadValueForOneTick );
|
||||||
|
ulReloadValue = ulReloadValueForOneTick - ulCountAfterSleep;
|
||||||
|
|
||||||
if( ulReloadValue == 0 )
|
if( ulReloadValue == 0 )
|
||||||
{
|
{
|
||||||
/* There is no fraction remaining. */
|
/* There is no fraction remaining. */
|
||||||
|
@ -314,12 +344,13 @@ TickType_t xModifiableIdleTime;
|
||||||
|
|
||||||
void RTC_IRQHandler( void )
|
void RTC_IRQHandler( void )
|
||||||
{
|
{
|
||||||
if( ulTickFlag == pdFALSE )
|
ulTickFlag = pdTRUE;
|
||||||
|
|
||||||
|
if( RTC_CompareGet( 0 ) != ulReloadValueForOneTick )
|
||||||
{
|
{
|
||||||
/* Set RTC interrupt to one RTOS tick period. */
|
/* Set RTC interrupt to one RTOS tick period. */
|
||||||
RTC_Enable( false );
|
RTC_Enable( false );
|
||||||
RTC_CompareSet( 0, ulReloadValueForOneTick );
|
RTC_CompareSet( 0, ulReloadValueForOneTick );
|
||||||
ulTickFlag = pdTRUE;
|
|
||||||
RTC_Enable( true );
|
RTC_Enable( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,6 +367,64 @@ void RTC_IRQHandler( void )
|
||||||
}
|
}
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#endif /* ( configCREATE_LOW_POWER_DEMO == 1 ) */
|
#if( lpINCLUDE_TEST_TIMER == 1 )
|
||||||
|
|
||||||
|
/* If lpINCLUDE_TEST_TIMER is defined then the BURTC is used to generate
|
||||||
|
interrupts that will wake the processor prior to the expected idle time
|
||||||
|
completing. The timer interval can be altered to test different
|
||||||
|
scenarios. */
|
||||||
|
static void prvSetupTestTimer( void )
|
||||||
|
{
|
||||||
|
BURTC_Init_TypeDef xBURTCInitStruct = BURTC_INIT_DEFAULT;
|
||||||
|
const uint32_t ulBURTClockHz = 2000UL, ulInterruptFrequency = 1000UL;
|
||||||
|
const uint32_t ulReload = ( ulBURTClockHz / ulInterruptFrequency );
|
||||||
|
|
||||||
|
/* Ensure LE modules are accessible. */
|
||||||
|
CMU_ClockEnable( cmuClock_CORELE, true );
|
||||||
|
|
||||||
|
/* Enable access to BURTC registers. */
|
||||||
|
RMU_ResetControl( rmuResetBU, false );
|
||||||
|
|
||||||
|
/* Generate periodic interrupts 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 );
|
||||||
|
|
||||||
|
NVIC_SetPriority( BURTC_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY );
|
||||||
|
NVIC_ClearPendingIRQ( BURTC_IRQn );
|
||||||
|
NVIC_EnableIRQ( BURTC_IRQn );
|
||||||
|
BURTC_CompareSet( 0, ulReload );
|
||||||
|
BURTC_IntClear( BURTC_IF_COMP0 );
|
||||||
|
BURTC_IntEnable( BURTC_IF_COMP0 );
|
||||||
|
BURTC_CounterReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( lpINCLUDE_TEST_TIMER == 1 )
|
||||||
|
|
||||||
|
/* If lpINCLUDE_TEST_TIMER is defined then the BURTC is used to generate
|
||||||
|
interrupts that will wake the processor prior to the expected idle time
|
||||||
|
completing. The timer interval can be altered to test different
|
||||||
|
scenarios. */
|
||||||
|
volatile uint32_t ulTestTimerCounts = 0;
|
||||||
|
|
||||||
|
void BURTC_IRQHandler( void )
|
||||||
|
{
|
||||||
|
/* Nothing to do here - just testing the code in the scenario where a
|
||||||
|
tickless idle period is ended prior to the expected maximum idle time
|
||||||
|
expiring. */
|
||||||
|
BURTC_IntClear( _RTC_IFC_MASK );
|
||||||
|
ulTestTimerCounts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif /* ( configCREATE_LOW_POWER_DEMO == 2 ) */
|
||||||
|
|
|
@ -84,10 +84,22 @@
|
||||||
* main_low_power() creates one queue, and two tasks. It then starts the
|
* main_low_power() creates one queue, and two tasks. It then starts the
|
||||||
* scheduler.
|
* scheduler.
|
||||||
*
|
*
|
||||||
* TBD
|
* The Queue Send Task:
|
||||||
|
* The queue send task is implemented by the prvQueueSendTask() function in
|
||||||
|
* this file. It sends the value 100 to the queue every second.
|
||||||
|
*
|
||||||
|
* The Queue Receive Task:
|
||||||
|
* The queue receive task is implemented by the prvQueueReceiveTask() function
|
||||||
|
* in this file. prvQueueReceiveTask() blocks on the queue, blipping (quickly
|
||||||
|
* turn on then off again) the LED each time it received the value 100 from the
|
||||||
|
* queue send task. The queue send task writes to the queue every second, so
|
||||||
|
* the LED will blip once a second.
|
||||||
|
*
|
||||||
|
* The RTOS tick is turned off when the queue send task and queue receive task
|
||||||
|
* are both in the Blocked state.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#warning Description of demo in comments above is not correct.
|
|
||||||
|
|
||||||
/* Kernel includes. */
|
/* Kernel includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
|
|
@ -87,8 +87,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#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"
|
||||||
|
@ -114,7 +112,7 @@ static void prvSetupHardware( void );
|
||||||
* main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1.
|
* 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.
|
* main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0.
|
||||||
*/
|
*/
|
||||||
#if( configCREATE_LOW_POWER_DEMO == 1 )
|
#if( configCREATE_LOW_POWER_DEMO != 0 )
|
||||||
extern void main_low_power( void );
|
extern void main_low_power( void );
|
||||||
#else
|
#else
|
||||||
extern void main_full( void );
|
extern void main_full( void );
|
||||||
|
|
|
@ -136,7 +136,7 @@ xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2;
|
||||||
xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4;
|
xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4;
|
||||||
xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6;
|
xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6;
|
||||||
const UBaseType_t uxQueueSize1 = 1, uxQueueSize5 = 5;
|
const UBaseType_t uxQueueSize1 = 1, uxQueueSize5 = 5;
|
||||||
const TickType_t xBlockTime = ( TickType_t ) 1000 / portTICK_PERIOD_MS;
|
const TickType_t xBlockTime = pdMS_TO_TICKS( ( TickType_t ) 1000 );
|
||||||
const TickType_t xDontBlock = ( TickType_t ) 0;
|
const TickType_t xDontBlock = ( TickType_t ) 0;
|
||||||
|
|
||||||
/* Create the first two tasks as described at the top of the file. */
|
/* Create the first two tasks as described at the top of the file. */
|
||||||
|
|
|
@ -122,7 +122,7 @@ that synchronise with the xEventGroupSync() function. */
|
||||||
#define ebDONT_BLOCK ( 0 )
|
#define ebDONT_BLOCK ( 0 )
|
||||||
|
|
||||||
/* A 5ms delay. */
|
/* A 5ms delay. */
|
||||||
#define ebSHORT_DELAY ( 5 / portTICK_PERIOD_MS )
|
#define ebSHORT_DELAY pdMS_TO_TICKS( ( TickType_t ) 5 )
|
||||||
|
|
||||||
/* Used in the selective bits test which checks no, one or both tasks blocked on
|
/* Used in the selective bits test which checks no, one or both tasks blocked on
|
||||||
event bits in a group are unblocked as appropriate as different bits get set. */
|
event bits in a group are unblocked as appropriate as different bits get set. */
|
||||||
|
|
|
@ -109,7 +109,7 @@ Changes from V2.0.0
|
||||||
|
|
||||||
#define pollqSTACK_SIZE configMINIMAL_STACK_SIZE
|
#define pollqSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
#define pollqQUEUE_SIZE ( 10 )
|
#define pollqQUEUE_SIZE ( 10 )
|
||||||
#define pollqPRODUCER_DELAY ( ( TickType_t ) 200 / portTICK_PERIOD_MS )
|
#define pollqPRODUCER_DELAY ( pdMS_TO_TICKS( ( TickType_t ) 200 ) )
|
||||||
#define pollqCONSUMER_DELAY ( pollqPRODUCER_DELAY - ( TickType_t ) ( 20 / portTICK_PERIOD_MS ) )
|
#define pollqCONSUMER_DELAY ( pollqPRODUCER_DELAY - ( TickType_t ) ( 20 / portTICK_PERIOD_MS ) )
|
||||||
#define pollqNO_DELAY ( ( TickType_t ) 0 )
|
#define pollqNO_DELAY ( ( TickType_t ) 0 )
|
||||||
#define pollqVALUES_TO_PRODUCE ( ( BaseType_t ) 3 )
|
#define pollqVALUES_TO_PRODUCE ( ( BaseType_t ) 3 )
|
||||||
|
|
|
@ -122,7 +122,7 @@ queuesetPRIORITY_CHANGE_LOOPS number of values are sent to a queue. */
|
||||||
/* A delay inserted when the Tx task changes its priority to be above the idle
|
/* A delay inserted when the Tx task changes its priority to be above the idle
|
||||||
task priority to ensure the idle priority tasks get some CPU time before the
|
task priority to ensure the idle priority tasks get some CPU time before the
|
||||||
next iteration of the queue set Tx task. */
|
next iteration of the queue set Tx task. */
|
||||||
#define queuesetTX_LOOP_DELAY ( 200 / portTICK_PERIOD_MS )
|
#define queuesetTX_LOOP_DELAY pdMS_TO_TICKS( ( TickType_t ) 200 )
|
||||||
|
|
||||||
/* The allowable maximum deviation between a received value and the expected
|
/* The allowable maximum deviation between a received value and the expected
|
||||||
received value. A deviation will occur when data is received from a queue
|
received value. A deviation will occur when data is received from a queue
|
||||||
|
|
|
@ -164,7 +164,7 @@ static portTASK_FUNCTION( vSuicidalTask, pvParameters )
|
||||||
{
|
{
|
||||||
volatile long l1, l2;
|
volatile long l1, l2;
|
||||||
TaskHandle_t xTaskToKill;
|
TaskHandle_t xTaskToKill;
|
||||||
const TickType_t xDelay = ( TickType_t ) 200 / portTICK_PERIOD_MS;
|
const TickType_t xDelay = pdMS_TO_TICKS( ( TickType_t ) 200 );
|
||||||
|
|
||||||
if( pvParameters != NULL )
|
if( pvParameters != NULL )
|
||||||
{
|
{
|
||||||
|
@ -203,7 +203,7 @@ const TickType_t xDelay = ( TickType_t ) 200 / portTICK_PERIOD_MS;
|
||||||
|
|
||||||
static portTASK_FUNCTION( vCreateTasks, pvParameters )
|
static portTASK_FUNCTION( vCreateTasks, pvParameters )
|
||||||
{
|
{
|
||||||
const TickType_t xDelay = ( TickType_t ) 1000 / portTICK_PERIOD_MS;
|
const TickType_t xDelay = pdMS_TO_TICKS( ( TickType_t ) 1000 );
|
||||||
UBaseType_t uxPriority;
|
UBaseType_t uxPriority;
|
||||||
|
|
||||||
uxPriority = *( UBaseType_t * ) pvParameters;
|
uxPriority = *( UBaseType_t * ) pvParameters;
|
||||||
|
|
Loading…
Reference in a new issue