初学VxWorks,请高手对vxworks下的一个例子程序windDemo.c做详细分析,附源程序,主要是我不理解调用过程。

terryjwf 2006-11-12 01:55:31
#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 (); //Get the calling task's ID.

FOREVER
{

/* spawn child tasks to exercise kernel routines,产生并激活一个任务*/

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

lowPriId = taskSpawn ("tLowPri", LOW_PRI, VX_SUPERVISOR_MODE, 4000,
(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 */
}
...全文
677 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tiercel2007 2007-04-13
  • 打赏
  • 举报
回复
顶!我认为alpha说的很好!条理很清淅!支持!!
面朝大大海 2007-04-11
  • 打赏
  • 举报
回复
刚学vxworks第三天,今天刚好看到了这个例子程序.
根据注释,我的理解是:
1.windDemo spawn 出两个task: tHighPri, tLowPri .然后windDemo挂起.
2.tHighPri 优先执行,在semTake(semId, WAIT_FOREVER)处被阻塞,等待semId
3.tLowPri 然后执行,用semGive(semId)释放semId
4.这时,tHighPri因获得senId而进入ready状态,接着调用taskSuspend()将自己挂起
5.因此tLowPri得到调度,用taskResume(tHighPri)重新使tHighPri得到调度执行
6.tHighPri这时向消息队列msgQId发送一个消息,接着又从msgQId接收一个消息,然后第二次从msgQId接收一个消息,这次msgQId中没有消息,tHighPri被阻塞
7. tLowPri此时被调度,向消息队列发送一条消息,tHighPri被unpend
8. tHighPri又重新被调度,启动watchdog(wdog在这里不起作用,只是出来客串一下)

大概就是这样,如果有什麽不对的地方请大家多指教!
吉祥的吉 2006-11-21
  • 打赏
  • 举报
回复
老板让做vxwork tron 一点都不懂,来学一下
terryjwf 2006-11-13
  • 打赏
  • 举报
回复
顶,高手出来帮忙啊!
city_lovelace 2006-11-13
  • 打赏
  • 举报
回复
我的msn:city_lovelace@hotmail.com
terryjwf 2006-11-13
  • 打赏
  • 举报
回复
四少爷,你好,首先感谢你对本问题的关注,我想和你讨论一下,可以吗?我的MSN是:terry_jwf@hotmail.com,谢谢!
city_lovelace 2006-11-13
  • 打赏
  • 举报
回复
一:此中的信号量应该是做同步用,而不是互斥;
二:semTake(semId, 100)时,因为刚刚有个semGive动作,这taskHighPri会取得此信号量,并不会发送任务切换,会发生任务切换的是semTake (semId, WAIT_FOREVER)。在vxworks中,此semId是全局可见的,低优先级任务可以不需要semTake而直接semGive;
三:发送消息本身不是阻塞动作,但因为唤醒的是高优先级任务,所以高优先级任务会抢占CPU
看门狗好象没看出什么意义  


terryjwf 2006-11-12
  • 打赏
  • 举报
回复
我的理解如下:
一。建立主任务windDemo,在该主任务中分别建立高优先级、低优先级2个任务,任务创建后立
即运行,分别建立消息队列和二进制信号量(该信号量用于2个任务的互斥操作),然后主任务
挂起,等待低优先级的任务解除阻塞。
二。在高优先级taskHighPri的任务中,通过semTake (semId, 100);操作,实现对信号量控制
100个时间片的控制权,此时信号量的状态变为不可用,此时发生任务切换吗?在低优先级的任务中没有semTake操作,如何获得信号量?这个我不理解?
三。还有就算发送消息和接收消息的时候,发生任务切换吗?看门狗在本程序中起什么作用?
请各位高手解答一下我的疑问,请帮忙,叩拜!

2,184

社区成员

发帖
与我相关
我的任务
社区描述
xworks是美国 Wind River System 公司( 以下简称风河公司 ,即 WRS 公司)推出的一个实时操作系统。
社区管理员
  • VxWorks开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