VxWorks Operating System Guide (2.6) Application Example Analysis

xiaoxiao2021-03-06  14

1.1. Application example analysis

By analyzing a specific instance, the task is created, the task communication, memory allocation, message management, etc. VxWorks system is applied further. (Example is selected from the Demo Example 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 Taskspend () / 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.

Thase 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 ()

| /

| /

| Taskspend () <------------- /

| /

| /

| / -------------> 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 prior 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 desnding 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 windowDemo task * /

/ * Forward declarations * /

Local void Taskhighpri (int ution);

Local void TasklowPri (int ution);

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

*

*

* Winddemo - Parent Task to Spawn Children

*

* This task calls Taskhighpri () and tasklowpri () to do the

* Actual Operations of the test and supends itself.

* Task is resulting 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 excercise kernel routines * /

HIGHPRIID = TasksPawn ("Thighpri", High_Pri, Vx_supervisor_Mode, 1000, (Funcptr) Taskhighpri, Itemion, 0,0,0,0,0,0,0,0,0,0,0,0ki

Lowpriid = Taskspawn ("TlowPri", Low_Pri, Vx_supervisor_Mode, 1000, (Funcptr) TasklowPri, Itemion, 0,0,0,0,0,10,0,0,0

Taskspend (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 ;

}

}

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

*

*

* Taskhightpri - 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 ie task.

*

* /

Local void Taskhighpri

(

INT ITERATION / * NUMBER OF ITERATIONTROUGH LOOP * /

)

{

Int ix; / * loop counter * /

MY_MSG MSG; / * Message to send * /

MY_MSG newmsg; / * Message to receive * /

For (ix = 0; 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 * /

Taskspend (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 THISK JUST SENT AND Print It - no context

* Switch Will Occur Since The a Message Already in the queue

* /

MsgqReceive (msgqid, (char *) & newmsg, msg_size, no_wait);

#ifdef status_info

Printf ("% S / N Number of Item 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 The the 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 Item By Task IS:% D / N",

Newmsg.buffer, newmsg.childloopcount;

#ENDIF / * STATUS_INFO * /

/ * Test WatchDog Timer * /

WDSTART (WDID, DELAY, (FUNCPTR) Tickget, 1);

WDCANCEL (WDID);

}

}

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

*

*

* TasklowPri - Low Priority Task

*

* This Task Runs At a Lower Priority and is designed to make available

* The resouces That The High Prior Task is Waiting for And * Subsequently UNBlock The High Priority Task.

*

* /

Local Void TasklowPri

(

INT ITERATION / * NUMBER OF TIMES THROUGH LOOP * /

)

{

Int ix; / * loop counter * /

MY_MSG MSG; / * Message to send * /

For (ix = 0; ix

{

Semgive (SEMID); / * Unblock Thighpri * /

TaskResume (HighPriid); / * unblock think "/ * Unblock Thighpri * /

/ * build message and send it * /

Msg.childloopcount = ix;

Msg.buffer = task_lowpri_text;

Msgqsend (msgqid, (char *) & msg, msg_size, 0, msg_pri_normal); Taskdelay (60);

}

TaskResume (WindDemoid); / * Wake Up The Winddemo Task * /

}

转载请注明原文地址:https://www.9cbs.com/read-50189.html

New Post(0)