mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Revision:
184:08ed48f1de7f
Parent:
174:b96e65c34a4d
Child:
186:707f6e361f3e
--- a/hal/mbed_sleep_manager.c	Tue Mar 20 17:01:51 2018 +0000
+++ b/hal/mbed_sleep_manager.c	Thu Apr 19 17:12:19 2018 +0100
@@ -14,18 +14,107 @@
  * limitations under the License.
  */
 
-#include "mbed_sleep.h"
+#include "mbed_assert.h"
+#include "mbed_power_mgmt.h"
 #include "mbed_critical.h"
 #include "sleep_api.h"
 #include "mbed_error.h"
+#include "mbed_debug.h"
 #include <limits.h>
+#include <stdio.h>
 
 #if DEVICE_SLEEP
 
 // deep sleep locking counter. A target is allowed to deep sleep if counter == 0
 static uint16_t deep_sleep_lock = 0U;
 
-void sleep_manager_lock_deep_sleep(void)
+#ifdef MBED_SLEEP_TRACING_ENABLED
+
+// Number of drivers that can be stored in the structure
+#define STATISTIC_COUNT  10
+
+typedef struct sleep_statistic {
+    const char* identifier;
+    uint8_t count;
+} sleep_statistic_t;
+
+static sleep_statistic_t sleep_stats[STATISTIC_COUNT];
+
+static sleep_statistic_t* sleep_tracker_find(const char *const filename)
+{
+    for (int i = 0; i < STATISTIC_COUNT; ++i) {
+        if (sleep_stats[i].identifier == filename) {
+            return &sleep_stats[i];
+        }
+    }
+
+    return NULL;
+}
+
+static sleep_statistic_t* sleep_tracker_add(const char* const filename)
+{
+    for (int i = 0; i < STATISTIC_COUNT; ++i) {
+        if (sleep_stats[i].identifier == NULL) {
+            sleep_stats[i].identifier = filename;
+
+            return &sleep_stats[i];
+        }
+    }
+
+    debug("No free indexes left to use in mbed sleep tracker.\r\n");
+
+    return NULL;
+}
+
+static void sleep_tracker_print_stats(void)
+{
+    debug("Sleep locks held:\r\n");
+    for (int i = 0; i < STATISTIC_COUNT; ++i) {
+        if (sleep_stats[i].count == 0) {
+            continue;
+        }
+
+        if (sleep_stats[i].identifier == NULL) {
+            return;
+        }
+
+        debug("[id: %s, count: %u]\r\n", sleep_stats[i].identifier,
+                                         sleep_stats[i].count);
+    }
+}
+
+void sleep_tracker_lock(const char* const filename, int line)
+{
+    sleep_statistic_t *stat = sleep_tracker_find(filename);
+
+    // Entry for this driver does not exist, create one.
+    if (stat == NULL) {
+        stat = sleep_tracker_add(filename);
+    }
+
+    core_util_atomic_incr_u8(&stat->count, 1);
+
+    debug("LOCK: %s, ln: %i, lock count: %u\r\n", filename, line, deep_sleep_lock);
+}
+
+void sleep_tracker_unlock(const char* const filename, int line)
+{
+    sleep_statistic_t *stat = sleep_tracker_find(filename);
+
+    // Entry for this driver does not exist, something went wrong.
+    if (stat == NULL) {
+        debug("Unlocking sleep for driver that was not previously locked: %s, ln: %i\r\n", filename, line);
+        return;
+    }
+
+    core_util_atomic_decr_u8(&stat->count, 1);
+
+    debug("UNLOCK: %s, ln: %i, lock count: %u\r\n", filename, line, deep_sleep_lock);
+}
+
+#endif // MBED_SLEEP_TRACING_ENABLED
+
+void sleep_manager_lock_deep_sleep_internal(void)
 {
     core_util_critical_section_enter();
     if (deep_sleep_lock == USHRT_MAX) {
@@ -36,7 +125,7 @@
     core_util_critical_section_exit();
 }
 
-void sleep_manager_unlock_deep_sleep(void)
+void sleep_manager_unlock_deep_sleep_internal(void)
 {
     core_util_critical_section_enter();
     if (deep_sleep_lock == 0) {
@@ -54,6 +143,9 @@
 
 void sleep_manager_sleep_auto(void)
 {
+#ifdef MBED_SLEEP_TRACING_ENABLED
+    sleep_tracker_print_stats();
+#endif
     core_util_critical_section_enter();
 // debug profile should keep debuggers attached, no deep sleep allowed
 #ifdef MBED_DEBUG
@@ -73,12 +165,12 @@
 // locking is valid only if DEVICE_SLEEP is defined
 // we provide empty implementation
 
-void sleep_manager_lock_deep_sleep(void)
+void sleep_manager_lock_deep_sleep_internal(void)
 {
 
 }
 
-void sleep_manager_unlock_deep_sleep(void)
+void sleep_manager_unlock_deep_sleep_internal(void)
 {
 
 }