Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbed_power_mgmt.h Source File

mbed_power_mgmt.h

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