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

VxWorks

开发平台:

C/C++

  1. /* cobble.c - sample program for tutorial in Tornado Getting Started Guide */
  2. /* This code is intentionally left buggy! */
  3. /*
  4. modification history
  5. --------------------
  6. 01b,01apr01,ems  better badness & cripser cleanups (with gracious help of wsl)
  7. 01a,01apr99,ems  written (with gracious help of dlk)
  8. */
  9. /*
  10. DESCRIPTION:
  11. This module is used as a simple example multitask application
  12. in the Tornado Getting Started Guide. It is intended to help
  13. the new Tornado user quickly become familiar with various
  14. Tornado tools that are available for debugging such
  15. applications.
  16. The program simulates a data collection system in which
  17. data is retrieved from an external source (e.g. a device
  18. which generates interrupts as data come in). A task simulating
  19. the ISR gives a semaphore each time a new datum arrives. (This
  20. task could easily be replaced by a VxWorks watchdog timer.)
  21. The data are processed in two stages. First, a sample consisting
  22. of NUM_SAMPLE data is collected. Second, various arcane
  23. arithmetical operations are performed on the sample to obtain
  24. a result value. Each stage is represented by a task; the
  25. first task gives a binary semaphore when the second task should
  26. begin the second stage work.
  27. The value of the result of the processing is monitored by yet
  28. another task, which prints a warning message whenever the result
  29. is out of the safety range.
  30. INCLUDE FILES: None.
  31. */
  32. /* includes */
  33. #include "vxWorks.h"
  34. #include "stdio.h"
  35. #include "stdlib.h"
  36. #include "semLib.h"
  37. #include "taskLib.h"
  38. /* defines */
  39. #define NUM_SAMPLE  10
  40. #define LUCKY  7
  41. #define HOT  20
  42. #define DELAY_TICKS     4
  43. #define STACK_SIZE 20000
  44. /* typedefs */
  45. typedef struct byLightning 
  46.     {
  47.     int    data;
  48.     int    nodeNum;
  49.     struct byLightning * pPrevNode;
  50.     } LIST_NODE;
  51. /* globals */
  52. int tidCosmos; /* Task IDs */
  53. int tidSchlep;
  54. int tidCrunch;
  55. int tidMonitor;
  56. int cosmicData = 0; /* Holds a datum available to read */
  57. int result = 0;                 /* Holds result of calculation */
  58. LIST_NODE * pCurrNode = NULL; /* head of list of data */
  59. SEM_ID dataSemId; /* Given when a datum is available          */
  60. SEM_ID syncSemId; /* Given when a data sample can be crunched */
  61. SEM_ID nodeListGuardSemId;      /* Given when pointer to current node can 
  62.    be accessed                              */
  63. /* forward declarations */
  64. void cosmos (void);
  65. void nodeAdd (int data, int nodeNum);
  66. void schlep (void);
  67. void nodeScrap (void);
  68. void crunch (void);
  69. void monitor (void);
  70. void progStop (void);
  71. /*************************************************************************
  72. *
  73. * progStart - start the sample program.
  74. *
  75. * Create various semaphores and spawn various tasks, while doing
  76. * incredibly little error checking.
  77. *
  78. * RETURNS: OK
  79. */
  80. STATUS progStart (void)
  81.     {
  82.     syncSemId = semBCreate (SEM_Q_FIFO, SEM_EMPTY);
  83.     dataSemId = semBCreate (SEM_Q_FIFO, SEM_EMPTY);
  84.     nodeListGuardSemId = semMCreate (  SEM_Q_PRIORITY
  85. | SEM_INVERSION_SAFE
  86. | SEM_DELETE_SAFE);
  87.     
  88.     pCurrNode = NULL; /* just in case */
  89.     /* get started */
  90.     tidCosmos = taskSpawn ("tCosmos", 200, 0, STACK_SIZE,
  91.         (FUNCPTR) cosmos,0,0,0,0,0,0,0,0,0,0);
  92.     tidSchlep = taskSpawn ("tSchlep", 220, 0, STACK_SIZE,
  93.         (FUNCPTR) schlep,0,0,0,0,0,0,0,0,0,0);
  94.     /*
  95.      * priority mis-assignment provides desired educational
  96.      * malfunction of not allowing tCrunch to run because 
  97.      * tMonitor is higher priority
  98.      */
  99.     tidCrunch = taskSpawn ("tCrunch", 240, 0, STACK_SIZE,
  100.         (FUNCPTR) crunch,0,0,0,0,0,0,0,0,0,0);
  101.     tidMonitor = taskSpawn ("tMonitor", 230, 0, STACK_SIZE,
  102.         (FUNCPTR) monitor,0,0,0,0,0,0,0,0,0,0);
  103.     return (OK);
  104.     }
  105. /*************************************************************************
  106. *
  107. * cosmos - simulate data arrival interrupt
  108. *
  109. * This routine is executed by a task which serves as a replacement for
  110. * an ISR which signals the availability of data from some device.
  111. * It periodically gives the semaphore dataSemId to indicate that a
  112. * datum is available and may be read from the cosmicData variable.
  113. */
  114. void cosmos (void)
  115.     {
  116.     int nadaNichtsIdx = 0;
  117.     FOREVER
  118. {
  119.         if (nadaNichtsIdx != LUCKY)
  120.             cosmicData = rand ();
  121.         else
  122.     {
  123.             cosmicData = 0; /* because you can't wait forever for nothing */
  124.             nadaNichtsIdx = 0; 
  125.     }
  126.         ++nadaNichtsIdx;
  127.        
  128.         /* semaphore and delay ensure only new data will be read */
  129.         semGive (dataSemId);
  130.         taskDelay (DELAY_TICKS);
  131. }
  132.     }
  133. /*************************************************************************
  134. *
  135. * nodeAdd - link a new node to front of data chain.
  136. *
  137. * Allocates and initializes a node, puts it onto the data chain. 
  138. * RETURNS: N/A
  139. */
  140. void nodeAdd
  141.     (
  142.     int data,
  143.     int nodeNum
  144.     )
  145.     {
  146.     LIST_NODE * node;
  147.     if ( (node = (LIST_NODE *) malloc (sizeof (LIST_NODE))) != NULL)
  148. {
  149. node->data = data;
  150. node->nodeNum = nodeNum;
  151. semTake (nodeListGuardSemId, WAIT_FOREVER); 
  152. node->pPrevNode = pCurrNode;
  153. pCurrNode = node;
  154. semGive (nodeListGuardSemId);
  155. }
  156.     else
  157. {
  158. printf ("cobble: Out of Memory.n");
  159. taskSuspend (0);
  160. }
  161.     return;
  162.     }
  163. /*************************************************************************
  164. *
  165. * schlep - collect data into a sample to be processed
  166. *
  167. * Repeatedly, wait for and place NUM_SAMPLE data onto the list,
  168. * then awaken the cruncher.
  169. */
  170. void schlep (void)
  171.     {
  172.     int nodeIdx;
  173.   
  174.     FOREVER
  175. {
  176. for (nodeIdx = 0; nodeIdx < NUM_SAMPLE; nodeIdx++)
  177.             {
  178.     semTake (dataSemId, WAIT_FOREVER); /* Wait for datum */
  179.     nodeAdd (cosmicData, nodeIdx);
  180.             }
  181. semGive (syncSemId); /* Give entire sample to cruncher! */
  182. }     
  183.     }
  184. /*************************************************************************
  185. *
  186. * nodeScrap - relegate a node to the dust bin of history
  187. *
  188. */
  189. void nodeScrap (void)
  190.     {
  191.     LIST_NODE * pTmpNode;
  192.     pTmpNode = pCurrNode;
  193.     pCurrNode = pCurrNode->pPrevNode; 
  194.     free (pTmpNode);         
  195.     return;
  196.     }
  197. /*************************************************************************
  198. *
  199. * crunch - process data samples
  200. *
  201. * Applies dubious transformations to data.
  202. * But first it waits for the schlepper to send it a sample.
  203. */
  204. void crunch (void)
  205.     {
  206.     int sampleSum = 0;
  207.     int div;
  208.     int * pDiv = &div; 
  209.     FOREVER
  210. {
  211. semTake (syncSemId, WAIT_FOREVER); /* Wait for dinner */
  212. semTake (nodeListGuardSemId, WAIT_FOREVER); /* reserve access to 
  213.                                           pCurrNode */
  214. while (pCurrNode != NULL)
  215.     {
  216.     sampleSum += pCurrNode->data;
  217.     div = pCurrNode->data;
  218.     nodeScrap ();
  219.     }
  220. semGive (nodeListGuardSemId);   /* release access to pCurrNode */
  221.         /* Oh! Woe! Errant exclamation point!  */
  222.         if (!(pDiv = NULL) && (*pDiv != 0))  
  223. /*      if ((pDiv != NULL) && (*pDiv != 0))  */ 
  224.             result = sampleSum / (*pDiv);
  225.         sampleSum = 0;    /* Clean up for the next round. */
  226. }
  227.     }
  228. /*************************************************************************
  229. *
  230. * monitor - monitors results of calculation
  231. *
  232. * Checks results of calculation and prints warning if too hot.
  233. */
  234. void monitor (void)
  235.     {
  236.     int isHot = FALSE;
  237.     FOREVER
  238. {
  239.         if (!isHot && result >= HOT)
  240.             {
  241.             isHot = TRUE;
  242.        printf ("WARNING: HOT!n");
  243.     }
  244. else if (isHot && result < HOT)
  245.     {                 
  246.     isHot = FALSE;
  247.     printf ("cooln");
  248.     }
  249. }
  250.     }
  251. /*************************************************************************
  252. *
  253. * progStop - stops the program 
  254. *
  255. * Call this routine to end it all. 
  256. */
  257. void progStop (void)
  258.     {
  259.     taskDelete (tidCosmos);
  260.     taskDelete (tidSchlep);
  261.     taskDelete (tidCrunch);
  262.     taskDelete (tidMonitor);
  263.     semDelete (dataSemId);
  264.     semDelete (syncSemId);
  265.     semDelete (nodeListGuardSemId);
  266.     
  267.     while (pCurrNode != NULL)
  268. nodeScrap();
  269.     /* My, aren't we tidy! */
  270.     printf ("BYE!TSCHUESS!ADIEU!n");
  271.     return;
  272.     }