⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msg.c

📁 vxworkws消息队列通信
💻 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 + -