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

📄 taskschedule.c

📁 vxworks下的多任务管理
💻 C
字号:
/* task  TaskSchdule.c */

/* 头文件 */ 
#include "vxWorks.h"
#include "stdio.h"
#include "stdlib.h" 
#include "msgQLib.h" 
#include "loglib.h"
#include "taskLib.h"
#include "string.h"
#include "semLib.h"
#include "tylib.h"
#include "ctype.h"
/* 宏定义 */ 
#define  MAX_MSGS    (10)  /* 消息队列长度 */
#define  MAX_MSG_LEN sizeof(MESSAGE) /* 消息队列中消息的最大长度 */
#define  MAX_STR_LEN (100)
#define  STACK_SIZE  20000 /* 分配给每个任务的堆栈大小 */

/* 类型定义 */
typedef struct _MESSAGE 
{
    int   mSendId;                      /* 发送任务的MESSAGE ID */
    char  aStr[MAX_STR_LEN];                        /* 消息中传递的数据 */
}MESSAGE;
/* 全局变量 */
SEM_ID dataSemId;        /* 同步信号量 */
int      tidTask1;         /* 任务ID定义 */
int      tidTask2; 
int      tidTask3;
MSG_Q_ID myMsgQId1;         /* 消息队列ID定义 */
MSG_Q_ID myMsgQId2;
MSG_Q_ID myMsgQId3;
int stdIN, stdOUT;              /* 标准输入/输出设备的文件描述符 */
char TaskStatus[MAX_STR_LEN];
char OverFlowFile[MAX_STR_LEN];
/* 函数声明 */
STATUS progStart(void);
STATUS task1(void);
STATUS task2(void);
STATUS task3(void);
void command(void);

/******************************************************************
*
* progStart - 启动实例程序
*
* 负责创建消息队列与任务
*
* RETURNS: OK, ERROR
*/
STATUS progStart(void)
{
    /* 创建消息队列 */
	int i; 
	myMsgQId1 = msgQCreate(MAX_MSGS, MAX_MSG_LEN, MSG_Q_PRIORITY);
	myMsgQId2 = msgQCreate(MAX_MSGS, MAX_MSG_LEN, MSG_Q_PRIORITY);
	myMsgQId3 = msgQCreate(MAX_MSGS, MAX_MSG_LEN, MSG_Q_PRIORITY);
	if (myMsgQId1 == NULL||myMsgQId2 == NULL||myMsgQId3 == NULL) 
	{
		return (ERROR); 
	}
	/* 创建信号量 */
	dataSemId  = semBCreate(SEM_Q_FIFO, SEM_EMPTY);

	/* 创建任务 */
	tidTask1 = taskSpawn("tTask1", 240, 0, STACK_SIZE,
                          (FUNCPTR)task1,0,0,0,0,0,0,0,0,0,0);
	tidTask2 = taskSpawn("tTask2", 220, 0, STACK_SIZE,
                          (FUNCPTR)task2,0,0,0,0,0,0,0,0,0,0);
	tidTask3 = taskSpawn("tTask3", 230, 0, STACK_SIZE,
                          (FUNCPTR)task3,0,0,0,0,0,0,0,0,0,0);
	/* 取标准输入/输出设备文件描述符 */
	stdIN  = ioGlobalStdGet(0);
	stdOUT = ioGlobalStdGet(1);
	for (i=0; i<100; i++) OverFlowFile[i] = 'a';
	return (OK);
}
/******************************************************************
*
*Task1--管理Task
*
*利用信号量的semFlash()负责系统启动时同步系统中其他Task的启动同步
*接收各Task的告警信息,并编号以logmsg()方式输出
*负责系统结束时的Task删除处理
*
* RETURNS: OK
*/

