vxWorks的计数信号量和看门狗定时器联合使用的示例



#include "vxWorks.h"
#include "wdLib.h"
#include "stdio.h"
#include "semLib.h"
#include "taskLib.h"
#include "usrLib.h"
#include "sysLib.h"

/* defines */

#define TASK_WORK_TIME				2   /* 2 ticks */
#define NUM_OF_GIVES				3   

/* globals */

LOCAL SEM_ID semId = NULL;		/* counting or binary semaphore ID */
LOCAL WDOG_ID wdId = NULL;              /* watchdog ID */
LOCAL int syncTaskTid = 0;              /* tid of syncTask */
LOCAL int numToGive = NUM_OF_GIVES;     /* Number of times semGive is called */

/* 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 TestCSem (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", 101, 0,5000,(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, 1, (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 binary
 *             semaphores.
 */

void syncTask (void)
    {
    int eventCount = 0;

    FOREVER
    {
		if (semTake (semId, WAIT_FOREVER) == ERROR)
	    {
            perror ("syncTask semTake");
            return;
        }

		/* Do "work" */
		taskDelay (TASK_WORK_TIME);
		semShow (semId, 1);

		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--;
    
    //看门狗定时器需要递归调用
    if (times > 0)
    {
        wdStart (wdId, 1, (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);

}





你可能感兴趣的:(vxWorks)