Erste version der Software für der Prototyp

Committer:
borlanic
Date:
Fri Mar 30 14:07:05 2018 +0000
Revision:
4:75df35ef4fb6
Parent:
0:380207fcb5c1
commentar

Who changed what in which revision?

UserRevisionLine numberNew contents of line
borlanic 0:380207fcb5c1 1 /* mbed Microcontroller Library
borlanic 0:380207fcb5c1 2 * Copyright (c) 2017 ARM Limited
borlanic 0:380207fcb5c1 3 *
borlanic 0:380207fcb5c1 4 * Licensed under the Apache License, Version 2.0 (the "License");
borlanic 0:380207fcb5c1 5 * you may not use this file except in compliance with the License.
borlanic 0:380207fcb5c1 6 * You may obtain a copy of the License at
borlanic 0:380207fcb5c1 7 *
borlanic 0:380207fcb5c1 8 * http://www.apache.org/licenses/LICENSE-2.0
borlanic 0:380207fcb5c1 9 *
borlanic 0:380207fcb5c1 10 * Unless required by applicable law or agreed to in writing, software
borlanic 0:380207fcb5c1 11 * distributed under the License is distributed on an "AS IS" BASIS,
borlanic 0:380207fcb5c1 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
borlanic 0:380207fcb5c1 13 * See the License for the specific language governing permissions and
borlanic 0:380207fcb5c1 14 * limitations under the License.
borlanic 0:380207fcb5c1 15 */
borlanic 0:380207fcb5c1 16
borlanic 0:380207fcb5c1 17 #include "mbed_assert.h"
borlanic 0:380207fcb5c1 18 #include "mbed_power_mgmt.h"
borlanic 0:380207fcb5c1 19 #include "mbed_critical.h"
borlanic 0:380207fcb5c1 20 #include "sleep_api.h"
borlanic 0:380207fcb5c1 21 #include "mbed_error.h"
borlanic 0:380207fcb5c1 22 #include "mbed_debug.h"
borlanic 0:380207fcb5c1 23 #include <limits.h>
borlanic 0:380207fcb5c1 24 #include <stdio.h>
borlanic 0:380207fcb5c1 25
borlanic 0:380207fcb5c1 26 #if DEVICE_SLEEP
borlanic 0:380207fcb5c1 27
borlanic 0:380207fcb5c1 28 // deep sleep locking counter. A target is allowed to deep sleep if counter == 0
borlanic 0:380207fcb5c1 29 static uint16_t deep_sleep_lock = 0U;
borlanic 0:380207fcb5c1 30
borlanic 0:380207fcb5c1 31 #ifdef MBED_SLEEP_TRACING_ENABLED
borlanic 0:380207fcb5c1 32
borlanic 0:380207fcb5c1 33 // Number of drivers that can be stored in the structure
borlanic 0:380207fcb5c1 34 #define STATISTIC_COUNT 10
borlanic 0:380207fcb5c1 35
borlanic 0:380207fcb5c1 36 typedef struct sleep_statistic {
borlanic 0:380207fcb5c1 37 const char* identifier;
borlanic 0:380207fcb5c1 38 uint8_t count;
borlanic 0:380207fcb5c1 39 } sleep_statistic_t;
borlanic 0:380207fcb5c1 40
borlanic 0:380207fcb5c1 41 static sleep_statistic_t sleep_stats[STATISTIC_COUNT];
borlanic 0:380207fcb5c1 42
borlanic 0:380207fcb5c1 43 static sleep_statistic_t* sleep_tracker_find(const char *const filename)
borlanic 0:380207fcb5c1 44 {
borlanic 0:380207fcb5c1 45 for (int i = 0; i < STATISTIC_COUNT; ++i) {
borlanic 0:380207fcb5c1 46 if (sleep_stats[i].identifier == filename) {
borlanic 0:380207fcb5c1 47 return &sleep_stats[i];
borlanic 0:380207fcb5c1 48 }
borlanic 0:380207fcb5c1 49 }
borlanic 0:380207fcb5c1 50
borlanic 0:380207fcb5c1 51 return NULL;
borlanic 0:380207fcb5c1 52 }
borlanic 0:380207fcb5c1 53
borlanic 0:380207fcb5c1 54 static sleep_statistic_t* sleep_tracker_add(const char* const filename)
borlanic 0:380207fcb5c1 55 {
borlanic 0:380207fcb5c1 56 for (int i = 0; i < STATISTIC_COUNT; ++i) {
borlanic 0:380207fcb5c1 57 if (sleep_stats[i].identifier == NULL) {
borlanic 0:380207fcb5c1 58 sleep_stats[i].identifier = filename;
borlanic 0:380207fcb5c1 59
borlanic 0:380207fcb5c1 60 return &sleep_stats[i];
borlanic 0:380207fcb5c1 61 }
borlanic 0:380207fcb5c1 62 }
borlanic 0:380207fcb5c1 63
borlanic 0:380207fcb5c1 64 debug("No free indexes left to use in mbed sleep tracker.\r\n");
borlanic 0:380207fcb5c1 65
borlanic 0:380207fcb5c1 66 return NULL;
borlanic 0:380207fcb5c1 67 }
borlanic 0:380207fcb5c1 68
borlanic 0:380207fcb5c1 69 static void sleep_tracker_print_stats(void)
borlanic 0:380207fcb5c1 70 {
borlanic 0:380207fcb5c1 71 debug("Sleep locks held:\r\n");
borlanic 0:380207fcb5c1 72 for (int i = 0; i < STATISTIC_COUNT; ++i) {
borlanic 0:380207fcb5c1 73 if (sleep_stats[i].count == 0) {
borlanic 0:380207fcb5c1 74 continue;
borlanic 0:380207fcb5c1 75 }
borlanic 0:380207fcb5c1 76
borlanic 0:380207fcb5c1 77 if (sleep_stats[i].identifier == NULL) {
borlanic 0:380207fcb5c1 78 return;
borlanic 0:380207fcb5c1 79 }
borlanic 0:380207fcb5c1 80
borlanic 0:380207fcb5c1 81 debug("[id: %s, count: %u]\r\n", sleep_stats[i].identifier,
borlanic 0:380207fcb5c1 82 sleep_stats[i].count);
borlanic 0:380207fcb5c1 83 }
borlanic 0:380207fcb5c1 84 }
borlanic 0:380207fcb5c1 85
borlanic 0:380207fcb5c1 86 void sleep_tracker_lock(const char* const filename, int line)
borlanic 0:380207fcb5c1 87 {
borlanic 0:380207fcb5c1 88 sleep_statistic_t *stat = sleep_tracker_find(filename);
borlanic 0:380207fcb5c1 89
borlanic 0:380207fcb5c1 90 // Entry for this driver does not exist, create one.
borlanic 0:380207fcb5c1 91 if (stat == NULL) {
borlanic 0:380207fcb5c1 92 stat = sleep_tracker_add(filename);
borlanic 0:380207fcb5c1 93 }
borlanic 0:380207fcb5c1 94
borlanic 0:380207fcb5c1 95 core_util_atomic_incr_u8(&stat->count, 1);
borlanic 0:380207fcb5c1 96
borlanic 0:380207fcb5c1 97 debug("LOCK: %s, ln: %i, lock count: %u\r\n", filename, line, deep_sleep_lock);
borlanic 0:380207fcb5c1 98 }
borlanic 0:380207fcb5c1 99
borlanic 0:380207fcb5c1 100 void sleep_tracker_unlock(const char* const filename, int line)
borlanic 0:380207fcb5c1 101 {
borlanic 0:380207fcb5c1 102 sleep_statistic_t *stat = sleep_tracker_find(filename);
borlanic 0:380207fcb5c1 103
borlanic 0:380207fcb5c1 104 // Entry for this driver does not exist, something went wrong.
borlanic 0:380207fcb5c1 105 if (stat == NULL) {
borlanic 0:380207fcb5c1 106 debug("Unlocking sleep for driver that was not previously locked: %s, ln: %i\r\n", filename, line);
borlanic 0:380207fcb5c1 107 return;
borlanic 0:380207fcb5c1 108 }
borlanic 0:380207fcb5c1 109
borlanic 0:380207fcb5c1 110 core_util_atomic_decr_u8(&stat->count, 1);
borlanic 0:380207fcb5c1 111
borlanic 0:380207fcb5c1 112 debug("UNLOCK: %s, ln: %i, lock count: %u\r\n", filename, line, deep_sleep_lock);
borlanic 0:380207fcb5c1 113 }
borlanic 0:380207fcb5c1 114
borlanic 0:380207fcb5c1 115 #endif // MBED_SLEEP_TRACING_ENABLED
borlanic 0:380207fcb5c1 116
borlanic 0:380207fcb5c1 117 void sleep_manager_lock_deep_sleep_internal(void)
borlanic 0:380207fcb5c1 118 {
borlanic 0:380207fcb5c1 119 core_util_critical_section_enter();
borlanic 0:380207fcb5c1 120 if (deep_sleep_lock == USHRT_MAX) {
borlanic 0:380207fcb5c1 121 core_util_critical_section_exit();
borlanic 0:380207fcb5c1 122 error("Deep sleep lock would overflow (> USHRT_MAX)");
borlanic 0:380207fcb5c1 123 }
borlanic 0:380207fcb5c1 124 core_util_atomic_incr_u16(&deep_sleep_lock, 1);
borlanic 0:380207fcb5c1 125 core_util_critical_section_exit();
borlanic 0:380207fcb5c1 126 }
borlanic 0:380207fcb5c1 127
borlanic 0:380207fcb5c1 128 void sleep_manager_unlock_deep_sleep_internal(void)
borlanic 0:380207fcb5c1 129 {
borlanic 0:380207fcb5c1 130 core_util_critical_section_enter();
borlanic 0:380207fcb5c1 131 if (deep_sleep_lock == 0) {
borlanic 0:380207fcb5c1 132 core_util_critical_section_exit();
borlanic 0:380207fcb5c1 133 error("Deep sleep lock would underflow (< 0)");
borlanic 0:380207fcb5c1 134 }
borlanic 0:380207fcb5c1 135 core_util_atomic_decr_u16(&deep_sleep_lock, 1);
borlanic 0:380207fcb5c1 136 core_util_critical_section_exit();
borlanic 0:380207fcb5c1 137 }
borlanic 0:380207fcb5c1 138
borlanic 0:380207fcb5c1 139 bool sleep_manager_can_deep_sleep(void)
borlanic 0:380207fcb5c1 140 {
borlanic 0:380207fcb5c1 141 return deep_sleep_lock == 0 ? true : false;
borlanic 0:380207fcb5c1 142 }
borlanic 0:380207fcb5c1 143
borlanic 0:380207fcb5c1 144 void sleep_manager_sleep_auto(void)
borlanic 0:380207fcb5c1 145 {
borlanic 0:380207fcb5c1 146 #ifdef MBED_SLEEP_TRACING_ENABLED
borlanic 0:380207fcb5c1 147 sleep_tracker_print_stats();
borlanic 0:380207fcb5c1 148 #endif
borlanic 0:380207fcb5c1 149 core_util_critical_section_enter();
borlanic 0:380207fcb5c1 150 // debug profile should keep debuggers attached, no deep sleep allowed
borlanic 0:380207fcb5c1 151 #ifdef MBED_DEBUG
borlanic 0:380207fcb5c1 152 hal_sleep();
borlanic 0:380207fcb5c1 153 #else
borlanic 0:380207fcb5c1 154 if (sleep_manager_can_deep_sleep()) {
borlanic 0:380207fcb5c1 155 hal_deepsleep();
borlanic 0:380207fcb5c1 156 } else {
borlanic 0:380207fcb5c1 157 hal_sleep();
borlanic 0:380207fcb5c1 158 }
borlanic 0:380207fcb5c1 159 #endif
borlanic 0:380207fcb5c1 160 core_util_critical_section_exit();
borlanic 0:380207fcb5c1 161 }
borlanic 0:380207fcb5c1 162
borlanic 0:380207fcb5c1 163 #else
borlanic 0:380207fcb5c1 164
borlanic 0:380207fcb5c1 165 // locking is valid only if DEVICE_SLEEP is defined
borlanic 0:380207fcb5c1 166 // we provide empty implementation
borlanic 0:380207fcb5c1 167
borlanic 0:380207fcb5c1 168 void sleep_manager_lock_deep_sleep_internal(void)
borlanic 0:380207fcb5c1 169 {
borlanic 0:380207fcb5c1 170
borlanic 0:380207fcb5c1 171 }
borlanic 0:380207fcb5c1 172
borlanic 0:380207fcb5c1 173 void sleep_manager_unlock_deep_sleep_internal(void)
borlanic 0:380207fcb5c1 174 {
borlanic 0:380207fcb5c1 175
borlanic 0:380207fcb5c1 176 }
borlanic 0:380207fcb5c1 177
borlanic 0:380207fcb5c1 178 bool sleep_manager_can_deep_sleep(void)
borlanic 0:380207fcb5c1 179 {
borlanic 0:380207fcb5c1 180 // no sleep implemented
borlanic 0:380207fcb5c1 181 return false;
borlanic 0:380207fcb5c1 182 }
borlanic 0:380207fcb5c1 183
borlanic 0:380207fcb5c1 184 #endif