Nut/OS  4.10.3
API Reference
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 #include <compiler.h>
00078 
00079 #include <cfg/os.h>
00080 
00081 #include <sys/thread.h>
00082 #include <sys/timer.h>
00083 #include <sys/event.h>
00084 #include <sys/heap.h>
00085 
00086 #include <sys/osdebug.h>
00087 
00088 #if defined(__arm__) || defined(__AVR32__) || defined(__m68k__) || defined(__H8300H__) || defined(__H8300S__) || defined(__NUT_EMULATION__)
00089 #define ARCH_32BIT
00090 #endif
00091 
00092 
00093 FILE *__os_trs;
00094 uint_fast8_t __os_trf;
00095 
00096 FILE *__heap_trs;
00097 uint_fast8_t __heap_trf;
00098 
00099 static char *states[] = { "TRM", "RUN", "RDY", "SLP" };
00100 
00101 #ifdef ARCH_32BIT
00102 /*                              12345678 12345678 1234 123 12345678 12345678 12345678 1234556789 123456789*/
00103 static prog_char qheader[] = "\nHandle   Name     Prio Sta Queue    Timer    StackPtr   FreeMem  MinStack\n";
00104 #else
00105 /*                              1234 12345678 1234 123 1234 1234 1234 1234567 12345678*/
00106 static prog_char qheader[] = "\nHndl Name     Prio Sta QUE  Timr StkP FreeMem MinStack\n";
00107 #endif
00108 
00118 void NutDumpThreadQueue(FILE * stream, NUTTHREADINFO * tdp)
00119 {
00120 #ifdef ARCH_32BIT
00121     static prog_char fmt[] = "%08lX %-8s %4u %s %08lX %08lX %08lX %9lu %s\n";
00122 #else
00123     static prog_char fmt[] = "%04lX %-8s %4u %s %04lX %04lX %04lX %5lu %s\n";
00124 #endif
00125 
00126     if (tdp == SIGNALED)
00127         fputs("SIGNALED\n", stream);
00128     else {
00129         while (tdp) {
00130 #ifdef __NUT_EMULATION__
00131             fprintf_P(stream, fmt, (uintptr_t) tdp, tdp->td_name, tdp->td_priority,
00132                       states[tdp->td_state], (uintptr_t) tdp->td_queue, (uintptr_t) tdp->td_timer, tdp->td_cs_level, 0, "--");
00133 #else
00134             fprintf_P(stream, fmt, (long) (intptr_t) tdp, tdp->td_name, tdp->td_priority,
00135                       states[tdp->td_state], (long) (intptr_t) tdp->td_queue,
00136                       (long) (intptr_t) tdp->td_timer, (long) tdp->td_sp,
00137                       (long) tdp->td_sp - (long) (intptr_t) tdp->td_memory,
00138                       *((uint32_t *) tdp->td_memory) != DEADBEEF
00139                       && *((uint32_t *) (tdp->td_memory + 4)) != DEADBEEF
00140                       && *((uint32_t *) (tdp->td_memory + 8)) != DEADBEEF
00141                       && *((uint32_t *) (tdp->td_memory + 12)) != DEADBEEF ? "FAIL" : "OK");
00142 #endif
00143             tdp = tdp->td_qnxt;
00144 
00145         }
00146     }
00147 }
00148 
00157 void NutDumpThreadList(FILE * stream)
00158 {
00159 
00160 #ifdef ARCH_32BIT
00161     static prog_char fmt1[] = "%08X %-8s %4u %s %08X %08X %08X %9u %9u %s";
00162     static prog_char fmt2[] = " %08X";
00163 #else
00164     static prog_char fmt1[] = "%04X %-8s %4u %s %04X %04X %04X %7u %8u %s";
00165     static prog_char fmt2[] = " %04X";
00166 #endif
00167     NUTTHREADINFO *tqp;
00168     NUTTHREADINFO *tdp;
00169 
00170     fputs_P(qheader, stream);
00171 
00172     tdp = nutThreadList;
00173     while (tdp) {
00174 #ifdef __NUT_EMULATION__
00175         fprintf_P(stream, fmt1, (uintptr_t) tdp, tdp->td_name, tdp->td_priority,
00176                   states[tdp->td_state], (uintptr_t) tdp->td_queue, (uintptr_t) tdp->td_timer, tdp->td_cs_level, 0, "--");
00177 #else
00178         fprintf_P(stream, fmt1, (int) tdp, tdp->td_name, tdp->td_priority,
00179                   states[tdp->td_state], (int) tdp->td_queue,
00180                   (int) tdp->td_timer, (int) tdp->td_sp,
00181                   (int) tdp->td_sp - (int) tdp->td_memory, (unsigned int) NutThreadStackAvailable(tdp->td_name), 
00182                   *((uint32_t *) tdp->td_memory) != DEADBEEF ? "FAIL" : "OK");
00183 #endif
00184         if (tdp->td_queue) {
00185             tqp = *(NUTTHREADINFO **) (tdp->td_queue);
00186             if (tqp == SIGNALED)
00187                 fputs("SIGNALED", stream);
00188             else {
00189                 while (tqp) {
00190                     fprintf_P(stream, fmt2, (int) tqp);
00191                     tqp = tqp->td_qnxt;
00192                 }
00193             }
00194         }
00195         fputc('\n', stream);
00196         tdp = tdp->td_next;
00197     }
00198 }
00199 
00208 void NutDumpTimerList(FILE * stream)
00209 {
00210 
00211     static prog_char wname[] = "NutThreadWake";
00212     static prog_char tname[] = "NutEventTimeout";
00213 #ifdef ARCH_32BIT
00214     static prog_char theader[] = "Address  Ticks  Left Callback\n";
00215     static prog_char fmt1[] = "%08X%6lu%6lu ";
00216     static prog_char fmt2[] = "%09lX";
00217     static prog_char fmt3[] = "(%08X)\n";
00218 #else
00219     static prog_char theader[] = "Addr Ticks  Left Callback\n";
00220     static prog_char fmt1[] = "%04X%6lu%6lu ";
00221     static prog_char fmt2[] = "%05lX";
00222     static prog_char fmt3[] = "(%04X)\n";
00223 #endif
00224 
00225     NUTTIMERINFO *tnp;
00226     if ((tnp = nutTimerList) != 0) {
00227         fputs_P(theader, stream);
00228         while (tnp) {
00229             fprintf_P(stream, fmt1, (int) tnp, tnp->tn_ticks, tnp->tn_ticks_left);
00230             if (tnp->tn_callback == NutThreadWake)
00231                 fputs_P(wname, stream);
00232             else if (tnp->tn_callback == NutEventTimeout)
00233                 fputs_P(tname, stream);
00234             else
00235                 fprintf_P(stream, fmt2, (uint32_t) ((uintptr_t) tnp->tn_callback) << 1);
00236             fprintf_P(stream, fmt3, (int) tnp->tn_arg);
00237             tnp = tnp->tn_next;
00238         }
00239     }
00240 }
00241 
00249 void NutTraceOs(FILE * stream, uint8_t flags)
00250 {
00251     if (stream)
00252         __os_trs = stream;
00253     if (__os_trs)
00254         __os_trf = flags;
00255     else
00256         __os_trf = 0;
00257 }
00258 
00265 void NutDumpHeap(FILE * stream)
00266 {
00267 
00268 #ifdef ARCH_32BIT
00269     static prog_char fmt1[] = "%08x %9d\n";
00270     static prog_char fmt2[] = "%u counted, but %u reported\n";
00271     static prog_char fmt3[] = "%u bytes free\n";
00272 #else
00273     static prog_char fmt1[] = "%04x %5d\n";
00274     static prog_char fmt2[] = "%u counted, but %u reported\n";
00275     static prog_char fmt3[] = "%u bytes free\n";
00276 #endif
00277     HEAPNODE *node;
00278     size_t sum = 0;
00279     size_t avail;
00280 
00281     fputc('\n', stream);
00282     for (node = heapFreeList; node; node = node->hn_next) {
00283         sum += node->hn_size;
00284         fprintf_P(stream, fmt1, (int) node, (unsigned int) node->hn_size);
00285         /* TODO: Remove hardcoded RAMSTART and RAMEND */
00286         if ((uintptr_t) node < 0x60 || (uintptr_t) node > 0x7fff)
00287             break;
00288     }
00289     if ((avail = NutHeapAvailable()) != sum)
00290         fprintf_P(stream, fmt2, (unsigned int) sum, (unsigned int) avail);
00291     else
00292         fprintf_P(stream, fmt3, (unsigned int) avail);
00293 }
00294 
00302 void NutTraceHeap(FILE * stream, uint8_t flags)
00303 {
00304     if (stream)
00305         __heap_trs = stream;
00306     if (__heap_trs)
00307         __heap_trf = flags;
00308     else
00309         __heap_trf = 0;
00310 }