mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbed_power_mgmt.h Source File

mbed_power_mgmt.h

00001 /** \addtogroup platform */
00002 /** @{*/
00003 /**
00004  * \defgroup platform_power_mgmt Power management functions
00005  * @{
00006  */
00007 
00008 /* mbed Microcontroller Library
00009  * Copyright (c) 2006-2018 ARM Limited
00010  * SPDX-License-Identifier: Apache-2.0
00011  *
00012  * Licensed under the Apache License, Version 2.0 (the "License");
00013  * you may not use this file except in compliance with the License.
00014  * You may obtain a copy of the License at
00015  *
00016  *     http://www.apache.org/licenses/LICENSE-2.0
00017  *
00018  * Unless required by applicable law or agreed to in writing, software
00019  * distributed under the License is distributed on an "AS IS" BASIS,
00020  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00021  * See the License for the specific language governing permissions and
00022  * limitations under the License.
00023  */
00024 #ifndef MBED_POWER_MGMT_H
00025 #define MBED_POWER_MGMT_H
00026 
00027 #include "hal/sleep_api.h"
00028 #include "mbed_toolchain.h"
00029 #include "hal/ticker_api.h"
00030 #include <stdbool.h>
00031 
00032 #ifdef __cplusplus
00033 extern "C" {
00034 #endif
00035 
00036 /**
00037  * @defgroup hal_sleep_manager Sleep manager API
00038  * The sleep manager provides API to automatically select sleep mode.
00039  *
00040  * There are two sleep modes:
00041  * - sleep
00042  * - deepsleep
00043  *
00044  * Use locking/unlocking deepsleep for drivers that depend on features that
00045  * are not allowed (=disabled) during the deepsleep. For instance, high frequency
00046  * clocks.
00047  *
00048  * # Defined behavior
00049  * * The lock is a counter
00050  * * The lock can be locked up to USHRT_MAX - Verified by ::test_lock_eq_ushrt_max
00051  * * The lock has to be equally unlocked as locked - Verified by ::test_lock_eq_ushrt_max
00052  * * The function sleep_manager_lock_deep_sleep_internal() locks the automatic deep mode selection - Verified by ::test_lock_unlock
00053  * * The function sleep_manager_unlock_deep_sleep_internal() unlocks the automatic deep mode selection - Verified by ::test_lock_unlock
00054  * * The function sleep_manager_sleep_auto() chooses the sleep or deep sleep modes based on the lock - Verified by ::test_sleep_auto
00055  * * The function sleep_manager_lock_deep_sleep_internal() is IRQ and thread safe - Verified by ::sleep_manager_multithread_test and ::sleep_manager_irq_test
00056  * * The function sleep_manager_unlock_deep_sleep_internal() is IRQ and thread safe - Verified by ::sleep_manager_multithread_test and ::sleep_manager_irq_test
00057  * * The function sleep_manager_sleep_auto() is IRQ and thread safe
00058  *
00059  * Example:
00060  * @code
00061  *
00062  * void driver::handler()
00063  * {
00064  *     if (_sensor.get_event()) {
00065  *         // any event - we are finished, unlock the deepsleep
00066  *         sleep_manager_unlock_deep_sleep();
00067  *         _callback();
00068  *     }
00069  * }
00070  *
00071  * int driver::measure(event_t event, callback_t& callback)
00072  * {
00073  *      _callback = callback;
00074  *      sleep_manager_lock_deep_sleep();
00075  *      // start async transaction, we are waiting for an event
00076  *      return _sensor.start(event, callback);
00077  * }
00078  * @endcode
00079  * @{
00080  */
00081 
00082 /**
00083  * @defgroup hal_sleep_manager_tests Sleep manager API tests
00084  * Tests to validate the proper implementation of the sleep manager
00085  *
00086  * To run the sleep manager hal tests use the command:
00087  *
00088  *     mbed test -t <toolchain> -m <target> -n tests-mbed_hal-sleep_manager*
00089  *
00090  */
00091 
00092 #ifdef MBED_SLEEP_TRACING_ENABLED
00093 
00094 void sleep_tracker_lock(const char *const filename, int line);
00095 void sleep_tracker_unlock(const char *const filename, int line);
00096 
00097 #define sleep_manager_lock_deep_sleep()              \
00098     do                                               \
00099     {                                                \
00100         sleep_manager_lock_deep_sleep_internal();    \
00101         sleep_tracker_lock(MBED_FILENAME, __LINE__); \
00102     } while (0);
00103 
00104 #define sleep_manager_unlock_deep_sleep()              \
00105     do                                                 \
00106     {                                                  \
00107         sleep_manager_unlock_deep_sleep_internal();    \
00108         sleep_tracker_unlock(MBED_FILENAME, __LINE__); \
00109     } while (0);
00110 
00111 #else
00112 
00113 #define sleep_manager_lock_deep_sleep() \
00114     sleep_manager_lock_deep_sleep_internal()
00115 
00116 #define sleep_manager_unlock_deep_sleep() \
00117     sleep_manager_unlock_deep_sleep_internal()
00118 
00119 #endif // MBED_SLEEP_TRACING_ENABLED
00120 
00121 /** Lock the deep sleep mode
00122  *
00123  * This locks the automatic deep mode selection.
00124  * sleep_manager_sleep_auto() will ignore deepsleep mode if
00125  * this function is invoked at least once (the internal counter is non-zero)
00126  *
00127  * Use this locking mechanism for interrupt driven API that are
00128  * running in the background and deepsleep could affect their functionality
00129  *
00130  * The lock is a counter, can be locked up to USHRT_MAX
00131  * This function is IRQ and thread safe
00132  */
00133 void sleep_manager_lock_deep_sleep_internal(void);
00134 
00135 /** Unlock the deep sleep mode
00136  *
00137  * Use unlocking in pair with sleep_manager_lock_deep_sleep().
00138  *
00139  * The lock is a counter, should be equally unlocked as locked
00140  * This function is IRQ and thread safe
00141  */
00142 void sleep_manager_unlock_deep_sleep_internal(void);
00143 
00144 /** Get the status of deep sleep allowance for a target
00145  *
00146  * @return true if a target can go to deepsleep, false otherwise
00147  */
00148 bool sleep_manager_can_deep_sleep(void);
00149 
00150 /** Check if the target can deep sleep within a period of time
00151  *
00152  * This function in intended for use in testing. The amount
00153  * of time this functions waits for deeps sleep to be available
00154  * is currently 2ms. This may change in the future depending
00155  * on testing requirements.
00156  *
00157  * @return true if a target can go to deepsleep, false otherwise
00158  */
00159 bool sleep_manager_can_deep_sleep_test_check(void);
00160 
00161 /** Enter auto selected sleep mode. It chooses the sleep or deepsleep modes based
00162  *  on the deepsleep locking counter
00163  *
00164  * This function is IRQ and thread safe
00165  *
00166  * @note
00167  * If MBED_DEBUG is defined, only hal_sleep is allowed. This ensures the debugger
00168  * to be active for debug modes.
00169  *
00170  */
00171 void sleep_manager_sleep_auto(void);
00172 
00173 /** Send the microcontroller to sleep
00174  *
00175  * @note This function can be a noop if not implemented by the platform.
00176  * @note This function will be a noop in debug mode (debug build profile when MBED_DEBUG is defined).
00177  * @note This function will be a noop if the following conditions are met:
00178  *   - The RTOS is present
00179  *   - The processor turn off the Systick clock during sleep
00180  *   - The target does not implement tickless mode
00181  *
00182  * The processor is setup ready for sleep, and sent to sleep using __WFI(). In this mode, the
00183  * system clock to the core is stopped until a reset or an interrupt occurs. This eliminates
00184  * dynamic power used by the processor, memory systems and buses. The processor, peripheral and
00185  * memory state are maintained, and the peripherals continue to work and can generate interrupts.
00186  *
00187  * The processor can be woken up by any internal peripheral interrupt or external pin interrupt.
00188  *
00189  * @note
00190  *  The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored.
00191  * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be
00192  * able to access the LocalFileSystem
00193  */
00194 static inline void sleep(void)
00195 {
00196 #if DEVICE_SLEEP
00197 #if (MBED_CONF_RTOS_PRESENT == 0) || (DEVICE_SYSTICK_CLK_OFF_DURING_SLEEP == 0) || defined(MBED_TICKLESS)
00198     sleep_manager_sleep_auto();
00199 #endif /* (MBED_CONF_RTOS_PRESENT == 0) || (DEVICE_SYSTICK_CLK_OFF_DURING_SLEEP == 0) || defined(MBED_TICKLESS) */
00200 #endif /* DEVICE_SLEEP */
00201 }
00202 
00203 /** Send the microcontroller to deep sleep
00204  *
00205  * @deprecated
00206  * Do not use this function. Applications should use sleep() API which puts the system in deepsleep mode if supported.
00207  *
00208  * @note This function can be a noop if not implemented by the platform.
00209  * @note This function will be a noop in debug mode (debug build profile when MBED_DEBUG is defined)
00210  *
00211  * This processor is setup ready for deep sleep, and sent to sleep. This mode
00212  * has the same sleep features as sleep plus it powers down peripherals and clocks. All state
00213  * is still maintained.
00214  *
00215  * The processor can only be woken up by an external interrupt on a pin or a watchdog timer.
00216  *
00217  * @note
00218  *  The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored.
00219  * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be
00220  * able to access the LocalFileSystem
00221  */
00222 
00223 MBED_DEPRECATED_SINCE("mbed-os-5.6", "One entry point for an application, use sleep()")
00224 static inline void deepsleep(void)
00225 {
00226 #if DEVICE_SLEEP
00227     sleep_manager_sleep_auto();
00228 #endif /* DEVICE_SLEEP */
00229 }
00230 
00231 /** Provides the time spent in sleep mode since boot.
00232  *
00233  *  @return  Time spent in sleep
00234  *  @note  Works only if platform supports LP ticker.
00235  */
00236 us_timestamp_t mbed_time_sleep(void);
00237 
00238 /** Provides the time spent in deep sleep mode since boot.
00239  *
00240  *  @return  Time spent in deep sleep
00241  *  @note  Works only if platform supports LP ticker.
00242  */
00243 us_timestamp_t mbed_time_deepsleep(void);
00244 
00245 /** Provides the time spent in idle mode since boot.
00246  *
00247  * @return  Idle thread time.
00248  * @note  Works only if platform supports LP ticker.
00249  */
00250 us_timestamp_t mbed_time_idle(void);
00251 
00252 /** Provides the time since the system is up i.e. boot.
00253  *
00254  * @return  System uptime.
00255  * @note  Works only if platform supports LP ticker.
00256  */
00257 us_timestamp_t mbed_uptime(void);
00258 
00259 /** @}*/
00260 
00261 /** Resets the processor and most of the sub-system
00262  *
00263  * @note Does not affect the debug sub-system
00264  */
00265 MBED_NORETURN static inline void system_reset(void)
00266 {
00267     NVIC_SystemReset();
00268 }
00269 
00270 #ifdef __cplusplus
00271 }
00272 #endif
00273 
00274 #endif
00275 
00276 /** @}*/
00277 /** @}*/