Basic debug library

Dependents:   modem_ref_helper_for_v5_3_217 modem_ref_helper

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?

UserRevisionLine numberNew 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 }