STATUS task1(void) 
{
	MESSAGE  rxMsg; /* 用于从消息队列中接收消息 */
	char msgBuf[MAX_MSG_LEN];
	semFlush(dataSemId);
	FOREVER
	{
		/* 清空消息接收缓冲 */
		memset(rxMsg.aStr, 0, MAX_STR_LEN);
		memset(msgBuf, 0, MAX_MSG_LEN);
        
		/* 从消息队列接收消息,当消息队列空时阻塞(Pend)等待 */ 
		if (msgQReceive(myMsgQId1, (char*)&rxMsg, MAX_MSG_LEN,WAIT_FOREVER)== ERROR)
		{
			return (ERROR);
		}
		if(rxMsg.mSendId == 2 && strcmp(rxMsg.aStr,"q") ==0 )
		{
			semDelete(dataSemId);
			/* 释放信号量资源 */
			msgQDelete(myMsgQId1);
			msgQDelete(myMsgQId2);
			msgQDelete(myMsgQId3);
    			
			/*delete task*/
			taskDelete(tidTask2);
			taskDelete(tidTask3);
			printf("Exit already!\n");
			taskDelete(0);
			return OK;
		}
		sprintf(msgBuf,"\nwarning: %s from Task(%d)\n\n",&rxMsg.aStr,rxMsg.mSendId);
		logMsg(msgBuf,0,0,0,0,0,0);
		command();
	}

	return OK;
}
/******************************************************************
*
*Task2--console命令行接收Task,分析console发来的命令行及参数
*
*设置5种命令,并依据其内容向Task3发送激励消息
*实现系统退出命令,使系统以适当方式安全退出
*收到非法命令向Task1告警
*
* RETURNS: OK
*/
STATUS task2(void) 
{
	char bStr[3][20];                  /* string buffer */
	MESSAGE  txMsg; /* 用于向消息队列中发送消息 */
	char c;                         /* 字符变量 */
	int i = 0;
	int j = 0;
	struct timespec * res;
	char TishiStr[35] = "\nplease input your order here!\n\n";		    /**/
	semTake(dataSemId,WAIT_FOREVER);
	/* 将标准输出设备输出模式设置为RAW */
	ioctl(stdOUT, FIOSETOPTIONS, OPT_RAW); 
	write(stdOUT, TishiStr, sizeof(TishiStr));
	command();

	FOREVER
	{
		i = 0; j = 0;
		/* 清空消息接收缓冲 */
		memset(bStr, 0, 3*20);
		memset(txMsg.aStr, 0, MAX_STR_LEN); 
		/* 向消息队列发送一条普通优先级的消息,
		* 当消息队列满时,阻塞(Pend)等待*/
		/*scanf("%s",bStr);*/
		/* 主循环 */
		while(1)
		{
			/* 在标准输入设备等待键盘输入字符 */
			read(stdIN,&c,1);
			write(stdOUT,&c,1);
			/* 判断若输入字符为"ESC键"则退出主循环 */
			if(c == '\r')
			{
				write(stdOUT,"\n",1);
				break;
			}
			if(c == ' ' || c == ',')
			{
				i++;
				j = -1;
			}
			bStr[i][j++] = c; 
		}
		/*for(i = 0;i<3; i++)
		{
			printf("\njj:%s\n",bStr[i]);
		}
		read(stdIN,bStr,MAX_STR_LEN);
		strncpy(bStr,bStr,strlen(bStr)-1);
		bStr[strlen(bStr)-1] = '\0';*/
		txMsg.mSendId = 2;
		if(strcmp(bStr[0],"q") == 0)/*安全退出系统*/
		{
			/*删除信号量,消息队列*/
			strcpy(txMsg.aStr,bStr[0]);
			if (msgQSend(myMsgQId1, (char*)&txMsg, MAX_MSG_LEN,WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)
			{
				return (ERROR);
			}
			return OK;
		}
      		
		if(strcmp(bStr[0],"taskShow") == 0)
		{
			if(strcmp(bStr[1],"1") == 0)
			{
				taskShow(tidTask1,0);
				write(stdOUT,"\n",1);
				command();
				continue;
			}
			else if(strcmp(bStr[1],"3") == 0)
			{
				taskShow(tidTask3,0);
				write(stdOUT,"\n",1);
				command();
				continue;
			}
		}
		if(strcmp(bStr[0],"toupper") == 0)
		{
			strncpy(&c,bStr[1],1);
			sprintf(txMsg.aStr,"\nupper form: %c\n\n",toupper(c));
			if (msgQSend(myMsgQId3, (char*)&txMsg, MAX_MSG_LEN,WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)
			{
				return (ERROR);
			}
			continue;     						
      						
		}
		if(strcmp(bStr[0],"taskStatusString") == 0)
		{
			memset(TaskStatus, 0, MAX_STR_LEN);
			if(strcmp(bStr[1],"1") == 0 )
			{
				taskStatusString(tidTask1,TaskStatus);
				sprintf(txMsg.aStr,"\nTask1's Status: %s\n\n",TaskStatus);
				if (msgQSend(myMsgQId3, (char*)&txMsg, MAX_MSG_LEN,WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)
				{
					return (ERROR);
				}
				continue;
			}
			else if(strcmp(bStr[1],"3") == 0)
			{
				/*taskStatusString(tidTask3,TaskStatus);*/
				sprintf(txMsg.aStr,"\nTask3's Status: %s\n\n",TaskStatus);
				if (msgQSend(myMsgQId3, (char*)&txMsg, MAX_MSG_LEN,WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)
				{
					return (ERROR);
				}
				continue;
			}
		}
		if(strcmp(bStr[0],"OutFile") == 0)
		{
			strcpy(txMsg.aStr,OverFlowFile);
			if (msgQSend(myMsgQId3, (char*)&txMsg, MAX_MSG_LEN,WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)
			{
				return (ERROR);
			}
			continue;
		}
		if(strcmp(bStr[0],"Info") == 0)
		{
			strcpy(txMsg.aStr,"\nBUPT VXWORKS HOMEWORK, by KongFeng:)\n\n");
			if (msgQSend(myMsgQId3, (char*)&txMsg, MAX_MSG_LEN,WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)
			{
				return (ERROR);
			}
			continue;
		}
      		      				
		/*命令错误,非法*/
		strcpy(txMsg.aStr," invalid command! ");
		if (msgQSend(myMsgQId1, (char*)&txMsg, MAX_MSG_LEN,WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)
		{
			return (ERROR);
		}      			
	}
	ioctl (stdOUT, FIOSETOPTIONS, OPT_TERMINAL);
	return (OK);
}
/******************************************************************
*
*Task3--console输出Task
*接收需打印输出的字串消息(命令),输出到控制台
*收到长度为0或超长字串向Task1告警
*
* RETURNS: OK
*/
STATUS task3(void) 
{
	MESSAGE  rxMsg; /* 用于从消息队列中接收消息 */
	MESSAGE  txMsg; /* 用于向消息队列中发送消息 */
	int msglen;
	semTake(dataSemId,WAIT_FOREVER);

	txMsg.mSendId = 3;
	FOREVER
	{
		/* 清空消息接收缓冲 */
		memset(rxMsg.aStr, 0, MAX_STR_LEN);
		/* 从消息队列接收消息,当消息队列空时阻塞(Pend)等待 */ 
		if (msgQReceive(myMsgQId3, (char*)&rxMsg, MAX_MSG_LEN,WAIT_FOREVER)== ERROR)
		{
			return (ERROR);
		}
		msglen = strlen(rxMsg.aStr);
		if(msglen == 0 || msglen > 80)
		{
			/*send msg to Task1 to warn*/
			strcpy(txMsg.aStr,"receive 0 or overlength string! ");
			if (msgQSend(myMsgQId1, (char*)&txMsg, MAX_MSG_LEN,WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)
			{
				return (ERROR);
			}
		}
		else
			write(stdOUT, rxMsg.aStr, sizeof(rxMsg.aStr));
		command();
		}
	return OK;
}
void command()
{
	write(stdOUT,">>",2);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -