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