现在的位置: 首页 > 综合 > 正文

VxWorks操作系统指南(2.6) 应用示例分析

2013年03月02日 ⁄ 综合 ⁄ 共 6409字 ⁄ 字号 评论关闭

1.1.应用示例分析

      下面通过对一具体实例的分析,对任务的创建、任务间通信、内存分配、消息管理等VxWorks系统应用更进一步的了解。(示例选自demo例子程序windDemo.c)

 

 

 

 

/* windDemo - repeatedly test various kernel function */

 

/*

modification history

--------------------

02c,23aug93,jcf  fixed synchronization.

02b,01aug93,dvs  fixed loop count printing.

02a,18mar93,dvs  took out timer/benchmark information.

                 ansified code.

        general cleanup of code to use as MicroWorks demo.

01a,12nov90,shl  written.

*/

 

/*

DESCRIPTION

This program repeatedly exercises different kernel facilities of

the Wind kernel.

 

The functions involved include the use of semaphores as sychronization

and mutual exclusion primitives, the use of taskSuspend()/taskResume() for task control, the use of message queues for communication and the

use of watchdogs for task timeouts.

 

To exercise these kernel facilities two tasks are used, a high priority task and a low priority task. The high priority task executes functions with which the resources are not available. As the high priority task blocks, the low priority task takes over and makes available the resources that the high priority task is waiting for. This may sound simple at first but the underlying execution of this test program involves context switching, rescheduling of tasks, and shuffling of the ready queue, pend queue, and the timer queue.

 

These functions are chosen because they are the most commonly used

functions in sychronization, mutual exclusion, task control, inter-task communication and timer facilities. These are the basic building blocks of the operating system itself and also used in applications.  Repeatedly execution of this "death loop" is a good indication of how the system will perform in real-life as these functions are utiltized heavily in every application.

 

The following is the thread of execution of this test program.

 

 

         Higher Priority     Lower Priority

         Task1           Task2

         ===============            ==============

         |

         V

    /----->semGive()

    |   semTake()

    |     |

    |     V

    |   semTake()

    |     /

    |      /  

    |       /------------->      semGive()

    |                          /

    |                        /

    |   taskSuspend()<-------------/

    |     /

    |      /

    |       /------------->      taskResume()

    |                           /

    |                     /

    |   msgQSend()<-------------/

    |   msgQReceive()

    |     |

    |     V

    |   msgQReceive()

    |     /

    |      /  

    |       /------------->      msgQSend()

    |                         /

    |                        /

        |   wdStart()    <-------------/

        |   wdCancel()

      /---------|

         V

       exit          

         /

          /  

           /------------->      exit

*/

 

#include "vxWorks.h"

#include "semLib.h"

#include "taskLib.h"

#include "msgQLib.h"

#include "wdLib.h"

#include "logLib.h"

#include "tickLib.h"

#include "sysLib.h"

#include "stdio.h"

 

 

/* defines */

 

#if FALSE

#define STATUS_INFO         /* define to allow printf() calls */

#endif

 

#define MAX_MSG      1      /* max number of messages in queue */

#define MSG_SIZE  sizeof (MY_MSG)   /* size of message */

#define DELAY     100    /* 100 ticks */

#define    HIGH_PRI   150    /* priority of high priority task */

#define LOW_PRI      200    /* priority of low priority task */

 

#define TASK_HIGHPRI_TEXT   "Hello from the 'high priority' task"

#define TASK_LOWPRI_TEXT "Hello from the 'low priority' task"

 

 

/* typedefs */

 

typedef struct my_msg

    {

    int    childLoopCount;       /* loop count in task sending msg */

    char * buffer;           /* message text */

    } MY_MSG;

 

 

/* globals */

 

SEM_ID     semId;        /* semaphore ID */

MSG_Q_ID   msgQId;           /* message queue ID */

WDOG_ID       wdId;         /* watchdog ID */

int    highPriId;    /* task ID of high priority task */

int    lowPriId;     /* task ID of low priority task */

int    windDemoId;       /* task ID of windDemo task */

 

 

