this is using the mbed os version 5-13-1

Dependencies:   mbed-http

Committer:
ocomeni
Date:
Sat Apr 13 14:17:29 2019 +0000
Revision:
92:ec9550034276
Child:
103:7b566b522427
implemented DEFINE switch to resolve mbed memory pool allocation failure

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ocomeni 92:ec9550034276 1 /*
ocomeni 92:ec9550034276 2 mbed Memory Status Helper
ocomeni 92:ec9550034276 3 Copyright (c) 2017 Max Vilimpoc
ocomeni 92:ec9550034276 4
ocomeni 92:ec9550034276 5 Permission is hereby granted, free of charge, to any person obtaining a copy
ocomeni 92:ec9550034276 6 of this software and associated documentation files (the "Software"), to deal
ocomeni 92:ec9550034276 7 in the Software without restriction, including without limitation the rights
ocomeni 92:ec9550034276 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
ocomeni 92:ec9550034276 9 copies of the Software, and to permit persons to whom the Software is
ocomeni 92:ec9550034276 10 furnished to do so, subject to the following conditions:
ocomeni 92:ec9550034276 11
ocomeni 92:ec9550034276 12 The above copyright notice and this permission notice shall be included in
ocomeni 92:ec9550034276 13 all copies or substantial portions of the Software.
ocomeni 92:ec9550034276 14
ocomeni 92:ec9550034276 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
ocomeni 92:ec9550034276 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
ocomeni 92:ec9550034276 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
ocomeni 92:ec9550034276 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
ocomeni 92:ec9550034276 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
ocomeni 92:ec9550034276 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
ocomeni 92:ec9550034276 21 THE SOFTWARE.
ocomeni 92:ec9550034276 22 */
ocomeni 92:ec9550034276 23
ocomeni 92:ec9550034276 24 /**
ocomeni 92:ec9550034276 25 * Purpose: Print out thread info and other useful details using
ocomeni 92:ec9550034276 26 * only raw serial access.
ocomeni 92:ec9550034276 27 *
ocomeni 92:ec9550034276 28 * Based on mbed_board.c's error printing functionality, minus
ocomeni 92:ec9550034276 29 * pulling in all the printf() code.
ocomeni 92:ec9550034276 30 */
ocomeni 92:ec9550034276 31
ocomeni 92:ec9550034276 32 // Not great having to pull in all of mbed.h just to get the MBED_VERSION macro,
ocomeni 92:ec9550034276 33 // but it's the only way to do it for both pre- and post-5.4 releases
ocomeni 92:ec9550034276 34 //
ocomeni 92:ec9550034276 35 // If you're only supporting something newer than 5.4, you could use this alone:
ocomeni 92:ec9550034276 36 // #include "platform/mbed_version.h"
ocomeni 92:ec9550034276 37 //
ocomeni 92:ec9550034276 38 // platform/mbed_version.h says:
ocomeni 92:ec9550034276 39 // 999999 is default value for development version (master branch)
ocomeni 92:ec9550034276 40
ocomeni 92:ec9550034276 41 #include "mbed.h"
ocomeni 92:ec9550034276 42
ocomeni 92:ec9550034276 43 // Critical sections header file renamed in mbed OS 5.4 release
ocomeni 92:ec9550034276 44 // See: https://github.com/ARMmbed/mbed-os/commit/aff49d8d1e3b5d4dc18286b0510336c36ae9603c
ocomeni 92:ec9550034276 45
ocomeni 92:ec9550034276 46 #ifndef MBED_VERSION
ocomeni 92:ec9550034276 47 #warning "You're probably using an unsupported version of mbed older than 5.2."
ocomeni 92:ec9550034276 48 #endif
ocomeni 92:ec9550034276 49
ocomeni 92:ec9550034276 50 #if MBED_VERSION >= 50400
ocomeni 92:ec9550034276 51 #include "platform/mbed_critical.h"
ocomeni 92:ec9550034276 52 #elif MBED_VERSION >= 50200
ocomeni 92:ec9550034276 53 #include "platform/critical.h"
ocomeni 92:ec9550034276 54 #endif
ocomeni 92:ec9550034276 55
ocomeni 92:ec9550034276 56 #include "platform/mbed_stats.h"
ocomeni 92:ec9550034276 57
ocomeni 92:ec9550034276 58 #if !MBED_STACK_STATS_ENABLED
ocomeni 92:ec9550034276 59 #warning MBED_STACK_STATS_ENABLED != 1, so there will be no stack usage measurements.
ocomeni 92:ec9550034276 60 #endif
ocomeni 92:ec9550034276 61
ocomeni 92:ec9550034276 62 #ifndef DEBUG_ISR_STACK_USAGE
ocomeni 92:ec9550034276 63 #define DEBUG_ISR_STACK_USAGE 0
ocomeni 92:ec9550034276 64 #endif
ocomeni 92:ec9550034276 65
ocomeni 92:ec9550034276 66 #ifndef DEBUG_MEMORY_CONTENTS
ocomeni 92:ec9550034276 67 #define DEBUG_MEMORY_CONTENTS 0
ocomeni 92:ec9550034276 68 #endif
ocomeni 92:ec9550034276 69
ocomeni 92:ec9550034276 70 #define OUTPUT_SERIAL 1
ocomeni 92:ec9550034276 71 #define OUTPUT_RTT 0
ocomeni 92:ec9550034276 72 #define OUTPUT_SWO 0
ocomeni 92:ec9550034276 73
ocomeni 92:ec9550034276 74 #if DEBUG_ISR_STACK_USAGE
ocomeni 92:ec9550034276 75 #include "compiler_abstraction.h"
ocomeni 92:ec9550034276 76
ocomeni 92:ec9550034276 77 // Value is sprayed into all of the ISR stack at boot time.
ocomeni 92:ec9550034276 78 static const uint32_t ISR_STACK_CANARY = 0xAFFEC7ED; // AFFECTED
ocomeni 92:ec9550034276 79
ocomeni 92:ec9550034276 80 // Refers to linker script defined symbol, may not be available
ocomeni 92:ec9550034276 81 // on all platforms.
ocomeni 92:ec9550034276 82 extern uint32_t __StackLimit;
ocomeni 92:ec9550034276 83 extern uint32_t __StackTop;
ocomeni 92:ec9550034276 84
ocomeni 92:ec9550034276 85 void fill_isr_stack_with_canary(void)
ocomeni 92:ec9550034276 86 {
ocomeni 92:ec9550034276 87 uint32_t * bottom = &__StackLimit;
ocomeni 92:ec9550034276 88 uint32_t * top = (uint32_t *) GET_SP();
ocomeni 92:ec9550034276 89
ocomeni 92:ec9550034276 90 for (; bottom < top; bottom++)
ocomeni 92:ec9550034276 91 {
ocomeni 92:ec9550034276 92 *bottom = ISR_STACK_CANARY;
ocomeni 92:ec9550034276 93 }
ocomeni 92:ec9550034276 94 }
ocomeni 92:ec9550034276 95 #endif // DEBUG_ISR_STACK_USAGE
ocomeni 92:ec9550034276 96
ocomeni 92:ec9550034276 97 #if OUTPUT_SERIAL && DEVICE_SERIAL
ocomeni 92:ec9550034276 98 #include "hal/serial_api.h"
ocomeni 92:ec9550034276 99
ocomeni 92:ec9550034276 100 extern int stdio_uart_inited;
ocomeni 92:ec9550034276 101 extern serial_t stdio_uart;
ocomeni 92:ec9550034276 102
ocomeni 92:ec9550034276 103 static void output_serial_init(void)
ocomeni 92:ec9550034276 104 {
ocomeni 92:ec9550034276 105 if (!stdio_uart_inited)
ocomeni 92:ec9550034276 106 {
ocomeni 92:ec9550034276 107 serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX);
ocomeni 92:ec9550034276 108 serial_baud(&stdio_uart, 115200); // This is hard coded.
ocomeni 92:ec9550034276 109 }
ocomeni 92:ec9550034276 110 }
ocomeni 92:ec9550034276 111
ocomeni 92:ec9550034276 112 static void output_serial_print_label(const char * label)
ocomeni 92:ec9550034276 113 {
ocomeni 92:ec9550034276 114 #if MBED_VERSION < 50902
ocomeni 92:ec9550034276 115 // After mbed OS 5.9.2, this locks up the system.
ocomeni 92:ec9550034276 116 core_util_critical_section_enter();
ocomeni 92:ec9550034276 117 #endif
ocomeni 92:ec9550034276 118
ocomeni 92:ec9550034276 119 output_serial_init();
ocomeni 92:ec9550034276 120
ocomeni 92:ec9550034276 121 while (*label) serial_putc(&stdio_uart, *label++);
ocomeni 92:ec9550034276 122
ocomeni 92:ec9550034276 123 #if MBED_VERSION < 50902
ocomeni 92:ec9550034276 124 core_util_critical_section_exit();
ocomeni 92:ec9550034276 125 #endif
ocomeni 92:ec9550034276 126 }
ocomeni 92:ec9550034276 127 #endif // OUTPUT_SERIAL && DEVICE_SERIAL
ocomeni 92:ec9550034276 128
ocomeni 92:ec9550034276 129 #if OUTPUT_RTT
ocomeni 92:ec9550034276 130 #include "RTT/SEGGER_RTT.h"
ocomeni 92:ec9550034276 131
ocomeni 92:ec9550034276 132 enum
ocomeni 92:ec9550034276 133 {
ocomeni 92:ec9550034276 134 DEFAULT_RTT_UP_BUFFER = 0
ocomeni 92:ec9550034276 135 };
ocomeni 92:ec9550034276 136
ocomeni 92:ec9550034276 137 static void output_rtt_init(void)
ocomeni 92:ec9550034276 138 {
ocomeni 92:ec9550034276 139 static int initialized = 0;
ocomeni 92:ec9550034276 140
ocomeni 92:ec9550034276 141 if (!initialized)
ocomeni 92:ec9550034276 142 {
ocomeni 92:ec9550034276 143 SEGGER_RTT_ConfigUpBuffer(DEFAULT_RTT_UP_BUFFER, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_TRIM);
ocomeni 92:ec9550034276 144
ocomeni 92:ec9550034276 145 initialized = 1;
ocomeni 92:ec9550034276 146 }
ocomeni 92:ec9550034276 147 }
ocomeni 92:ec9550034276 148
ocomeni 92:ec9550034276 149 static void output_rtt_print_label(const char * label)
ocomeni 92:ec9550034276 150 {
ocomeni 92:ec9550034276 151 output_rtt_init();
ocomeni 92:ec9550034276 152 SEGGER_RTT_WriteString(DEFAULT_RTT_UP_BUFFER, label);
ocomeni 92:ec9550034276 153 }
ocomeni 92:ec9550034276 154 #endif // OUTPUT_RTT
ocomeni 92:ec9550034276 155
ocomeni 92:ec9550034276 156 #if OUTPUT_SWO
ocomeni 92:ec9550034276 157 #if defined (NRF52) && !defined (ENABLE_SWO)
ocomeni 92:ec9550034276 158 #error "You need to enable SWO using `-D ENABLE_SWO` on the mbed compile command line."
ocomeni 92:ec9550034276 159 #endif
ocomeni 92:ec9550034276 160
ocomeni 92:ec9550034276 161 #ifdef NRF52
ocomeni 92:ec9550034276 162 #include "nrf.h"
ocomeni 92:ec9550034276 163 #endif
ocomeni 92:ec9550034276 164
ocomeni 92:ec9550034276 165 static void output_swo_init(void)
ocomeni 92:ec9550034276 166 {
ocomeni 92:ec9550034276 167 static int initialized = 0;
ocomeni 92:ec9550034276 168
ocomeni 92:ec9550034276 169 if (!initialized)
ocomeni 92:ec9550034276 170 {
ocomeni 92:ec9550034276 171 NRF_CLOCK->TRACECONFIG = (NRF_CLOCK->TRACECONFIG & ~CLOCK_TRACECONFIG_TRACEPORTSPEED_Msk) |
ocomeni 92:ec9550034276 172 (CLOCK_TRACECONFIG_TRACEPORTSPEED_4MHz << CLOCK_TRACECONFIG_TRACEPORTSPEED_Pos);
ocomeni 92:ec9550034276 173
ocomeni 92:ec9550034276 174 ITM->TCR |= 1;
ocomeni 92:ec9550034276 175 ITM->TER |= 1;
ocomeni 92:ec9550034276 176
ocomeni 92:ec9550034276 177 initialized = 1;
ocomeni 92:ec9550034276 178 }
ocomeni 92:ec9550034276 179 }
ocomeni 92:ec9550034276 180
ocomeni 92:ec9550034276 181 static void output_swo_print_label(const char * label)
ocomeni 92:ec9550034276 182 {
ocomeni 92:ec9550034276 183 output_swo_init();
ocomeni 92:ec9550034276 184 while (*label) ITM_SendChar(*label++);
ocomeni 92:ec9550034276 185 }
ocomeni 92:ec9550034276 186 #endif // OUTPUT_SWO
ocomeni 92:ec9550034276 187
ocomeni 92:ec9550034276 188 static void nway_print_label(const char * label)
ocomeni 92:ec9550034276 189 {
ocomeni 92:ec9550034276 190 #if OUTPUT_SERIAL
ocomeni 92:ec9550034276 191 output_serial_print_label(label);
ocomeni 92:ec9550034276 192 #endif
ocomeni 92:ec9550034276 193
ocomeni 92:ec9550034276 194 #if OUTPUT_RTT
ocomeni 92:ec9550034276 195 output_rtt_print_label(label);
ocomeni 92:ec9550034276 196 #endif
ocomeni 92:ec9550034276 197
ocomeni 92:ec9550034276 198 #if OUTPUT_SWO
ocomeni 92:ec9550034276 199 output_swo_print_label(label);
ocomeni 92:ec9550034276 200 #endif
ocomeni 92:ec9550034276 201 }
ocomeni 92:ec9550034276 202
ocomeni 92:ec9550034276 203 static const char HEX[] = "0123456789ABCDEF";
ocomeni 92:ec9550034276 204
ocomeni 92:ec9550034276 205 static void debug_print_u32(uint32_t u32)
ocomeni 92:ec9550034276 206 {
ocomeni 92:ec9550034276 207 char output[9] = {0};
ocomeni 92:ec9550034276 208
ocomeni 92:ec9550034276 209 // Always printed as big endian.
ocomeni 92:ec9550034276 210 output[0] = HEX[(((uint32_t) u32 & 0xf0000000) >> 28)];
ocomeni 92:ec9550034276 211 output[1] = HEX[(((uint32_t) u32 & 0x0f000000) >> 24)];
ocomeni 92:ec9550034276 212 output[2] = HEX[(((uint32_t) u32 & 0x00f00000) >> 20)];
ocomeni 92:ec9550034276 213 output[3] = HEX[(((uint32_t) u32 & 0x000f0000) >> 16)];
ocomeni 92:ec9550034276 214 output[4] = HEX[(((uint32_t) u32 & 0x0000f000) >> 12)];
ocomeni 92:ec9550034276 215 output[5] = HEX[(((uint32_t) u32 & 0x00000f00) >> 8)];
ocomeni 92:ec9550034276 216 output[6] = HEX[(((uint32_t) u32 & 0x000000f0) >> 4)];
ocomeni 92:ec9550034276 217 output[7] = HEX[(((uint32_t) u32 & 0x0000000f) >> 0)];
ocomeni 92:ec9550034276 218
ocomeni 92:ec9550034276 219 nway_print_label(output);
ocomeni 92:ec9550034276 220 }
ocomeni 92:ec9550034276 221
ocomeni 92:ec9550034276 222 static void debug_print_pointer(const void * pointer)
ocomeni 92:ec9550034276 223 {
ocomeni 92:ec9550034276 224 debug_print_u32((uint32_t) pointer);
ocomeni 92:ec9550034276 225 }
ocomeni 92:ec9550034276 226
ocomeni 92:ec9550034276 227 #define DPL(X) nway_print_label((X))
ocomeni 92:ec9550034276 228
ocomeni 92:ec9550034276 229 #if (defined (MBED_CONF_RTOS_PRESENT) && (MBED_CONF_RTOS_PRESENT != 0))
ocomeni 92:ec9550034276 230 #include "cmsis_os.h"
ocomeni 92:ec9550034276 231
ocomeni 92:ec9550034276 232 // cmsis_os.h provides some useful defines:
ocomeni 92:ec9550034276 233 //
ocomeni 92:ec9550034276 234 // For mbed OS 5.4 and lower, osCMSIS == 0x10002U (see: rtos/rtx/TARGET_CORTEX_M)
ocomeni 92:ec9550034276 235 // For mbed OS 5.5 and higher, osCMSIS == 0x20001U (see: rtos/TARGET_CORTEX/rtx{4|5})
ocomeni 92:ec9550034276 236 //
ocomeni 92:ec9550034276 237 // Starting in mbed OS 5.5, a new RTOS layer was introduced with a different API.
ocomeni 92:ec9550034276 238
ocomeni 92:ec9550034276 239 #if (osCMSIS < 0x20000U)
ocomeni 92:ec9550034276 240 // Temporarily #undef NULL or the compiler complains about previous def.
ocomeni 92:ec9550034276 241 #undef NULL
ocomeni 92:ec9550034276 242 #include "rt_TypeDef.h"
ocomeni 92:ec9550034276 243 #else
ocomeni 92:ec9550034276 244 #include "rtx_lib.h"
ocomeni 92:ec9550034276 245 // #include <stdlib.h> // Include if you need malloc() / free() below. (probably better for non-C99 compilers)
ocomeni 92:ec9550034276 246 #endif
ocomeni 92:ec9550034276 247
ocomeni 92:ec9550034276 248 #if (osCMSIS < 0x20000U)
ocomeni 92:ec9550034276 249
ocomeni 92:ec9550034276 250 // No public forward declaration for this.
ocomeni 92:ec9550034276 251 extern "C" P_TCB rt_tid2ptcb (osThreadId thread_id);
ocomeni 92:ec9550034276 252
ocomeni 92:ec9550034276 253 static void print_thread_info(osThreadId threadId)
ocomeni 92:ec9550034276 254 {
ocomeni 92:ec9550034276 255 if (!threadId) return;
ocomeni 92:ec9550034276 256
ocomeni 92:ec9550034276 257 osEvent event;
ocomeni 92:ec9550034276 258
ocomeni 92:ec9550034276 259 P_TCB tcb = rt_tid2ptcb(threadId);
ocomeni 92:ec9550034276 260
ocomeni 92:ec9550034276 261 DPL(" stack ( start: ");
ocomeni 92:ec9550034276 262 debug_print_pointer(tcb->stack);
ocomeni 92:ec9550034276 263
ocomeni 92:ec9550034276 264 event = _osThreadGetInfo(threadId, osThreadInfoStackSize);
ocomeni 92:ec9550034276 265
ocomeni 92:ec9550034276 266 DPL(" end: ");
ocomeni 92:ec9550034276 267 debug_print_pointer(((uint8_t *) tcb->stack + event.value.v)); // (tcb->priv_stack)));
ocomeni 92:ec9550034276 268
ocomeni 92:ec9550034276 269 DPL(" size: ");
ocomeni 92:ec9550034276 270 debug_print_u32(event.value.v);
ocomeni 92:ec9550034276 271
ocomeni 92:ec9550034276 272 event = _osThreadGetInfo(threadId, osThreadInfoStackMax);
ocomeni 92:ec9550034276 273 DPL(" used: ");
ocomeni 92:ec9550034276 274 debug_print_u32(event.value.v);
ocomeni 92:ec9550034276 275
ocomeni 92:ec9550034276 276
ocomeni 92:ec9550034276 277 DPL(" ) ");
ocomeni 92:ec9550034276 278
ocomeni 92:ec9550034276 279 DPL("thread ( id: ");
ocomeni 92:ec9550034276 280 debug_print_pointer(threadId);
ocomeni 92:ec9550034276 281
ocomeni 92:ec9550034276 282 event = _osThreadGetInfo(threadId, osThreadInfoEntry);
ocomeni 92:ec9550034276 283 DPL(" entry: ");
ocomeni 92:ec9550034276 284 debug_print_pointer(event.value.p);
ocomeni 92:ec9550034276 285
ocomeni 92:ec9550034276 286 DPL(" )\r\n");
ocomeni 92:ec9550034276 287 }
ocomeni 92:ec9550034276 288
ocomeni 92:ec9550034276 289 void print_all_thread_info(void)
ocomeni 92:ec9550034276 290 {
ocomeni 92:ec9550034276 291 osThreadEnumId enumId = _osThreadsEnumStart();
ocomeni 92:ec9550034276 292 osThreadId threadId = (osThreadId) NULL; // Can't use nullptr yet because mbed doesn't support C++11.
ocomeni 92:ec9550034276 293
ocomeni 92:ec9550034276 294 while ((threadId = _osThreadEnumNext(enumId)))
ocomeni 92:ec9550034276 295 {
ocomeni 92:ec9550034276 296 print_thread_info(threadId);
ocomeni 92:ec9550034276 297 }
ocomeni 92:ec9550034276 298
ocomeni 92:ec9550034276 299 _osThreadEnumFree(enumId);
ocomeni 92:ec9550034276 300 }
ocomeni 92:ec9550034276 301
ocomeni 92:ec9550034276 302 #else
ocomeni 92:ec9550034276 303
ocomeni 92:ec9550034276 304 static void print_thread_info(osThreadId threadId)
ocomeni 92:ec9550034276 305 {
ocomeni 92:ec9550034276 306 // Refs: rtx_lib.h - #define os_thread_t osRtxThread_t
ocomeni 92:ec9550034276 307 // rtx_os.h - typedef struct osRtxThread_s { } osRtxThread_t
ocomeni 92:ec9550034276 308
ocomeni 92:ec9550034276 309 if (!threadId) return;
ocomeni 92:ec9550034276 310
ocomeni 92:ec9550034276 311 os_thread_t * tcb = (os_thread_t *) threadId;
ocomeni 92:ec9550034276 312
ocomeni 92:ec9550034276 313 uint32_t stackSize = osThreadGetStackSize(threadId);
ocomeni 92:ec9550034276 314 uint32_t stackUsed = osThreadGetStackSpace(threadId);
ocomeni 92:ec9550034276 315
ocomeni 92:ec9550034276 316 DPL(" stack ( start: ");
ocomeni 92:ec9550034276 317 debug_print_pointer(tcb->stack_mem);
ocomeni 92:ec9550034276 318
ocomeni 92:ec9550034276 319 DPL(" end: ");
ocomeni 92:ec9550034276 320 debug_print_pointer((uint8_t *) tcb->stack_mem + stackSize);
ocomeni 92:ec9550034276 321
ocomeni 92:ec9550034276 322 DPL(" size: ");
ocomeni 92:ec9550034276 323 debug_print_u32(stackSize);
ocomeni 92:ec9550034276 324
ocomeni 92:ec9550034276 325 DPL(" used: ");
ocomeni 92:ec9550034276 326 debug_print_u32(stackSize - stackUsed);
ocomeni 92:ec9550034276 327
ocomeni 92:ec9550034276 328 DPL(" ) ");
ocomeni 92:ec9550034276 329
ocomeni 92:ec9550034276 330 DPL("thread ( id: ");
ocomeni 92:ec9550034276 331 debug_print_pointer(threadId);
ocomeni 92:ec9550034276 332
ocomeni 92:ec9550034276 333 DPL(" entry: ");
ocomeni 92:ec9550034276 334 debug_print_u32(tcb->thread_addr);
ocomeni 92:ec9550034276 335
ocomeni 92:ec9550034276 336 DPL(" name: ");
ocomeni 92:ec9550034276 337 DPL(osThreadGetName(threadId) ? osThreadGetName(threadId) : "unknown");
ocomeni 92:ec9550034276 338
ocomeni 92:ec9550034276 339 DPL(" )\r\n");
ocomeni 92:ec9550034276 340 }
ocomeni 92:ec9550034276 341
ocomeni 92:ec9550034276 342 void print_all_thread_info(void)
ocomeni 92:ec9550034276 343 {
ocomeni 92:ec9550034276 344 // Refs: mbed_stats.c - mbed_stats_stack_get_each()
ocomeni 92:ec9550034276 345
ocomeni 92:ec9550034276 346 uint32_t threadCount = osThreadGetCount();
ocomeni 92:ec9550034276 347 osThreadId_t threads[threadCount]; // g++ will throw a -Wvla on this, but it is likely ok.
ocomeni 92:ec9550034276 348
ocomeni 92:ec9550034276 349 // osThreadId_t * threads = malloc(sizeof(osThreadId_t) * threadCount);
ocomeni 92:ec9550034276 350 // MBED_ASSERT(NULL != threads);
ocomeni 92:ec9550034276 351
ocomeni 92:ec9550034276 352 memset(threads, 0, threadCount * sizeof(osThreadId_t));
ocomeni 92:ec9550034276 353
ocomeni 92:ec9550034276 354 // This will probably only work if the number of threads remains constant
ocomeni 92:ec9550034276 355 // (i.e. the number of thread control blocks remains constant)
ocomeni 92:ec9550034276 356 //
ocomeni 92:ec9550034276 357 // This is probably the case on a deterministic realtime embedded system
ocomeni 92:ec9550034276 358 // with limited SRAM.
ocomeni 92:ec9550034276 359
ocomeni 92:ec9550034276 360 osKernelLock();
ocomeni 92:ec9550034276 361
ocomeni 92:ec9550034276 362 threadCount = osThreadEnumerate(threads, threadCount);
ocomeni 92:ec9550034276 363
ocomeni 92:ec9550034276 364 for (uint32_t i = 0; i < threadCount; i++)
ocomeni 92:ec9550034276 365 {
ocomeni 92:ec9550034276 366 // There seems to be a Heisenbug when calling print_thread_info()
ocomeni 92:ec9550034276 367 // inside of osKernelLock()!
ocomeni 92:ec9550034276 368
ocomeni 92:ec9550034276 369 // This error may appear on the serial console:
ocomeni 92:ec9550034276 370 // mbed assertation failed: os_timer->get_tick() == svcRtxKernelGetTickCount(), file: .\mbed-os\rtos\TARGET_CORTEX\mbed_rtx_idle.c
ocomeni 92:ec9550034276 371
ocomeni 92:ec9550034276 372 // The RTOS seems to be asserting an idle constraint violation due
ocomeni 92:ec9550034276 373 // to the slowness of sending data through the serial port, but it
ocomeni 92:ec9550034276 374 // does not happen consistently.
ocomeni 92:ec9550034276 375 print_thread_info(threads[i]);
ocomeni 92:ec9550034276 376 }
ocomeni 92:ec9550034276 377
ocomeni 92:ec9550034276 378 osKernelUnlock();
ocomeni 92:ec9550034276 379
ocomeni 92:ec9550034276 380 // free(threads);
ocomeni 92:ec9550034276 381 }
ocomeni 92:ec9550034276 382
ocomeni 92:ec9550034276 383 #endif
ocomeni 92:ec9550034276 384
ocomeni 92:ec9550034276 385 void print_current_thread_id(void)
ocomeni 92:ec9550034276 386 {
ocomeni 92:ec9550034276 387 DPL("Current thread: ");
ocomeni 92:ec9550034276 388 debug_print_pointer(osThreadGetId());
ocomeni 92:ec9550034276 389 DPL("\r\n");
ocomeni 92:ec9550034276 390 }
ocomeni 92:ec9550034276 391 #endif // MBED_CONF_RTOS_PRESENT
ocomeni 92:ec9550034276 392
ocomeni 92:ec9550034276 393 #if DEBUG_MEMORY_CONTENTS
ocomeni 92:ec9550034276 394 static void print_memory_contents(const uint32_t * start, const uint32_t * end)
ocomeni 92:ec9550034276 395 {
ocomeni 92:ec9550034276 396 uint8_t line = 0;
ocomeni 92:ec9550034276 397
ocomeni 92:ec9550034276 398 for (; start < end; start++)
ocomeni 92:ec9550034276 399 {
ocomeni 92:ec9550034276 400 if (0 == line)
ocomeni 92:ec9550034276 401 {
ocomeni 92:ec9550034276 402 debug_print_pointer(start);
ocomeni 92:ec9550034276 403 DPL(": ");
ocomeni 92:ec9550034276 404 }
ocomeni 92:ec9550034276 405
ocomeni 92:ec9550034276 406 debug_print_u32(*start);
ocomeni 92:ec9550034276 407
ocomeni 92:ec9550034276 408 line++;
ocomeni 92:ec9550034276 409
ocomeni 92:ec9550034276 410 if (16 == line)
ocomeni 92:ec9550034276 411 {
ocomeni 92:ec9550034276 412 DPL("\r\n");
ocomeni 92:ec9550034276 413 line = 0;
ocomeni 92:ec9550034276 414 }
ocomeni 92:ec9550034276 415 }
ocomeni 92:ec9550034276 416 }
ocomeni 92:ec9550034276 417 #endif
ocomeni 92:ec9550034276 418
ocomeni 92:ec9550034276 419 extern uint32_t mbed_stack_isr_size;
ocomeni 92:ec9550034276 420
ocomeni 92:ec9550034276 421 #if DEBUG_ISR_STACK_USAGE
ocomeni 92:ec9550034276 422 uint32_t calculate_isr_stack_usage(void)
ocomeni 92:ec9550034276 423 {
ocomeni 92:ec9550034276 424 for (const uint32_t * stack = &__StackLimit; stack < &__StackTop; stack++)
ocomeni 92:ec9550034276 425 {
ocomeni 92:ec9550034276 426 if (*stack != ISR_STACK_CANARY)
ocomeni 92:ec9550034276 427 {
ocomeni 92:ec9550034276 428 return (uint32_t) &__StackTop - (uint32_t) stack;
ocomeni 92:ec9550034276 429 }
ocomeni 92:ec9550034276 430 }
ocomeni 92:ec9550034276 431
ocomeni 92:ec9550034276 432 return mbed_stack_isr_size;
ocomeni 92:ec9550034276 433 }
ocomeni 92:ec9550034276 434 #endif
ocomeni 92:ec9550034276 435
ocomeni 92:ec9550034276 436 void print_heap_and_isr_stack_info(void)
ocomeni 92:ec9550034276 437 {
ocomeni 92:ec9550034276 438 extern unsigned char * mbed_heap_start;
ocomeni 92:ec9550034276 439 extern uint32_t mbed_heap_size;
ocomeni 92:ec9550034276 440
ocomeni 92:ec9550034276 441 extern unsigned char * mbed_stack_isr_start;
ocomeni 92:ec9550034276 442
ocomeni 92:ec9550034276 443 mbed_stats_heap_t heap_stats;
ocomeni 92:ec9550034276 444
ocomeni 92:ec9550034276 445 mbed_stats_heap_get(&heap_stats);
ocomeni 92:ec9550034276 446
ocomeni 92:ec9550034276 447 DPL(" heap ( start: ");
ocomeni 92:ec9550034276 448 debug_print_pointer(mbed_heap_start);
ocomeni 92:ec9550034276 449
ocomeni 92:ec9550034276 450 DPL(" end: ");
ocomeni 92:ec9550034276 451 debug_print_pointer(mbed_heap_start + mbed_heap_size);
ocomeni 92:ec9550034276 452
ocomeni 92:ec9550034276 453 DPL(" size: ");
ocomeni 92:ec9550034276 454 debug_print_u32(mbed_heap_size);
ocomeni 92:ec9550034276 455
ocomeni 92:ec9550034276 456 DPL(" used: ");
ocomeni 92:ec9550034276 457 debug_print_u32(heap_stats.max_size);
ocomeni 92:ec9550034276 458
ocomeni 92:ec9550034276 459 DPL(" ) alloc ( ok: ");
ocomeni 92:ec9550034276 460 debug_print_u32(heap_stats.alloc_cnt);
ocomeni 92:ec9550034276 461
ocomeni 92:ec9550034276 462 DPL(" fail: ");
ocomeni 92:ec9550034276 463 debug_print_u32(heap_stats.alloc_fail_cnt);
ocomeni 92:ec9550034276 464
ocomeni 92:ec9550034276 465 DPL(" )\r\n");
ocomeni 92:ec9550034276 466
ocomeni 92:ec9550034276 467 DPL("isr_stack ( start: ");
ocomeni 92:ec9550034276 468 debug_print_pointer(mbed_stack_isr_start);
ocomeni 92:ec9550034276 469
ocomeni 92:ec9550034276 470 DPL(" end: ");
ocomeni 92:ec9550034276 471 debug_print_pointer(mbed_stack_isr_start + mbed_stack_isr_size);
ocomeni 92:ec9550034276 472
ocomeni 92:ec9550034276 473 DPL(" size: ");
ocomeni 92:ec9550034276 474 debug_print_u32(mbed_stack_isr_size);
ocomeni 92:ec9550034276 475
ocomeni 92:ec9550034276 476 #if DEBUG_ISR_STACK_USAGE
ocomeni 92:ec9550034276 477 DPL(" used: ");
ocomeni 92:ec9550034276 478 debug_print_u32(calculate_isr_stack_usage());
ocomeni 92:ec9550034276 479 #endif
ocomeni 92:ec9550034276 480
ocomeni 92:ec9550034276 481 DPL(" )\r\n");
ocomeni 92:ec9550034276 482
ocomeni 92:ec9550034276 483 #if DEBUG_MEMORY_CONTENTS
ocomeni 92:ec9550034276 484 // Print ISR stack contents.
ocomeni 92:ec9550034276 485 print_memory_contents(&__StackLimit, &__StackTop);
ocomeni 92:ec9550034276 486 #endif
ocomeni 92:ec9550034276 487 }
ocomeni 92:ec9550034276 488