Basic debug library

Dependents:   modem_ref_helper_for_v5_3_217 modem_ref_helper

Committer:
Jeej
Date:
Wed Jan 31 11:34:34 2018 +0000
Revision:
5:63ef3a21e932
Parent:
4:31e1101e6999
Child:
6:70e985e34364
Bigger print buffer.

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 "CBuffer.h"
Jeej 0:1d3ed1850649 5 #include <stdio.h>
Jeej 0:1d3ed1850649 6 #include <string.h>
Jeej 0:1d3ed1850649 7 #include <stdarg.h>
Jeej 0:1d3ed1850649 8
Jeej 5:63ef3a21e932 9 #define DBG_MAX_STRING_SIZE (512)
Jeej 0:1d3ed1850649 10
Jeej 0:1d3ed1850649 11 static CBuffer<uint8_t, 2048> g_dbg_buf;
Jeej 0:1d3ed1850649 12 static char g_dbg_msg[DBG_MAX_STRING_SIZE];
Jeej 0:1d3ed1850649 13 static Thread g_dbg_thread(osPriorityIdle, 512, NULL);
Jeej 0:1d3ed1850649 14 static RawSerial* g_dbg_serial;
Jeej 0:1d3ed1850649 15 static Mutex g_dbg_ressource;
Jeej 0:1d3ed1850649 16 static Semaphore g_dbg_print(0);
Jeej 0:1d3ed1850649 17 static uint32_t g_dbg_nb_mallocs;
Jeej 0:1d3ed1850649 18 static PinName g_dbg_led;
Jeej 0:1d3ed1850649 19 static uint32_t g_dbg_missing;
Jeej 0:1d3ed1850649 20
Jeej 0:1d3ed1850649 21 void dbg_print_thread();
Jeej 0:1d3ed1850649 22
Jeej 0:1d3ed1850649 23 // Redefine mbed error function
Jeej 0:1d3ed1850649 24 void error(const char* format, ...)
Jeej 0:1d3ed1850649 25 {
Jeej 0:1d3ed1850649 26 char buf[DBG_MAX_STRING_SIZE];
Jeej 0:1d3ed1850649 27
Jeej 0:1d3ed1850649 28 va_list args;
Jeej 0:1d3ed1850649 29 va_start(args, format);
Jeej 0:1d3ed1850649 30 vsprintf(buf, format, args);
Jeej 0:1d3ed1850649 31 va_end(args);
Jeej 0:1d3ed1850649 32
Jeej 0:1d3ed1850649 33 ASSERT(false, buf);
Jeej 0:1d3ed1850649 34 }
Jeej 0:1d3ed1850649 35
Jeej 0:1d3ed1850649 36 void dbg_open(PinName led, PinName tx, PinName rx)
Jeej 0:1d3ed1850649 37 {
Jeej 0:1d3ed1850649 38 //FPRINT("\r\n");
Jeej 0:1d3ed1850649 39
Jeej 0:1d3ed1850649 40 g_dbg_nb_mallocs = 0;
Jeej 0:1d3ed1850649 41 g_dbg_led = led;
Jeej 0:1d3ed1850649 42 g_dbg_missing = 0;
Jeej 0:1d3ed1850649 43
Jeej 0:1d3ed1850649 44 g_dbg_serial = new RawSerial(tx, rx, 115200);
Jeej 0:1d3ed1850649 45 g_dbg_serial->format(8, SerialBase::None, 1);
Jeej 0:1d3ed1850649 46
Jeej 0:1d3ed1850649 47 g_dbg_thread.start(dbg_print_thread);
Jeej 0:1d3ed1850649 48 }
Jeej 0:1d3ed1850649 49
Jeej 0:1d3ed1850649 50 // Destructor
Jeej 0:1d3ed1850649 51 void dbg_close( void )
Jeej 0:1d3ed1850649 52 {
Jeej 0:1d3ed1850649 53 FPRINT("\r\n");
Jeej 0:1d3ed1850649 54 g_dbg_thread.terminate();
Jeej 0:1d3ed1850649 55 delete g_dbg_serial;
Jeej 0:1d3ed1850649 56 }
Jeej 0:1d3ed1850649 57
Jeej 0:1d3ed1850649 58 void dbg_set_led(PinName led, PinName dummy1, PinName dummy2)
Jeej 0:1d3ed1850649 59 {
Jeej 0:1d3ed1850649 60 FPRINT("\r\n");
Jeej 0:1d3ed1850649 61 g_dbg_led = led;
Jeej 0:1d3ed1850649 62 }
Jeej 0:1d3ed1850649 63
Jeej 0:1d3ed1850649 64 static void dbg_add_to_buf(char* msg, int size)
Jeej 0:1d3ed1850649 65 {
Jeej 2:9e2ab0547cd0 66 #ifdef __FORCE_FLUSH__
Jeej 2:9e2ab0547cd0 67 for (int i = 0; i < size; i++)
Jeej 2:9e2ab0547cd0 68 {
Jeej 2:9e2ab0547cd0 69 g_dbg_serial->putc(msg[i]);
Jeej 2:9e2ab0547cd0 70 }
Jeej 2:9e2ab0547cd0 71 #else
Jeej 0:1d3ed1850649 72 if(size > 0)
Jeej 0:1d3ed1850649 73 {
Jeej 0:1d3ed1850649 74 if (g_dbg_buf.remaining_space() < size)
Jeej 0:1d3ed1850649 75 {
Jeej 2:9e2ab0547cd0 76 #ifdef __FLUSH_IF_FULL__
Jeej 0:1d3ed1850649 77 // Flush just what is needed
Jeej 0:1d3ed1850649 78 do {
Jeej 0:1d3ed1850649 79 g_dbg_serial->putc(g_dbg_buf.pop());
Jeej 0:1d3ed1850649 80 } while (g_dbg_buf.remaining_space() < size);
Jeej 0:1d3ed1850649 81
Jeej 0:1d3ed1850649 82 g_dbg_buf.add((uint8_t*)msg, size);
Jeej 2:9e2ab0547cd0 83 #else
Jeej 0:1d3ed1850649 84 // Discard
Jeej 0:1d3ed1850649 85 g_dbg_missing++;
Jeej 2:9e2ab0547cd0 86 #endif
Jeej 0:1d3ed1850649 87 }
Jeej 0:1d3ed1850649 88 else
Jeej 0:1d3ed1850649 89 {
Jeej 0:1d3ed1850649 90 // add
Jeej 0:1d3ed1850649 91 g_dbg_buf.add((uint8_t*)msg, size);
Jeej 0:1d3ed1850649 92 }
Jeej 0:1d3ed1850649 93
Jeej 0:1d3ed1850649 94 // Allow printing
Jeej 0:1d3ed1850649 95 g_dbg_print.release();
Jeej 0:1d3ed1850649 96 }
Jeej 2:9e2ab0547cd0 97 #endif
Jeej 0:1d3ed1850649 98 }
Jeej 0:1d3ed1850649 99
Jeej 0:1d3ed1850649 100 // Asserts and trap processor.
Jeej 0:1d3ed1850649 101 void dbg_assert(bool test, const char* format, ...)
Jeej 0:1d3ed1850649 102 {
Jeej 0:1d3ed1850649 103 if (test) return;
Jeej 0:1d3ed1850649 104
Jeej 0:1d3ed1850649 105 char* assert_msg = "ASSERT ";
Jeej 0:1d3ed1850649 106 int assert_size;
Jeej 0:1d3ed1850649 107
Jeej 0:1d3ed1850649 108 assert_size = sprintf(g_dbg_msg, assert_msg);
Jeej 0:1d3ed1850649 109
Jeej 0:1d3ed1850649 110 // expand assert string
Jeej 0:1d3ed1850649 111 va_list args;
Jeej 0:1d3ed1850649 112 va_start(args, format);
Jeej 4:31e1101e6999 113 vsprintf(g_dbg_msg+assert_size, format, args);
Jeej 0:1d3ed1850649 114 va_end(args);
Jeej 0:1d3ed1850649 115
Jeej 0:1d3ed1850649 116 dbg_flush();
Jeej 0:1d3ed1850649 117
Jeej 0:1d3ed1850649 118 g_dbg_serial->printf(g_dbg_msg);
Jeej 0:1d3ed1850649 119
Jeej 0:1d3ed1850649 120 #ifdef __REBOOT_ON_ASSERT__
Jeej 0:1d3ed1850649 121 Thread::wait(1000);
Jeej 0:1d3ed1850649 122 NVIC_SystemReset();
Jeej 0:1d3ed1850649 123 #else
Jeej 0:1d3ed1850649 124 DigitalOut* dbg_led = NULL;
Jeej 0:1d3ed1850649 125 if (g_dbg_led != NC)
Jeej 0:1d3ed1850649 126 {
Jeej 0:1d3ed1850649 127 dbg_led = new DigitalOut(g_dbg_led);
Jeej 0:1d3ed1850649 128 }
Jeej 0:1d3ed1850649 129
Jeej 0:1d3ed1850649 130 // Die...
Jeej 0:1d3ed1850649 131 while(1)
Jeej 0:1d3ed1850649 132 {
Jeej 0:1d3ed1850649 133 if (dbg_led != NULL)
Jeej 0:1d3ed1850649 134 {
Jeej 0:1d3ed1850649 135 *(dbg_led) = !(*(dbg_led));
Jeej 0:1d3ed1850649 136 }
Jeej 0:1d3ed1850649 137 Thread::wait(30);
Jeej 0:1d3ed1850649 138 //wait_ms(30);
Jeej 0:1d3ed1850649 139 }
Jeej 0:1d3ed1850649 140 #endif
Jeej 0:1d3ed1850649 141 }
Jeej 0:1d3ed1850649 142
Jeej 0:1d3ed1850649 143 // Prints a message to the debug port.
Jeej 0:1d3ed1850649 144 void dbg_print(const char* format, ...)
Jeej 0:1d3ed1850649 145 {
Jeej 0:1d3ed1850649 146 // Critical section
Jeej 0:1d3ed1850649 147 g_dbg_ressource.lock();
Jeej 0:1d3ed1850649 148
Jeej 0:1d3ed1850649 149 int size;
Jeej 0:1d3ed1850649 150
Jeej 0:1d3ed1850649 151 va_list args;
Jeej 0:1d3ed1850649 152 va_start(args, format);
Jeej 0:1d3ed1850649 153 size = vsprintf(g_dbg_msg, format, args);
Jeej 0:1d3ed1850649 154 va_end(args);
Jeej 0:1d3ed1850649 155
Jeej 0:1d3ed1850649 156 dbg_add_to_buf(g_dbg_msg, size);
Jeej 0:1d3ed1850649 157
Jeej 0:1d3ed1850649 158 // End of critical section
Jeej 0:1d3ed1850649 159 g_dbg_ressource.unlock();
Jeej 0:1d3ed1850649 160 }
Jeej 0:1d3ed1850649 161
Jeej 0:1d3ed1850649 162 // Flush the pending debug messages.
Jeej 0:1d3ed1850649 163 void dbg_flush( void )
Jeej 0:1d3ed1850649 164 {
Jeej 0:1d3ed1850649 165 g_dbg_ressource.lock();
Jeej 0:1d3ed1850649 166 while(!g_dbg_buf.empty())
Jeej 0:1d3ed1850649 167 {
Jeej 0:1d3ed1850649 168 g_dbg_serial->putc(g_dbg_buf.pop());
Jeej 0:1d3ed1850649 169 }
Jeej 0:1d3ed1850649 170 g_dbg_ressource.unlock();
Jeej 0:1d3ed1850649 171 }
Jeej 0:1d3ed1850649 172
Jeej 0:1d3ed1850649 173 // Prints malloc parameters.
Jeej 0:1d3ed1850649 174 void* dbg_malloc(size_t size, const char* f, uint32_t l)
Jeej 0:1d3ed1850649 175 {
Jeej 0:1d3ed1850649 176 void* a;
Jeej 0:1d3ed1850649 177 a = malloc(size);
Jeej 0:1d3ed1850649 178 g_dbg_nb_mallocs++;
Jeej 0:1d3ed1850649 179 dbg_print("M @%08x %dB %s:%d (%d)\r\n", (uint32_t)a, size, f, l, g_dbg_nb_mallocs);
Jeej 0:1d3ed1850649 180 return a;
Jeej 0:1d3ed1850649 181 }
Jeej 0:1d3ed1850649 182
Jeej 0:1d3ed1850649 183 // Prints realloc parameters.
Jeej 0:1d3ed1850649 184 void* dbg_realloc(void* p, size_t size, const char* f, uint32_t l)
Jeej 0:1d3ed1850649 185 {
Jeej 0:1d3ed1850649 186 void* a;
Jeej 0:1d3ed1850649 187 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 188 a = realloc(p, size);
Jeej 0:1d3ed1850649 189 dbg_print("R @%08x->@%08x %dB %s:%d\r\n", (uint32_t)p, (uint32_t)a, size, f, l);
Jeej 0:1d3ed1850649 190 return a;
Jeej 0:1d3ed1850649 191 }
Jeej 0:1d3ed1850649 192
Jeej 0:1d3ed1850649 193 // Prints free parameters.
Jeej 0:1d3ed1850649 194 void dbg_free(void* p, const char* f, uint32_t l)
Jeej 0:1d3ed1850649 195 {
Jeej 0:1d3ed1850649 196 g_dbg_nb_mallocs--;
Jeej 0:1d3ed1850649 197 dbg_print("F @%08x %s:%d (%d)\r\n", (uint32_t)p, f, l, g_dbg_nb_mallocs);
Jeej 0:1d3ed1850649 198 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 199 free(p);
Jeej 0:1d3ed1850649 200 }
Jeej 0:1d3ed1850649 201
Jeej 0:1d3ed1850649 202 void dbg_print_data(const char* before, const char* format, uint8_t* data, uint8_t length, const char* after)
Jeej 0:1d3ed1850649 203 {
Jeej 0:1d3ed1850649 204 // Critical section
Jeej 0:1d3ed1850649 205 g_dbg_ressource.lock();
Jeej 0:1d3ed1850649 206
Jeej 0:1d3ed1850649 207 uint32_t total_len = 0;
Jeej 0:1d3ed1850649 208
Jeej 0:1d3ed1850649 209 total_len += sprintf(g_dbg_msg, before);
Jeej 0:1d3ed1850649 210
Jeej 0:1d3ed1850649 211 for (uint8_t i=0 ; i<length ; i++)
Jeej 0:1d3ed1850649 212 {
Jeej 0:1d3ed1850649 213 total_len += sprintf(&g_dbg_msg[total_len], format, data[i]);
Jeej 0:1d3ed1850649 214 dbg_assert(total_len < DBG_MAX_STRING_SIZE, "Print data too long.\r\n");
Jeej 0:1d3ed1850649 215 }
Jeej 0:1d3ed1850649 216
Jeej 0:1d3ed1850649 217 total_len += sprintf(&g_dbg_msg[total_len], after);
Jeej 0:1d3ed1850649 218
Jeej 0:1d3ed1850649 219 dbg_add_to_buf(g_dbg_msg, total_len);
Jeej 0:1d3ed1850649 220
Jeej 0:1d3ed1850649 221 // End of critical section
Jeej 0:1d3ed1850649 222 g_dbg_ressource.unlock();
Jeej 0:1d3ed1850649 223 }
Jeej 0:1d3ed1850649 224
Jeej 0:1d3ed1850649 225
Jeej 0:1d3ed1850649 226 // Thread for printing debug messages.
Jeej 0:1d3ed1850649 227 void dbg_print_thread()
Jeej 0:1d3ed1850649 228 {
Jeej 0:1d3ed1850649 229 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:1d3ed1850649 230
Jeej 0:1d3ed1850649 231 while (true)
Jeej 0:1d3ed1850649 232 {
Jeej 0:1d3ed1850649 233 g_dbg_print.wait();
Jeej 0:1d3ed1850649 234
Jeej 0:1d3ed1850649 235 if (g_dbg_missing)
Jeej 0:1d3ed1850649 236 {
Jeej 0:1d3ed1850649 237 g_dbg_serial->printf("Missing %d traces!!!\r\n", g_dbg_missing);
Jeej 0:1d3ed1850649 238 g_dbg_missing = 0;
Jeej 0:1d3ed1850649 239 }
Jeej 0:1d3ed1850649 240
Jeej 0:1d3ed1850649 241 while(!g_dbg_buf.empty())
Jeej 0:1d3ed1850649 242 {
Jeej 0:1d3ed1850649 243 g_dbg_ressource.lock();
Jeej 0:1d3ed1850649 244
Jeej 0:1d3ed1850649 245 #ifdef __FORCE_LINE_INTEGRITY__
Jeej 0:1d3ed1850649 246 // Flush until EOL
Jeej 0:1d3ed1850649 247 uint8_t byte;
Jeej 0:1d3ed1850649 248 do {
Jeej 0:1d3ed1850649 249 byte = g_dbg_buf.pop();
Jeej 0:1d3ed1850649 250 g_dbg_serial->putc(byte);
Jeej 0:1d3ed1850649 251 } while (byte != '\n');
Jeej 0:1d3ed1850649 252 #else
Jeej 0:1d3ed1850649 253 // Flush characters one by one
Jeej 0:1d3ed1850649 254 g_dbg_serial->putc(g_dbg_buf.pop());
Jeej 0:1d3ed1850649 255 #endif
Jeej 0:1d3ed1850649 256
Jeej 0:1d3ed1850649 257 g_dbg_ressource.unlock();
Jeej 0:1d3ed1850649 258 Thread::yield();
Jeej 0:1d3ed1850649 259 }
Jeej 0:1d3ed1850649 260
Jeej 0:1d3ed1850649 261 }
Jeej 0:1d3ed1850649 262 }
Jeej 0:1d3ed1850649 263
Jeej 0:1d3ed1850649 264 // Reset_Handler
Jeej 0:1d3ed1850649 265 // NMI_Handler
Jeej 0:1d3ed1850649 266 // HardFault_Handler
Jeej 0:1d3ed1850649 267 // MemManage_Handler
Jeej 0:1d3ed1850649 268 // BusFault_Handler
Jeej 0:1d3ed1850649 269 // UsageFault_Handler
Jeej 0:1d3ed1850649 270 extern "C" void HardFault_Handler() {
Jeej 0:1d3ed1850649 271 ASSERT(false, "Hard Fault!\r\n");
Jeej 0:1d3ed1850649 272 //NVIC_SystemReset();
Jeej 0:1d3ed1850649 273 }
Jeej 0:1d3ed1850649 274 extern "C" void NMI_Handler() {
Jeej 0:1d3ed1850649 275 ASSERT(false, "NMI Fault!\r\n");
Jeej 0:1d3ed1850649 276 //NVIC_SystemReset();
Jeej 0:1d3ed1850649 277 }
Jeej 0:1d3ed1850649 278 extern "C" void MemManage_Handler() {
Jeej 0:1d3ed1850649 279 ASSERT(false, "MemManage Fault!\r\n");
Jeej 0:1d3ed1850649 280 //NVIC_SystemReset();
Jeej 0:1d3ed1850649 281 }
Jeej 0:1d3ed1850649 282 extern "C" void BusFault_Handler() {
Jeej 0:1d3ed1850649 283 ASSERT(false, "BusFault Fault!\r\n");
Jeej 0:1d3ed1850649 284 //NVIC_SystemReset();
Jeej 0:1d3ed1850649 285 }
Jeej 0:1d3ed1850649 286 extern "C" void UsageFault_Handler() {
Jeej 0:1d3ed1850649 287 ASSERT(false, "UsageFault Fault!\r\n");
Jeej 0:1d3ed1850649 288 //NVIC_SystemReset();
Jeej 0:1d3ed1850649 289 }