Now you can download a copy of these docs so you can use them offline! Download now
Utility.cpp
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) FIRST 2008. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
5 /*----------------------------------------------------------------------------*/
6 
7 #include "Utility.h"
8 
9 #include "NetworkCommunication/FRCComm.h"
10 #include "ChipObject.h"
11 #include "Task.h"
12 #include <dbgLib.h>
13 #include <stdio.h>
14 #include <sysSymTbl.h>
15 #include "nivision.h"
16 
17 #define DBG_DEMANGLE_PRINT_LEN 256 /* Num chars of demangled names to print */
18 
19 extern "C"
20 {
21  extern char * cplusDemangle (char *source, char *dest, int32_t n);
22 }
23 
24 char *wpi_getLabel(UINT addr, int32_t *found)
25 {
26  int pVal;
27  SYM_TYPE pType;
28  char name[MAX_SYS_SYM_LEN + 1];
29  static char label[DBG_DEMANGLE_PRINT_LEN + 1 + 11];
30  bzero(label, DBG_DEMANGLE_PRINT_LEN + 1 + 11);
31 
32  if (symFindByValue(sysSymTbl, addr, name, &pVal, &pType) == OK)
33  {
34  cplusDemangle(name, label, sizeof(label) - 11);
35  if ((UINT)pVal != addr)
36  {
37  sprintf(&label[strlen(label)], "+0x%04x", addr-pVal);
38  if (found) *found = 2;
39  }
40  else
41  {
42  if (found) *found = 1;
43  }
44  }
45  else
46  {
47  sprintf(label, "0x%04x", addr);
48  if (found) *found = 0;
49  }
50 
51  return label;
52 }
53 /*
54 static void wpiTracePrint(INSTR *caller, int32_t func, int32_t nargs, int32_t *args, int32_t taskId, BOOL isKernelAdrs)
55 {
56  char buf [MAX_SYS_SYM_LEN * 2];
57  int32_t ix;
58  int32_t len = 0;
59  len += sprintf (&buf [len], "%s <%#010x>: ", wpi_getLabel((UINT)caller), (int32_t)caller);
60  len += sprintf (&buf [len], "%s <%#010x> (", wpi_getLabel((UINT)func), func);
61  for (ix = 0; ix < nargs; ix++)
62  {
63  if (ix != 0)
64  len += sprintf (&buf [len], ", ");
65  len += sprintf (&buf [len], "%#x", args [ix]);
66  }
67  len += sprintf (&buf [len], ")\n");
68 
69  printf(buf);
70 }
71 */
72 static void wpiCleanTracePrint(INSTR *caller, int32_t func, int32_t nargs, int32_t *args, int32_t taskId, BOOL isKernelAdrs)
73 {
74  char buf [MAX_SYS_SYM_LEN];
75  int32_t ix;
76  int32_t len = 0;
77  int32_t nameFound = 0;
78  int32_t params = 0;
79  int32_t totalnargs = nargs;
80  char *funcName = wpi_getLabel((UINT)func, &nameFound);
81  // Ignore names that are not exact symbol address matches.
82  if (nameFound != 1) return;
83 
84  // Ignore internal function name matches.
85  if (strncmp(funcName, "wpi_assert", 10) == 0) return;
86  if (strncmp(funcName, "wpi_fatal", 9) == 0) return;
87  if (strncmp(funcName, "wpi_selfTrace", 13) == 0) return;
88  if (strncmp(funcName, "Error::Set", 10) == 0) return;
89  if (strncmp(funcName, "ErrorBase::SetError", 19) == 0) return;
90  if (strncmp(funcName, "Error::Report", 13) == 0) return;
91 
92  // Find the number of arguments in the name string.
93  char *start = strchr(funcName, '(');
94  char *end = strrchr(funcName, ')');
95  if (start + 1 != end && start != NULL)
96  {
97  do
98  {
99  params++;
100  if(strncmp(start+1, "bool", 4) == 0 || strncmp(start+2, "bool", 4) == 0)
101  {
102  totalnargs++;
103  }
104  start = strchr(start + 1, ',');
105  }
106  while(start < end && start != NULL);
107  }
108  char *funcNameEnd = strchr(funcName, '(');
109  *funcNameEnd = 0;
110  len += sprintf (&buf [len], funcName);
111 
112  // If this is a member function, print out the this pointer value.
113  if (totalnargs - params == 1)
114  {
115  len += sprintf (&buf [len], "<this=%#lx>", args [0]);
116  }
117 
118  // Print out the argument values.
119  len += sprintf (&buf [len], "(");
120  for (ix = totalnargs - params; ix < nargs; ix++)
121  {
122  if (ix != totalnargs - params)
123  len += sprintf (&buf [len], ", ");
124  len += sprintf (&buf [len], "%#lx", args [ix]);
125  }
126  len += sprintf (&buf [len], ")\n");
127 
128  printf(buf);
129 }
130 
131 extern "C"
132 {
133  extern void trcStack(REG_SET* pRegs, FUNCPTR printRtn, int32_t tid);
134 }
135 
136 static int32_t wpiStackTask(int32_t taskId)
137 {
138  taskDelay(1);
139  //tt(taskId);
140 
141  REG_SET regs;
142  taskRegsGet(taskId, &regs);
143  trcStack(&regs, (FUNCPTR) wpiCleanTracePrint, taskId);
144  printf("\n");
145 
146  // The task should be resumed because it had to be suspended to get the stack trace.
147  taskResume(taskId);
148  return 0;
149 }
150 
151 void wpi_selfTrace()
152 {
153  int priority=100;
154  taskPriorityGet(0, &priority);
155  // Lower priority than the calling task.
156  Task traceTask("StackTrace", (FUNCPTR)wpiStackTask, priority + 1);
157  traceTask.Start(taskIdSelf());
158 
159  // Task to be traced must be suspended for the stack trace to work.
160  taskSuspend(0);
161 }
162 
163 static bool stackTraceEnabled = false;
164 static bool suspendOnAssertEnabled = false;
165 
169 void wpi_stackTraceOnAssertEnable(bool enabled)
170 {
171  stackTraceEnabled = enabled;
172 }
173 
180 void wpi_suspendOnAssertEnabled(bool enabled)
181 {
182  suspendOnAssertEnabled = enabled;
183 }
184 
185 static void wpi_handleTracing()
186 {
187  if (stackTraceEnabled)
188  {
189  printf("\n-----------<Stack Trace>----------------\n");
190  wpi_selfTrace();
191  }
192  printf("\n");
193 }
194 
200 bool wpi_assert_impl(bool conditionValue,
201  const char *conditionText,
202  const char *message,
203  const char *fileName,
204  uint32_t lineNumber,
205  const char *funcName)
206 {
207  if (!conditionValue)
208  {
209  // Error string buffer
210  char error[256];
211 
212  // If an error message was specified, include it
213  // Build error string
214  if(message != NULL) {
215  sprintf(error, "Assertion failed: \"%s\", \"%s\" failed in %s() in %s at line %ld\n",
216  message, conditionText, funcName, fileName, lineNumber);
217  } else {
218  sprintf(error, "Assertion failed: \"%s\" in %s() in %s at line %ld\n",
219  conditionText, funcName, fileName, lineNumber);
220  }
221 
222  // Print to console and send to remote dashboard
223  printf("\n\n>>>>%s", error);
224  setErrorData(error, strlen(error), 100);
225 
226  wpi_handleTracing();
227  if (suspendOnAssertEnabled) taskSuspend(0);
228  }
229  return conditionValue;
230 }
231 
237 void wpi_assertEqual_common_impl(int valueA,
238  int valueB,
239  const char *equalityType,
240  const char *message,
241  const char *fileName,
242  uint32_t lineNumber,
243  const char *funcName)
244 {
245  // Error string buffer
246  char error[256];
247 
248  // If an error message was specified, include it
249  // Build error string
250  if(message != NULL) {
251  sprintf(error, "Assertion failed: \"%s\", \"%d\" %s \"%d\" in %s() in %s at line %ld\n",
252  message, valueA, equalityType, valueB, funcName, fileName, lineNumber);
253  } else {
254  sprintf(error, "Assertion failed: \"%d\" %s \"%d\" in %s() in %s at line %ld\n",
255  valueA, equalityType, valueB, funcName, fileName, lineNumber);
256  }
257 
258  // Print to console and send to remote dashboard
259  printf("\n\n>>>>%s", error);
260  setErrorData(error, strlen(error), 100);
261 
262  wpi_handleTracing();
263  if (suspendOnAssertEnabled) taskSuspend(0);
264 }
265 
272 bool wpi_assertEqual_impl(int valueA,
273  int valueB,
274  const char *message,
275  const char *fileName,
276  uint32_t lineNumber,
277  const char *funcName)
278 {
279  if(!(valueA == valueB))
280  {
281  wpi_assertEqual_common_impl(valueA, valueB, "!=", message, fileName, lineNumber, funcName);
282  }
283  return valueA == valueB;
284 }
285 
292 bool wpi_assertNotEqual_impl(int valueA,
293  int valueB,
294  const char *message,
295  const char *fileName,
296  uint32_t lineNumber,
297  const char *funcName)
298 {
299  if(!(valueA != valueB))
300  {
301  wpi_assertEqual_common_impl(valueA, valueB, "==", message, fileName, lineNumber, funcName);
302  }
303  return valueA != valueB;
304 }
305 
306 
312 uint16_t GetFPGAVersion()
313 {
314  tRioStatusCode status = 0;
315  tGlobal *global = tGlobal::create(&status);
316  uint16_t version = global->readVersion(&status);
317  delete global;
318  wpi_setGlobalError(status);
319  return version;
320 }
321 
330 uint32_t GetFPGARevision()
331 {
332  tRioStatusCode status = 0;
333  tGlobal *global = tGlobal::create(&status);
334  uint32_t revision = global->readRevision(&status);
335  delete global;
336  wpi_setGlobalError(status);
337  return revision;
338 }
339 
345 uint32_t GetFPGATime()
346 {
347  tRioStatusCode status = 0;
348  tGlobal *global = tGlobal::create(&status);
349  uint32_t time = global->readLocalTime(&status);
350  delete global;
351  wpi_setGlobalError(status);
352  return time;
353 }
354 
355 // RT hardware access functions exported from ni_emb.out
356 extern "C"
357 {
358  int32_t UserSwitchInput(int32_t nSwitch);
359  int32_t LedInput(int32_t led);
360  int32_t LedOutput(int32_t led, int32_t value);
361 }
362 
366 int32_t GetRIOUserSwitch()
367 {
368  int32_t switchValue = UserSwitchInput(0);
369  wpi_assert(switchValue >= 0);
370  return switchValue > 0;
371 }
372 
376 void SetRIOUserLED(uint32_t state)
377 {
378  LedOutput(0, state > 0);
379 }
380 
385 int32_t GetRIOUserLED()
386 {
387  return LedInput(0);
388 }
389 
394 int32_t ToggleRIOUserLED()
395 {
396  int32_t ledState = !GetRIOUserLED();
397  SetRIOUserLED(ledState);
398  return ledState;
399 }
400 
404 void SetRIO_FPGA_LED(uint32_t state)
405 {
406  tRioStatusCode status = 0;
407  tGlobal *global = tGlobal::create(&status);
408  global->writeFPGA_LED(state, &status);
409  wpi_setGlobalError(status);
410  delete global;
411 }
412 
417 int32_t GetRIO_FPGA_LED()
418 {
419  tRioStatusCode status = 0;
420  tGlobal *global = tGlobal::create(&status);
421  bool ledValue = global->readFPGA_LED(&status);
422  wpi_setGlobalError(status);
423  delete global;
424  return ledValue;
425 }
426 
431 int32_t ToggleRIO_FPGA_LED()
432 {
433  int32_t ledState = !GetRIO_FPGA_LED();
434  SetRIO_FPGA_LED(ledState);
435  return ledState;
436 }
437 
438 
Definition: Task.h:17

Generated on Sat Apr 26 2014 12:26:45 for WPILibC++ by doxygen 1.8.6