windDemo.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:8k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* windDemo - repeatedly test various kernel function */
  2. /*
  3. modification history
  4. --------------------
  5. 02d,28apr99,jrp  upped stack size to make it run on sparc ss5 etc.
  6. 02c,23aug93,jcf  fixed synchronization.
  7. 02b,01aug93,dvs  fixed loop count printing.
  8. 02a,18mar93,dvs  took out timer/benchmark information.
  9.                  ansified code.
  10.  general cleanup of code to use as MicroWorks demo.
  11. 01a,12nov90,shl  written.
  12. */
  13. /*
  14. DESCRIPTION
  15. This program repeatedly exercises different kernel facilities of 
  16. the Wind kernel.
  17. The functions involved include the use of semaphores as sychronization
  18. and mutual exclusion primitives, the use of taskSuspend()/taskResume() 
  19. for task control, the use of message queues for communication and the 
  20. use of watchdogs for task timeouts.
  21. To exercise these kernel facilities two tasks are used, a high priority 
  22. task and a low priority task. The high priority task executes functions
  23. with which the resources are not available. As the high priority
  24. task blocks, the low priority task takes over and makes available
  25. the resources that the high priority task is waiting for. This may
  26. sound simple at first but the underlying execution of this test program
  27. involves context switching, rescheduling of tasks, and shuffling of
  28. the ready queue, pend queue, and the timer queue.
  29. These functions are chosen because they are the most commonly used
  30. functions in sychronization, mutual exclusion, task control, inter-task
  31. communication and timer facilities. These are the basic building blocks of
  32. the operating system itself and also used in applications.  Repeatedly
  33. execution of this "death loop" is a good indication of how the system will
  34. perform in real-life as these functions are utiltized heavily in every
  35. application.
  36. The following is the thread of execution of this test program.
  37.      Higher Priority     Lower Priority
  38.   Task1     Task2
  39.      ===============            ==============
  40.   |
  41.   V
  42. /-----> semGive()
  43. | semTake()
  44. |   |
  45. |   V
  46. | semTake()
  47. |   
  48. |    
  49. |     ------------->    semGive()
  50. |        /
  51. |       /
  52. | taskSuspend()  <-------------/
  53. |   
  54. |    
  55. |     ------------->    taskResume()
  56. |        /
  57. |       /
  58. | msgQSend()     <-------------/
  59. | msgQReceive()
  60. |   |
  61. |   V
  62. | msgQReceive()
  63. |   
  64. |    
  65. |     ------------->    msgQSend()
  66. |        /
  67. |       /
  68.      | wdStart()      <-------------/
  69.       | wdCancel()
  70.         ---------|
  71.   V
  72. exit           
  73.   
  74.    
  75.     ------------->    exit
  76. */
  77. #include "vxWorks.h"
  78. #include "semLib.h"
  79. #include "taskLib.h"
  80. #include "msgQLib.h"
  81. #include "wdLib.h"
  82. #include "logLib.h"
  83. #include "tickLib.h"
  84. #include "sysLib.h"
  85. #include "stdio.h"
  86. /* defines */
  87. #if FALSE
  88. #define STATUS_INFO /* define to allow printf() calls */
  89. #endif
  90. #define MAX_MSG 1 /* max number of messages in queue */
  91. #define MSG_SIZE sizeof (MY_MSG) /* size of message */
  92. #define DELAY 100 /* 100 ticks */
  93. #define HIGH_PRI 150 /* priority of high priority task */
  94. #define LOW_PRI 200 /* priority of low priority task */
  95. #define TASK_HIGHPRI_TEXT "Hello from the 'high priority' task"
  96. #define TASK_LOWPRI_TEXT "Hello from the 'low priority' task"
  97. /* typedefs */
  98. typedef struct my_msg
  99. {
  100. int    childLoopCount; /* loop count in task sending msg */
  101. char * buffer; /* message text */
  102. } MY_MSG;
  103. /* globals */
  104. SEM_ID semId; /* semaphore ID */
  105. MSG_Q_ID msgQId; /* message queue ID */
  106. WDOG_ID wdId; /* watchdog ID */
  107. int highPriId; /* task ID of high priority task */
  108. int lowPriId; /* task ID of low priority task */
  109. int windDemoId; /* task ID of windDemo task */
  110. /* forward declarations */
  111. LOCAL void taskHighPri (int iteration);
  112. LOCAL void taskLowPri (int iteration);
  113. /*******************************************************************************
  114. *
  115. * windDemo - parent task to spawn children 
  116. *
  117. * This task calls taskHighPri() and taskLowPri() to do the
  118. * actual operations of the test and suspends itself.
  119. * Task is resumed by the low priority task.
  120. *
  121. */
  122. void windDemo 
  123.     (
  124.     int iteration /* number of iterations of child code */
  125.     )
  126.     {
  127.     int loopCount = 0;  /* number of times through windDemo */
  128. #ifdef STATUS_INFO
  129.     printf ("Entering windDemon");
  130. #endif /* STATUS_INFO */
  131.     if (iteration == 0) /* set default to 10,000 */
  132. iteration = 10000;
  133.     /* create objects used by the child tasks */
  134.     msgQId = msgQCreate (MAX_MSG, MSG_SIZE, MSG_Q_FIFO);
  135.     semId = semBCreate (SEM_Q_PRIORITY, SEM_FULL);
  136.     wdId = wdCreate ();
  137.     windDemoId = taskIdSelf ();
  138.     FOREVER
  139. {
  140. /* spawn child tasks to exercise kernel routines */
  141.      highPriId = taskSpawn ("tHighPri", HIGH_PRI, VX_SUPERVISOR_MODE, 4000, 
  142.    (FUNCPTR) taskHighPri, iteration,0,0,0,0,0,0,0,0,0);
  143.      lowPriId = taskSpawn ("tLowPri", LOW_PRI, VX_SUPERVISOR_MODE, 4000, 
  144.    (FUNCPTR) taskLowPri, iteration,0,0,0,0,0,0,0,0,0);
  145.      taskSuspend (0); /* to be waken up by taskLowPri */ 
  146. #ifdef STATUS_INFO
  147.      printf ("nParent windDemo has just completed loop number %dn",
  148. loopCount);
  149. #endif /* STATUS_INFO */
  150.      loopCount++;
  151. }
  152.     }
  153. /*******************************************************************************
  154. *
  155. * taskHighPri - high priority task
  156. *
  157. * This tasks exercises various kernel functions. It will block if the
  158. * resource is not available and relingish the CPU to the next ready task.
  159. *
  160. */
  161. LOCAL void taskHighPri 
  162.     (
  163.     int iteration /* number of iterations through loop */
  164.     )
  165.     {
  166.     int    ix; /* loop counter */
  167.     MY_MSG msg; /* message to send */
  168.     MY_MSG newMsg; /* message to receive */
  169.     for (ix = 0; ix < iteration; ix++)
  170. {
  171. /* take and give a semaphore - no context switch involved */
  172. semGive (semId);
  173. semTake (semId, 100); /* semTake with timeout */
  174. /* 
  175.  * take semaphore - context switch will occur since semaphore 
  176.  * is unavailable 
  177.  */
  178. semTake (semId, WAIT_FOREVER); /* semaphore not available */
  179. taskSuspend (0); /* suspend itself */
  180. /* build message and send it */
  181. msg.childLoopCount = ix;
  182. msg.buffer = TASK_HIGHPRI_TEXT;
  183. msgQSend (msgQId, (char *) &msg, MSG_SIZE, 0, MSG_PRI_NORMAL);
  184. /* 
  185.  * read message that this task just sent and print it - no context 
  186.  * switch will occur since there is a message already in the queue 
  187.  */
  188. msgQReceive (msgQId, (char *) &newMsg, MSG_SIZE, NO_WAIT);
  189. #ifdef STATUS_INFO
  190. printf ("%sn Number of iterations is %dn", 
  191. newMsg.buffer, newMsg.childLoopCount);
  192. #endif /* STATUS_INFO */
  193. /* 
  194.  * block on message queue waiting for message from low priority task 
  195.  * context switch will occur since there is no message in the queue
  196.  * when message is received, print it 
  197.  */
  198. msgQReceive (msgQId, (char *) &newMsg, MSG_SIZE, WAIT_FOREVER);
  199. #ifdef STATUS_INFO
  200. printf ("%sn Number of iterations by this task is: %dn", 
  201. newMsg.buffer, newMsg.childLoopCount);
  202. #endif /* STATUS_INFO */
  203. /* test watchdog timer */
  204. wdStart (wdId, DELAY, (FUNCPTR) tickGet, 1); 
  205. wdCancel (wdId);
  206. }
  207.     }
  208. /*******************************************************************************
  209. *
  210. * taskLowPri - low priority task
  211. *
  212. * This task runs at a lower priority and is designed to make available
  213. * the resouces that the high priority task is waiting for and subsequently
  214. * unblock the high priority task.
  215. *
  216. */
  217. LOCAL void taskLowPri 
  218.     (
  219.     int iteration /* number of times through loop */
  220.     )
  221.     {
  222.     int    ix; /* loop counter */
  223.     MY_MSG msg; /* message to send */
  224.     for (ix = 0; ix < iteration; ix++)
  225. {
  226. semGive (semId); /* unblock tHighPri */
  227. taskResume (highPriId); /* unblock tHighPri */
  228. /* build message and send it */
  229. msg.childLoopCount = ix;
  230. msg.buffer = TASK_LOWPRI_TEXT;
  231. msgQSend (msgQId, (char *) &msg, MSG_SIZE, 0, MSG_PRI_NORMAL);
  232. taskDelay (60);
  233. }
  234.     taskResume (windDemoId); /* wake up the windDemo task */
  235.     }