Tidy up STM32L low power demo and add 'comprehensive demo' option.
This commit is contained in:
parent
5638fe28a2
commit
751103d848
@ -49,7 +49,7 @@
|
|||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>RunToEnable</name>
|
<name>RunToEnable</name>
|
||||||
<state>0</state>
|
<state>1</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>RunToName</name>
|
<name>RunToName</name>
|
||||||
|
@ -39,20 +39,20 @@
|
|||||||
<option>
|
<option>
|
||||||
<name>Input variant</name>
|
<name>Input variant</name>
|
||||||
<version>3</version>
|
<version>3</version>
|
||||||
<state>1</state>
|
<state>7</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>Input description</name>
|
<name>Input description</name>
|
||||||
<state>Full formatting.</state>
|
<state>No specifier n, no float nor long long, no scan set, no assignment suppressing, without multibyte support.</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>Output variant</name>
|
<name>Output variant</name>
|
||||||
<version>2</version>
|
<version>2</version>
|
||||||
<state>1</state>
|
<state>7</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>Output description</name>
|
<name>Output description</name>
|
||||||
<state>Full formatting.</state>
|
<state>No specifier a, A, no specifier n, no float nor long long, no flags.</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>GOutputBinary</name>
|
<name>GOutputBinary</name>
|
||||||
@ -70,16 +70,16 @@
|
|||||||
<option>
|
<option>
|
||||||
<name>GRuntimeLibSelect</name>
|
<name>GRuntimeLibSelect</name>
|
||||||
<version>0</version>
|
<version>0</version>
|
||||||
<state>2</state>
|
<state>1</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>GRuntimeLibSelectSlave</name>
|
<name>GRuntimeLibSelectSlave</name>
|
||||||
<version>0</version>
|
<version>0</version>
|
||||||
<state>2</state>
|
<state>1</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>RTDescription</name>
|
<name>RTDescription</name>
|
||||||
<state>Use the full configuration of the C/C++ runtime library. Full locale interface, C locale, file descriptor support, multibytes in printf and scanf, and hex floats in strtod.</state>
|
<state>Use the normal configuration of the C/C++ runtime library. No locale interface, C locale, no file descriptor support, no multibytes in printf and scanf, and no hex floats in strtod.</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>OGProductVersion</name>
|
<name>OGProductVersion</name>
|
||||||
@ -103,7 +103,7 @@
|
|||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>GenLowLevelInterface</name>
|
<name>GenLowLevelInterface</name>
|
||||||
<state>1</state>
|
<state>0</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>GEndianModeBE</name>
|
<name>GEndianModeBE</name>
|
||||||
@ -133,7 +133,7 @@
|
|||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>RTConfigPath2</name>
|
<name>RTConfigPath2</name>
|
||||||
<state>$TOOLKIT_DIR$\INC\c\DLib_Config_Full.h</state>
|
<state>$TOOLKIT_DIR$\INC\c\DLib_Config_Normal.h</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>GFPUCoreSlave</name>
|
<name>GFPUCoreSlave</name>
|
||||||
@ -309,6 +309,7 @@
|
|||||||
<state>$PROJ_DIR$\ST_Code\libraries\CMSIS\Device\ST\STM32L1xx\Include</state>
|
<state>$PROJ_DIR$\ST_Code\libraries\CMSIS\Device\ST\STM32L1xx\Include</state>
|
||||||
<state>$PROJ_DIR$\..\..\Source\include</state>
|
<state>$PROJ_DIR$\..\..\Source\include</state>
|
||||||
<state>$PROJ_DIR$\..\..\Source\portable\IAR\ARM_CM3</state>
|
<state>$PROJ_DIR$\..\..\Source\portable\IAR\ARM_CM3</state>
|
||||||
|
<state>$PROJ_DIR$\..\Common\include</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>CCStdIncCheck</name>
|
<name>CCStdIncCheck</name>
|
||||||
@ -645,7 +646,7 @@
|
|||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>IlinkOutputFile</name>
|
<name>IlinkOutputFile</name>
|
||||||
<state>STM32L-Discovery.out</state>
|
<state>RTOSDemo.out</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>IlinkDebugInfoEnable</name>
|
<name>IlinkDebugInfoEnable</name>
|
||||||
@ -1064,6 +1065,33 @@
|
|||||||
</file>
|
</file>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
|
<group>
|
||||||
|
<name>Standard Demo Tasks</name>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\..\Common\Minimal\BlockQ.c</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\..\Common\Minimal\blocktim.c</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\..\Common\Minimal\countsem.c</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\..\Common\Minimal\dynamic.c</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\..\Common\Minimal\GenQTest.c</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\..\Common\Minimal\PollQ.c</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\..\Common\Minimal\recmutex.c</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\..\Common\Minimal\semtest.c</name>
|
||||||
|
</file>
|
||||||
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<name>System</name>
|
<name>System</name>
|
||||||
<file>
|
<file>
|
||||||
@ -1088,6 +1116,12 @@
|
|||||||
<file>
|
<file>
|
||||||
<name>$PROJ_DIR$\main.c</name>
|
<name>$PROJ_DIR$\main.c</name>
|
||||||
</file>
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\main_full.c</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\main_low_power.c</name>
|
||||||
|
</file>
|
||||||
<file>
|
<file>
|
||||||
<name>$PROJ_DIR$\stm32l1xx_it.c</name>
|
<name>$PROJ_DIR$\stm32l1xx_it.c</name>
|
||||||
</file>
|
</file>
|
||||||
|
@ -75,8 +75,8 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* When configCREATE_LOW_POWER_DEMO is set to 1 then the tick interrupt
|
* When configCREATE_LOW_POWER_DEMO is set to 1 then the tick interrupt
|
||||||
* is generated by the wakeup interrupt of the real time clock (RTC). The RTC
|
* is generated by the TIM2 peripheral. The TIM2 configuration and handling
|
||||||
* configuration and handling functions are defined in this file.
|
* functions are defined in this file.
|
||||||
*
|
*
|
||||||
* When configCREATE_LOW_POWER_DEMO is set to 0 the tick interrupt is
|
* When configCREATE_LOW_POWER_DEMO is set to 0 the tick interrupt is
|
||||||
* generated by the standard FreeRTOS Cortex-M port layer, which uses the
|
* generated by the standard FreeRTOS Cortex-M port layer, which uses the
|
||||||
@ -84,23 +84,17 @@
|
|||||||
*/
|
*/
|
||||||
#if configCREATE_LOW_POWER_DEMO == 1
|
#if configCREATE_LOW_POWER_DEMO == 1
|
||||||
|
|
||||||
/* The frequency at which TIM2 should run. */
|
/* The frequency at which TIM2 will run. */
|
||||||
#define lpCLOCK_INPUT_FREQUENCY ( 1000UL )
|
#define lpCLOCK_INPUT_FREQUENCY ( 1000UL )
|
||||||
|
|
||||||
/* Constants required to pend a PendSV interrupt from the tick ISR if the
|
/* STM32 register used to ensure the TIM2 clock stops when the MCU is in debug
|
||||||
preemptive scheduler is being used. These are just standard bits and registers
|
mode. */
|
||||||
within the Cortex-M core itself. */
|
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
|
||||||
|
|
||||||
#define DBGMCU_APB1_FZ ( * ( ( volatile unsigned long * ) 0xE0042008 ) )
|
#define DBGMCU_APB1_FZ ( * ( ( volatile unsigned long * ) 0xE0042008 ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The tick interrupt is generated by the TIM2 timer. The default interrupt
|
* The tick interrupt is generated by the TIM2 timer.
|
||||||
* handler cannot be used (even with the TIM2 being handled from the tick hook
|
|
||||||
* function) because the default tick interrupt accesses the SysTick registers
|
|
||||||
* when configUSE_TICKLESS_IDLE set to 1. TIM2_IRQHandler() is the default name
|
|
||||||
* for the TIM2 interrupt handler.
|
|
||||||
*/
|
*/
|
||||||
void TIM2_IRQHandler( void );
|
void TIM2_IRQHandler( void );
|
||||||
|
|
||||||
@ -115,15 +109,9 @@ initialisation. */
|
|||||||
static portTickType xMaximumPossibleSuppressedTicks = 0;
|
static portTickType 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 RTC interrupt or a different interrupt. */
|
sleep mode was exited because of an tick interrupt or a different interrupt. */
|
||||||
static volatile uint32_t ulTickFlag = pdFALSE;
|
static volatile uint32_t ulTickFlag = pdFALSE;
|
||||||
|
|
||||||
/* The RTC counter is stopped temporarily each time it is re-programmed. The
|
|
||||||
following variable offsets the RTC counter alarm value by the number of RTC
|
|
||||||
counts that would typically be missed while the counter was stopped to
|
|
||||||
compensate for the lost time. _RB_ Value needs calculating correctly. */
|
|
||||||
static uint32_t ulStoppedTimerCompensation = 1;//_RB_ / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The tick interrupt handler. This is always the same other than the part that
|
/* The tick interrupt handler. This is always the same other than the part that
|
||||||
@ -131,10 +119,13 @@ clears the interrupt, which is specific to the clock being used to generate the
|
|||||||
tick. */
|
tick. */
|
||||||
void TIM2_IRQHandler( void )
|
void TIM2_IRQHandler( void )
|
||||||
{
|
{
|
||||||
|
/* Clear the interrupt. */
|
||||||
TIM_ClearITPendingBit( TIM2, TIM_IT_Update );
|
TIM_ClearITPendingBit( TIM2, TIM_IT_Update );
|
||||||
TIM_SetAutoreload( TIM2, ( uint16_t ) ulReloadValueForOneTick );
|
|
||||||
|
|
||||||
/* Protect incrementing the tick with an interrupt safe critical section. */
|
/* The next block of code is from the standard FreeRTOS tick interrupt
|
||||||
|
handler. The standard handler is not called directly in case future
|
||||||
|
versions contain changes that make it no longer suitable for calling
|
||||||
|
here. */
|
||||||
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
@ -148,39 +139,42 @@ void TIM2_IRQHandler( void )
|
|||||||
}
|
}
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
|
||||||
|
|
||||||
|
/* In case this is the first tick since the MCU left a low power mode the
|
||||||
|
reload value is reset to its default. */
|
||||||
|
TIM2->ARR = ( uint16_t ) ulReloadValueForOneTick;
|
||||||
|
|
||||||
/* The CPU woke because of a tick. */
|
/* The CPU woke because of a tick. */
|
||||||
ulTickFlag = pdTRUE;
|
ulTickFlag = pdTRUE;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Override the default definition of vPortSetupTimerInterrupt() that is weakly
|
/* Override the default definition of vPortSetupTimerInterrupt() that is weakly
|
||||||
defined in the FreeRTOS Cortex-M3 port layer with a version that configures the
|
defined in the FreeRTOS Cortex-M3 port layer with a version that configures TIM2
|
||||||
wakeup timer of the RTC to generate the tick interrupt. */
|
to generate the tick interrupt. */
|
||||||
void vPortSetupTimerInterrupt( void )
|
void vPortSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
NVIC_InitTypeDef NVIC_InitStructure;
|
NVIC_InitTypeDef NVIC_InitStructure;
|
||||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||||
|
|
||||||
/* Enable the TIM2 clock, which is used to generate long tickless periods
|
/* Enable the TIM2 clock. */
|
||||||
when the tickless period is finite. */
|
|
||||||
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2, ENABLE );
|
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2, ENABLE );
|
||||||
|
|
||||||
/* Ensure clock stops in debug mode. */
|
/* Ensure clock stops in debug mode. */
|
||||||
DBGMCU_APB1_FZ |= DBGMCU_APB1_FZ_DBG_TIM2_STOP;
|
DBGMCU_APB1_FZ |= DBGMCU_APB1_FZ_DBG_TIM2_STOP;
|
||||||
|
|
||||||
/* Scale the clock so very long tickless periods can be acheived. The
|
/* Scale the clock so longer tickless periods can be achieved. The SysTick
|
||||||
SysTick is not used as even when its frequency is divided by 8 the maximum
|
is not used as even when its frequency is divided by 8 the maximum tickless
|
||||||
tickless period with a system clock of 16MHz is only 8.3 seconds. Using
|
period with a system clock of 16MHz is only 8.3 seconds. Using a prescaled
|
||||||
a prescaled clock on the 16-bit TIM2 allows a tickless period of nearly
|
clock on the 16-bit TIM2 allows a tickless period of nearly 66 seconds,
|
||||||
66 seconds, albeit at low resolution. */
|
albeit at low resolution. */
|
||||||
TIM_TimeBaseStructure.TIM_Prescaler = ( uint16_t ) ( SystemCoreClock / lpCLOCK_INPUT_FREQUENCY );
|
TIM_TimeBaseStructure.TIM_Prescaler = ( uint16_t ) ( SystemCoreClock / lpCLOCK_INPUT_FREQUENCY );
|
||||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||||
TIM_TimeBaseStructure.TIM_Period = ( uint16_t ) ( lpCLOCK_INPUT_FREQUENCY / configTICK_RATE_HZ );
|
TIM_TimeBaseStructure.TIM_Period = ( uint16_t ) ( lpCLOCK_INPUT_FREQUENCY / configTICK_RATE_HZ );
|
||||||
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
||||||
TIM_TimeBaseInit( TIM2, &TIM_TimeBaseStructure );
|
TIM_TimeBaseInit( TIM2, &TIM_TimeBaseStructure );
|
||||||
|
|
||||||
/* Enable the TIM2 interrupt - used for the tick interrupt when the tickless
|
/* Enable the TIM2 interrupt. This must execute at the lowest interrupt
|
||||||
period is finite. */
|
priority. */
|
||||||
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
|
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
|
||||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY; /* Must be set to lowest priority. */
|
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY; /* Must be set to lowest priority. */
|
||||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||||
@ -216,17 +210,11 @@ const portTickType xRegulatorOffIdleTime = 30;
|
|||||||
/* Calculate the reload value required to wait xExpectedIdleTime tick
|
/* Calculate the reload value required to wait xExpectedIdleTime tick
|
||||||
periods. */
|
periods. */
|
||||||
ulCounterValue = ulReloadValueForOneTick * xExpectedIdleTime;
|
ulCounterValue = ulReloadValueForOneTick * xExpectedIdleTime;
|
||||||
if( ulCounterValue > ulStoppedTimerCompensation )
|
|
||||||
{
|
|
||||||
/* Compensate for the fact that TIM2 is going to be stopped
|
|
||||||
momentarily. */
|
|
||||||
ulCounterValue -= ulStoppedTimerCompensation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stop TIM2 momentarily. The time TIM2 is stopped for is accounted for as
|
/* Stop TIM2 momentarily. The time TIM2 is stopped for is not accounted for
|
||||||
best it can be, but using the tickless mode will inevitably result in some
|
in this implementation (as it is in the generic implementation) because the
|
||||||
tiny drift of the time maintained by the kernel with respect to calendar
|
clock is so slow it is unlikely to be stopped for a complete count period
|
||||||
time. */
|
anyway. */
|
||||||
TIM_Cmd( TIM2, DISABLE );
|
TIM_Cmd( TIM2, DISABLE );
|
||||||
|
|
||||||
/* 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
|
||||||
@ -255,13 +243,25 @@ const portTickType xRegulatorOffIdleTime = 30;
|
|||||||
}
|
}
|
||||||
else if( eSleepAction == eNoTasksWaitingTimeout )
|
else if( eSleepAction == eNoTasksWaitingTimeout )
|
||||||
{
|
{
|
||||||
|
/* A user definable macro that allows application code to be inserted
|
||||||
|
here. Such application code can be used to minimise power consumption
|
||||||
|
further by turning off IO, peripheral clocks, the Flash, etc. */
|
||||||
|
configPRE_STOP_PROCESSING();
|
||||||
|
|
||||||
/* There are no running state tasks and no tasks that are blocked with a
|
/* There are no running state tasks and no tasks that are blocked with a
|
||||||
time out. Assuming the application does not care if the tick time slips
|
time out. Assuming the application does not care if the tick time slips
|
||||||
with respect to calendar time then enter a deep sleep that can only be
|
with respect to calendar time then enter a deep sleep that can only be
|
||||||
woken by (in this demo case) the user button being pushed on the
|
woken by (in this demo case) the user button being pushed on the
|
||||||
STM32L discovery board. */
|
STM32L discovery board. If the application does require the tick time
|
||||||
configPRE_STOP_PROCESSING();
|
to keep better track of the calender time then the RTC peripheral can be
|
||||||
|
used to make rough adjustments. */
|
||||||
PWR_EnterSTOPMode( PWR_Regulator_LowPower, PWR_SLEEPEntry_WFI );
|
PWR_EnterSTOPMode( PWR_Regulator_LowPower, PWR_SLEEPEntry_WFI );
|
||||||
|
|
||||||
|
/* A user definable macro that allows application code to be inserted
|
||||||
|
here. Such application code can be used to reverse any actions taken
|
||||||
|
by the configPRE_STOP_PROCESSING(). In this demo
|
||||||
|
configPOST_STOP_PROCESSING() is used to re-initialise the clocks that
|
||||||
|
were turned off when STOP mode was entered. */
|
||||||
configPOST_STOP_PROCESSING();
|
configPOST_STOP_PROCESSING();
|
||||||
|
|
||||||
/* Restart tick. */
|
/* Restart tick. */
|
||||||
@ -274,36 +274,48 @@ const portTickType xRegulatorOffIdleTime = 30;
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Trap underflow before the next calculation. */
|
||||||
|
configASSERT( ulCounterValue >= TIM_GetCounter( TIM2 ) );
|
||||||
|
|
||||||
/* Adjust the TIM2 value to take into account that the current time
|
/* Adjust the TIM2 value to take into account that the current time
|
||||||
slice is already partially complete. */
|
slice is already partially complete. */
|
||||||
configASSERT( ulCounterValue >= TIM_GetCounter( TIM2 ) );
|
|
||||||
ulCounterValue -= ( uint32_t ) TIM_GetCounter( TIM2 );
|
ulCounterValue -= ( uint32_t ) TIM_GetCounter( TIM2 );
|
||||||
|
|
||||||
|
/* Trap overflow/underflow before the calculated value is written to
|
||||||
|
TIM2. */
|
||||||
configASSERT( ulCounterValue < ( uint32_t ) USHRT_MAX );
|
configASSERT( ulCounterValue < ( uint32_t ) USHRT_MAX );
|
||||||
configASSERT( ulCounterValue != 0 );
|
configASSERT( ulCounterValue != 0 );
|
||||||
|
|
||||||
|
/* Update to use the calculated overflow value. */
|
||||||
TIM_SetAutoreload( TIM2, ( uint16_t ) ulCounterValue );
|
TIM_SetAutoreload( TIM2, ( uint16_t ) ulCounterValue );
|
||||||
TIM_SetCounter( TIM2, 0 );
|
TIM_SetCounter( TIM2, 0 );
|
||||||
|
|
||||||
/* Restart the TIM2. */
|
/* Restart the TIM2. */
|
||||||
TIM_Cmd( TIM2, ENABLE );
|
TIM_Cmd( TIM2, ENABLE );
|
||||||
|
|
||||||
/* Allow the application to define some pre-sleep processing. */
|
/* Allow the application to define some pre-sleep processing. This is
|
||||||
|
the standard configPRE_SLEEP_PROCESSING() macro as described on the
|
||||||
|
FreeRTOS.org website. */
|
||||||
xModifiableIdleTime = xExpectedIdleTime;
|
xModifiableIdleTime = xExpectedIdleTime;
|
||||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||||
|
|
||||||
/* xExpectedIdleTime being set to 0 by configPRE_SLEEP_PROCESSING()
|
/* xExpectedIdleTime being set to 0 by configPRE_SLEEP_PROCESSING()
|
||||||
means the application defined code has already executed the WAIT
|
means the application defined code has already executed the wait/sleep
|
||||||
instruction. */
|
instruction. */
|
||||||
if( xModifiableIdleTime > 0 )
|
if( xModifiableIdleTime > 0 )
|
||||||
{
|
{
|
||||||
/* The sleep mode used is dependent on the expected idle time
|
/* The sleep mode used is dependent on the expected idle time
|
||||||
as the deeper the sleep the longer the wake up time. */
|
as the deeper the sleep the longer the wake up time. See the
|
||||||
|
comments at the top of main_low_power.c. Note xRegulatorOffIdleTime
|
||||||
|
is set purely for convenience of demonstration and is not intended
|
||||||
|
to be an optimised value. */
|
||||||
if( xModifiableIdleTime > xRegulatorOffIdleTime )
|
if( xModifiableIdleTime > xRegulatorOffIdleTime )
|
||||||
{
|
{
|
||||||
/* A slightly lower power sleep mode with a longer wake up
|
/* A slightly lower power sleep mode with a longer wake up
|
||||||
time. */
|
time. */
|
||||||
PWR_EnterSleepMode( PWR_Regulator_LowPower, PWR_SLEEPEntry_WFI );
|
PWR_EnterSleepMode( PWR_Regulator_LowPower, PWR_SLEEPEntry_WFI );
|
||||||
}
|
}
|
||||||
else if( pdTRUE )
|
else
|
||||||
{
|
{
|
||||||
/* A slightly higher power sleep mode with a faster wake up
|
/* A slightly higher power sleep mode with a faster wake up
|
||||||
time. */
|
time. */
|
||||||
@ -311,13 +323,14 @@ const portTickType xRegulatorOffIdleTime = 30;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allow the application to define some post sleep processing. */
|
/* Allow the application to define some post sleep processing. This is
|
||||||
|
the standard configPOST_SLEEP_PROCESSING() macro, as described on the
|
||||||
|
FreeRTOS.org website. */
|
||||||
configPOST_SLEEP_PROCESSING( xModifiableIdleTime );
|
configPOST_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||||
|
|
||||||
/* Stop TIM2. Again, the time the SysTick is stopped for is accounted
|
/* Stop TIM2. Again, the time the clock is stopped for in not accounted
|
||||||
for as best it can be, but using the tickless mode will inevitably
|
for here (as it would normally be) because the clock is so slow it is
|
||||||
result in some tiny drift of the time maintained by the kernel with
|
unlikely it will be stopped for a complete count period anyway. */
|
||||||
respect to calendar time. */
|
|
||||||
TIM_Cmd( TIM2, DISABLE );
|
TIM_Cmd( TIM2, DISABLE );
|
||||||
|
|
||||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||||
@ -328,14 +341,20 @@ const portTickType xRegulatorOffIdleTime = 30;
|
|||||||
|
|
||||||
if( ulTickFlag != pdFALSE )
|
if( ulTickFlag != pdFALSE )
|
||||||
{
|
{
|
||||||
|
/* Trap overflows before the next calculation. */
|
||||||
|
configASSERT( ulReloadValueForOneTick >= ( uint32_t ) TIM_GetCounter( TIM2 ) );
|
||||||
|
|
||||||
/* The tick interrupt has already executed, although because this
|
/* The tick interrupt has already executed, although because this
|
||||||
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. */
|
||||||
configASSERT( ulReloadValueForOneTick >= ( uint32_t ) TIM_GetCounter( TIM2 ) );
|
|
||||||
ulCounterValue = ulReloadValueForOneTick - ( uint32_t ) TIM_GetCounter( TIM2 );
|
ulCounterValue = ulReloadValueForOneTick - ( uint32_t ) TIM_GetCounter( TIM2 );
|
||||||
|
|
||||||
|
/* Trap under/overflows before the calculated value is used. */
|
||||||
configASSERT( ulCounterValue <= ( uint32_t ) USHRT_MAX );
|
configASSERT( ulCounterValue <= ( uint32_t ) USHRT_MAX );
|
||||||
configASSERT( ulCounterValue != 0 );
|
configASSERT( ulCounterValue != 0 );
|
||||||
|
|
||||||
|
/* Use the calculated reload value. */
|
||||||
TIM_SetAutoreload( TIM2, ( uint16_t ) ulCounterValue );
|
TIM_SetAutoreload( TIM2, ( uint16_t ) ulCounterValue );
|
||||||
TIM_SetCounter( TIM2, 0 );
|
TIM_SetCounter( TIM2, 0 );
|
||||||
|
|
||||||
@ -353,9 +372,11 @@ const portTickType xRegulatorOffIdleTime = 30;
|
|||||||
sleeping? */
|
sleeping? */
|
||||||
ulCompleteTickPeriods = ( ( uint32_t ) TIM_GetCounter( TIM2 ) ) / ulReloadValueForOneTick;
|
ulCompleteTickPeriods = ( ( uint32_t ) TIM_GetCounter( TIM2 ) ) / ulReloadValueForOneTick;
|
||||||
|
|
||||||
|
/* Check for over/under flows before the following calculation. */
|
||||||
|
configASSERT( ( ( uint32_t ) TIM_GetCounter( TIM2 ) ) >= ( ulCompleteTickPeriods * 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. */
|
||||||
configASSERT( ( ( uint32_t ) TIM_GetCounter( TIM2 ) ) >= ( ulCompleteTickPeriods * ulReloadValueForOneTick ) );
|
|
||||||
ulCounterValue = ( ( uint32_t ) TIM_GetCounter( TIM2 ) ) - ( ulCompleteTickPeriods * ulReloadValueForOneTick );
|
ulCounterValue = ( ( uint32_t ) TIM_GetCounter( TIM2 ) ) - ( ulCompleteTickPeriods * ulReloadValueForOneTick );
|
||||||
configASSERT( ulCounterValue <= ( uint32_t ) USHRT_MAX );
|
configASSERT( ulCounterValue <= ( uint32_t ) USHRT_MAX );
|
||||||
if( ulCounterValue == 0 )
|
if( ulCounterValue == 0 )
|
||||||
@ -379,7 +400,5 @@ const portTickType xRegulatorOffIdleTime = 30;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* configCREATE_LOW_POWER_DEMO == 1 */
|
#endif /* configCREATE_LOW_POWER_DEMO == 1 */
|
||||||
|
|
||||||
|
@ -78,7 +78,8 @@
|
|||||||
* See http://www.freertos.org/a00110.html.
|
* See http://www.freertos.org/a00110.html.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Ensure stdint is only used by the compiler, and not the assembler. */
|
/* Ensure stdint and C code is only used by the compiler, and not the
|
||||||
|
assembler. */
|
||||||
#ifdef __ICCARM__
|
#ifdef __ICCARM__
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
extern uint32_t SystemCoreClock;
|
extern uint32_t SystemCoreClock;
|
||||||
@ -88,30 +89,42 @@
|
|||||||
|
|
||||||
/* Set configCREATE_LOW_POWER_DEMO to one to run the simple blinky low power
|
/* Set configCREATE_LOW_POWER_DEMO to one to run the simple blinky low power
|
||||||
demo, or 0 to run the more comprehensive test and demo application. */
|
demo, or 0 to run the more comprehensive test and demo application. */
|
||||||
#define configCREATE_LOW_POWER_DEMO 1
|
#define configCREATE_LOW_POWER_DEMO 0
|
||||||
|
|
||||||
|
/* A few settings are dependent on the configCREATE_LOW_POWER_DEMO setting. */
|
||||||
#if configCREATE_LOW_POWER_DEMO == 1
|
#if configCREATE_LOW_POWER_DEMO == 1
|
||||||
#define configCPU_CLOCK_HZ SystemCoreClock
|
|
||||||
#define configUSE_TICKLESS_IDLE 1
|
|
||||||
#define configTICK_RATE_HZ ( 100 )
|
#define configTICK_RATE_HZ ( 100 )
|
||||||
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP ( 20 + 1 ) /* ( ( 200 / portTICK_RATE_MS ) + 1 ) written out pre-processed to enable #error statements to check its value. */
|
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP ( 20 + 1 ) /* ( ( 200 / portTICK_RATE_MS ) + 1 ) written out pre-processed to enable #error statements to check its value. */
|
||||||
|
#define configUSE_TIMERS 0
|
||||||
#else
|
#else
|
||||||
#define configCPU_CLOCK_HZ SystemCoreClock
|
#define configSYSTICK_CLOCK_HZ ( SystemCoreClock >> 3UL ) /* Systick clock is one eighth the system clock. */
|
||||||
#define configSYSTICK_CLOCK_HZ ( SystemCoreClock >> 3UL )
|
|
||||||
#define configUSE_TICKLESS_IDLE 0
|
|
||||||
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
|
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
|
||||||
|
#define configUSE_TIMERS 1
|
||||||
#endif /* configCREATE_LOW_POWER_DEMO */
|
#endif /* configCREATE_LOW_POWER_DEMO */
|
||||||
|
|
||||||
|
/* Demo specific macros that allow the application writer to insert code to be
|
||||||
|
executed immediately before the MCU's STOP low power mode is entered and exited
|
||||||
|
respectively. These macros are in addition to the standard
|
||||||
|
configPRE_SLEEP_PROCESSING() and configPOST_SLEEP_PROCESSING() macros, which are
|
||||||
|
called pre and post the low power SLEEP mode being entered and exited. These
|
||||||
|
macros can be used to turn turn off and on IO, clocks, the Flash etc. to obtain
|
||||||
|
the lowest power possible while the tick is off. See the comments at the top of
|
||||||
|
main_low_power.c and in STM32L_low_power_tick_management.c. */
|
||||||
#define configPRE_STOP_PROCESSING()
|
#define configPRE_STOP_PROCESSING()
|
||||||
#define configPOST_STOP_PROCESSING() vMainPostStopProcessing()
|
#define configPOST_STOP_PROCESSING() vMainPostStopProcessing()
|
||||||
|
|
||||||
|
/* The configUSE_TICKLESS_IDLE setting is dependent on the users setting of
|
||||||
|
configCREATE_LOW_POWER_DEMO at the top of this file. */
|
||||||
|
#define configUSE_TICKLESS_IDLE configCREATE_LOW_POWER_DEMO
|
||||||
|
|
||||||
|
#define configCPU_CLOCK_HZ SystemCoreClock
|
||||||
#define configUSE_PREEMPTION 1
|
#define configUSE_PREEMPTION 1
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#define configUSE_IDLE_HOOK 1
|
#define configUSE_IDLE_HOOK 1
|
||||||
#define configUSE_TICK_HOOK 1
|
#define configUSE_TICK_HOOK 1
|
||||||
#define configMAX_PRIORITIES ( 5 )
|
#define configMAX_PRIORITIES ( 5 )
|
||||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )
|
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )
|
||||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 10 * 1024 ) )
|
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 14 * 1024 ) )
|
||||||
#define configMAX_TASK_NAME_LEN ( 16 )
|
#define configMAX_TASK_NAME_LEN ( 16 )
|
||||||
#define configUSE_TRACE_FACILITY 1
|
#define configUSE_TRACE_FACILITY 1
|
||||||
#define configUSE_16_BIT_TICKS 0
|
#define configUSE_16_BIT_TICKS 0
|
||||||
@ -119,9 +132,15 @@ demo, or 0 to run the more comprehensive test and demo application. */
|
|||||||
#define configUSE_MUTEXES 1
|
#define configUSE_MUTEXES 1
|
||||||
#define configQUEUE_REGISTRY_SIZE 5
|
#define configQUEUE_REGISTRY_SIZE 5
|
||||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||||
#define configUSE_RECURSIVE_MUTEXES 0
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
#define configUSE_MALLOC_FAILED_HOOK 1
|
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||||
#define configUSE_APPLICATION_TASK_TAG 0
|
#define configUSE_APPLICATION_TASK_TAG 0
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
|
||||||
|
/* Software timer related definitions. */
|
||||||
|
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
|
||||||
|
#define configTIMER_QUEUE_LENGTH 10
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
/* Co-routine definitions. */
|
/* Co-routine definitions. */
|
||||||
#define configUSE_CO_ROUTINES 0
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
File diff suppressed because it is too large
Load Diff
263
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/main_full.c
Normal file
263
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/main_full.c
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that has become a de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
* Thank you! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
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 from the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
|
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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and 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!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* NOTE 1: This project provides two demo applications. A low power tickless
|
||||||
|
* project, 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 FreeRTOSConfig.h. 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
|
||||||
|
* required to configure the hardware, are defined in main.c.
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* main_full() creates all the demo application tasks and a software timer, then
|
||||||
|
* starts the scheduler. The web documentation provides more details of the
|
||||||
|
* standard demo application tasks, which provide no particular functionality,
|
||||||
|
* but do provide a good example of how to use the FreeRTOS API.
|
||||||
|
*
|
||||||
|
* In addition to the standard demo tasks, the following tasks and tests are
|
||||||
|
* defined and/or created within this file:
|
||||||
|
*
|
||||||
|
* "Check" timer - The check software timer period is initially set to three
|
||||||
|
* seconds. The callback function associated with the check software timer
|
||||||
|
* checks that all the standard demo tasks are not only still executing, but
|
||||||
|
* are executing without reporting any errors. If the check software timer
|
||||||
|
* discovers that a task has either stalled, or reported an error, then it
|
||||||
|
* changes its own execution period from the initial three seconds, to just
|
||||||
|
* 200ms. The check software timer callback function also toggles an LED each
|
||||||
|
* time it is called. This provides a visual indication of the system status:
|
||||||
|
* If the LED toggles every three seconds, then no issues have been discovered.
|
||||||
|
* If the LED toggles every 200ms, then an issue has been discovered with at
|
||||||
|
* least one task.
|
||||||
|
*
|
||||||
|
* See the documentation page for this demo on the FreeRTOS.org web site for
|
||||||
|
* full information, including hardware setup requirements.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* Kernel includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "timers.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* Standard demo application includes. */
|
||||||
|
#include "PollQ.h"
|
||||||
|
#include "semtest.h"
|
||||||
|
#include "dynamic.h"
|
||||||
|
#include "BlockQ.h"
|
||||||
|
#include "blocktim.h"
|
||||||
|
#include "countsem.h"
|
||||||
|
#include "GenQTest.h"
|
||||||
|
#include "recmutex.h"
|
||||||
|
|
||||||
|
/* ST library functions. */
|
||||||
|
#include "stm32l1xx.h"
|
||||||
|
#include "discover_board.h"
|
||||||
|
#include "discover_functions.h"
|
||||||
|
#include "stm32l_discovery_lcd.h"
|
||||||
|
|
||||||
|
/* Priorities for the demo application tasks. */
|
||||||
|
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL )
|
||||||
|
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
|
||||||
|
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
|
||||||
|
|
||||||
|
/* A block time of zero simply means "don't block". */
|
||||||
|
#define mainDONT_BLOCK ( 0UL )
|
||||||
|
|
||||||
|
/* The period after which the check timer will expire providing no errors
|
||||||
|
have been reported by any of the standard demo tasks. ms are converted to the
|
||||||
|
equivalent in ticks using the portTICK_RATE_MS constant. */
|
||||||
|
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_RATE_MS )
|
||||||
|
|
||||||
|
/* The period at which the check timer will expire, in ms, if an error has been
|
||||||
|
reported in one of the standard demo tasks. ms are converted to the equivalent
|
||||||
|
in ticks using the portTICK_RATE_MS constant. */
|
||||||
|
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_RATE_MS )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The check timer callback function, as described at the top of this file.
|
||||||
|
*/
|
||||||
|
static void prvCheckTimerCallback( xTimerHandle xTimer );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void main_full( void )
|
||||||
|
{
|
||||||
|
xTimerHandle xCheckTimer = NULL;
|
||||||
|
|
||||||
|
/* Start all the other standard demo/test tasks. They have not particular
|
||||||
|
functionality, but do demonstrate how to use the FreeRTOS API and test the
|
||||||
|
kernel port. */
|
||||||
|
vStartDynamicPriorityTasks();
|
||||||
|
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
|
||||||
|
vCreateBlockTimeTasks();
|
||||||
|
vStartCountingSemaphoreTasks();
|
||||||
|
vStartGenericQueueTasks( tskIDLE_PRIORITY );
|
||||||
|
vStartRecursiveMutexTasks();
|
||||||
|
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
|
||||||
|
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
|
||||||
|
|
||||||
|
/* Create the software timer that performs the 'check' functionality,
|
||||||
|
as described at the top of this file. */
|
||||||
|
xCheckTimer = xTimerCreate( ( const signed char * ) "CheckTimer",/* A text name, purely to help debugging. */
|
||||||
|
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
|
||||||
|
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
|
||||||
|
( void * ) 0, /* The ID is not used, so can be set to anything. */
|
||||||
|
prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
|
||||||
|
);
|
||||||
|
|
||||||
|
if( xCheckTimer != NULL )
|
||||||
|
{
|
||||||
|
xTimerStart( xCheckTimer, mainDONT_BLOCK );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start the scheduler. */
|
||||||
|
vTaskStartScheduler();
|
||||||
|
|
||||||
|
/* If all is well, the scheduler will now be running, and the following line
|
||||||
|
will never be reached. If the following line does execute, then there was
|
||||||
|
insufficient FreeRTOS heap memory available for the idle and/or timer tasks
|
||||||
|
to be created. See the memory management section on the FreeRTOS web site
|
||||||
|
for more details. */
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckTimerCallback( xTimerHandle xTimer )
|
||||||
|
{
|
||||||
|
static long lChangedTimerPeriodAlready = pdFALSE;
|
||||||
|
unsigned long ulErrorFound = pdFALSE;
|
||||||
|
|
||||||
|
/* Check all the demo tasks to ensure they are all still running, and that
|
||||||
|
none have detected an error. */
|
||||||
|
|
||||||
|
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorFound = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreBlockingQueuesStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorFound = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorFound = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorFound = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorFound = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xArePollingQueuesStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorFound = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
ulErrorFound = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toggle the check LED to give an indication of the system status. If
|
||||||
|
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
|
||||||
|
everything is ok. A faster toggle indicates an error. */
|
||||||
|
GPIO_TOGGLE( LD_GPIO_PORT, LD_GREEN_GPIO_PIN );
|
||||||
|
|
||||||
|
/* Have any errors been latch in ulErrorFound? If so, shorten the
|
||||||
|
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
|
||||||
|
This will result in an increase in the rate at which mainCHECK_LED
|
||||||
|
toggles. */
|
||||||
|
if( ulErrorFound != pdFALSE )
|
||||||
|
{
|
||||||
|
if( lChangedTimerPeriodAlready == pdFALSE )
|
||||||
|
{
|
||||||
|
lChangedTimerPeriodAlready = pdTRUE;
|
||||||
|
|
||||||
|
/* This call to xTimerChangePeriod() uses a zero block time.
|
||||||
|
Functions called from inside of a timer callback function must
|
||||||
|
*never* attempt to block. */
|
||||||
|
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
337
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/main_low_power.c
Normal file
337
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/main_low_power.c
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that has become a de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
* Thank you! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
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 from the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
|
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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and 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!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ****************************************************************************
|
||||||
|
* When configCREATE_LOW_POWER_DEMO is set to 1 in FreeRTOSConfig.h main() will
|
||||||
|
* call main_low_power(), which is defined in this file. main_low_power()
|
||||||
|
* demonstrates FreeRTOS tick suppression being used to allow the MCU to be
|
||||||
|
* placed into the Sleep, Low Power Sleep and Stop low power modes. When
|
||||||
|
* configCREATE_LOW_POWER_DEMO is set to 0 main will instead call main_full(),
|
||||||
|
* which is a more comprehensive RTOS demonstration.
|
||||||
|
* ****************************************************************************
|
||||||
|
*
|
||||||
|
* This application demonstrates the FreeRTOS tickless idle mode (tick
|
||||||
|
* suppression) being used to allow the STM32L to enter various low power modes
|
||||||
|
* during extended idle periods. See
|
||||||
|
* http://www.freertos.org/low-power-tickless-rtos.html for information on
|
||||||
|
* tickless operation.
|
||||||
|
*
|
||||||
|
* Deeper low power modes have longer wake up periods that lighter low power
|
||||||
|
* modes, and power is also used simply entering and especially exiting the low
|
||||||
|
* power modes. How the low power modes are used therefore requires careful
|
||||||
|
* consideration to ensure power consumption is truly minimised and that the
|
||||||
|
* embedded device meets its real time requirements. This demo is configured to
|
||||||
|
* select between four different modes depending on the anticipated idle period.
|
||||||
|
* Note the time thresholds used to decide which low power mode to enter are
|
||||||
|
* purely for convenience of demonstration and are not intended to represent
|
||||||
|
* optimal values for any particular application.
|
||||||
|
*
|
||||||
|
* The STM32L specific part of the tickless operation is implemented in
|
||||||
|
* STM32L_low_power_tick_management.c.
|
||||||
|
*
|
||||||
|
* The demo is configured to execute on the STM32L Discovery board.
|
||||||
|
*
|
||||||
|
* Functionality:
|
||||||
|
*
|
||||||
|
* + Two tasks are created, an Rx task and a Tx task. A queue is created to
|
||||||
|
* pass a message from the Tx task to the Rx task.
|
||||||
|
*
|
||||||
|
* + The Rx task blocks on a queue to wait for data, blipping an LED each time
|
||||||
|
* data is received (turning it on and then off again) before returning to
|
||||||
|
* block on the queue once more.
|
||||||
|
*
|
||||||
|
* + The Tx task repeatedly blocks on an attempt to obtain a semaphore, and
|
||||||
|
* unblocks if either the semaphore is received or its block time expires.
|
||||||
|
* After leaving the blocked state the Tx task uses the queue to send a
|
||||||
|
* value to the Rx task, which in turn causes the Rx task to exit the
|
||||||
|
* Blocked state and blip the LED. The rate at which the LED is seen to blip
|
||||||
|
* is therefore dependent on the block time.
|
||||||
|
*
|
||||||
|
* + The Tx task's block time is changed by the interrupt service routine that
|
||||||
|
* executes when the USER button is pressed. The low power mode entered
|
||||||
|
* depends on the block time (as described in the Observed Behaviour section
|
||||||
|
* below). Four block times are used: short, medium, long and infinite.
|
||||||
|
*
|
||||||
|
* Observed behaviour:
|
||||||
|
*
|
||||||
|
* 1) The block time used by the Tx task is initialised to its 'short' value,
|
||||||
|
* so when the Tx task blocks on the semaphore it times-out quickly, resulting
|
||||||
|
* in the LED toggling rapidly. The timeout period is less than the value of
|
||||||
|
* configEXPECTED_IDLE_TIME_BEFORE_SLEEP (set in FreeRTOSConfig.h), so the
|
||||||
|
* initial state does not suppress the tick interrupt or enter a low power mode.
|
||||||
|
*
|
||||||
|
* 2) When the button is pressed the block time used by the Tx task is increased
|
||||||
|
* to its 'medium' value. The longer block time results in a slowing of the
|
||||||
|
* rate at which the LED toggles. The time the Tx task spends in the blocked
|
||||||
|
* state is now greater than configEXPECTED_IDLE_TIME_BEFORE_SLEEP, so the tick
|
||||||
|
* is suppressed. The MCU is placed into the 'Sleep' low power state while the
|
||||||
|
* tick is suppressed.
|
||||||
|
*
|
||||||
|
* 3) When the button is pressed again the block time used by the Tx task is
|
||||||
|
* increased to its 'long' value, so the rate at which the LED is observed to
|
||||||
|
* blip gets even slow. When the 'long' block time is used the MCU is placed
|
||||||
|
* into its 'Low Power Sleep' low power state.
|
||||||
|
*
|
||||||
|
* 4) The next time the button is pressed the block time used by the Tx task is
|
||||||
|
* set to infinite, so the Tx task does not time out when it attempts to obtain
|
||||||
|
* the semaphore, and therefore the LED stops blipping completely. Both tasks
|
||||||
|
* are not blocked indefinitely and the MCU is placed into its 'Stop' low power
|
||||||
|
* state.
|
||||||
|
*
|
||||||
|
* 5) Pressing the button one final time results in the semaphore being 'given'
|
||||||
|
* to unblock the Tx task, the CPU clocks being returned to their pre-stop
|
||||||
|
* state, and the block time being reset to its 'short' time. The system is
|
||||||
|
* then back to its initial condition with the LED blipping rapidly.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Kernel includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* ST library functions. */
|
||||||
|
#include "stm32l1xx.h"
|
||||||
|
#include "discover_board.h"
|
||||||
|
#include "discover_functions.h"
|
||||||
|
#include "stm32l_discovery_lcd.h"
|
||||||
|
|
||||||
|
/* Priorities at which the Rx and Tx tasks are created. */
|
||||||
|
#define configQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||||
|
#define configQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||||
|
|
||||||
|
/* The number of items the queue can hold. This is 1 as the Rx task will
|
||||||
|
remove items as they are added so the Tx task should always find the queue
|
||||||
|
empty. */
|
||||||
|
#define mainQUEUE_LENGTH ( 1 )
|
||||||
|
|
||||||
|
/* A block time of zero simply means "don't block". */
|
||||||
|
#define mainDONT_BLOCK ( 0 )
|
||||||
|
|
||||||
|
/* The value that is sent from the Tx task to the Rx task on the queue. */
|
||||||
|
#define mainQUEUED_VALUE ( 100UL )
|
||||||
|
|
||||||
|
/* The length of time the LED will remain on for. */
|
||||||
|
#define mainLED_TOGGLE_DELAY ( 10 / portTICK_RATE_MS )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Rx and Tx tasks as described at the top of this file.
|
||||||
|
*/
|
||||||
|
static void prvQueueReceiveTask( void *pvParameters );
|
||||||
|
static void prvQueueSendTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The queue used to pass data from the Tx task to the Rx task. */
|
||||||
|
static xQueueHandle xQueue = NULL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Holds the block time used by the Tx task. */
|
||||||
|
portTickType xSendBlockTime = ( 100UL / portTICK_RATE_MS );
|
||||||
|
|
||||||
|
/* The lower an upper limits of the block time. An infinite block time is used
|
||||||
|
if xSendBlockTime is incremented past xMaxBlockTime. */
|
||||||
|
static const portTickType xMaxBlockTime = ( 500L / portTICK_RATE_MS ), xMinBlockTime = ( 100L / portTICK_RATE_MS );
|
||||||
|
|
||||||
|
/* The semaphore on which the Tx task blocks. */
|
||||||
|
static xSemaphoreHandle xTxSemaphore = NULL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* See the comments at the top of the file. */
|
||||||
|
void main_low_power( void )
|
||||||
|
{
|
||||||
|
/* Create the semaphore as described at the top of this file. */
|
||||||
|
xTxSemaphore = xSemaphoreCreateBinary();
|
||||||
|
configASSERT( xTxSemaphore );
|
||||||
|
|
||||||
|
/* Create the queue as described at the top of this file. */
|
||||||
|
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
|
||||||
|
configASSERT( xQueue );
|
||||||
|
|
||||||
|
/* Start the two tasks as described at the top of this file. */
|
||||||
|
xTaskCreate( prvQueueReceiveTask, ( const signed char * const ) "Rx", configMINIMAL_STACK_SIZE, NULL, configQUEUE_RECEIVE_TASK_PRIORITY, NULL );
|
||||||
|
xTaskCreate( prvQueueSendTask, ( const signed char * const ) "TX", configMINIMAL_STACK_SIZE, NULL, configQUEUE_SEND_TASK_PRIORITY, NULL );
|
||||||
|
|
||||||
|
/* Start the scheduler running running. */
|
||||||
|
vTaskStartScheduler();
|
||||||
|
|
||||||
|
/* If all is well the next line of code will not be reached as the
|
||||||
|
scheduler will be running. If the next line is reached then it is likely
|
||||||
|
there was insufficient FreeRTOS heap available for the idle task and/or
|
||||||
|
timer task to be created. See http://www.freertos.org/a00111.html. */
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvQueueSendTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
const unsigned long ulValueToSend = mainQUEUED_VALUE;
|
||||||
|
|
||||||
|
/* Remove compiler warning about unused parameter. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Enter the Blocked state to wait for the semaphore. The task will
|
||||||
|
leave the Blocked state if either the semaphore is received or
|
||||||
|
xSendBlockTime ticks pass without the semaphore being received. */
|
||||||
|
xSemaphoreTake( xTxSemaphore, xSendBlockTime );
|
||||||
|
|
||||||
|
/* Send to the queue - causing the Tx task to flash its LED. */
|
||||||
|
xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvQueueReceiveTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
unsigned long ulReceivedValue;
|
||||||
|
|
||||||
|
/* Remove compiler warning about unused parameter. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Wait until something arrives in the queue. */
|
||||||
|
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
|
||||||
|
|
||||||
|
/* To get here something must have arrived, but is it the expected
|
||||||
|
value? If it is, turn the LED on for a short while. */
|
||||||
|
if( ulReceivedValue == mainQUEUED_VALUE )
|
||||||
|
{
|
||||||
|
/* LED on... */
|
||||||
|
GPIO_HIGH( LD_GPIO_PORT, LD_GREEN_GPIO_PIN );
|
||||||
|
|
||||||
|
/* ... short delay ... */
|
||||||
|
vTaskDelay( mainLED_TOGGLE_DELAY );
|
||||||
|
|
||||||
|
/* ... LED off again. */
|
||||||
|
GPIO_LOW( LD_GPIO_PORT, LD_GREEN_GPIO_PIN );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Handles interrupts generated by pressing the USER button. */
|
||||||
|
void EXTI0_IRQHandler(void)
|
||||||
|
{
|
||||||
|
static const portTickType xIncrement = 200UL / portTICK_RATE_MS;
|
||||||
|
|
||||||
|
/* If xSendBlockTime is already portMAX_DELAY then the Tx task was blocked
|
||||||
|
indefinitely, and this interrupt is bringing the MCU out of STOP low power
|
||||||
|
mode. */
|
||||||
|
if( xSendBlockTime == portMAX_DELAY )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
|
||||||
|
/* Unblock the Tx task. */
|
||||||
|
xSemaphoreGiveFromISR( xTxSemaphore, &xHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
/* Start over with the 'short' block time as described at the top of
|
||||||
|
this file. */
|
||||||
|
xSendBlockTime = xMinBlockTime;
|
||||||
|
|
||||||
|
/* Request a yield if calling xSemaphoreGiveFromISR() caused a task to
|
||||||
|
leave the Blocked state (which it will have done) and the task that left
|
||||||
|
the Blocked state has a priority higher than the currently running task
|
||||||
|
(which it will have). */
|
||||||
|
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Increase the block time used by the Tx task, as described at the top
|
||||||
|
of this file. */
|
||||||
|
xSendBlockTime += xIncrement;
|
||||||
|
|
||||||
|
/* If the block time has gone over the configured maximum then set it to
|
||||||
|
an infinite block time to allow the MCU to go into its STOP low power
|
||||||
|
mode. */
|
||||||
|
if( xSendBlockTime > xMaxBlockTime )
|
||||||
|
{
|
||||||
|
xSendBlockTime = portMAX_DELAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTI_ClearITPendingBit( EXTI_Line0 );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The configPOST_STOP_PROCESSING() macro is called when the MCU leaves its
|
||||||
|
STOP low power mode. The macro is set in FreeRTOSConfig.h to call
|
||||||
|
vMainPostStopProcessing(). */
|
||||||
|
void vMainPostStopProcessing( void )
|
||||||
|
{
|
||||||
|
extern void SetSysClock( void );
|
||||||
|
|
||||||
|
/* The STOP low power mode has been exited. Reconfigure the system clocks
|
||||||
|
ready for normally running again. */
|
||||||
|
SetSysClock();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
@ -10,7 +10,7 @@ define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
|
|||||||
define symbol __ICFEDIT_region_RAM_end__ = 0x20003FFF;
|
define symbol __ICFEDIT_region_RAM_end__ = 0x20003FFF;
|
||||||
/*-Sizes-*/
|
/*-Sizes-*/
|
||||||
define symbol __ICFEDIT_size_cstack__ = 0x400;
|
define symbol __ICFEDIT_size_cstack__ = 0x400;
|
||||||
define symbol __ICFEDIT_size_heap__ = 0x200;
|
define symbol __ICFEDIT_size_heap__ = 0x0;
|
||||||
/**** End of ICF editor section. ###ICF###*/
|
/**** End of ICF editor section. ###ICF###*/
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user