source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/hal/mbed_sleep_manager.c@ 374

Last change on this file since 374 was 374, checked in by coas-nagasima, 5 years ago

mbed関連を更新
シリアルドライバをmbedのHALを使うよう変更
ファイルディスクリプタの処理を更新

  • Property charset set to UTF-8
  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 6.2 KB
Line 
1/* mbed Microcontroller Library
2 * Copyright (c) 2017 ARM Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "platform/mbed_assert.h"
18#include "platform/mbed_power_mgmt.h"
19#include "platform/mbed_critical.h"
20#include "hal/sleep_api.h"
21#include "platform/mbed_error.h"
22#include "platform/mbed_debug.h"
23#include "platform/mbed_stats.h"
24#include "hal/us_ticker_api.h"
25#include "hal/lp_ticker_api.h"
26#include <limits.h>
27#include <stdio.h>
28#include "platform/mbed_stats.h"
29
30
31#if DEVICE_SLEEP
32
33// deep sleep locking counter. A target is allowed to deep sleep if counter == 0
34static uint16_t deep_sleep_lock = 0U;
35static us_timestamp_t sleep_time = 0;
36static us_timestamp_t deep_sleep_time = 0;
37
38#if defined(MBED_CPU_STATS_ENABLED) && defined(DEVICE_LPTICKER)
39static ticker_data_t *sleep_ticker = NULL;
40#endif
41
42static inline us_timestamp_t read_us(void)
43{
44#if defined(MBED_CPU_STATS_ENABLED) && defined(DEVICE_LPTICKER)
45 if (NULL == sleep_ticker) {
46 sleep_ticker = (ticker_data_t *)get_lp_ticker_data();
47 }
48 return ticker_read_us(sleep_ticker);
49#else
50 return 0;
51#endif
52}
53
54us_timestamp_t mbed_time_idle(void)
55{
56 return (sleep_time + deep_sleep_time);
57}
58
59us_timestamp_t mbed_uptime(void)
60{
61 return read_us();
62}
63
64us_timestamp_t mbed_time_sleep(void)
65{
66 return sleep_time;
67}
68
69us_timestamp_t mbed_time_deepsleep(void)
70{
71 return deep_sleep_time;
72}
73
74#ifdef MBED_SLEEP_TRACING_ENABLED
75
76// Number of drivers that can be stored in the structure
77#define STATISTIC_COUNT 10
78
79typedef struct sleep_statistic {
80 const char *identifier;
81 uint8_t count;
82} sleep_statistic_t;
83
84static sleep_statistic_t sleep_stats[STATISTIC_COUNT];
85
86static sleep_statistic_t *sleep_tracker_find(const char *const filename)
87{
88 for (int i = 0; i < STATISTIC_COUNT; ++i) {
89 if (sleep_stats[i].identifier == filename) {
90 return &sleep_stats[i];
91 }
92 }
93
94 return NULL;
95}
96
97static sleep_statistic_t *sleep_tracker_add(const char *const filename)
98{
99 for (int i = 0; i < STATISTIC_COUNT; ++i) {
100 if (sleep_stats[i].identifier == NULL) {
101 sleep_stats[i].identifier = filename;
102
103 return &sleep_stats[i];
104 }
105 }
106
107 debug("No free indexes left to use in mbed sleep tracker.\r\n");
108
109 return NULL;
110}
111
112static void sleep_tracker_print_stats(void)
113{
114 debug("Sleep locks held:\r\n");
115 for (int i = 0; i < STATISTIC_COUNT; ++i) {
116 if (sleep_stats[i].count == 0) {
117 continue;
118 }
119
120 if (sleep_stats[i].identifier == NULL) {
121 return;
122 }
123
124 debug("[id: %s, count: %u]\r\n", sleep_stats[i].identifier,
125 sleep_stats[i].count);
126 }
127}
128
129void sleep_tracker_lock(const char *const filename, int line)
130{
131 sleep_statistic_t *stat = sleep_tracker_find(filename);
132
133 // Entry for this driver does not exist, create one.
134 if (stat == NULL) {
135 stat = sleep_tracker_add(filename);
136 }
137
138 core_util_atomic_incr_u8(&stat->count, 1);
139
140 debug("LOCK: %s, ln: %i, lock count: %u\r\n", filename, line, deep_sleep_lock);
141}
142
143void sleep_tracker_unlock(const char *const filename, int line)
144{
145 sleep_statistic_t *stat = sleep_tracker_find(filename);
146
147 // Entry for this driver does not exist, something went wrong.
148 if (stat == NULL) {
149 debug("Unlocking sleep for driver that was not previously locked: %s, ln: %i\r\n", filename, line);
150 return;
151 }
152
153 core_util_atomic_decr_u8(&stat->count, 1);
154
155 debug("UNLOCK: %s, ln: %i, lock count: %u\r\n", filename, line, deep_sleep_lock);
156}
157
158#endif // MBED_SLEEP_TRACING_ENABLED
159
160void sleep_manager_lock_deep_sleep_internal(void)
161{
162 core_util_critical_section_enter();
163 if (deep_sleep_lock == USHRT_MAX) {
164 core_util_critical_section_exit();
165 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_HAL, MBED_ERROR_CODE_OVERFLOW), "DeepSleepLock overflow (> USHRT_MAX)", deep_sleep_lock);
166 }
167 core_util_atomic_incr_u16(&deep_sleep_lock, 1);
168 core_util_critical_section_exit();
169}
170
171void sleep_manager_unlock_deep_sleep_internal(void)
172{
173 core_util_critical_section_enter();
174 if (deep_sleep_lock == 0) {
175 core_util_critical_section_exit();
176 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_HAL, MBED_ERROR_CODE_UNDERFLOW), "DeepSleepLock underflow (< 0)", deep_sleep_lock);
177 }
178 core_util_atomic_decr_u16(&deep_sleep_lock, 1);
179 core_util_critical_section_exit();
180}
181
182bool sleep_manager_can_deep_sleep(void)
183{
184 return deep_sleep_lock == 0 ? true : false;
185}
186
187bool sleep_manager_can_deep_sleep_test_check()
188{
189 const uint32_t check_time_us = 2000;
190 const ticker_data_t *const ticker = get_us_ticker_data();
191 uint32_t start = ticker_read(ticker);
192 while ((ticker_read(ticker) - start) < check_time_us) {
193 if (sleep_manager_can_deep_sleep()) {
194 return true;
195 }
196 }
197 return false;
198}
199
200void sleep_manager_sleep_auto(void)
201{
202#ifdef MBED_SLEEP_TRACING_ENABLED
203 sleep_tracker_print_stats();
204#endif
205 core_util_critical_section_enter();
206 us_timestamp_t start = read_us();
207 bool deep = false;
208
209// debug profile should keep debuggers attached, no deep sleep allowed
210#ifdef MBED_DEBUG
211 hal_sleep();
212#else
213 if (sleep_manager_can_deep_sleep()) {
214 deep = true;
215 hal_deepsleep();
216 } else {
217 hal_sleep();
218 }
219#endif
220
221 us_timestamp_t end = read_us();
222 if (true == deep) {
223 deep_sleep_time += end - start;
224 } else {
225 sleep_time += end - start;
226 }
227 core_util_critical_section_exit();
228}
229
230#else
231
232// locking is valid only if DEVICE_SLEEP is defined
233// we provide empty implementation
234
235void sleep_manager_lock_deep_sleep_internal(void)
236{
237
238}
239
240void sleep_manager_unlock_deep_sleep_internal(void)
241{
242
243}
244
245bool sleep_manager_can_deep_sleep(void)
246{
247 // no sleep implemented
248 return false;
249}
250
251#endif
Note: See TracBrowser for help on using the repository browser.