/* forward declarations */

 

LOCAL void taskHighPri (int iteration);

LOCAL void taskLowPri (int iteration);

 

 

 

/******************************************************************************

*

*

* windDemo - parent task to spawn children

*

* This task calls taskHighPri() and taskLowPri() to do the

* actual operations of the test and suspends itself.

* Task is resumed by the low priority task.

*

*/

 

void windDemo

(

  int iteration          /* number of iterations of child code */

)

{

    int loopCount = 0;      /* number of times through windDemo */

 

#ifdef STATUS_INFO

    printf ("Entering windDemo/n");

#endif /* STATUS_INFO */

 

    if (iteration == 0)         /* set default to 10,000 */

    iteration = 10000;

 

    /* create objects used by the child tasks */

 

    msgQId = msgQCreate (MAX_MSG, MSG_SIZE, MSG_Q_FIFO);

    semId  = semBCreate (SEM_Q_PRIORITY, SEM_FULL);

    wdId   = wdCreate ();

 

    windDemoId = taskIdSelf ();

 

    FOREVER              //while(1)

{

 

    /* spawn child tasks to exercise kernel routines */

 

        highPriId = taskSpawn ("tHighPri", HIGH_PRI, VX_SUPERVISOR_MODE,          1000,(FUNCPTR) taskHighPri, iteration,0,0,0,0,0,0,0,0,0);

 

        lowPriId = taskSpawn ("tLowPri", LOW_PRI, VX_SUPERVISOR_MODE,             1000,(FUNCPTR) taskLowPri, iteration,0,0,0,0,0,0,0,0,0);

 

 

        taskSuspend (0);     /* to be waken up by taskLowPri */

 

#ifdef STATUS_INFO

        printf ("/nParent windDemo has just completed loop number %d/n",

       loopCount);

#endif /* STATUS_INFO */

 

        loopCount++;

}

 }

 

/******************************************************************************

*

*

* taskHighPri - high priority task

*

* This tasks exercises various kernel functions. It will block if the

* resource is not available and relingish the CPU to the next ready task.

*

*/

 

LOCAL void taskHighPri

(

  int iteration          /* number of iterations through loop */

)

{

    int    ix;            /* loop counter */

    MY_MSG msg;              /* message to send */

    MY_MSG newMsg;           /* message to receive */

 

    for (ix = 0; ix < iteration; ix++)

    {

 

    /* take and give a semaphore - no context switch involved */

 

    semGive (semId);    

    semTake (semId, 100);       /* semTake with timeout */

 

 

    /*

     * take semaphore - context switch will occur since semaphore

     * is unavailable

     */

 

    semTake (semId, WAIT_FOREVER);  /* semaphore not available */

 

    taskSuspend (0);     /* suspend itself */

 

 

    /* build message and send it */

 

    msg.childLoopCount = ix;

    msg.buffer = TASK_HIGHPRI_TEXT;

 

    msgQSend (msgQId, (char *) &msg, MSG_SIZE, 0, MSG_PRI_NORMAL);

 

/*

 * read message that this task just sent and print it - no context

 * switch will occur since there is a message already in the queue

*/

 

    msgQReceive (msgQId, (char *) &newMsg, MSG_SIZE, NO_WAIT);

 

#ifdef STATUS_INFO

    printf ("%s/n Number of iterations is %d/n",

       newMsg.buffer, newMsg.childLoopCount);

#endif /* STATUS_INFO */

 

/*

 * block on message queue waiting for message from low priority task

 * context switch will occur since there is no message in the queue

 * when message is received, print it

 */

 

    msgQReceive (msgQId, (char *) &newMsg, MSG_SIZE, WAIT_FOREVER);

 

#ifdef STATUS_INFO

    printf ("%s/n Number of iterations by this task is: %d/n",

       newMsg.buffer, newMsg.childLoopCount);

#endif /* STATUS_INFO */

 

    /* test watchdog timer */

 

  wdStart (wdId, DELAY, (FUNCPTR) tickGet, 1);

 

  wdCancel (wdId);

 }

}

 

抱歉!评论已关闭.