Now you can download a copy of these docs so you can use them offline! Download now
Utility.cpp
00001 /*----------------------------------------------------------------------------*/ 00002 /* Copyright (c) FIRST 2008. All Rights Reserved. */ 00003 /* Open Source Software - may be modified and shared by FRC teams. The code */ 00004 /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */ 00005 /*----------------------------------------------------------------------------*/ 00006 00007 #include "Utility.h" 00008 00009 #include "NetworkCommunication/FRCComm.h" 00010 #include "ChipObject.h" 00011 #include "Task.h" 00012 #include <dbgLib.h> 00013 #include <stdio.h> 00014 #include <sysSymTbl.h> 00015 #include "nivision.h" 00016 00017 #define DBG_DEMANGLE_PRINT_LEN 256 /* Num chars of demangled names to print */ 00018 00019 extern "C" 00020 { 00021 extern char * cplusDemangle (char *source, char *dest, INT32 n); 00022 } 00023 00024 char *wpi_getLabel(UINT addr, INT32 *found) 00025 { 00026 INT32 pVal; 00027 SYM_TYPE pType; 00028 char name[MAX_SYS_SYM_LEN + 1]; 00029 static char label[DBG_DEMANGLE_PRINT_LEN + 1 + 11]; 00030 bzero(label, DBG_DEMANGLE_PRINT_LEN + 1 + 11); 00031 00032 if (symFindByValue(sysSymTbl, addr, name, &pVal, &pType) == OK) 00033 { 00034 cplusDemangle(name, label, sizeof(label) - 11); 00035 if ((UINT)pVal != addr) 00036 { 00037 sprintf(&label[strlen(label)], "+0x%04x", addr-pVal); 00038 if (found) *found = 2; 00039 } 00040 else 00041 { 00042 if (found) *found = 1; 00043 } 00044 } 00045 else 00046 { 00047 sprintf(label, "0x%04x", addr); 00048 if (found) *found = 0; 00049 } 00050 00051 return label; 00052 } 00053 /* 00054 static void wpiTracePrint(INSTR *caller, INT32 func, INT32 nargs, INT32 *args, INT32 taskId, BOOL isKernelAdrs) 00055 { 00056 char buf [MAX_SYS_SYM_LEN * 2]; 00057 INT32 ix; 00058 INT32 len = 0; 00059 len += sprintf (&buf [len], "%s <%#010x>: ", wpi_getLabel((UINT)caller), (INT32)caller); 00060 len += sprintf (&buf [len], "%s <%#010x> (", wpi_getLabel((UINT)func), func); 00061 for (ix = 0; ix < nargs; ix++) 00062 { 00063 if (ix != 0) 00064 len += sprintf (&buf [len], ", "); 00065 len += sprintf (&buf [len], "%#x", args [ix]); 00066 } 00067 len += sprintf (&buf [len], ")\n"); 00068 00069 printf(buf); 00070 } 00071 */ 00072 static void wpiCleanTracePrint(INSTR *caller, INT32 func, INT32 nargs, INT32 *args, INT32 taskId, BOOL isKernelAdrs) 00073 { 00074 char buf [MAX_SYS_SYM_LEN]; 00075 INT32 ix; 00076 INT32 len = 0; 00077 INT32 nameFound = 0; 00078 INT32 params = 0; 00079 INT32 totalnargs = nargs; 00080 char *funcName = wpi_getLabel((UINT)func, &nameFound); 00081 // Ignore names that are not exact symbol address matches. 00082 if (nameFound != 1) return; 00083 00084 // Ignore internal function name matches. 00085 if (strncmp(funcName, "wpi_assert", 10) == 0) return; 00086 if (strncmp(funcName, "wpi_fatal", 9) == 0) return; 00087 if (strncmp(funcName, "wpi_selfTrace", 13) == 0) return; 00088 if (strncmp(funcName, "Error::Set", 10) == 0) return; 00089 if (strncmp(funcName, "ErrorBase::SetError", 19) == 0) return; 00090 if (strncmp(funcName, "Error::Report", 13) == 0) return; 00091 00092 // Find the number of arguments in the name string. 00093 char *start = strchr(funcName, '('); 00094 char *end = strrchr(funcName, ')'); 00095 if (start + 1 != end && start != NULL) 00096 { 00097 do 00098 { 00099 params++; 00100 if(strncmp(start+1, "bool", 4) == 0 || strncmp(start+2, "bool", 4) == 0) 00101 { 00102 totalnargs++; 00103 } 00104 start = strchr(start + 1, ','); 00105 } 00106 while(start < end && start != NULL); 00107 } 00108 char *funcNameEnd = strchr(funcName, '('); 00109 *funcNameEnd = 0; 00110 len += sprintf (&buf [len], funcName); 00111 00112 // If this is a member function, print out the this pointer value. 00113 if (totalnargs - params == 1) 00114 { 00115 len += sprintf (&buf [len], "<this=%#x>", args [0]); 00116 } 00117 00118 // Print out the argument values. 00119 len += sprintf (&buf [len], "("); 00120 for (ix = totalnargs - params; ix < nargs; ix++) 00121 { 00122 if (ix != totalnargs - params) 00123 len += sprintf (&buf [len], ", "); 00124 len += sprintf (&buf [len], "%#x", args [ix]); 00125 } 00126 len += sprintf (&buf [len], ")\n"); 00127 00128 printf(buf); 00129 } 00130 00131 extern "C" 00132 { 00133 extern void trcStack(REG_SET* pRegs, FUNCPTR printRtn, INT32 tid); 00134 } 00135 00136 static INT32 wpiStackTask(INT32 taskId) 00137 { 00138 taskDelay(1); 00139 //tt(taskId); 00140 00141 REG_SET regs; 00142 taskRegsGet(taskId, ®s); 00143 trcStack(®s, (FUNCPTR) wpiCleanTracePrint, taskId); 00144 printf("\n"); 00145 00146 // The task should be resumed because it had to be suspended to get the stack trace. 00147 taskResume(taskId); 00148 return 0; 00149 } 00150 00151 void wpi_selfTrace() 00152 { 00153 INT32 priority=100; 00154 taskPriorityGet(0, &priority); 00155 // Lower priority than the calling task. 00156 Task traceTask("StackTrace", (FUNCPTR)wpiStackTask, priority + 1); 00157 traceTask.Start(taskIdSelf()); 00158 00159 // Task to be traced must be suspended for the stack trace to work. 00160 taskSuspend(0); 00161 } 00162 00163 static bool stackTraceEnabled = false; 00164 static bool suspendOnAssertEnabled = false; 00165 00169 void wpi_stackTraceOnAssertEnable(bool enabled) 00170 { 00171 stackTraceEnabled = enabled; 00172 } 00173 00180 void wpi_suspendOnAssertEnabled(bool enabled) 00181 { 00182 suspendOnAssertEnabled = enabled; 00183 } 00184 00185 static void wpi_handleTracing() 00186 { 00187 if (stackTraceEnabled) 00188 { 00189 printf("\n-----------<Stack Trace>----------------\n"); 00190 wpi_selfTrace(); 00191 } 00192 printf("\n"); 00193 } 00194 00200 bool wpi_assert_impl(bool conditionValue, 00201 const char *conditionText, 00202 const char *message, 00203 const char *fileName, 00204 UINT32 lineNumber, 00205 const char *funcName) 00206 { 00207 if (!conditionValue) 00208 { 00209 // Error string buffer 00210 char error[256]; 00211 00212 // If an error message was specified, include it 00213 // Build error string 00214 if(message != NULL) { 00215 sprintf(error, "Assertion failed: \"%s\", \"%s\" failed in %s() in %s at line %d\n", 00216 message, conditionText, funcName, fileName, lineNumber); 00217 } else { 00218 sprintf(error, "Assertion failed: \"%s\" in %s() in %s at line %d\n", 00219 conditionText, funcName, fileName, lineNumber); 00220 } 00221 00222 // Print to console and send to remote dashboard 00223 printf("\n\n>>>>%s", error); 00224 setErrorData(error, strlen(error), 100); 00225 00226 wpi_handleTracing(); 00227 if (suspendOnAssertEnabled) taskSuspend(0); 00228 } 00229 return conditionValue; 00230 } 00231 00237 void wpi_assertEqual_common_impl(int valueA, 00238 int valueB, 00239 const char *equalityType, 00240 const char *message, 00241 const char *fileName, 00242 UINT32 lineNumber, 00243 const char *funcName) 00244 { 00245 // Error string buffer 00246 char error[256]; 00247 00248 // If an error message was specified, include it 00249 // Build error string 00250 if(message != NULL) { 00251 sprintf(error, "Assertion failed: \"%s\", \"%d\" %s \"%d\" in %s() in %s at line %d\n", 00252 message, valueA, equalityType, valueB, funcName, fileName, lineNumber); 00253 } else { 00254 sprintf(error, "Assertion failed: \"%d\" %s \"%d\" in %s() in %s at line %d\n", 00255 valueA, equalityType, valueB, funcName, fileName, lineNumber); 00256 } 00257 00258 // Print to console and send to remote dashboard 00259 printf("\n\n>>>>%s", error); 00260 setErrorData(error, strlen(error), 100); 00261 00262 wpi_handleTracing(); 00263 if (suspendOnAssertEnabled) taskSuspend(0); 00264 } 00265 00272 bool wpi_assertEqual_impl(int valueA, 00273 int valueB, 00274 const char *message, 00275 const char *fileName, 00276 UINT32 lineNumber, 00277 const char *funcName) 00278 { 00279 if(!(valueA == valueB)) 00280 { 00281 wpi_assertEqual_common_impl(valueA, valueB, "!=", message, fileName, lineNumber, funcName); 00282 } 00283 return valueA == valueB; 00284 } 00285 00292 bool wpi_assertNotEqual_impl(int valueA, 00293 int valueB, 00294 const char *message, 00295 const char *fileName, 00296 UINT32 lineNumber, 00297 const char *funcName) 00298 { 00299 if(!(valueA != valueB)) 00300 { 00301 wpi_assertEqual_common_impl(valueA, valueB, "==", message, fileName, lineNumber, funcName); 00302 } 00303 return valueA != valueB; 00304 } 00305 00306 00312 UINT16 GetFPGAVersion() 00313 { 00314 tRioStatusCode status = 0; 00315 tGlobal *global = tGlobal::create(&status); 00316 UINT16 version = global->readVersion(&status); 00317 delete global; 00318 wpi_setGlobalError(status); 00319 return version; 00320 } 00321 00330 UINT32 GetFPGARevision() 00331 { 00332 tRioStatusCode status = 0; 00333 tGlobal *global = tGlobal::create(&status); 00334 UINT32 revision = global->readRevision(&status); 00335 delete global; 00336 wpi_setGlobalError(status); 00337 return revision; 00338 } 00339 00345 UINT32 GetFPGATime() 00346 { 00347 tRioStatusCode status = 0; 00348 tGlobal *global = tGlobal::create(&status); 00349 UINT32 time = global->readLocalTime(&status); 00350 delete global; 00351 wpi_setGlobalError(status); 00352 return time; 00353 } 00354 00355 // RT hardware access functions exported from ni_emb.out 00356 extern "C" 00357 { 00358 INT32 UserSwitchInput(INT32 nSwitch); 00359 INT32 LedInput(INT32 led); 00360 INT32 LedOutput(INT32 led, INT32 value); 00361 } 00362 00366 INT32 GetRIOUserSwitch() 00367 { 00368 INT32 switchValue = UserSwitchInput(0); 00369 wpi_assert(switchValue >= 0); 00370 return switchValue > 0; 00371 } 00372 00376 void SetRIOUserLED(UINT32 state) 00377 { 00378 LedOutput(0, state > 0); 00379 } 00380 00385 INT32 GetRIOUserLED() 00386 { 00387 return LedInput(0); 00388 } 00389 00394 INT32 ToggleRIOUserLED() 00395 { 00396 INT32 ledState = !GetRIOUserLED(); 00397 SetRIOUserLED(ledState); 00398 return ledState; 00399 } 00400 00404 void SetRIO_FPGA_LED(UINT32 state) 00405 { 00406 tRioStatusCode status = 0; 00407 tGlobal *global = tGlobal::create(&status); 00408 global->writeFPGA_LED(state, &status); 00409 wpi_setGlobalError(status); 00410 delete global; 00411 } 00412 00417 INT32 GetRIO_FPGA_LED() 00418 { 00419 tRioStatusCode status = 0; 00420 tGlobal *global = tGlobal::create(&status); 00421 bool ledValue = global->readFPGA_LED(&status); 00422 wpi_setGlobalError(status); 00423 delete global; 00424 return ledValue; 00425 } 00426 00431 INT32 ToggleRIO_FPGA_LED() 00432 { 00433 INT32 ledState = !GetRIO_FPGA_LED(); 00434 SetRIO_FPGA_LED(ledState); 00435 return ledState; 00436 } 00437 00438
Generated on Thu Jan 12 2012 22:35:25 for WPILibC++ by
1.7.1