osdebug.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2005 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00034 /*
00035  * $Log$
00036  * Revision 1.10  2009/03/05 22:16:57  freckle
00037  * use __NUT_EMULATION instead of __APPLE__, __linux__, or __CYGWIN__
00038  *
00039  * Revision 1.9  2009/01/17 11:26:52  haraldkipp
00040  * Getting rid of two remaining BSD types in favor of stdint.
00041  * Replaced 'u_int' by 'unsinged int' and 'uptr_t' by 'uintptr_t'.
00042  *
00043  * Revision 1.8  2008/08/11 07:00:34  haraldkipp
00044  * BSD types replaced by stdint types (feature request #1282721).
00045  *
00046  * Revision 1.7  2005/07/26 15:50:00  haraldkipp
00047  * Cygwin support added.
00048  *
00049  * Revision 1.6  2005/07/12 14:07:14  freckle
00050  * removed unnecessary critical sections
00051  *
00052  * Revision 1.5  2005/06/12 16:55:24  haraldkipp
00053  * Timer pool has been removed from the kernel.
00054  *
00055  * Revision 1.4  2004/04/07 12:13:58  haraldkipp
00056  * Matthias Ringwald's *nix emulation added
00057  *
00058  * Revision 1.3  2004/03/19 09:05:12  jdubiec
00059  * Fixed format strings declarations for AVR.
00060  *
00061  * Revision 1.2  2004/03/16 16:48:45  haraldkipp
00062  * Added Jan Dubiec's H8/300 port.
00063  *
00064  * Revision 1.1.1.1  2003/05/09 14:41:52  haraldkipp
00065  * Initial using 3.2.1
00066  *
00067  * Revision 1.8  2003/04/21 17:09:01  harald
00068  * *** empty log message ***
00069  *
00070  * Revision 1.7  2003/02/04 18:15:57  harald
00071  * Version 3 released
00072  *
00073  * Revision 1.6  2002/06/26 17:29:44  harald
00074  * First pre-release with 2.4 stack
00075  *
00076  */
00077 
00078 #include <compiler.h>
00079 #include <sys/thread.h>
00080 #include <sys/timer.h>
00081 #include <sys/event.h>
00082 #include <sys/heap.h>
00083 
00084 #include <sys/osdebug.h>
00085 
00086 #if defined(__arm__) || defined(__AVR32__) || defined(__m68k__) || defined(__H8300H__) || defined(__H8300S__) || defined(__NUT_EMULATION__)
00087 #define ARCH_32BIT
00088 #endif
00089 
00090 
00091 FILE *__os_trs;
00092 uint_fast8_t __os_trf;
00093 
00094 FILE *__heap_trs;
00095 uint_fast8_t __heap_trf;
00096 
00097 static char *states[] = { "TRM", "RUN", "RDY", "SLP" };
00098 
00099 #ifdef ARCH_32BIT
00100 /*                              12345678 12345678 1234 123 12345678 12345678 12345678 1234556789 */
00101 static prog_char qheader[] = "\nHandle   Name     Prio Sta Queue    Timer    StackPtr FreeMem\n";
00102 #else
00103 /*                              1234 12345678 1234 123 1234 1234 1234 12345 */
00104 static prog_char qheader[] = "\nHndl Name     Prio Sta QUE  Timr StkP FreeMem\n";
00105 #endif
00106 
00116 void NutDumpThreadQueue(FILE * stream, NUTTHREADINFO * tdp)
00117 {
00118 #ifdef ARCH_32BIT
00119     static prog_char fmt[] = "%08lX %-8s %4u %s %08lX %08lX %08lX %9lu %s\n";
00120 #else
00121     static prog_char fmt[] = "%04X %-8s %4u %s %04X %04X %04X %5u %s\n";
00122 #endif
00123 
00124     if (tdp == SIGNALED)
00125         fputs("SIGNALED\n", stream);
00126     else {
00127         while (tdp) {
00128 #ifdef __NUT_EMULATION__
00129             fprintf_P(stream, fmt, (uintptr_t) tdp, tdp->td_name, tdp->td_priority,
00130                       states[tdp->td_state], (uintptr_t) tdp->td_queue, (uintptr_t) tdp->td_timer, tdp->td_cs_level, 0, "--");
00131 #else
00132             fprintf_P(stream, fmt, (uintptr_t) tdp, tdp->td_name, tdp->td_priority,
00133                       states[tdp->td_state], (uintptr_t) tdp->td_queue,
00134                       (uintptr_t) tdp->td_timer, tdp->td_sp,
00135                       (uintptr_t) tdp->td_sp - (uintptr_t) tdp->td_memory,
00136                       *((uint32_t *) tdp->td_memory) != DEADBEEF
00137                       && *((uint32_t *) (tdp->td_memory + 4)) != DEADBEEF
00138                       && *((uint32_t *) (tdp->td_memory + 8)) != DEADBEEF
00139                       && *((uint32_t *) (tdp->td_memory + 12)) != DEADBEEF ? "FAIL" : "OK");
00140 #endif
00141             tdp = tdp->td_qnxt;
00142 
00143         }
00144     }
00145 }
00146 
00155 void NutDumpThreadList(FILE * stream)
00156 {
00157 
00158 #ifdef ARCH_32BIT
00159     static prog_char fmt1[] = "%08lX %-8s %4u %s %08lX %08lX %08lX %9lu %s";
00160     static prog_char fmt2[] = " %08lX";
00161 #else
00162     static prog_char fmt1[] = "%04X %-8s %4u %s %04X %04X %04X %5u %s";
00163     static prog_char fmt2[] = " %04X";
00164 #endif
00165     NUTTHREADINFO *tqp;
00166     NUTTHREADINFO *tdp;
00167 
00168     fputs_P(qheader, stream);
00169 
00170     tdp = nutThreadList;
00171     while (tdp) {
00172 #ifdef __NUT_EMULATION__
00173         fprintf_P(stream, fmt1, (uintptr_t) tdp, tdp->td_name, tdp->td_priority,
00174                   states[tdp->td_state], (uintptr_t) tdp->td_queue, (uintptr_t) tdp->td_timer, tdp->td_cs_level, 0, "--");
00175 #else
00176         fprintf_P(stream, fmt1, (uintptr_t) tdp, tdp->td_name, tdp->td_priority,
00177                   states[tdp->td_state], (uintptr_t) tdp->td_queue,
00178                   (uintptr_t) tdp->td_timer, tdp->td_sp,
00179                   (uintptr_t) tdp->td_sp - (uintptr_t) tdp->td_memory, *((uint32_t *) tdp->td_memory) != DEADBEEF ? "FAIL" : "OK");
00180 #endif
00181         if (tdp->td_queue) {
00182             tqp = *(NUTTHREADINFO **) (tdp->td_queue);
00183             if (tqp == SIGNALED)
00184                 fputs("SIGNALED", stream);
00185             else {
00186                 while (tqp) {
00187                     fprintf_P(stream, fmt2, (uintptr_t) tqp);
00188                     tqp = tqp->td_qnxt;
00189                 }
00190             }
00191         }
00192         fputc('\n', stream);
00193         tdp = tdp->td_next;
00194     }
00195 }
00196 
00205 void NutDumpTimerList(FILE * stream)
00206 {
00207 
00208     static prog_char wname[] = "NutThreadWake";
00209     static prog_char tname[] = "NutEventTimeout";
00210 #ifdef ARCH_32BIT
00211     static prog_char theader[] = "Address  Ticks  Left Callback\n";
00212     static prog_char fmt1[] = "%08lX%6lu%6lu ";
00213     static prog_char fmt2[] = "%09lX";
00214     static prog_char fmt3[] = "(%08lX)\n";
00215 #else
00216     static prog_char theader[] = "Addr Ticks  Left Callback\n";
00217     static prog_char fmt1[] = "%04X%6lu%6lu ";
00218     static prog_char fmt2[] = "%05lX";
00219     static prog_char fmt3[] = "(%04X)\n";
00220 #endif
00221 
00222     NUTTIMERINFO *tnp;
00223     if ((tnp = nutTimerList) != 0) {
00224         fputs_P(theader, stream);
00225         while (tnp) {
00226             fprintf_P(stream, fmt1, (uintptr_t) tnp, tnp->tn_ticks, tnp->tn_ticks_left);
00227             if (tnp->tn_callback == NutThreadWake)
00228                 fputs_P(wname, stream);
00229             else if (tnp->tn_callback == NutEventTimeout)
00230                 fputs_P(tname, stream);
00231             else
00232                 fprintf_P(stream, fmt2, (uint32_t) ((uintptr_t) tnp->tn_callback) << 1);
00233             fprintf_P(stream, fmt3, (uintptr_t) tnp->tn_arg);
00234             tnp = tnp->tn_next;
00235         }
00236     }
00237 }
00238 
00246 void NutTraceOs(FILE * stream, uint8_t flags)
00247 {
00248     if (stream)
00249         __os_trs = stream;
00250     if (__os_trs)
00251         __os_trf = flags;
00252     else
00253         __os_trf = 0;
00254 }
00255 
00262 void NutDumpHeap(FILE * stream)
00263 {
00264 
00265 #ifdef ARCH_32BIT
00266     static prog_char fmt1[] = "%08lx %9ld\n";
00267     static prog_char fmt2[] = "%lu counted, but %lu reported\n";
00268     static prog_char fmt3[] = "%lu bytes free\n";
00269 #else
00270     static prog_char fmt1[] = "%04x %5d\n";
00271     static prog_char fmt2[] = "%u counted, but %u reported\n";
00272     static prog_char fmt3[] = "%u bytes free\n";
00273 #endif
00274     HEAPNODE *node;
00275     size_t sum = 0;
00276     size_t avail;
00277 
00278     fputc('\n', stream);
00279     for (node = heapFreeList; node; node = node->hn_next) {
00280         sum += node->hn_size;
00281         fprintf_P(stream, fmt1, (uintptr_t) node, node->hn_size);
00282         /* TODO: Remove hardcoded RAMSTART and RAMEND */
00283         if ((uintptr_t) node < 0x60 || (uintptr_t) node > 0x7fff)
00284             break;
00285     }
00286     if ((avail = NutHeapAvailable()) != sum)
00287         fprintf_P(stream, fmt2, sum, avail);
00288     else
00289         fprintf_P(stream, fmt3, avail);
00290 }
00291 
00299 void NutTraceHeap(FILE * stream, uint8_t flags)
00300 {
00301     if (stream)
00302         __heap_trs = stream;
00303     if (__heap_trs)
00304         __heap_trf = flags;
00305     else
00306         __heap_trf = 0;
00307 }

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/