Basic debug library
Dependents: modem_ref_helper_for_v5_3_217 modem_ref_helper
WizziDebug.cpp@10:0e6e54fb08c0, 2021-01-25 (annotated)
- Committer:
- Jeej
- Date:
- Mon Jan 25 11:23:47 2021 +0000
- Revision:
- 10:0e6e54fb08c0
- Parent:
- 9:87d9cc850af1
- Child:
- 11:45093cacde63
Use same buffer as WizziCom
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Jeej | 0:1d3ed1850649 | 1 | #include "mbed.h" |
Jeej | 0:1d3ed1850649 | 2 | #include "rtos.h" |
Jeej | 0:1d3ed1850649 | 3 | #include "WizziDebug.h" |
Jeej | 0:1d3ed1850649 | 4 | #include <stdio.h> |
Jeej | 0:1d3ed1850649 | 5 | #include <string.h> |
Jeej | 0:1d3ed1850649 | 6 | #include <stdarg.h> |
Jeej | 0:1d3ed1850649 | 7 | |
Jeej | 10:0e6e54fb08c0 | 8 | #define DBG_MAX_STRING_SIZE (256) |
Jeej | 10:0e6e54fb08c0 | 9 | #define TX_BUF_SIZE (512) |
Jeej | 0:1d3ed1850649 | 10 | |
Jeej | 10:0e6e54fb08c0 | 11 | static kal_buf_circ_handle_t g_cbuf; |
Jeej | 10:0e6e54fb08c0 | 12 | static kal_buf_circ_static_handle_t g_cbuf_h; |
Jeej | 10:0e6e54fb08c0 | 13 | static kal_buf_circ_static_buffer_t(g_cbuf_b, TX_BUF_SIZE, sizeof(uint8_t)); |
Jeej | 0:1d3ed1850649 | 14 | static char g_dbg_msg[DBG_MAX_STRING_SIZE]; |
Jeej | 9:87d9cc850af1 | 15 | static Thread g_dbg_thread(osPriorityLow, 512); |
Jeej | 0:1d3ed1850649 | 16 | static RawSerial* g_dbg_serial; |
Jeej | 0:1d3ed1850649 | 17 | static Mutex g_dbg_ressource; |
Jeej | 0:1d3ed1850649 | 18 | static Semaphore g_dbg_print(0); |
Jeej | 0:1d3ed1850649 | 19 | static uint32_t g_dbg_nb_mallocs; |
Jeej | 6:70e985e34364 | 20 | static PinName __attribute__((unused)) g_dbg_led; |
Jeej | 0:1d3ed1850649 | 21 | static uint32_t g_dbg_missing; |
Jeej | 7:8e75991f65e5 | 22 | static void (*g_dbg_rx_callback)(char c) = NULL; |
Jeej | 0:1d3ed1850649 | 23 | |
Jeej | 0:1d3ed1850649 | 24 | void dbg_print_thread(); |
Jeej | 0:1d3ed1850649 | 25 | |
Jeej | 7:8e75991f65e5 | 26 | static void dbg_serial_rx_isr(void) |
Jeej | 7:8e75991f65e5 | 27 | { |
Jeej | 7:8e75991f65e5 | 28 | if (!g_dbg_rx_callback) |
Jeej | 7:8e75991f65e5 | 29 | { |
Jeej | 7:8e75991f65e5 | 30 | PRINT("%c", g_dbg_serial->getc()); |
Jeej | 7:8e75991f65e5 | 31 | return; |
Jeej | 7:8e75991f65e5 | 32 | } |
Jeej | 7:8e75991f65e5 | 33 | |
Jeej | 7:8e75991f65e5 | 34 | // Loop just in case more than one character is in UART's receive FIFO buffer |
Jeej | 7:8e75991f65e5 | 35 | while (g_dbg_serial->readable()) |
Jeej | 7:8e75991f65e5 | 36 | { |
Jeej | 7:8e75991f65e5 | 37 | g_dbg_rx_callback(g_dbg_serial->getc()); |
Jeej | 7:8e75991f65e5 | 38 | } |
Jeej | 7:8e75991f65e5 | 39 | } |
Jeej | 7:8e75991f65e5 | 40 | |
Jeej | 0:1d3ed1850649 | 41 | // Redefine mbed error function |
Jeej | 0:1d3ed1850649 | 42 | void error(const char* format, ...) |
Jeej | 0:1d3ed1850649 | 43 | { |
Jeej | 0:1d3ed1850649 | 44 | char buf[DBG_MAX_STRING_SIZE]; |
Jeej | 0:1d3ed1850649 | 45 | |
Jeej | 0:1d3ed1850649 | 46 | va_list args; |
Jeej | 0:1d3ed1850649 | 47 | va_start(args, format); |
Jeej | 0:1d3ed1850649 | 48 | vsprintf(buf, format, args); |
Jeej | 0:1d3ed1850649 | 49 | va_end(args); |
Jeej | 0:1d3ed1850649 | 50 | |
Jeej | 0:1d3ed1850649 | 51 | ASSERT(false, buf); |
Jeej | 0:1d3ed1850649 | 52 | } |
Jeej | 0:1d3ed1850649 | 53 | |
Jeej | 0:1d3ed1850649 | 54 | void dbg_open(PinName led, PinName tx, PinName rx) |
Jeej | 0:1d3ed1850649 | 55 | { |
Jeej | 0:1d3ed1850649 | 56 | //FPRINT("\r\n"); |
Jeej | 0:1d3ed1850649 | 57 | |
Jeej | 0:1d3ed1850649 | 58 | g_dbg_nb_mallocs = 0; |
Jeej | 0:1d3ed1850649 | 59 | g_dbg_led = led; |
Jeej | 0:1d3ed1850649 | 60 | g_dbg_missing = 0; |
Jeej | 0:1d3ed1850649 | 61 | |
Jeej | 10:0e6e54fb08c0 | 62 | g_cbuf = &g_cbuf_h; |
Jeej | 10:0e6e54fb08c0 | 63 | kal_buf_circ_create_static(&g_cbuf_h, g_cbuf_b, TX_BUF_SIZE, sizeof(char)); |
Jeej | 10:0e6e54fb08c0 | 64 | |
Jeej | 0:1d3ed1850649 | 65 | g_dbg_serial = new RawSerial(tx, rx, 115200); |
Jeej | 0:1d3ed1850649 | 66 | g_dbg_serial->format(8, SerialBase::None, 1); |
Jeej | 7:8e75991f65e5 | 67 | g_dbg_serial->attach(callback(&dbg_serial_rx_isr), Serial::RxIrq); |
Jeej | 0:1d3ed1850649 | 68 | |
Jeej | 0:1d3ed1850649 | 69 | g_dbg_thread.start(dbg_print_thread); |
Jeej | 0:1d3ed1850649 | 70 | } |
Jeej | 0:1d3ed1850649 | 71 | |
Jeej | 0:1d3ed1850649 | 72 | // Destructor |
Jeej | 0:1d3ed1850649 | 73 | void dbg_close( void ) |
Jeej | 0:1d3ed1850649 | 74 | { |
Jeej | 0:1d3ed1850649 | 75 | FPRINT("\r\n"); |
Jeej | 0:1d3ed1850649 | 76 | g_dbg_thread.terminate(); |
Jeej | 0:1d3ed1850649 | 77 | delete g_dbg_serial; |
Jeej | 0:1d3ed1850649 | 78 | } |
Jeej | 0:1d3ed1850649 | 79 | |
Jeej | 0:1d3ed1850649 | 80 | void dbg_set_led(PinName led, PinName dummy1, PinName dummy2) |
Jeej | 0:1d3ed1850649 | 81 | { |
Jeej | 0:1d3ed1850649 | 82 | FPRINT("\r\n"); |
Jeej | 0:1d3ed1850649 | 83 | g_dbg_led = led; |
Jeej | 0:1d3ed1850649 | 84 | } |
Jeej | 0:1d3ed1850649 | 85 | |
Jeej | 0:1d3ed1850649 | 86 | static void dbg_add_to_buf(char* msg, int size) |
Jeej | 0:1d3ed1850649 | 87 | { |
Jeej | 10:0e6e54fb08c0 | 88 | uint8_t c; |
Jeej | 10:0e6e54fb08c0 | 89 | |
Jeej | 2:9e2ab0547cd0 | 90 | #ifdef __FORCE_FLUSH__ |
Jeej | 2:9e2ab0547cd0 | 91 | for (int i = 0; i < size; i++) |
Jeej | 2:9e2ab0547cd0 | 92 | { |
Jeej | 2:9e2ab0547cd0 | 93 | g_dbg_serial->putc(msg[i]); |
Jeej | 2:9e2ab0547cd0 | 94 | } |
Jeej | 2:9e2ab0547cd0 | 95 | #else |
Jeej | 0:1d3ed1850649 | 96 | if(size > 0) |
Jeej | 0:1d3ed1850649 | 97 | { |
Jeej | 10:0e6e54fb08c0 | 98 | if (kal_buf_circ_space(g_cbuf) < size) |
Jeej | 0:1d3ed1850649 | 99 | { |
Jeej | 2:9e2ab0547cd0 | 100 | #ifdef __FLUSH_IF_FULL__ |
Jeej | 0:1d3ed1850649 | 101 | // Flush just what is needed |
Jeej | 0:1d3ed1850649 | 102 | do { |
Jeej | 10:0e6e54fb08c0 | 103 | kal_buf_circ_pop(g_cbuf, &c); |
Jeej | 10:0e6e54fb08c0 | 104 | g_dbg_serial->putc(c); |
Jeej | 10:0e6e54fb08c0 | 105 | } while (kal_buf_circ_space(g_cbuf) < size); |
Jeej | 0:1d3ed1850649 | 106 | |
Jeej | 10:0e6e54fb08c0 | 107 | kal_buf_circ_put(g_cbuf, (uint8_t*)msg, size); |
Jeej | 2:9e2ab0547cd0 | 108 | #else |
Jeej | 0:1d3ed1850649 | 109 | // Discard |
Jeej | 0:1d3ed1850649 | 110 | g_dbg_missing++; |
Jeej | 2:9e2ab0547cd0 | 111 | #endif |
Jeej | 0:1d3ed1850649 | 112 | } |
Jeej | 0:1d3ed1850649 | 113 | else |
Jeej | 0:1d3ed1850649 | 114 | { |
Jeej | 0:1d3ed1850649 | 115 | // add |
Jeej | 10:0e6e54fb08c0 | 116 | kal_buf_circ_put(g_cbuf, (uint8_t*)msg, size); |
Jeej | 0:1d3ed1850649 | 117 | } |
Jeej | 0:1d3ed1850649 | 118 | |
Jeej | 0:1d3ed1850649 | 119 | // Allow printing |
Jeej | 0:1d3ed1850649 | 120 | g_dbg_print.release(); |
Jeej | 0:1d3ed1850649 | 121 | } |
Jeej | 2:9e2ab0547cd0 | 122 | #endif |
Jeej | 0:1d3ed1850649 | 123 | } |
Jeej | 0:1d3ed1850649 | 124 | |
Jeej | 0:1d3ed1850649 | 125 | // Asserts and trap processor. |
Jeej | 0:1d3ed1850649 | 126 | void dbg_assert(bool test, const char* format, ...) |
Jeej | 0:1d3ed1850649 | 127 | { |
Jeej | 0:1d3ed1850649 | 128 | if (test) return; |
Jeej | 0:1d3ed1850649 | 129 | |
Jeej | 0:1d3ed1850649 | 130 | int assert_size; |
Jeej | 0:1d3ed1850649 | 131 | |
Jeej | 8:87a867b8a129 | 132 | assert_size = sprintf(g_dbg_msg, "ASSERT "); |
Jeej | 0:1d3ed1850649 | 133 | |
Jeej | 0:1d3ed1850649 | 134 | // expand assert string |
Jeej | 0:1d3ed1850649 | 135 | va_list args; |
Jeej | 0:1d3ed1850649 | 136 | va_start(args, format); |
Jeej | 4:31e1101e6999 | 137 | vsprintf(g_dbg_msg+assert_size, format, args); |
Jeej | 0:1d3ed1850649 | 138 | va_end(args); |
Jeej | 0:1d3ed1850649 | 139 | |
Jeej | 0:1d3ed1850649 | 140 | dbg_flush(); |
Jeej | 0:1d3ed1850649 | 141 | |
Jeej | 0:1d3ed1850649 | 142 | g_dbg_serial->printf(g_dbg_msg); |
Jeej | 0:1d3ed1850649 | 143 | |
Jeej | 0:1d3ed1850649 | 144 | #ifdef __REBOOT_ON_ASSERT__ |
Jeej | 8:87a867b8a129 | 145 | ThisThread::sleep_for(1000); |
Jeej | 0:1d3ed1850649 | 146 | NVIC_SystemReset(); |
Jeej | 0:1d3ed1850649 | 147 | #else |
Jeej | 0:1d3ed1850649 | 148 | DigitalOut* dbg_led = NULL; |
Jeej | 0:1d3ed1850649 | 149 | if (g_dbg_led != NC) |
Jeej | 0:1d3ed1850649 | 150 | { |
Jeej | 0:1d3ed1850649 | 151 | dbg_led = new DigitalOut(g_dbg_led); |
Jeej | 0:1d3ed1850649 | 152 | } |
Jeej | 0:1d3ed1850649 | 153 | |
Jeej | 0:1d3ed1850649 | 154 | // Die... |
Jeej | 0:1d3ed1850649 | 155 | while(1) |
Jeej | 0:1d3ed1850649 | 156 | { |
Jeej | 0:1d3ed1850649 | 157 | if (dbg_led != NULL) |
Jeej | 0:1d3ed1850649 | 158 | { |
Jeej | 0:1d3ed1850649 | 159 | *(dbg_led) = !(*(dbg_led)); |
Jeej | 0:1d3ed1850649 | 160 | } |
Jeej | 8:87a867b8a129 | 161 | ThisThread::sleep_for(30); |
Jeej | 0:1d3ed1850649 | 162 | //wait_ms(30); |
Jeej | 0:1d3ed1850649 | 163 | } |
Jeej | 0:1d3ed1850649 | 164 | #endif |
Jeej | 0:1d3ed1850649 | 165 | } |
Jeej | 0:1d3ed1850649 | 166 | |
Jeej | 0:1d3ed1850649 | 167 | // Prints a message to the debug port. |
Jeej | 0:1d3ed1850649 | 168 | void dbg_print(const char* format, ...) |
Jeej | 0:1d3ed1850649 | 169 | { |
Jeej | 0:1d3ed1850649 | 170 | int size; |
Jeej | 0:1d3ed1850649 | 171 | |
Jeej | 0:1d3ed1850649 | 172 | va_list args; |
Jeej | 0:1d3ed1850649 | 173 | va_start(args, format); |
Jeej | 0:1d3ed1850649 | 174 | size = vsprintf(g_dbg_msg, format, args); |
Jeej | 0:1d3ed1850649 | 175 | va_end(args); |
Jeej | 0:1d3ed1850649 | 176 | |
Jeej | 0:1d3ed1850649 | 177 | dbg_add_to_buf(g_dbg_msg, size); |
Jeej | 0:1d3ed1850649 | 178 | } |
Jeej | 0:1d3ed1850649 | 179 | |
Jeej | 0:1d3ed1850649 | 180 | // Flush the pending debug messages. |
Jeej | 0:1d3ed1850649 | 181 | void dbg_flush( void ) |
Jeej | 0:1d3ed1850649 | 182 | { |
Jeej | 10:0e6e54fb08c0 | 183 | uint8_t c; |
Jeej | 10:0e6e54fb08c0 | 184 | |
Jeej | 0:1d3ed1850649 | 185 | g_dbg_ressource.lock(); |
Jeej | 10:0e6e54fb08c0 | 186 | while(!kal_buf_circ_empty(g_cbuf)) |
Jeej | 0:1d3ed1850649 | 187 | { |
Jeej | 10:0e6e54fb08c0 | 188 | kal_buf_circ_pop(g_cbuf, &c); |
Jeej | 10:0e6e54fb08c0 | 189 | g_dbg_serial->putc(c); |
Jeej | 0:1d3ed1850649 | 190 | } |
Jeej | 0:1d3ed1850649 | 191 | g_dbg_ressource.unlock(); |
Jeej | 0:1d3ed1850649 | 192 | } |
Jeej | 0:1d3ed1850649 | 193 | |
Jeej | 0:1d3ed1850649 | 194 | // Prints malloc parameters. |
Jeej | 0:1d3ed1850649 | 195 | void* dbg_malloc(size_t size, const char* f, uint32_t l) |
Jeej | 0:1d3ed1850649 | 196 | { |
Jeej | 0:1d3ed1850649 | 197 | void* a; |
Jeej | 0:1d3ed1850649 | 198 | a = malloc(size); |
Jeej | 0:1d3ed1850649 | 199 | g_dbg_nb_mallocs++; |
Jeej | 0:1d3ed1850649 | 200 | dbg_print("M @%08x %dB %s:%d (%d)\r\n", (uint32_t)a, size, f, l, g_dbg_nb_mallocs); |
Jeej | 0:1d3ed1850649 | 201 | return a; |
Jeej | 0:1d3ed1850649 | 202 | } |
Jeej | 0:1d3ed1850649 | 203 | |
Jeej | 0:1d3ed1850649 | 204 | // Prints realloc parameters. |
Jeej | 0:1d3ed1850649 | 205 | void* dbg_realloc(void* p, size_t size, const char* f, uint32_t l) |
Jeej | 0:1d3ed1850649 | 206 | { |
Jeej | 0:1d3ed1850649 | 207 | void* a; |
Jeej | 0:1d3ed1850649 | 208 | dbg_assert(((uint32_t)p >= RAM_START_ADDRESS) && ((uint32_t)p < RAM_END_ADDRESS), "Trying to realloc illegal address @08x\r\n", (uint32_t)p); |
Jeej | 0:1d3ed1850649 | 209 | a = realloc(p, size); |
Jeej | 0:1d3ed1850649 | 210 | dbg_print("R @%08x->@%08x %dB %s:%d\r\n", (uint32_t)p, (uint32_t)a, size, f, l); |
Jeej | 0:1d3ed1850649 | 211 | return a; |
Jeej | 0:1d3ed1850649 | 212 | } |
Jeej | 0:1d3ed1850649 | 213 | |
Jeej | 0:1d3ed1850649 | 214 | // Prints free parameters. |
Jeej | 0:1d3ed1850649 | 215 | void dbg_free(void* p, const char* f, uint32_t l) |
Jeej | 0:1d3ed1850649 | 216 | { |
Jeej | 0:1d3ed1850649 | 217 | g_dbg_nb_mallocs--; |
Jeej | 0:1d3ed1850649 | 218 | dbg_print("F @%08x %s:%d (%d)\r\n", (uint32_t)p, f, l, g_dbg_nb_mallocs); |
Jeej | 0:1d3ed1850649 | 219 | dbg_assert(((uint32_t)p >= RAM_START_ADDRESS) && ((uint32_t)p < RAM_END_ADDRESS), "Trying to free illegal address @08x\r\n", (uint32_t)p); |
Jeej | 0:1d3ed1850649 | 220 | free(p); |
Jeej | 0:1d3ed1850649 | 221 | } |
Jeej | 0:1d3ed1850649 | 222 | |
Jeej | 0:1d3ed1850649 | 223 | void dbg_print_data(const char* before, const char* format, uint8_t* data, uint8_t length, const char* after) |
Jeej | 0:1d3ed1850649 | 224 | { |
Jeej | 0:1d3ed1850649 | 225 | uint32_t total_len = 0; |
Jeej | 0:1d3ed1850649 | 226 | |
Jeej | 0:1d3ed1850649 | 227 | total_len += sprintf(g_dbg_msg, before); |
Jeej | 0:1d3ed1850649 | 228 | |
Jeej | 0:1d3ed1850649 | 229 | for (uint8_t i=0 ; i<length ; i++) |
Jeej | 0:1d3ed1850649 | 230 | { |
Jeej | 0:1d3ed1850649 | 231 | total_len += sprintf(&g_dbg_msg[total_len], format, data[i]); |
Jeej | 0:1d3ed1850649 | 232 | dbg_assert(total_len < DBG_MAX_STRING_SIZE, "Print data too long.\r\n"); |
Jeej | 0:1d3ed1850649 | 233 | } |
Jeej | 0:1d3ed1850649 | 234 | |
Jeej | 0:1d3ed1850649 | 235 | total_len += sprintf(&g_dbg_msg[total_len], after); |
Jeej | 0:1d3ed1850649 | 236 | |
Jeej | 0:1d3ed1850649 | 237 | dbg_add_to_buf(g_dbg_msg, total_len); |
Jeej | 0:1d3ed1850649 | 238 | } |
Jeej | 0:1d3ed1850649 | 239 | |
Jeej | 0:1d3ed1850649 | 240 | |
Jeej | 0:1d3ed1850649 | 241 | // Thread for printing debug messages. |
Jeej | 0:1d3ed1850649 | 242 | void dbg_print_thread() |
Jeej | 0:1d3ed1850649 | 243 | { |
Jeej | 10:0e6e54fb08c0 | 244 | uint8_t c; |
Jeej | 10:0e6e54fb08c0 | 245 | |
Jeej | 0:1d3ed1850649 | 246 | FPRINT("(id:0x%08x)\r\n", osThreadGetId()); |
Jeej | 0:1d3ed1850649 | 247 | |
Jeej | 0:1d3ed1850649 | 248 | while (true) |
Jeej | 0:1d3ed1850649 | 249 | { |
Jeej | 9:87d9cc850af1 | 250 | g_dbg_print.acquire(); |
Jeej | 0:1d3ed1850649 | 251 | |
Jeej | 0:1d3ed1850649 | 252 | if (g_dbg_missing) |
Jeej | 0:1d3ed1850649 | 253 | { |
Jeej | 0:1d3ed1850649 | 254 | g_dbg_serial->printf("Missing %d traces!!!\r\n", g_dbg_missing); |
Jeej | 0:1d3ed1850649 | 255 | g_dbg_missing = 0; |
Jeej | 0:1d3ed1850649 | 256 | } |
Jeej | 0:1d3ed1850649 | 257 | |
Jeej | 10:0e6e54fb08c0 | 258 | while(!kal_buf_circ_empty(g_cbuf)) |
Jeej | 0:1d3ed1850649 | 259 | { |
Jeej | 0:1d3ed1850649 | 260 | g_dbg_ressource.lock(); |
Jeej | 0:1d3ed1850649 | 261 | |
Jeej | 0:1d3ed1850649 | 262 | #ifdef __FORCE_LINE_INTEGRITY__ |
Jeej | 0:1d3ed1850649 | 263 | // Flush until EOL |
Jeej | 0:1d3ed1850649 | 264 | uint8_t byte; |
Jeej | 0:1d3ed1850649 | 265 | do { |
Jeej | 10:0e6e54fb08c0 | 266 | kal_buf_circ_pop(g_cbuf, &c); |
Jeej | 10:0e6e54fb08c0 | 267 | g_dbg_serial->putc(c); |
Jeej | 10:0e6e54fb08c0 | 268 | } while (byte != '\n' && !kal_buf_circ_empty(g_cbuf)); |
Jeej | 0:1d3ed1850649 | 269 | #else |
Jeej | 0:1d3ed1850649 | 270 | // Flush characters one by one |
Jeej | 10:0e6e54fb08c0 | 271 | kal_buf_circ_pop(g_cbuf, &c); |
Jeej | 10:0e6e54fb08c0 | 272 | g_dbg_serial->putc(c); |
Jeej | 0:1d3ed1850649 | 273 | #endif |
Jeej | 0:1d3ed1850649 | 274 | |
Jeej | 0:1d3ed1850649 | 275 | g_dbg_ressource.unlock(); |
Jeej | 8:87a867b8a129 | 276 | ThisThread::yield(); |
Jeej | 0:1d3ed1850649 | 277 | } |
Jeej | 0:1d3ed1850649 | 278 | } |
Jeej | 0:1d3ed1850649 | 279 | } |
Jeej | 0:1d3ed1850649 | 280 | |
Jeej | 7:8e75991f65e5 | 281 | void dbg_set_rx_callback(void (*rx_isr)(char c)) |
Jeej | 7:8e75991f65e5 | 282 | { |
Jeej | 7:8e75991f65e5 | 283 | g_dbg_rx_callback = rx_isr; |
Jeej | 7:8e75991f65e5 | 284 | } |