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