📄 msg.c
字号:
/*
本实验对VxWorks任务通信中的消息队列通信进行了实验
在实验中,有一个作为服务器的任务tServer与NUM_CLIENT个作为客户tClient,每个任务拥有一个属于自己的消息队列:
progStart()、progStop()分别用来停止、启动本演示程序。本实例中NUM_CLIENT个客户任务使用同一个函数创建,在实际应用中,也可使用不同的函数创建。
tClientX(X=1,2,……NUM_CLIENT)负责向tServer发送消息,并等待接受tServer回应的ACK(应答)。
tServer负责接受来自各个tClientX的消息,简单处理后向对应tClientX发送ACK(应答)。
通过progStart()来启动实例程序。启动过程中,先创建消息队列,再创建任务,以保证消息队列在被任务使用之前已经创建。另外,tServer任务需要先于tClientX任务创建,因为tClientX随时可能向tServer发送请求。本实例中,创建客户任务tClientX时,基于同一个函数client(),各个客户任务通过ID来进行区分。
通过Server()来处理来自各个客户任务的消息。Server()针对来自不同客户任务的消息进行相应地处理,将收到消息rxMsg中的数据转存到消息txMsg中,作为ACK回传给对应的客户任务。
Client()用来向服务器任务发请求消息。Client()首先生成一个随即的数据,然后将数据放入发送消息txMsg中,发给服务器任务,然后等待回应的ACK消息,并检验回应的数据是否正确。
progStop()用于停止实例程序,删除创建的任务并释放消息队列资源。
*/
#include "vxworks.h"
#include "msgQLib.h"
/*消息队列长度*/
#define MAX_MSGS (10)
/*消息队列中消息的最大长度*/
#define MAX_MSG_LEN sizeof(MESSAGE)
/*分配给每个任务堆栈的大小*/
#define STACK_SIZE 20000
/*client发送消息的时间间隔*/
#define DELAY_TICKS 50
/*客户程序的个数*/
#define NUM_CLIENT 2
/*任务ID*/
#define MID_CLIENT(id) (id)
#define MID_SERVER NUM_CLIENT
/*消息定义*/
typedef struct Msg
{
int mSendId;
int mRecvId;
int mData;
}MESSAGE;
/*任务ID定义*/
int tidServer;
int tidClient[NUM_CLIENT];
/*消息队列ID定义*/
MSG_Q_ID msgQIdServer;
MSG_Q_ID msgQIdClient[NUM_CLIENT];
/*函数声明*/
STATUS progStart(void);
STATUS server(void);
STATUS client(int id);
void progStop(void);
STATUS progStart(void)
{
int id;
/*创建消息队列*/
msgQIdServer = msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_PRIORITY);
if (msgQIdServer == NULL)
{
return(ERROR);
}
/*创建消息队列*/
for (id = 0 ; id < NUM_CLIENT; id++)
{
msgQIdClient[id] = msgQCreate(MAX_MSGS, MAX_MSG_LEN, MSG_Q_PRIORITY);
if (msgQIdClient[id] == NULL)
{
return (ERROR);
}
}
/*穿件任务*/
tidServer = taskSpawn("tServer", 220 , 0, STACK_SIZE, (FUNCPTR)server, 0,0,0,0,0,0,0,0,0,0);
for (id = 0; id < NUM_CLIENT; id++)
{
char tempName[20];
sprintf(tempName, "tClient%d", id);
tidClient[id] = taskSpawn(tempName, 200, 0, STACK_SIZE, (FUNCPTR)client, id,0,0,0,0,0,0,0,0,0);
}
return OK;
}
STATUS server(void)
{
MESSAGE rxMsg; /*用于从消息队列中接收消息*/
MESSAGE txMsg; /*用于向消息队列中发送消息*/
/*发送消息的ID即为服务端的ID*/
txMsg.mSendId = MID_SERVER;
FOREVER
{
/*从消息队列中接收消息,当消息队列空时阻塞等待*/
if (msgQReceive(msgQIdServer, (char*)&rxMsg, MAX_MSG_LEN, WAIT_FOREVER) == ERROR)
{
return (ERROR);
}
/*接收到的消息应该是发送给自己的*/
if (rxMsg.mRecvId != MID_SERVER)
{
return (ERROR);
}
/*接收到的消息应该是某个client发的*/
if ( (rxMsg.mSendId < MID_CLIENT(0)) || (rxMsg.mSendId > MID_CLIENT(NUM_CLIENT - 1)) )
{
return (ERROR);
}
printf("\n tServer: receive a date %d from tClient%d \n ", rxMsg.mData, rxMsg.mSendId);
/*根据接收到的消息配置回应消息*/
txMsg.mRecvId = rxMsg.mSendId;
txMsg.mData = rxMsg.mData;
/*向对应的消息队列发送ACK,当消息队列满时,阻塞等待*/
if (msgQSend(msgQIdClient[rxMsg.mSendId], (char*)&txMsg, sizeof(MESSAGE), WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)
{
return ERROR;
}
}
return OK;
}
/*id标示了客户端*/
STATUS client(int id)
{
MESSAGE rxMsg; /*用于从消息队列中接收消息*/
MESSAGE txMsg;/*用于向消息队列发送消息*/
/*初始化txMsg,填写mSendId与mRecvId字段*/
txMsg.mSendId = MID_CLIENT(id);
txMsg.mRecvId = MID_SERVER;
FOREVER
{
/*得到随机数*/
txMsg.mData = rand();
/*向对应的服务器消息队列发送消息,当消息队列满时,阻塞等待*/
if ( msgQSend(msgQIdServer,(char*)&txMsg, sizeof(MESSAGE), WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)
{
return OK;
}
printf("\n tClient%d transmit a data %d to tServer\n", id ,txMsg.mData);
/*接收服务器发回来的消息*/
if (msgQReceive(msgQIdClient[id], (char*)&rxMsg, MAX_MSG_LEN, 20) == ERROR)
{
printf("\n tClient%d: wait ACK timeout!!!\n");
continue;
}
printf("\n tClient%d: receive the ACK from tServer", id);
/*检查是否收到正确的server回应*/
if (txMsg.mData == rxMsg.mData)
{
printf(", and data check ok ! \n\n");
}
else
{
printf("\n, but data check ERROR !!!\n");
printf("tx data(%d) != ACK data(%d)\n", txMsg.mData , rxMsg.mData);
}
taskDelay(DELAY_TICKS + (txMsg.mData % DELAY_TICKS));
}
return OK;
}
void progStop(void)
{
int id; /*用来区分不同的客户任务*/
for (id = 0 ; id < NUM_CLIENT; id++)
{
taskDelete(tidClient[id]);
}
taskDelete(tidServer);
msgQDelete(msgQIdServer);
for (id = 0; id < NUM_CLIENT; id++)
{
msgQDelete(msgQIdClient[id]);
}
printf("\n BYE \n");
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -