00001 /** @file 00002 * @brief TiROS Debugging Interface 00003 */ 00004 00005 #ifndef __TIROS_DEBUG_H_ 00006 #define __TIROS_DEBUG_H_ 00007 00008 /* Author: Ratish J. Punnoose, 2006 00009 * This file is part of TiROS, the Tickless Real-Time Operating System. 00010 * Copyright(c) 2006, 2007: Ratish J. Punnoose. 00011 * Copyright(c) 2006 Sandia Corporation. Under the terms of Contract 00012 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains 00013 * certain rights in this software. 00014 * 00015 * TiROS is free software; you can redistribute it and/or modify it under 00016 * the terms of the GNU General Public License as published by the Free 00017 * Software Foundation; either version 2 or (at your option) any later version. 00018 * 00019 * TiROS is distributed in the hope that it will be useful, but WITHOUT ANY 00020 * WARRANTY; without even the implied warranty of MERCHANTABILITY or 00021 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00022 * for more details. 00023 * 00024 * You should have received a copy of the GNU General Public License along 00025 * with TiROS; if not, write to the Free Software Foundation, Inc., 00026 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00027 * 00028 * As a special exception, if other files instantiate templates or use macros 00029 * or inline functions from this file, or you compile this file and link it 00030 * with other works to produce a work based on this file, this file does not 00031 * by itself cause the resulting work to be covered by the GNU General Public 00032 * License. However the source code for this file must still be made available 00033 * in accordance with section (3) of the GNU General Public License. 00034 * 00035 * This exception does not invalidate any other reasons why a work based on 00036 * this file might be covered by the GNU General Public License. 00037 * 00038 */ 00039 00040 00041 00042 00043 /** @addtogroup os_advanced 00044 * 00045 * @{ */ 00046 00047 00048 /** A representation of the debug header data. 00049 * 00050 * TiROS does not use this structure directly. This is presented here 00051 * to illustrate the type of debug data that TiROS encodes. */ 00052 struct os_data_hdr { 00053 /** Byte 1: Options. RegisterPassing, ExtraDebugging, 00054 * \verbatim 00055 Reserved - 4 bit. 00056 prio_sort_method - 2 bits -- 00 - not included. 00057 01 - method = 1 00058 10 - method = 2 00059 11 - method = 3 00060 RegisterPassing - 1 bit. 00061 StackChecking - 1 bit. 00062 \endverbatim 00063 */ 00064 unsigned char os_options; 00065 00066 /** Byte 2: Data Type sizes 1. 00067 * Data type sizes are either 8,16,32,64 bits. Any value in 00068 * between (for ex. 24 bits) is padded up to the next highest 00069 * value. 00070 *\verbatim 00071 tid_t size - 2 bits: 8, 16, 32, 64 bits. 00072 subtime_t size - 2 bits: 8, 16, 32, 64 bits. 00073 flag_t size - 2 bits: 8, 16, 32, 64 bits. 00074 osword_t size - 2bits 00075 \endverbatim */ 00076 unsigned char data_sizes1; 00077 00078 /** Byte 3: Data Type sizes 2. 00079 Pointer Word size - 2 bits: 8, 16, 32, 64 bits */ 00080 unsigned char data_sizes2; 00081 00082 00083 unsigned char os_max_procs; /**< TIROS_MAX_PROCS */ 00084 00085 /* This structure will align nicely on a four byte boundary */ 00086 }; 00087 00088 /** \cond */ 00089 00090 #define TIROS_DEBUG_PRIOSORT_SET(x) ( (x&0x03) << 2) 00091 #define TIROS_DEBUG_PRIOSORT_GET(x) ( (x >> 2) & 0x03) 00092 00093 #define TIROS_DEBUG_REG_PASSING (0x01 << 1) 00094 #define TIROS_DEBUG_STKCHK (0x01 << 0) 00095 00096 #define TIROS_DEBUG_SETNUMBYTES(val, bitpos) ( (val & 0x03) << bitpos) 00097 #define TIROS_DEBUG_GETSZ(byte, bitpos) ( 1 << ((byte >> bitpos) & 0x03)) 00098 00099 #define osword_t_OFFSET 0 00100 #define tid_t_OFFSET 6 00101 #define subtime_t_OFFSET 4 00102 #define flag_t_OFFSET 2 00103 #define osptrword_t_OFFSET 0 00104 00105 /** \endcond */ 00106 00107 00108 #ifdef TIROSINT_DATA_DEBUG 00109 #include "tr_int.h" 00110 #include "tr_llmgr.h" 00111 00112 00113 /* tr_int.h and tr_llmgr.h are included since they are also relevant 00114 * for debugging. tr_int.h provides apis to get the state of kernel 00115 * data structures. tr_llmgr.h does the same, but contains all the 00116 * list management specific data. 00117 * tr_int.h provides osint_gettrdata(trintdata_t *); 00118 * tr_llmgr.h provides osint_getlistdata(trlistdata_t *); 00119 **/ 00120 00121 00122 /** This structure is a representation of the global debug data. 00123 * This structure is not used anywhere directly. It is used here to 00124 * describe the order and nature of the collected debug data. */ 00125 struct os_data_global { 00126 uint32_t curr_time_units; 00127 subtime_t curr_time_subunits; 00128 tid_t running_task; 00129 tid_t readylisthead; 00130 tid_t waitlisthead; 00131 tid_t isr_nesting; 00132 /* The above data will align nicely on a four byte boundary */ 00133 00134 osword_t ctxt_switch_cnt; 00135 /* This will still keep it aligned on a word boundary */ 00136 }; 00137 00138 00139 00140 /** This structure is a representation of the variable internal data. 00141 * 00142 * This structure shows how TiROS packs the debugging data. 00143 * Note that TiROS does not uses this structure directly. 00144 */ 00145 struct os_data_per_task { 00146 struct TCB task_TCB; /* Per task TCB */ 00147 00148 osptr_t task_pc; /* Program counter */ 00149 00150 #ifdef TIROS_STK_CHECK 00151 osword_t curr_stkusage; /* Current stack occupancy */ 00152 osword_t max_stkusage; /* Maximum stack occupancy of the task at 00153 * any time */ 00154 #endif 00155 00156 00157 #if (TIROS_PRIO_SORT_METHOD == 1) 00158 /* The following data is not related to this task, but is the 00159 * entry in the appropriate queue for this tid index. */ 00160 tid_t readyQ_val; /* Task that is in the readyQ at index x */ 00161 tid_t waitQ_val; /* Task that is in the waitQ at index x */ 00162 #else 00163 #error "TIROS_PRIO_SOFT_METHOD has undefined debug information" 00164 00165 #endif 00166 00167 }; 00168 00169 00170 00171 /** This structure describes the data returned by osint_snapshot. 00172 * Note however, that the data is not organized into this structure. 00173 * The way this data is packed into a data stream is dependent 00174 * on the compiler, processor architecture and the sizes of the data 00175 * types used. So TiROS dos not use this structure, rather osint_snapshot 00176 * packs the data efficiently into a byte stream. */ 00177 struct os_internal_debug_data { 00178 struct os_data_hdr hdr; 00179 struct os_data_global globals; 00180 struct os_data_per_task per_task[TIROS_MAX_PROCS]; 00181 }; 00182 00183 00184 00185 00186 00187 /** Recommended size of the buffer to hold the TiROS internal debug data*/ 00188 #define TIROS_DEBUG_DATA_SZ (sizeof (struct os_internal_debug_data)) 00189 00190 00191 /** A snapshot of all the internal os data. 00192 * 00193 * This can be used by a dedicated task to send out debugging info 00194 * The data is packed into a tight architecture independent 00195 * little-endian byte stream. The type of data that is packed is 00196 * illustrated in os_internal_debug_data. 00197 * To use this function, tr_debug.h should be included by 00198 * the source file and TIROSINT_DATA_DEBUG should be defined in 00199 * proj_config.h 00200 * 00201 * The TiROS state is written in a compact endian-neutral format. This can be parsed using the 00202 * tiros_parse program that is included with the distribution. This 00203 * form of debugging provides a wealth of information. Here is example 00204 * output, parsed by tiros_parse, showing the debug data output by the 00205 * example in os_examples/os_debug_example. This output was obtained 00206 * from an msp430_gcc port. 00207 * 00208 * NOTE: The information about the debugging task itself may not be 00209 * fully accurate. It will reflect the state of the task at the last 00210 * context switch. 00211 \verbatim 00212 -------------------------------------------------- 00213 os_options = 0x07, data_sizes1 = 0x15, data_sizes2 = 0x01, max_procs = 8 00214 Record size = 240 00215 TIROS Settings 00216 PrioSort: 1 reg_passing: 1 stk_chk_info: 1 oswordt_sz: 2 00217 tidtsz: 1 subtimet_sz: 2 flagt_sz: 2 osptrwordt_sz: 2 00218 max_procs: 8 00219 gdata_len: 12 data_per_task_len: 28 task_tcb_len: 20 record_sz: 240 00220 ******************************************************************************** 00221 5:41515 RUN: 1 RDY: 1 WT: 0 NESTING: 0 CTXT_CNT: 12 00222 -------------------------------------------------------------------------------- 00223 TSK CP PRIO EFF FLAGS MUTXS TIMEOUT LK_PTR EVTS ... 00224 0 0x1310 0 0 0x10 0 6: 640 0xffff 0x0000 ... 00225 1 0x13aa 1 1 0x00 0 5:41483 0xffff 0x0000 ... 00226 2 0x1442 2 2 0x10 0 4294967295:65535 0x1530 0x0001 ... 00227 3 0x150e 3 3 0x00 0 0: 0 0xffff 0x0000 ... 00228 4 0xffff 0 0 0x00 0 0: 0 0x0000 0x0000 ... 00229 5 0xffff 0 0 0x00 0 0: 0 0x0000 0x0000 ... 00230 6 0xffff 0 0 0x00 0 0: 0 0x0000 0x0000 ... 00231 7 0xffff 0 0 0x00 0 0: 0 0x0000 0x0000 ... 00232 ---------------------------------------------------------------------- 00233 ... STK STKSZ PC CUR_STK MAX_STK R/W Q LK Q 00234 ... 0x12b8 79 0x472a 35 36 0x02 0xff 00235 ... 0x1356 79 0xffff 0 38 0x03 0xff 00236 ... 0x13f4 79 0x472a 40 41 0xff 0xff 00237 ... 0x1492 79 0x59ec 17 30 0xff 0xff 00238 ... 0x0000 0 0xffff 0 0 0xff 0xff 00239 ... 0x0000 0 0xffff 0 0 0xff 0xff 00240 ... 0x0000 0 0xffff 0 0 0xff 0xff 00241 ... 0x0000 0 0xffff 0 0 0xff 0xff 00242 ---------------------------------------------------------------------- 00243 \endverbatim 00244 As can be seen, there is a prolific amount of information: 00245 <UL> 00246 <LI>the sizes of all the data types including task control block sizes. </LI> 00247 <LI> the TIROS_MAX_PROCS value that was configured into the program 00248 during compilation.</LI> 00249 <LI> Time. 00250 <LI> The running task ID, task IDs of the heads of the ready queue 00251 and wait queue. 00252 <LI> the ISR nesting level. </LI> 00253 <LI> number of context switches since reset. </LI> 00254 </UL> 00255 On a per-task basis, the following information is available: 00256 <UL> 00257 <LI> TSK: The task id. </LI> 00258 <LI> CP: The current context pointer. </LI> 00259 <LI> PRIO: The priority of the task. </LI> 00260 <LI> EFF: The effective priorityof the task. </LI> 00261 <LI> FLAGS: Internal flags used to mark the task's state. </LI> 00262 <LI> MUTXS: The number of mutexes held by the task. </LI> 00263 <LI> TIMEOUT: The wait or sleep timeout. </LI> 00264 <LI> LK_PTR: Pointer to a lock that the task is waiting on if 00265 any. </LI> 00266 <LI> EVTS: Event bitmask that the task is waiting on. </LI> 00267 <LI> STK: The base stack pointer provided during task 00268 initialization. (only if TIROS_STK_CHECK is defined).</LI> 00269 <LI> STKSZ: The stack size provided during task initialization. (only 00270 if TIROS_STK_CHECK is defined).</LI> 00271 <LI> PC: The program counter (or instruction pointer) is available if 00272 the hardware port supports this. </LI> 00273 <LI> CUR_STK: The current stack usage is provided if the hardware 00274 port supports this. </LI> 00275 <LI> MAX_STK: The maximum stack usage of the task (throughout its run 00276 so far) is provided if the hardware port supports this. </LI> 00277 </UL> 00278 The R/W Q and LK Q columns can be used to decipher the order of the 00279 tasks in the read/wait list and lock list respectively. 00280 00281 * 00282 * @param [in] memaddr Memory address to copy the data structures. 00283 * If this is set to ILLEGAL_ADDR, the return 00284 * value contains the size that the data 00285 * structures would occupy in bytes. 00286 * It is recommended that buffer be 00287 * TIROS_DEBUG_DATA_SZ long. 00288 * @param [in] memsz Size of the memory location. 00289 * @return If memaddr is set to ILLEGAL_ADDR< this returns the size 00290 * of the data structures, else 00291 * ERR_FAILED, if not enough memory. 00292 * the actual length of the byte stream, if success. 00293 */ 00294 int osint_snapshot(unsigned char *buffer , int memsz); 00295 00296 00297 /** @} */ 00298 00299 00300 00301 #endif 00302 00303 00304 00305 #endif /* TIROS_DEBUG_H */