/* include files */
#include "vxWorks.h"
#include "wdLib.h"
#include "stdio.h"
#include "semLib.h"
#include "taskLib.h"
#include "usrLib.h"
#include "sysLib.h"
/* defines */
#define TASK_PRIORITY 101
#define TASK_STACK_SIZE 5000
#define TIME_BETWEEN_INTERRUPTS 1 /* 1 tick */
#define TASK_WORK_TIME 2 /* 2 ticks */
#define NUM_OF_GIVES 3
/* globals */
/* counting or binary semaphore ID */
LOCAL SEM_ID semId = NULL;
/* watchdog ID */
LOCAL WDOG_ID wdId = NULL;
/* tid of syncTask */
LOCAL int syncTaskTid = 0;
/* Number of times semGive is called */
LOCAL int numToGive = NUM_OF_GIVES;
/* forward declaratiuon */
void syncISR(int);/* ISR to unblock syncTask */
void cleanUp (); /* cleanup routine */
void syncTask (); /* task that needs to be synchronized
* with external events */
/******************************************
* countingSemDemo - demonstrates
task synchronization using counting
* semaphores. User can also select to
use binary semaphore instead of
* counting semaphore in this demonstration,
for comparision between the two
* semaphores.
*
* RETURNS: OK or ERROR
*
*/
STATUS countingSemDemo (
char semType /* counting semaphore type
'c' or binary semaphore
* type 'b'
*/)
{
switch (semType)
{
case 'c':
case 'C':
if ((semId = semCCreate(SEM_Q_PRIORITY,
0)) == NULL)
{
perror ("semCCreate");
return (ERROR);
}
break;
case 'b':
case 'B':
if ((semId = semBCreate(SEM_Q_PRIORITY,
SEM_EMPTY)) == NULL)
{
perror ("semBCreate");
return (ERROR);
}
break;
default:
printf ("Unknown semType-- must be 'c' or 'b'\n");
return (ERROR);
}
if ((wdId = wdCreate()) == NULL)
{
perror ("wdCreate");
cleanUp ();
return (ERROR);
}
if ((syncTaskTid = taskSpawn ("tsyncTask", TASK_PRIORITY,0,
TASK_STACK_SIZE,(FUNCPTR) syncTask,
0,0,0,0,0,0,0,0,0,0)) == ERROR)
{
perror ("taskSpawn");
cleanUp();
return (ERROR);
}
/* watchdog simulates hardware interrupts */
if (wdStart (wdId, TIME_BETWEEN_INTERRUPTS,
(FUNCPTR) syncISR, numToGive)
== ERROR)
{
perror ("wdStart");
cleanUp ();
return (ERROR);
}
/* arbitrary delay to allow
program to complete before clean up */
taskDelay (sysClkRateGet() +
((TASK_WORK_TIME + 2) * numToGive));
cleanUp();
return (OK);
}
/*************************************************
* syncTask - synchronizes with interrupts using
* counting or binarysemaphores.
*/
void syncTask (void)
{
int eventCount = 0;
FOREVER
{
if (semTake (semId, WAIT_FOREVER) == ERROR)
{
perror ("syncTask semTake");
return;
}
/* Do "work" */
taskDelay (TASK_WORK_TIME);
printf("A\n");
eventCount++;
printf ("semaphore taken %d times\n", eventCount);
}
}
/************************************************
* syncISR - simulates a hardware device
which generates interrupts very
* quickly and synchronizes with
syncTask using semaphores.
*/
void syncISR(int times)
{
semGive (semId);
times--;
printf("times=%d\n",times);
if (times > 0)
wdStart (wdId, TIME_BETWEEN_INTERRUPTS,
(FUNCPTR) syncISR, times);
}
/********************************************
* cleanUP - deletes the syncTask, deletes the
* semaphore and the watchdog timer previously created
* by countingSemDemo.*/
void cleanUp ()
{
if (syncTaskTid)
taskDelete (syncTaskTid);
if (semId)
semDelete (semId);
if (wdId)
wdDelete (wdId);
}
}