Basic debug library

Dependents:   modem_ref_helper_for_v5_3_217 modem_ref_helper

Committer:
Jeej
Date:
Wed Apr 26 12:31:00 2017 +0000
Revision:
0:1d3ed1850649
Child:
2:9e2ab0547cd0
Initial version

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 0:1d3ed1850649 9 #define DBG_MAX_STRING_SIZE (150)
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 0:1d3ed1850649 66 if(size > 0)
Jeej 0:1d3ed1850649 67 {
Jeej 0:1d3ed1850649 68 if (g_dbg_buf.remaining_space() < size)
Jeej 0:1d3ed1850649 69 {
Jeej 0:1d3ed1850649 70 #ifdef __FLUSH_IF_FULL__
Jeej 0:1d3ed1850649 71 // Flush just what is needed
Jeej 0:1d3ed1850649 72 do {
Jeej 0:1d3ed1850649 73 g_dbg_serial->putc(g_dbg_buf.pop());
Jeej 0:1d3ed1850649 74 } while (g_dbg_buf.remaining_space() < size);
Jeej 0:1d3ed1850649 75
Jeej 0:1d3ed1850649 76 g_dbg_buf.add((uint8_t*)msg, size);
Jeej 0:1d3ed1850649 77 #else
Jeej 0:1d3ed1850649 78 // Discard
Jeej 0:1d3ed1850649 79 g_dbg_missing++;
Jeej 0:1d3ed1850649 80 #endif
Jeej 0:1d3ed1850649 81 }
Jeej 0:1d3ed1850649 82 else
Jeej 0:1d3ed1850649 83 {
Jeej 0:1d3ed1850649 84 // add
Jeej 0:1d3ed1850649 85 g_dbg_buf.add((uint8_t*)msg, size);
Jeej 0:1d3ed1850649 86 }
Jeej 0:1d3ed1850649 87
Jeej 0:1d3ed1850649 88 // Allow printing
Jeej 0:1d3ed1850649 89 g_dbg_print.release();
Jeej 0:1d3ed1850649 90 }
Jeej 0:1d3ed1850649 91 }
Jeej 0:1d3ed1850649 92
Jeej 0:1d3ed1850649 93 // Asserts and trap processor.
Jeej 0:1d3ed1850649 94 void dbg_assert(bool test, const char* format, ...)
Jeej 0:1d3ed1850649 95 {
Jeej 0:1d3ed1850649 96 if (test) return;
Jeej 0:1d3ed1850649 97
Jeej 0:1d3ed1850649 98 char* assert_msg = "ASSERT ";
Jeej 0:1d3ed1850649 99 int assert_size;
Jeej 0:1d3ed1850649 100 int size;
Jeej 0:1d3ed1850649 101
Jeej 0:1d3ed1850649 102 assert_size = sprintf(g_dbg_msg, assert_msg);
Jeej 0:1d3ed1850649 103
Jeej 0:1d3ed1850649 104 // expand assert string
Jeej 0:1d3ed1850649 105 va_list args;
Jeej 0:1d3ed1850649 106 va_start(args, format);
Jeej 0:1d3ed1850649 107 size = vsprintf(g_dbg_msg+assert_size, format, args);
Jeej 0:1d3ed1850649 108 va_end(args);
Jeej 0:1d3ed1850649 109
Jeej 0:1d3ed1850649 110 dbg_flush();
Jeej 0:1d3ed1850649 111
Jeej 0:1d3ed1850649 112 g_dbg_serial->printf(g_dbg_msg);
Jeej 0:1d3ed1850649 113
Jeej 0:1d3ed1850649 114 #ifdef __REBOOT_ON_ASSERT__
Jeej 0:1d3ed1850649 115 Thread::wait(1000);
Jeej 0:1d3ed1850649 116 NVIC_SystemReset();
Jeej 0:1d3ed1850649 117 #else
Jeej 0:1d3ed1850649 118 DigitalOut* dbg_led = NULL;
Jeej 0:1d3ed1850649 119 if (g_dbg_led != NC)
Jeej 0:1d3ed1850649 120 {
Jeej 0:1d3ed1850649 121 dbg_led = new DigitalOut(g_dbg_led);
Jeej 0:1d3ed1850649 122 }
Jeej 0:1d3ed1850649 123
Jeej 0:1d3ed1850649 124 // Die...
Jeej 0:1d3ed1850649 125 while(1)
Jeej 0:1d3ed1850649 126 {
Jeej 0:1d3ed1850649 127 if (dbg_led != NULL)
Jeej 0:1d3ed1850649 128 {
Jeej 0:1d3ed1850649 129 *(dbg_led) = !(*(dbg_led));
Jeej 0:1d3ed1850649 130 }
Jeej 0:1d3ed1850649 131 Thread::wait(30);
Jeej 0:1d3ed1850649 132 //wait_ms(30);
Jeej 0:1d3ed1850649 133 }
Jeej 0:1d3ed1850649 134 #endif
Jeej 0:1d3ed1850649 135 }
Jeej 0:1d3ed1850649 136
Jeej 0:1d3ed1850649 137 // Prints a message to the debug port.
Jeej 0:1d3ed1850649 138 void dbg_print(const char* format, ...)
Jeej 0:1d3ed1850649 139 {
Jeej 0:1d3ed1850649 140 // Critical section
Jeej 0:1d3ed1850649 141 g_dbg_ressource.lock();
Jeej 0:1d3ed1850649 142
Jeej 0:1d3ed1850649 143 int size;
Jeej 0:1d3ed1850649 144
Jeej 0:1d3ed1850649 145 va_list args;
Jeej 0:1d3ed1850649 146 va_start(args, format);
Jeej 0:1d3ed1850649 147 size = vsprintf(g_dbg_msg, format, args);
Jeej 0:1d3ed1850649 148 va_end(args);
Jeej 0:1d3ed1850649 149
Jeej 0:1d3ed1850649 150 dbg_add_to_buf(g_dbg_msg, size);
Jeej 0:1d3ed1850649 151
Jeej 0:1d3ed1850649 152 // End of critical section
Jeej 0:1d3ed1850649 153 g_dbg_ressource.unlock();
Jeej 0:1d3ed1850649 154 }
Jeej 0:1d3ed1850649 155
Jeej 0:1d3ed1850649 156 // Flush the pending debug messages.
Jeej 0:1d3ed1850649 157 void dbg_flush( void )
Jeej 0:1d3ed1850649 158 {
Jeej 0:1d3ed1850649 159 g_dbg_ressource.lock();
Jeej 0:1d3ed1850649 160 while(!g_dbg_buf.empty())
Jeej 0:1d3ed1850649 161 {
Jeej 0:1d3ed1850649 162 g_dbg_serial->putc(g_dbg_buf.pop());
Jeej 0:1d3ed1850649 163 }
Jeej 0:1d3ed1850649 164 g_dbg_ressource.unlock();
Jeej 0:1d3ed1850649 165 }
Jeej 0:1d3ed1850649 166
Jeej 0:1d3ed1850649 167 // Prints malloc parameters.
Jeej 0:1d3ed1850649 168 void* dbg_malloc(size_t size, const char* f, uint32_t l)
Jeej 0:1d3ed1850649 169 {
Jeej 0:1d3ed1850649 170 void* a;
Jeej 0:1d3ed1850649 171 a = malloc(size);
Jeej 0:1d3ed1850649 172 g_dbg_nb_mallocs++;
Jeej 0:1d3ed1850649 173 dbg_print("M @%08x %dB %s:%d (%d)\r\n", (uint32_t)a, size, f, l, g_dbg_nb_mallocs);
Jeej 0:1d3ed1850649 174 return a;
Jeej 0:1d3ed1850649 175 }
Jeej 0:1d3ed1850649 176
Jeej 0:1d3ed1850649 177 // Prints realloc parameters.
Jeej 0:1d3ed1850649 178 void* dbg_realloc(void* p, size_t size, const char* f, uint32_t l)
Jeej 0:1d3ed1850649 179 {
Jeej 0:1d3ed1850649 180 void* a;
Jeej 0:1d3ed1850649 181 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 182 a = realloc(p, size);
Jeej 0:1d3ed1850649 183 dbg_print("R @%08x->@%08x %dB %s:%d\r\n", (uint32_t)p, (uint32_t)a, size, f, l);
Jeej 0:1d3ed1850649 184 return a;
Jeej 0:1d3ed1850649 185 }
Jeej 0:1d3ed1850649 186
Jeej 0:1d3ed1850649 187 // Prints free parameters.
Jeej 0:1d3ed1850649 188 void dbg_free(void* p, const char* f, uint32_t l)
Jeej 0:1d3ed1850649 189 {
Jeej 0:1d3ed1850649 190 g_dbg_nb_mallocs--;
Jeej 0:1d3ed1850649 191 dbg_print("F @%08x %s:%d (%d)\r\n", (uint32_t)p, f, l, g_dbg_nb_mallocs);
Jeej 0:1d3ed1850649 192 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 193 free(p);
Jeej 0:1d3ed1850649 194 }
Jeej 0:1d3ed1850649 195
Jeej 0:1d3ed1850649 196 void dbg_print_data(const char* before, const char* format, uint8_t* data, uint8_t length, const char* after)
Jeej 0:1d3ed1850649 197 {
Jeej 0:1d3ed1850649 198 // Critical section
Jeej 0:1d3ed1850649 199 g_dbg_ressource.lock();
Jeej 0:1d3ed1850649 200
Jeej 0:1d3ed1850649 201 uint32_t total_len = 0;
Jeej 0:1d3ed1850649 202
Jeej 0:1d3ed1850649 203 total_len += sprintf(g_dbg_msg, before);
Jeej 0:1d3ed1850649 204
Jeej 0:1d3ed1850649 205 for (uint8_t i=0 ; i<length ; i++)
Jeej 0:1d3ed1850649 206 {
Jeej 0:1d3ed1850649 207 total_len += sprintf(&g_dbg_msg[total_len], format, data[i]);
Jeej 0:1d3ed1850649 208 dbg_assert(total_len < DBG_MAX_STRING_SIZE, "Print data too long.\r\n");
Jeej 0:1d3ed1850649 209 }
Jeej 0:1d3ed1850649 210
Jeej 0:1d3ed1850649 211 total_len += sprintf(&g_dbg_msg[total_len], after);
Jeej 0:1d3ed1850649 212
Jeej 0:1d3ed1850649 213 dbg_add_to_buf(g_dbg_msg, total_len);
Jeej 0:1d3ed1850649 214
Jeej 0:1d3ed1850649 215 // End of critical section
Jeej 0:1d3ed1850649 216 g_dbg_ressource.unlock();
Jeej 0:1d3ed1850649 217 }
Jeej 0:1d3ed1850649 218
Jeej 0:1d3ed1850649 219
Jeej 0:1d3ed1850649 220 // Thread for printing debug messages.
Jeej 0:1d3ed1850649 221 void dbg_print_thread()
Jeej 0:1d3ed1850649 222 {
Jeej 0:1d3ed1850649 223 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:1d3ed1850649 224
Jeej 0:1d3ed1850649 225 while (true)
Jeej 0:1d3ed1850649 226 {
Jeej 0:1d3ed1850649 227 g_dbg_print.wait();
Jeej 0:1d3ed1850649 228
Jeej 0:1d3ed1850649 229 if (g_dbg_missing)
Jeej 0:1d3ed1850649 230 {
Jeej 0:1d3ed1850649 231 g_dbg_serial->printf("Missing %d traces!!!\r\n", g_dbg_missing);
Jeej 0:1d3ed1850649 232 g_dbg_missing = 0;
Jeej 0:1d3ed1850649 233 }
Jeej 0:1d3ed1850649 234
Jeej 0:1d3ed1850649 235 while(!g_dbg_buf.empty())
Jeej 0:1d3ed1850649 236 {
Jeej 0:1d3ed1850649 237 g_dbg_ressource.lock();
Jeej 0:1d3ed1850649 238
Jeej 0:1d3ed1850649 239 #ifdef __FORCE_LINE_INTEGRITY__
Jeej 0:1d3ed1850649 240 // Flush until EOL
Jeej 0:1d3ed1850649 241 uint8_t byte;
Jeej 0:1d3ed1850649 242 do {
Jeej 0:1d3ed1850649 243 byte = g_dbg_buf.pop();
Jeej 0:1d3ed1850649 244 g_dbg_serial->putc(byte);
Jeej 0:1d3ed1850649 245 } while (byte != '\n');
Jeej 0:1d3ed1850649 246 #else
Jeej 0:1d3ed1850649 247 // Flush characters one by one
Jeej 0:1d3ed1850649 248 g_dbg_serial->putc(g_dbg_buf.pop());
Jeej 0:1d3ed1850649 249 #endif
Jeej 0:1d3ed1850649 250
Jeej 0:1d3ed1850649 251 g_dbg_ressource.unlock();
Jeej 0:1d3ed1850649 252 Thread::yield();
Jeej 0:1d3ed1850649 253 }
Jeej 0:1d3ed1850649 254
Jeej 0:1d3ed1850649 255 }
Jeej 0:1d3ed1850649 256 }
Jeej 0:1d3ed1850649 257
Jeej 0:1d3ed1850649 258 // Reset_Handler
Jeej 0:1d3ed1850649 259 // NMI_Handler
Jeej 0:1d3ed1850649 260 // HardFault_Handler
Jeej 0:1d3ed1850649 261 // MemManage_Handler
Jeej 0:1d3ed1850649 262 // BusFault_Handler
Jeej 0:1d3ed1850649 263 // UsageFault_Handler
Jeej 0:1d3ed1850649 264 extern "C" void HardFault_Handler() {
Jeej 0:1d3ed1850649 265 ASSERT(false, "Hard Fault!\r\n");
Jeej 0:1d3ed1850649 266 //NVIC_SystemReset();
Jeej 0:1d3ed1850649 267 }
Jeej 0:1d3ed1850649 268 extern "C" void NMI_Handler() {
Jeej 0:1d3ed1850649 269 ASSERT(false, "NMI Fault!\r\n");
Jeej 0:1d3ed1850649 270 //NVIC_SystemReset();
Jeej 0:1d3ed1850649 271 }
Jeej 0:1d3ed1850649 272 extern "C" void MemManage_Handler() {
Jeej 0:1d3ed1850649 273 ASSERT(false, "MemManage Fault!\r\n");
Jeej 0:1d3ed1850649 274 //NVIC_SystemReset();
Jeej 0:1d3ed1850649 275 }
Jeej 0:1d3ed1850649 276 extern "C" void BusFault_Handler() {
Jeej 0:1d3ed1850649 277 ASSERT(false, "BusFault Fault!\r\n");
Jeej 0:1d3ed1850649 278 //NVIC_SystemReset();
Jeej 0:1d3ed1850649 279 }
Jeej 0:1d3ed1850649 280 extern "C" void UsageFault_Handler() {
Jeej 0:1d3ed1850649 281 ASSERT(false, "UsageFault Fault!\r\n");
Jeej 0:1d3ed1850649 282 //NVIC_SystemReset();
Jeej 0:1d3ed1850649 283 }