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