kdebug.c
Go to the documentation of this file.00001
00040 #include "cfg/cfg_debug.h"
00041 #include <cfg/macros.h>
00042 #include <cfg/debug.h>
00043 #include <cfg/os.h>
00044
00045 #include <cpu/attr.h>
00046 #include <cpu/types.h>
00047
00048 #include <mware/formatwr.h>
00049 #include <cpu/pgm.h>
00050
00051 #ifdef _DEBUG
00052
00053 #if CPU_HARVARD && !defined(_PROGMEM)
00054 #error This module build correctly only in program memory!
00055 #endif
00056
00057
00058 #if OS_HOSTED
00059 #include <unistd.h>
00060
00061 #define KDBG_WAIT_READY() do { } while(0)
00062 #define KDBG_WRITE_CHAR(c) do { char __c = (c); write(STDERR_FILENO, &__c, sizeof(__c)); } while(0)
00063 #define KDBG_MASK_IRQ(old) do { (void)(old); } while(0)
00064 #define KDBG_RESTORE_IRQ(old) do { } while(0)
00065 typedef char kdbg_irqsave_t;
00066
00067 #define kdbg_hw_init() do {} while (0)
00068
00069 #if CONFIG_KDEBUG_PORT == 666
00070 #error BITBANG debug console missing for this platform
00071 #endif
00072 #else
00073 #include CPU_CSOURCE(kdebug)
00074 #endif
00075
00076
00077 void kdbg_init(void)
00078 {
00079
00080 kdbg_hw_init();
00081 kputs("\n\n*** BeRTOS DBG START ***\n");
00082 }
00083
00084
00088 static void __kputchar(char c, UNUSED_ARG(void *, unused))
00089 {
00090
00091 KDBG_WAIT_READY();
00092
00093
00094 if (c == '\n')
00095 {
00096 KDBG_WRITE_CHAR('\r');
00097 KDBG_WAIT_READY();
00098 }
00099
00100 KDBG_WRITE_CHAR(c);
00101 }
00102
00103
00104 void kputchar(char c)
00105 {
00106
00107 kdbg_irqsave_t irqsave;
00108 KDBG_MASK_IRQ(irqsave);
00109
00110 __kputchar(c, 0);
00111
00112
00113 KDBG_RESTORE_IRQ(irqsave);
00114 }
00115
00116
00117 static void PGM_FUNC(kvprintf)(const char * PGM_ATTR fmt, va_list ap)
00118 {
00119 #if CONFIG_PRINTF
00120
00121 kdbg_irqsave_t irqsave;
00122 KDBG_MASK_IRQ(irqsave);
00123
00124 PGM_FUNC(_formatted_write)(fmt, __kputchar, 0, ap);
00125
00126
00127 KDBG_RESTORE_IRQ(irqsave);
00128 #else
00129
00130 PGM_FUNC(kputs)(fmt);
00131 #endif
00132 }
00133
00134 void PGM_FUNC(kprintf)(const char * PGM_ATTR fmt, ...)
00135 {
00136 va_list ap;
00137
00138 va_start(ap, fmt);
00139 PGM_FUNC(kvprintf)(fmt, ap);
00140 va_end(ap);
00141 }
00142
00143 void PGM_FUNC(kputs)(const char * PGM_ATTR str)
00144 {
00145 char c;
00146
00147
00148 kdbg_irqsave_t irqsave;
00149 KDBG_MASK_IRQ(irqsave);
00150
00151 while ((c = PGM_READ_CHAR(str++)))
00152 __kputchar(c, 0);
00153
00154 KDBG_RESTORE_IRQ(irqsave);
00155 }
00156
00157
00161 int kputnum(int num)
00162 {
00163 int output_len = 0;
00164 int divisor = 10000;
00165 int digit;
00166
00167 do
00168 {
00169 digit = num / divisor;
00170 num %= divisor;
00171
00172 if (digit || output_len || divisor == 1)
00173 {
00174 kputchar(digit + '0');
00175 ++output_len;
00176 }
00177 }
00178 while (divisor /= 10);
00179
00180 return output_len;
00181 }
00182
00183
00184 static void klocation(const char * PGM_ATTR file, int line)
00185 {
00186 PGM_FUNC(kputs)(file);
00187 kputchar(':');
00188 kputnum(line);
00189 PGM_FUNC(kputs)(PGM_STR(": "));
00190 }
00191
00192 int PGM_FUNC(__bassert)(const char * PGM_ATTR cond, const char * PGM_ATTR file, int line)
00193 {
00194 klocation(file, line);
00195 PGM_FUNC(kputs)(PGM_STR("Assertion failed: "));
00196 PGM_FUNC(kputs)(cond);
00197 kputchar('\n');
00198 BREAKPOINT;
00199 return 1;
00200 }
00201
00202
00203
00204
00205
00206
00207 void PGM_FUNC(__trace)(const char *name)
00208 {
00209 PGM_FUNC(kprintf)(PGM_STR("%s()\n"), name);
00210 }
00211
00212 void PGM_FUNC(__tracemsg)(const char *name, const char * PGM_ATTR fmt, ...)
00213 {
00214 va_list ap;
00215
00216 PGM_FUNC(kprintf)(PGM_STR("%s(): "), name);
00217 va_start(ap, fmt);
00218 PGM_FUNC(kvprintf)(fmt, ap);
00219 va_end(ap);
00220 kputchar('\n');
00221 }
00222
00223 int PGM_FUNC(__invalid_ptr)(void *value, const char * PGM_ATTR name, const char * PGM_ATTR file, int line)
00224 {
00225 klocation(file, line);
00226 PGM_FUNC(kputs)(PGM_STR("Invalid ptr: "));
00227 PGM_FUNC(kputs)(name);
00228 #if CONFIG_PRINTF
00229 PGM_FUNC(kprintf)(PGM_STR(" = 0x%p\n"), value);
00230 #else
00231 (void)value;
00232 kputchar('\n');
00233 #endif
00234 return 1;
00235 }
00236
00237
00238 void __init_wall(long *wall, int size)
00239 {
00240 while(size--)
00241 *wall++ = WALL_VALUE;
00242 }
00243
00244
00245 int PGM_FUNC(__check_wall)(long *wall, int size, const char * PGM_ATTR name, const char * PGM_ATTR file, int line)
00246 {
00247 int i, fail = 0;
00248
00249 for (i = 0; i < size; i++)
00250 {
00251 if (wall[i] != WALL_VALUE)
00252 {
00253 klocation(file, line);
00254 PGM_FUNC(kputs)(PGM_STR("Wall broken: "));
00255 PGM_FUNC(kputs)(name);
00256 #if CONFIG_PRINTF
00257 PGM_FUNC(kprintf)(PGM_STR("[%d] (0x%p) = 0x%lx\n"), i, wall + i, wall[i]);
00258 #else
00259 kputchar('\n');
00260 #endif
00261 fail = 1;
00262 }
00263 }
00264
00265 return fail;
00266 }
00267
00268
00269 #if CONFIG_PRINTF
00270
00274 void kdump(const void *_buf, size_t len)
00275 {
00276 const unsigned char *buf = (const unsigned char *)_buf;
00277
00278 while (len--)
00279 kprintf("%02X", *buf++);
00280 kputchar('\n');
00281 }
00282
00283 #endif
00284
00285 #endif