Basic debug library
Dependents: modem_ref_helper_for_v5_3_217 modem_ref_helper
WizziDebug.cpp
00001 #include "mbed.h" 00002 #include "rtos.h" 00003 #include "WizziDebug.h" 00004 #include <stdio.h> 00005 #include <string.h> 00006 #include <stdarg.h> 00007 00008 #define DBG_MAX_STRING_SIZE (256) 00009 #define TX_BUF_SIZE (512) 00010 00011 static kal_buf_circ_handle_t g_cbuf; 00012 static kal_buf_circ_static_handle_t g_cbuf_h; 00013 static kal_buf_circ_static_buffer_t(g_cbuf_b, TX_BUF_SIZE, sizeof(uint8_t)); 00014 static char g_dbg_msg[DBG_MAX_STRING_SIZE]; 00015 static Thread g_dbg_thread(osPriorityLow, 512, NULL, "wizzidbg"); 00016 static RawSerial* g_dbg_serial; 00017 static Mutex g_dbg_ressource; 00018 static Semaphore g_dbg_print(0); 00019 static uint32_t g_dbg_nb_mallocs; 00020 static PinName __attribute__((unused)) g_dbg_led; 00021 static uint32_t g_dbg_missing; 00022 static void (*g_dbg_rx_callback)(char c) = NULL; 00023 00024 void dbg_print_thread(); 00025 00026 static void dbg_serial_rx_isr(void) 00027 { 00028 if (!g_dbg_rx_callback) 00029 { 00030 PRINT("%c", g_dbg_serial->getc()); 00031 return; 00032 } 00033 00034 // Loop just in case more than one character is in UART's receive FIFO buffer 00035 while (g_dbg_serial->readable()) 00036 { 00037 g_dbg_rx_callback(g_dbg_serial->getc()); 00038 } 00039 } 00040 00041 // Redefine mbed error function 00042 void error(const char* format, ...) 00043 { 00044 char buf[DBG_MAX_STRING_SIZE]; 00045 00046 va_list args; 00047 va_start(args, format); 00048 vsprintf(buf, format, args); 00049 va_end(args); 00050 00051 ASSERT(false, buf); 00052 } 00053 00054 void dbg_open(PinName led, PinName tx, PinName rx) 00055 { 00056 //FPRINT("\r\n"); 00057 00058 g_dbg_nb_mallocs = 0; 00059 g_dbg_led = led; 00060 g_dbg_missing = 0; 00061 00062 g_cbuf = &g_cbuf_h; 00063 kal_buf_circ_create_static(&g_cbuf_h, g_cbuf_b, TX_BUF_SIZE, sizeof(char)); 00064 00065 g_dbg_serial = new RawSerial(tx, rx, 115200); 00066 g_dbg_serial->format(8, SerialBase::None, 1); 00067 g_dbg_serial->attach(callback(&dbg_serial_rx_isr), Serial::RxIrq); 00068 00069 g_dbg_thread.start(dbg_print_thread); 00070 } 00071 00072 // Destructor 00073 void dbg_close( void ) 00074 { 00075 FPRINT("\r\n"); 00076 g_dbg_thread.terminate(); 00077 delete g_dbg_serial; 00078 } 00079 00080 void dbg_set_led(PinName led, PinName dummy1, PinName dummy2) 00081 { 00082 FPRINT("\r\n"); 00083 g_dbg_led = led; 00084 } 00085 00086 static void dbg_add_to_buf(char* msg, int size) 00087 { 00088 uint8_t c; 00089 00090 #ifdef __FORCE_FLUSH__ 00091 for (int i = 0; i < size; i++) 00092 { 00093 g_dbg_serial->putc(msg[i]); 00094 } 00095 #else 00096 if(size > 0) 00097 { 00098 if (kal_buf_circ_space(g_cbuf) < size) 00099 { 00100 #ifdef __FLUSH_IF_FULL__ 00101 // Flush just what is needed 00102 do { 00103 kal_buf_circ_pop(g_cbuf, &c); 00104 g_dbg_serial->putc(c); 00105 } while (kal_buf_circ_space(g_cbuf) < size); 00106 00107 kal_buf_circ_put(g_cbuf, (uint8_t*)msg, size); 00108 #else 00109 // Discard 00110 g_dbg_missing++; 00111 #endif 00112 } 00113 else 00114 { 00115 // add 00116 kal_buf_circ_put(g_cbuf, (uint8_t*)msg, size); 00117 } 00118 00119 // Allow printing 00120 g_dbg_print.release(); 00121 } 00122 #endif 00123 } 00124 00125 // Asserts and trap processor. 00126 void dbg_assert(bool test, const char* format, ...) 00127 { 00128 if (test) return; 00129 00130 int assert_size; 00131 00132 assert_size = sprintf(g_dbg_msg, "ASSERT "); 00133 00134 // expand assert string 00135 va_list args; 00136 va_start(args, format); 00137 vsprintf(g_dbg_msg+assert_size, format, args); 00138 va_end(args); 00139 00140 dbg_flush(); 00141 00142 g_dbg_serial->printf(g_dbg_msg); 00143 00144 #ifdef __REBOOT_ON_ASSERT__ 00145 ThisThread::sleep_for(1000); 00146 NVIC_SystemReset(); 00147 #else 00148 DigitalOut* dbg_led = NULL; 00149 if (g_dbg_led != NC) 00150 { 00151 dbg_led = new DigitalOut(g_dbg_led); 00152 } 00153 00154 // Die... 00155 while(1) 00156 { 00157 if (dbg_led != NULL) 00158 { 00159 *(dbg_led) = !(*(dbg_led)); 00160 } 00161 ThisThread::sleep_for(30); 00162 //wait_ms(30); 00163 } 00164 #endif 00165 } 00166 00167 // Prints a message to the debug port. 00168 void dbg_print(const char* format, ...) 00169 { 00170 int size; 00171 00172 va_list args; 00173 va_start(args, format); 00174 size = vsprintf(g_dbg_msg, format, args); 00175 va_end(args); 00176 00177 dbg_add_to_buf(g_dbg_msg, size); 00178 } 00179 00180 // Flush the pending debug messages. 00181 void dbg_flush( void ) 00182 { 00183 uint8_t c; 00184 00185 g_dbg_ressource.lock(); 00186 while(!kal_buf_circ_empty(g_cbuf)) 00187 { 00188 kal_buf_circ_pop(g_cbuf, &c); 00189 g_dbg_serial->putc(c); 00190 } 00191 g_dbg_ressource.unlock(); 00192 } 00193 00194 // Prints malloc parameters. 00195 void* dbg_malloc(size_t size, const char* f, uint32_t l) 00196 { 00197 void* a; 00198 a = malloc(size); 00199 g_dbg_nb_mallocs++; 00200 dbg_print("M @%08x %dB %s:%d (%d)\r\n", (uint32_t)a, size, f, l, g_dbg_nb_mallocs); 00201 return a; 00202 } 00203 00204 // Prints realloc parameters. 00205 void* dbg_realloc(void* p, size_t size, const char* f, uint32_t l) 00206 { 00207 void* a; 00208 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); 00209 a = realloc(p, size); 00210 dbg_print("R @%08x->@%08x %dB %s:%d\r\n", (uint32_t)p, (uint32_t)a, size, f, l); 00211 return a; 00212 } 00213 00214 // Prints free parameters. 00215 void dbg_free(void* p, const char* f, uint32_t l) 00216 { 00217 g_dbg_nb_mallocs--; 00218 dbg_print("F @%08x %s:%d (%d)\r\n", (uint32_t)p, f, l, g_dbg_nb_mallocs); 00219 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); 00220 free(p); 00221 } 00222 00223 void dbg_print_data(const char* before, const char* format, uint8_t* data, uint8_t length, const char* after) 00224 { 00225 uint32_t total_len = 0; 00226 00227 total_len += sprintf(g_dbg_msg, before); 00228 00229 for (uint8_t i=0 ; i<length ; i++) 00230 { 00231 total_len += sprintf(&g_dbg_msg[total_len], format, data[i]); 00232 dbg_assert(total_len < DBG_MAX_STRING_SIZE, "Print data too long.\r\n"); 00233 } 00234 00235 total_len += sprintf(&g_dbg_msg[total_len], after); 00236 00237 dbg_add_to_buf(g_dbg_msg, total_len); 00238 } 00239 00240 00241 // Thread for printing debug messages. 00242 void dbg_print_thread() 00243 { 00244 uint8_t c; 00245 00246 FPRINT("(id:0x%08x)\r\n", osThreadGetId()); 00247 00248 while (true) 00249 { 00250 g_dbg_print.acquire(); 00251 00252 if (g_dbg_missing) 00253 { 00254 g_dbg_serial->printf("Missing %d traces!!!\r\n", g_dbg_missing); 00255 g_dbg_missing = 0; 00256 } 00257 00258 while(!kal_buf_circ_empty(g_cbuf)) 00259 { 00260 g_dbg_ressource.lock(); 00261 00262 #ifdef __FORCE_LINE_INTEGRITY__ 00263 // Flush until EOL 00264 uint8_t byte; 00265 do { 00266 kal_buf_circ_pop(g_cbuf, &c); 00267 g_dbg_serial->putc(c); 00268 } while (byte != '\n' && !kal_buf_circ_empty(g_cbuf)); 00269 #else 00270 // Flush characters one by one 00271 kal_buf_circ_pop(g_cbuf, &c); 00272 g_dbg_serial->putc(c); 00273 #endif 00274 00275 g_dbg_ressource.unlock(); 00276 ThisThread::yield(); 00277 } 00278 } 00279 } 00280 00281 void dbg_set_rx_callback(void (*rx_isr)(char c)) 00282 { 00283 g_dbg_rx_callback = rx_isr; 00284 }
Generated on Sat Jul 16 2022 17:03:31 by 1.7.2