VxWorks操作系统指南(2.6) 应用示例分析
2005-03-06 16:10
537 查看
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);
}
}
/******************************************************************************
*
*
* taskLowPri - low priority task
*
* This task runs at a lower priority and is designed to make available
* the resouces that the high priority 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 < iteration; ix++)
{
semGive (semId); /* unblock tHighPri */
taskResume (highPriId); /* 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 */
}
相关文章推荐
- VxWorks操作系统指南(2) VxWorks应用指导
- VxWorks操作系统指南(2.2) 应用系统配置
- VxWorks操作系统指南(2.5) 应用软件开发指导
- VxWorks操作系统指南(1.7) 时钟管理
- 笔记:Java 性能优化权威指南 第6章 Java 应用性能分析技巧
- Excel XP数据分析应用指南
- Zookeeper C API 指南八(Zookeeper C API 应用示例)
- Kurento应用开发指南(以Kurento 5.0为模板) 之四:示例教程 一对一视频呼叫
- Kurento应用开发指南(以Kurento 5.0为模板) 之二:示例教程helloworld
- x264源码分析与应用示例(三)——浅谈码率控制的优化问题
- ArcGIS教程:水文分析应用示例
- x264源码分析与应用示例(三)——浅谈码率控制的优化问题
- VxWorks操作系统指南(1.2) VxWorks操作系统内核
- VxWorks操作系统指南(2.1) 系统启动
- 四种嵌入式操作系统安全启动分析(unix、linux、qnx、vxworks)
- Kurento应用开发指南(以Kurento 5.0为模板) 之三:示例教程 一对多的视频呼叫
- 【x264】x264源码分析与应用示例——码率控制
- VxWorks操作系统指南(1.3) 任务管理
- Kurento应用开发指南(以Kurento 5.0为模板) 之三:示例教程 一对多的视频呼叫
- ArcGIS教程:太阳辐射分析的应用示例