/* ********************************************************************************************************* * AR100 System * AR100 Software System Develop Kits * Debugger Module * * (c) Copyright 2012-2016, Sunny China * All Rights Reserved * * File : debugger.c * By : Sunny * Version : v1.0 * Date : 2012-5-3 * Descript: debugger module. * Update : date auther ver notes * 2012-5-3 17:16:47 Sunny 1.0 Create this file. ********************************************************************************************************* */ #include "debugger_i.h" u32 debug_level = 3; volatile unsigned int print_timeflg = 1; #define DEBUG_BUFFER_SIZE (128) /* debug buffer size */ /* ********************************************************************************************************* * INITIALIZE DEBUGGER * * Description: initialize debugger. * * Arguments : none. * * Returns : OK if initialize debugger succeeded, others if failed. ********************************************************************************************************* */ s32 debugger_init(void) { /* initialize serial module */ uart_init(); #ifdef CFG_SHELL_USED extern s32 getcmd(void *parg); install_isr(INTC_R_UART_IRQ, getcmd, NULL); interrupt_enable(INTC_R_UART_IRQ); #endif return OK; } /* ********************************************************************************************************* * EXIT DEBUGGER * * Description: exit debugger. * * Arguments : none. * * Returns : OK if exit debugger succeeded, others if failed. ********************************************************************************************************* */ s32 debugger_exit(void) { return OK; } /* ********************************************************************************************************* * PUT A CHARSET * * Description: put out a charset. * * Arguments : ch : the charset which we want to put out. * * Returns : OK if put out charset succeeded, others if failed. ********************************************************************************************************* */ s32 debugger_putc(char ch) { uart_putc(ch); return OK; } /* ********************************************************************************************************* * GET A CHARSET * * Description: get a charset. * * Arguments : none. * * Returns : the charset we read from uart. ********************************************************************************************************* */ u32 debugger_get(char *buf) { return uart_get(buf); } /* ********************************************************************************************************* * PUT A STRING * * Description: put out a string. * * Arguments : string : the string which we want to put out. * * Returns : OK if put out string succeeded, others if failed. ********************************************************************************************************* */ s32 debugger_puts(char *string) { uart_puts(string); return OK; } /* ********************************************************************************************************* * FORMATTED PRINTF * * Description: print out a formatted string, similar to ANSI-C function printf(). * This function can support and only support the following conversion specifiers: * %d signed decimal integer. * %u unsigned decimal integer. * %x unsigned hexadecimal integer, using hex digits 0x. * %c single character. * %s character string. * * Arguments : format : format control. * ... : arguments. * * Returns : the number of characters printed out. * * Note : the usage refer to ANSI-C function printf(). ********************************************************************************************************* */ char debugger_buffer[DEBUG_BUFFER_SIZE]; s32 debugger_printf(u32 level, const char *format, ...) { va_list args; char string[16]; /* align by cpu word */ char *pdest; char *psrc; s32 align; s32 len = 0; s32 cpsr; if (level & (0xf0 >> (debug_level + 1))) { cpsr = cpu_disable_int(); /* dump current timestemp */ if (print_timeflg) print_current_time(); pdest = debugger_buffer; va_start(args, format); while (*format) { if (*format == '%') { ++format; if (('0' < (*format)) && ((*format) <= '9')) { /* we just suport wide from 1 to 9. */ align = *format - '0'; ++format; } else { align = 0; } switch (*format) { case 'd': { /* int */ itoa(va_arg(args, int), string, 10); len = strlen(string); len += print_align(string, len, align); strcpy(pdest, string); pdest += len; break; } case 'x': case 'p': { /* hex */ utoa(va_arg(args, unsigned long), string, 16); len = strlen(string); len += print_align(string, len, align); strcpy(pdest, string); pdest += len; break; } case 'u': { /* unsigned int */ utoa(va_arg(args, unsigned long), string, 10); len = strlen(string); len += print_align(string, len, align); strcpy(pdest, string); pdest += len; break; } case 'c': { /* charset, aligned by cpu word */ *pdest = (char)va_arg(args, int); break; } case 's': { /* string */ psrc = va_arg(args, char *); strcpy(pdest, psrc); pdest += strlen(psrc); break; } default: { /* no-conversion */ *pdest++ = '%'; *pdest++ = *format; } } } else { *pdest++ = *format; } /* parse next token */ ++format; } va_end(args); if (*(pdest - 1) == '\n') print_timeflg = 1; else print_timeflg = 0; /* must end with '\0' */ *pdest = '\0'; pdest++; debugger_puts(debugger_buffer); cpu_enable_int(cpsr); return (pdest - debugger_buffer); } return OK; } static s32 print_align(char *string, s32 len, s32 align) { /* * fill with space ' ' when align request, * the max align length is 16 byte. */ char fill_ch[] = " "; if (len < align) { /* fill at right */ strncat(string, fill_ch, align - len); return align - len; } /* not fill anything */ return 0; } /* ********************************************************************************************************* * print current time * * Description: print current time. * * Arguments : none. * * Returns : OK if print current time succeeded, others if failed. ********************************************************************************************************* */ static s32 print_current_time(void) { char time[12]; u32 millisec; u32 sec; u32 div; u32 i; /* convert current ticks to millisecond. */ millisec = current_time_tick() * (1000 / TICK_PER_SEC); /* * time print format : [secs.ms] s, * example : [0001.00] s. */ time[0] = '['; time[5] = '.'; time[8] = ']'; time[9] = ' '; time[10] = '\0'; /* second */ sec = millisec / 1000; sec = sec % 10000; div = 1000; for (i = 1; i <= 4; i++) { time[i] = ((u8)(sec / div)) + '0'; sec = sec % div; div = div / 10; } /* millisecond */ millisec = millisec % 1000; div = 100; for (i = 6; i <= 7; i++) { time[i] = ((u8)(millisec / div)) + '0'; millisec = millisec % div; div = div / 10; } /* dump time buffer */ debugger_puts(time); return OK; } /* ********************************************************************************************************* * SET DEBUG LEVEL * * Description: set debug level. * * Arguments : para level. * * Returns : OK if set the debug level succeeded. ********************************************************************************************************* */ s32 set_debug_level(u32 level) { LOG("debug_mask from %d to %d\n", debug_level, level); debug_level = level; return OK; }