Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

Committer:
switches
Date:
Fri Dec 16 16:27:57 2016 +0000
Revision:
3:1198227e6421
Parent:
0:5c4d7b2438d3
Changed ADC scale for MAX32625 platforms to 1.2V full scale to match MAX32630 platforms

Who changed what in which revision?

UserRevisionLine numberNew contents of line
switches 0:5c4d7b2438d3 1 /*
switches 0:5c4d7b2438d3 2 * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved
switches 0:5c4d7b2438d3 3 * SPDX-License-Identifier: Apache-2.0
switches 0:5c4d7b2438d3 4 *
switches 0:5c4d7b2438d3 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
switches 0:5c4d7b2438d3 6 * not use this file except in compliance with the License.
switches 0:5c4d7b2438d3 7 * You may obtain a copy of the License at
switches 0:5c4d7b2438d3 8 *
switches 0:5c4d7b2438d3 9 * http://www.apache.org/licenses/LICENSE-2.0
switches 0:5c4d7b2438d3 10 *
switches 0:5c4d7b2438d3 11 * Unless required by applicable law or agreed to in writing, software
switches 0:5c4d7b2438d3 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
switches 0:5c4d7b2438d3 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
switches 0:5c4d7b2438d3 14 * See the License for the specific language governing permissions and
switches 0:5c4d7b2438d3 15 * limitations under the License.
switches 0:5c4d7b2438d3 16 */
switches 0:5c4d7b2438d3 17
switches 0:5c4d7b2438d3 18 #include "mbed.h"
switches 0:5c4d7b2438d3 19 #include "rtos.h"
switches 0:5c4d7b2438d3 20 #include "mbed_stats.h"
switches 0:5c4d7b2438d3 21 #include "cmsis_os.h"
switches 0:5c4d7b2438d3 22 #include "greentea-client/test_env.h"
switches 0:5c4d7b2438d3 23 #include "greentea-client/greentea_metrics.h"
switches 0:5c4d7b2438d3 24 #include "SingletonPtr.h"
switches 0:5c4d7b2438d3 25 #include "CircularBuffer.h"
switches 0:5c4d7b2438d3 26
switches 0:5c4d7b2438d3 27 #define THREAD_BUF_COUNT 16
switches 0:5c4d7b2438d3 28
switches 0:5c4d7b2438d3 29 typedef struct {
switches 0:5c4d7b2438d3 30 uint32_t entry;
switches 0:5c4d7b2438d3 31 uint32_t arg;
switches 0:5c4d7b2438d3 32 uint32_t stack_size;
switches 0:5c4d7b2438d3 33 uint32_t max_stack;
switches 0:5c4d7b2438d3 34 } thread_info_t;
switches 0:5c4d7b2438d3 35
switches 0:5c4d7b2438d3 36 // Mutex to protect "buf"
switches 0:5c4d7b2438d3 37 SingletonPtr<Mutex> mutex;
switches 0:5c4d7b2438d3 38 #if defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED
switches 0:5c4d7b2438d3 39 static char buf[128];
switches 0:5c4d7b2438d3 40 static SingletonPtr<CircularBuffer<thread_info_t, THREAD_BUF_COUNT> > queue;
switches 0:5c4d7b2438d3 41 #endif
switches 0:5c4d7b2438d3 42
switches 0:5c4d7b2438d3 43 static void send_heap_info(void);
switches 0:5c4d7b2438d3 44 #if defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED
switches 0:5c4d7b2438d3 45 static void send_stack_info(void);
switches 0:5c4d7b2438d3 46 static void on_thread_terminate(osThreadId id);
switches 0:5c4d7b2438d3 47 static void enqeue_thread_info(osThreadId id);
switches 0:5c4d7b2438d3 48 static void deque_and_print_thread_info(void);
switches 0:5c4d7b2438d3 49
switches 0:5c4d7b2438d3 50 // sprintf uses a lot of stack so use these instead
switches 0:5c4d7b2438d3 51 static uint32_t print_hex(char *buf, uint32_t value);
switches 0:5c4d7b2438d3 52 static uint32_t print_dec(char *buf, uint32_t value);
switches 0:5c4d7b2438d3 53 #endif
switches 0:5c4d7b2438d3 54
switches 0:5c4d7b2438d3 55 void greentea_metrics_setup()
switches 0:5c4d7b2438d3 56 {
switches 0:5c4d7b2438d3 57 #if defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED
switches 0:5c4d7b2438d3 58 Thread::attach_terminate_hook(on_thread_terminate);
switches 0:5c4d7b2438d3 59 #endif
switches 0:5c4d7b2438d3 60 }
switches 0:5c4d7b2438d3 61
switches 0:5c4d7b2438d3 62 void greentea_metrics_report()
switches 0:5c4d7b2438d3 63 {
switches 0:5c4d7b2438d3 64 send_heap_info();
switches 0:5c4d7b2438d3 65 #if defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED
switches 0:5c4d7b2438d3 66 send_stack_info();
switches 0:5c4d7b2438d3 67 Thread::attach_terminate_hook(NULL);
switches 0:5c4d7b2438d3 68 #endif
switches 0:5c4d7b2438d3 69 }
switches 0:5c4d7b2438d3 70
switches 0:5c4d7b2438d3 71 static void send_heap_info()
switches 0:5c4d7b2438d3 72 {
switches 0:5c4d7b2438d3 73 mbed_stats_heap_t heap_stats;
switches 0:5c4d7b2438d3 74 mbed_stats_heap_get(&heap_stats);
switches 0:5c4d7b2438d3 75 greentea_send_kv("max_heap_usage",heap_stats.max_size);
switches 0:5c4d7b2438d3 76 }
switches 0:5c4d7b2438d3 77
switches 0:5c4d7b2438d3 78 #if defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED
switches 0:5c4d7b2438d3 79 MBED_UNUSED static void send_stack_info()
switches 0:5c4d7b2438d3 80 {
switches 0:5c4d7b2438d3 81 mutex->lock();
switches 0:5c4d7b2438d3 82
switches 0:5c4d7b2438d3 83 // Flush any queued stack entries
switches 0:5c4d7b2438d3 84 while (!queue->empty()) {
switches 0:5c4d7b2438d3 85 deque_and_print_thread_info();
switches 0:5c4d7b2438d3 86 }
switches 0:5c4d7b2438d3 87
switches 0:5c4d7b2438d3 88 // Print info for all other threads
switches 0:5c4d7b2438d3 89 osThreadEnumId enum_id = _osThreadsEnumStart();
switches 0:5c4d7b2438d3 90 while (true) {
switches 0:5c4d7b2438d3 91 osThreadId thread_id = _osThreadEnumNext(enum_id);
switches 0:5c4d7b2438d3 92 if (NULL == thread_id) {
switches 0:5c4d7b2438d3 93 // End of enumeration
switches 0:5c4d7b2438d3 94 break;
switches 0:5c4d7b2438d3 95 }
switches 0:5c4d7b2438d3 96 enqeue_thread_info(thread_id);
switches 0:5c4d7b2438d3 97 deque_and_print_thread_info();
switches 0:5c4d7b2438d3 98 }
switches 0:5c4d7b2438d3 99 _osThreadEnumFree(enum_id);
switches 0:5c4d7b2438d3 100
switches 0:5c4d7b2438d3 101 mutex->unlock();
switches 0:5c4d7b2438d3 102 }
switches 0:5c4d7b2438d3 103
switches 0:5c4d7b2438d3 104 MBED_UNUSED static void on_thread_terminate(osThreadId id)
switches 0:5c4d7b2438d3 105 {
switches 0:5c4d7b2438d3 106 mutex->lock();
switches 0:5c4d7b2438d3 107
switches 0:5c4d7b2438d3 108 // There should always be space in the queue
switches 0:5c4d7b2438d3 109 enqeue_thread_info(id);
switches 0:5c4d7b2438d3 110
switches 0:5c4d7b2438d3 111 // If queue is full then print out a single entry
switches 0:5c4d7b2438d3 112 if (queue->full()) {
switches 0:5c4d7b2438d3 113 deque_and_print_thread_info();
switches 0:5c4d7b2438d3 114 }
switches 0:5c4d7b2438d3 115
switches 0:5c4d7b2438d3 116 mutex->unlock();
switches 0:5c4d7b2438d3 117 }
switches 0:5c4d7b2438d3 118
switches 0:5c4d7b2438d3 119 static void enqeue_thread_info(osThreadId id)
switches 0:5c4d7b2438d3 120 {
switches 0:5c4d7b2438d3 121 osEvent info;
switches 0:5c4d7b2438d3 122 thread_info_t thread_info = {};
switches 0:5c4d7b2438d3 123 info = _osThreadGetInfo(id, osThreadInfoEntry);
switches 0:5c4d7b2438d3 124 if (info.status != osOK) {
switches 0:5c4d7b2438d3 125 return;
switches 0:5c4d7b2438d3 126 }
switches 0:5c4d7b2438d3 127 thread_info.entry = (uint32_t)info.value.p;
switches 0:5c4d7b2438d3 128 info = _osThreadGetInfo(id, osThreadInfoArg);
switches 0:5c4d7b2438d3 129 if (info.status != osOK) {
switches 0:5c4d7b2438d3 130 return;
switches 0:5c4d7b2438d3 131 }
switches 0:5c4d7b2438d3 132 thread_info.arg = (uint32_t)info.value.p;
switches 0:5c4d7b2438d3 133 info = _osThreadGetInfo(id, osThreadInfoStackSize);
switches 0:5c4d7b2438d3 134 if (info.status != osOK) {
switches 0:5c4d7b2438d3 135 return;
switches 0:5c4d7b2438d3 136 }
switches 0:5c4d7b2438d3 137 thread_info.stack_size = (uint32_t)info.value.v;
switches 0:5c4d7b2438d3 138 info = _osThreadGetInfo(id, osThreadInfoStackMax);
switches 0:5c4d7b2438d3 139 if (info.status != osOK) {
switches 0:5c4d7b2438d3 140 return;
switches 0:5c4d7b2438d3 141 }
switches 0:5c4d7b2438d3 142 thread_info.max_stack = (uint32_t)info.value.v;
switches 0:5c4d7b2438d3 143 queue->push(thread_info);
switches 0:5c4d7b2438d3 144 }
switches 0:5c4d7b2438d3 145
switches 0:5c4d7b2438d3 146 static void deque_and_print_thread_info()
switches 0:5c4d7b2438d3 147 {
switches 0:5c4d7b2438d3 148 thread_info_t thread_info;
switches 0:5c4d7b2438d3 149 bool ret = queue->pop(thread_info);
switches 0:5c4d7b2438d3 150 MBED_ASSERT(ret);
switches 0:5c4d7b2438d3 151 uint32_t pos = 0;
switches 0:5c4d7b2438d3 152 buf[pos++] = '\"';
switches 0:5c4d7b2438d3 153 pos += print_hex(buf + pos, thread_info.entry);
switches 0:5c4d7b2438d3 154 buf[pos++] = '-';
switches 0:5c4d7b2438d3 155 pos += print_hex(buf + pos, thread_info.arg);
switches 0:5c4d7b2438d3 156 buf[pos++] = '\"';
switches 0:5c4d7b2438d3 157 buf[pos++] = ',';
switches 0:5c4d7b2438d3 158 pos += print_dec(buf + pos, thread_info.max_stack);
switches 0:5c4d7b2438d3 159 buf[pos++] = ',';
switches 0:5c4d7b2438d3 160 pos += print_dec(buf + pos, thread_info.stack_size);
switches 0:5c4d7b2438d3 161 buf[pos++] = 0;
switches 0:5c4d7b2438d3 162 greentea_send_kv("__thread_info", buf);
switches 0:5c4d7b2438d3 163 }
switches 0:5c4d7b2438d3 164
switches 0:5c4d7b2438d3 165 static uint32_t print_hex(char *buf, uint32_t value)
switches 0:5c4d7b2438d3 166 {
switches 0:5c4d7b2438d3 167 uint32_t pos = 0;
switches 0:5c4d7b2438d3 168 buf[pos] = '0';
switches 0:5c4d7b2438d3 169 pos++;
switches 0:5c4d7b2438d3 170 buf[pos] = 'x';
switches 0:5c4d7b2438d3 171 pos++;
switches 0:5c4d7b2438d3 172 for (int i = 8; i >= 0; i--) {
switches 0:5c4d7b2438d3 173 uint32_t val = (value >> (4 * i)) & 0xF;
switches 0:5c4d7b2438d3 174 if (val <= 9) {
switches 0:5c4d7b2438d3 175 buf[pos] = '0' + val;
switches 0:5c4d7b2438d3 176 pos++;
switches 0:5c4d7b2438d3 177 } else {
switches 0:5c4d7b2438d3 178 buf[pos] = 'a' + val - 10;
switches 0:5c4d7b2438d3 179 pos++;
switches 0:5c4d7b2438d3 180 }
switches 0:5c4d7b2438d3 181 }
switches 0:5c4d7b2438d3 182 return pos;
switches 0:5c4d7b2438d3 183 }
switches 0:5c4d7b2438d3 184
switches 0:5c4d7b2438d3 185 static uint32_t print_dec(char *buf, uint32_t value)
switches 0:5c4d7b2438d3 186 {
switches 0:5c4d7b2438d3 187 uint32_t pos = 0;
switches 0:5c4d7b2438d3 188
switches 0:5c4d7b2438d3 189 // The value 0 is special case
switches 0:5c4d7b2438d3 190 if (0 == value) {
switches 0:5c4d7b2438d3 191 buf[pos] = '0';
switches 0:5c4d7b2438d3 192 pos++;
switches 0:5c4d7b2438d3 193 return pos;
switches 0:5c4d7b2438d3 194 }
switches 0:5c4d7b2438d3 195
switches 0:5c4d7b2438d3 196 // Write out value in reverse order
switches 0:5c4d7b2438d3 197 while (value != 0) {
switches 0:5c4d7b2438d3 198 uint32_t next = value / 10;
switches 0:5c4d7b2438d3 199 buf[pos] = '0' + (value - next * 10);
switches 0:5c4d7b2438d3 200 value = next;
switches 0:5c4d7b2438d3 201 pos++;
switches 0:5c4d7b2438d3 202 }
switches 0:5c4d7b2438d3 203
switches 0:5c4d7b2438d3 204 // Reverse order
switches 0:5c4d7b2438d3 205 for (uint32_t i = 0; i < pos / 2; i++) {
switches 0:5c4d7b2438d3 206 char temp = buf[i];
switches 0:5c4d7b2438d3 207 buf[i] = buf[pos - 1 - i];
switches 0:5c4d7b2438d3 208 buf[pos - 1 - i] = temp;
switches 0:5c4d7b2438d3 209 }
switches 0:5c4d7b2438d3 210
switches 0:5c4d7b2438d3 211 return pos;
switches 0:5c4d7b2438d3 212 }
switches 0:5c4d7b2438d3 213
switches 0:5c4d7b2438d3 214 #endif