excLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:10k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* excLib.c - generic exception handling facilities */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01s,13nov01,yvp  Included private/excLibP.h
  8. 01r,13sep01,pcm  moved excShowInit() from excInit() to usrConfig.c (SPR 7333)
  9. 01q,04sep98,cdp  apply 01o for all ARM CPUs with ARM_THUMB==TRUE.
  10. 01p,25feb98,jgn  make logMsg calls indirect for scalability (SPR #20625)
  11. 01o,03dec97,cdp  force excTask to call func in Thumb state (ARM7TDMI_T).
  12. 01n,09oct06,dgp  doc: correct excHookAdd() reference to ESF0 per SPR 7013
  13. 01m,19jun96,dgp  doc: change excHookAdd() description (SPR #6684)
  14. 01l,06oct95,jdi  removed .pG "Debugging".
  15. 01k,21jan93,jdi  documentation cleanup for 5.1.
  16. 01j,23aug92,jcf  added _func_excJobAdd for scalability.
  17. 01i,02aug92,jcf  moved printExc() to fioLib.c.
  18. 01h,30jul92,rrr  backed out 01g (now back to 01f)
  19. 01g,30jul92,kdl  backed out 01f changes pending rest of exc handling.
  20. 01f,29jul92,rrr  removed excDeliverHook and excDeliverSignal now in signals
  21.                  added hooks for exc<Arch>Lib
  22. 01e,28jul92,rdc  made printExc write enable sysExcMsg memory.
  23. 01d,27jul92,rrr  added excDeliverHook for signal delivery
  24. 01c,04jul92,jcf  scalable/ANSI/cleanup effort.
  25. 01b,26may92,rrr  the tree shuffle
  26. 01a,09jan92,yao  written from 960/excLib.c version 03f.  fixed document,
  27.  spr#1148.
  28. */
  29. /*
  30. This library provides generic initialization facilities for handling
  31. exceptions.  It safely traps and reports exceptions caused by program
  32. errors in VxWorks tasks, and it reports occurrences of interrupts that are
  33. explicitly connected to other handlers.  For information about
  34. architecture-dependent exception handling facilities, see the manual entry
  35. for excArchLib.
  36. INITIALIZATION
  37. Initialization of excLib facilities occurs in two steps.  First, the routine
  38. excVecInit() is called to set all vectors to the default handlers for an
  39. architecture provided by the corresponding architecture exception handling
  40. library.  Since this does not involve VxWorks' kernel facilities, it is
  41. usually done early in the system start-up routine usrInit() in the library
  42. usrConfig.c with interrupts disabled.
  43. The rest of this package is initialized by calling excInit(), which spawns
  44. the exception support task, excTask(), and creates the message queues used to
  45. communicate with it.
  46. Exceptions or uninitialized interrupts that occur after the vectors
  47. have been initialized by excVecInit(), but before excInit() is called,
  48. cause a trap to the ROM monitor.
  49. NORMAL EXCEPTION HANDLING
  50. When a program error generates an exception (such as divide by zero, or a
  51. bus or address error), the task that was executing when the error occurred
  52. is suspended, and a description of the exception is displayed on standard
  53. output.  The VxWorks kernel and other system tasks continue uninterrupted.
  54. The suspended task can be examined with the usual VxWorks routines,
  55. including ti() for task information and tt() for a stack trace.  It may
  56. be possible to fix the task and resume execution with tr().  However, tasks
  57. aborted in this way are often unsalvageable and can be deleted with td().
  58. When an interrupt that is not connected to a handler occurs, the default
  59. handler provided by the architecture-specific module displays a
  60. description of the interrupt on standard output.
  61. ADDITIONAL EXCEPTION HANDLING ROUTINE
  62. The excHookAdd() routine adds a routine that will be called when a hardware
  63. exception occurs.  This routine is called at the end of normal exception
  64. handling.
  65. TASK-LEVEL SUPPORT
  66. The excInit() routine spawns excTask(), which performs special exception
  67. handling functions that need to be done at task level.  Do not suspend,
  68. delete, or change the priority of this task.
  69. DBGLIB
  70. The facilities of excLib, including excTask(), are used by dbgLib to support
  71. breakpoints, single-stepping, and additional exception handling functions.
  72. SIGLIB
  73. A higher-level, UNIX-compatible interface for hardware and software
  74. exceptions is provided by sigLib.  If sigvec() is used to initialize
  75. the appropriate hardware exception/interrupt (e.g., BUS ERROR == SIGSEGV),
  76. excLib will use the signal mechanism instead.
  77. INCLUDE FILES: excLib.h
  78. SEE ALSO: dbgLib, sigLib, intLib
  79. */
  80. /* LINTLIBRARY */
  81. #include "vxWorks.h"
  82. #include "esf.h"
  83. #include "iv.h"
  84. #include "intLib.h"
  85. #include "msgQLib.h"
  86. #include "signal.h"
  87. #include "taskLib.h"
  88. #include "errno.h"
  89. #include "stdarg.h"
  90. #include "logLib.h"
  91. #include "stdio.h"
  92. #include "private/excLibP.h"
  93. #include "private/funcBindP.h"
  94. /* global variables */
  95. FUNCPTR excExcepHook; /* add'l rtn to call when exceptions occur */
  96. MSG_Q_ID excMsgQId; /* ID of msgQ to excTask */
  97. /* excTask parameters */
  98. int excTaskId;
  99. int excTaskPriority = 0;
  100. int excTaskOptions = VX_SUPERVISOR_MODE | VX_UNBREAKABLE;
  101. int excTaskStackSize = 8000;
  102. #define EXC_MAX_ARGS 6 /* max args to task level call */
  103. #define EXC_MAX_MSGS 10 /* max number of exception msgs */
  104. typedef struct /* EXC_MSG */
  105.     {
  106.     VOIDFUNCPTR func; /* pointer to function to invoke */
  107.     int arg [EXC_MAX_ARGS]; /* args for function */
  108.     } EXC_MSG;
  109. /* local variables */
  110. LOCAL int excMsgsLost; /* count of messages to excTask lost */
  111. /*******************************************************************************
  112. *
  113. * excInit - initialize the exception handling package
  114. *
  115. * This routine installs the exception handling facilities and spawns excTask(),
  116. * which performs special exception handling functions that need to be done at
  117. * task level.  It also creates the message queue used to communicate with
  118. * excTask().
  119. *
  120. * NOTE:
  121. * The exception handling facilities should be installed as early as
  122. * possible during system initialization in the root task, usrRoot(), in
  123. * usrConfig.c.
  124. *
  125. * RETURNS:
  126. * OK, or ERROR if a message queue cannot be created or excTask() cannot be
  127. * spawned.
  128. *
  129. * SEE ALSO: excTask()
  130. */
  131. STATUS excInit ()
  132.     {
  133.     _func_excJobAdd = (FUNCPTR) excJobAdd;
  134.     excMsgQId = msgQCreate (EXC_MAX_MSGS, sizeof (EXC_MSG), MSG_Q_FIFO);
  135.     if (excMsgQId == NULL)
  136. return (ERROR);
  137.     excTaskId = taskSpawn ("tExcTask", excTaskPriority,
  138.    excTaskOptions, excTaskStackSize,
  139.    (FUNCPTR) excTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  140.     return (excTaskId == ERROR ? ERROR : OK);
  141.     }
  142. /*******************************************************************************
  143. *
  144. * excHookAdd - specify a routine to be called with exceptions
  145. *
  146. * This routine specifies a routine that will be called when hardware
  147. * exceptions occur.  The specified routine is called after normal exception
  148. * handling, which includes displaying information about the error.  Upon return
  149. * from the specified routine, the task that incurred the error is suspended.
  150. *
  151. * The exception handling routine should be declared as:
  152. * .tS
  153. *     void myHandler
  154. *         (
  155. *         int      task,    /@ ID of offending task             @/
  156. *         int      vecNum,  /@ exception vector number          @/
  157. *         <ESFxx>  *pEsf    /@ pointer to exception stack frame @/
  158. *         )
  159. * .tE
  160. * where <task> is the ID of the task that was running when the exception
  161. * occurred. <ESFxx> is architecture-specific and can be found by examining
  162. * `/target/h/arch/<arch>/esf<arch>.h'; for example, the PowerPC uses ESFPPC.
  163. *
  164. * This facility is normally used by dbgLib() to activate its exception
  165. * handling mechanism.  If an application provides its own exception handler,
  166. * it will supersede the dbgLib mechanism.
  167. *
  168. * RETURNS: N/A
  169. *
  170. * SEE ALSO: excTask()
  171. */
  172. void excHookAdd
  173.     (
  174.     FUNCPTR excepHook /* routine to call when exceptions occur */
  175.     )
  176.     {
  177.     excExcepHook = excepHook;
  178.     }
  179. /*******************************************************************************
  180. *
  181. * excJobAdd - request a task-level function call from interrupt level
  182. *
  183. * This routine allows interrupt level code to request a function call
  184. * to be made by excTask at task-level.
  185. *
  186. * NOMANUAL
  187. */
  188. STATUS excJobAdd (func, arg1, arg2, arg3, arg4, arg5, arg6)
  189.     VOIDFUNCPTR func;
  190.     int arg1;
  191.     int arg2;
  192.     int arg3;
  193.     int arg4;
  194.     int arg5;
  195.     int arg6;
  196.     {
  197.     EXC_MSG msg;
  198.     msg.func = func;
  199.     msg.arg[0] = arg1;
  200.     msg.arg[1] = arg2;
  201.     msg.arg[2] = arg3;
  202.     msg.arg[3] = arg4;
  203.     msg.arg[4] = arg5;
  204.     msg.arg[5] = arg6;
  205.     if (msgQSend (excMsgQId, (char *) &msg, sizeof (msg),
  206.   INT_CONTEXT() ? NO_WAIT : WAIT_FOREVER, MSG_PRI_NORMAL) != OK)
  207.         {
  208.         ++excMsgsLost;
  209.         return (ERROR);
  210.         }
  211.     return (OK);
  212.     }
  213. /*******************************************************************************
  214. *
  215. * excTask - handle task-level exceptions
  216. *
  217. * This routine is spawned as a task by excInit() to perform functions
  218. * that cannot be performed at interrupt or trap level.  It has a priority of 0.
  219. * Do not suspend, delete, or change the priority of this task.
  220. *
  221. * RETURNS: N/A
  222. *
  223. * SEE ALSO: excInit()
  224. */
  225. void excTask ()
  226.     {
  227.     static int oldMsgsLost = 0;
  228.     int newMsgsLost;
  229.     EXC_MSG msg;
  230.     FOREVER
  231. {
  232. if (msgQReceive (excMsgQId, (char *) &msg, sizeof (msg),
  233.  WAIT_FOREVER) != sizeof (msg))
  234.             {
  235.             if (_func_logMsg != NULL)
  236. _func_logMsg ("excTask: error receiving msg, status = %#x.n",
  237.               errno, 0, 0, 0, 0, 0);
  238.             }
  239.         else
  240. #if ((CPU_FAMILY == ARM) && ARM_THUMB)
  241.     /* force call in Thumb state */
  242.     (* (VOIDFUNCPTR)((UINT32)(msg.func) | 1)) (msg.arg[0], msg.arg[1],
  243.        msg.arg[2], msg.arg[3],
  244.        msg.arg[4], msg.arg[5]);
  245. #else
  246.             (* msg.func) (msg.arg[0], msg.arg[1], msg.arg[2],
  247.   msg.arg[3], msg.arg[4], msg.arg[5]);
  248. #endif /* CPU_FAMILY == ARM */
  249. /* check to see if interrupt level lost any more calls */
  250. if ((newMsgsLost = excMsgsLost) != oldMsgsLost)
  251.     {
  252.     if (_func_logMsg != NULL)
  253. _func_logMsg ("%d messages from interrupt level lost.n",
  254.               newMsgsLost - oldMsgsLost, 0, 0, 0, 0, 0);
  255.     oldMsgsLost = newMsgsLost;
  256.     }
  257. }
  258.     }