Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of OmniWheels by
mbed_sleep_manager.c
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "mbed_assert.h" 00018 #include "mbed_power_mgmt.h" 00019 #include "mbed_critical.h" 00020 #include "sleep_api.h" 00021 #include "mbed_error.h" 00022 #include "mbed_debug.h" 00023 #include <limits.h> 00024 #include <stdio.h> 00025 00026 #if DEVICE_SLEEP 00027 00028 // deep sleep locking counter. A target is allowed to deep sleep if counter == 0 00029 static uint16_t deep_sleep_lock = 0U; 00030 00031 #ifdef MBED_SLEEP_TRACING_ENABLED 00032 00033 // Number of drivers that can be stored in the structure 00034 #define STATISTIC_COUNT 10 00035 00036 typedef struct sleep_statistic { 00037 const char* identifier; 00038 uint8_t count; 00039 } sleep_statistic_t; 00040 00041 static sleep_statistic_t sleep_stats[STATISTIC_COUNT]; 00042 00043 static sleep_statistic_t* sleep_tracker_find(const char *const filename) 00044 { 00045 for (int i = 0; i < STATISTIC_COUNT; ++i) { 00046 if (sleep_stats[i].identifier == filename) { 00047 return &sleep_stats[i]; 00048 } 00049 } 00050 00051 return NULL; 00052 } 00053 00054 static sleep_statistic_t* sleep_tracker_add(const char* const filename) 00055 { 00056 for (int i = 0; i < STATISTIC_COUNT; ++i) { 00057 if (sleep_stats[i].identifier == NULL) { 00058 sleep_stats[i].identifier = filename; 00059 00060 return &sleep_stats[i]; 00061 } 00062 } 00063 00064 debug("No free indexes left to use in mbed sleep tracker.\r\n"); 00065 00066 return NULL; 00067 } 00068 00069 static void sleep_tracker_print_stats(void) 00070 { 00071 debug("Sleep locks held:\r\n"); 00072 for (int i = 0; i < STATISTIC_COUNT; ++i) { 00073 if (sleep_stats[i].count == 0) { 00074 continue; 00075 } 00076 00077 if (sleep_stats[i].identifier == NULL) { 00078 return; 00079 } 00080 00081 debug("[id: %s, count: %u]\r\n", sleep_stats[i].identifier, 00082 sleep_stats[i].count); 00083 } 00084 } 00085 00086 void sleep_tracker_lock(const char* const filename, int line) 00087 { 00088 sleep_statistic_t *stat = sleep_tracker_find(filename); 00089 00090 // Entry for this driver does not exist, create one. 00091 if (stat == NULL) { 00092 stat = sleep_tracker_add(filename); 00093 } 00094 00095 core_util_atomic_incr_u8(&stat->count, 1); 00096 00097 debug("LOCK: %s, ln: %i, lock count: %u\r\n", filename, line, deep_sleep_lock); 00098 } 00099 00100 void sleep_tracker_unlock(const char* const filename, int line) 00101 { 00102 sleep_statistic_t *stat = sleep_tracker_find(filename); 00103 00104 // Entry for this driver does not exist, something went wrong. 00105 if (stat == NULL) { 00106 debug("Unlocking sleep for driver that was not previously locked: %s, ln: %i\r\n", filename, line); 00107 return; 00108 } 00109 00110 core_util_atomic_decr_u8(&stat->count, 1); 00111 00112 debug("UNLOCK: %s, ln: %i, lock count: %u\r\n", filename, line, deep_sleep_lock); 00113 } 00114 00115 #endif // MBED_SLEEP_TRACING_ENABLED 00116 00117 void sleep_manager_lock_deep_sleep_internal(void) 00118 { 00119 core_util_critical_section_enter(); 00120 if (deep_sleep_lock == USHRT_MAX) { 00121 core_util_critical_section_exit(); 00122 error("Deep sleep lock would overflow (> USHRT_MAX)"); 00123 } 00124 core_util_atomic_incr_u16(&deep_sleep_lock, 1); 00125 core_util_critical_section_exit(); 00126 } 00127 00128 void sleep_manager_unlock_deep_sleep_internal(void) 00129 { 00130 core_util_critical_section_enter(); 00131 if (deep_sleep_lock == 0) { 00132 core_util_critical_section_exit(); 00133 error("Deep sleep lock would underflow (< 0)"); 00134 } 00135 core_util_atomic_decr_u16(&deep_sleep_lock, 1); 00136 core_util_critical_section_exit(); 00137 } 00138 00139 bool sleep_manager_can_deep_sleep(void) 00140 { 00141 return deep_sleep_lock == 0 ? true : false; 00142 } 00143 00144 void sleep_manager_sleep_auto(void) 00145 { 00146 #ifdef MBED_SLEEP_TRACING_ENABLED 00147 sleep_tracker_print_stats(); 00148 #endif 00149 core_util_critical_section_enter(); 00150 // debug profile should keep debuggers attached, no deep sleep allowed 00151 #ifdef MBED_DEBUG 00152 hal_sleep(); 00153 #else 00154 if (sleep_manager_can_deep_sleep()) { 00155 hal_deepsleep(); 00156 } else { 00157 hal_sleep(); 00158 } 00159 #endif 00160 core_util_critical_section_exit(); 00161 } 00162 00163 #else 00164 00165 // locking is valid only if DEVICE_SLEEP is defined 00166 // we provide empty implementation 00167 00168 void sleep_manager_lock_deep_sleep_internal(void) 00169 { 00170 00171 } 00172 00173 void sleep_manager_unlock_deep_sleep_internal(void) 00174 { 00175 00176 } 00177 00178 bool sleep_manager_can_deep_sleep(void) 00179 { 00180 // no sleep implemented 00181 return false; 00182 } 00183 00184 #endif
Generated on Fri Jul 22 2022 04:53:56 by
 1.7.2
 1.7.2 
    