📄 exp3com.c
字号:
/*
Name: Exp3 CommunicationTask
Copyright: TY
Author: Tony Yau
Date: 23/06/08 14:35
Description:
*/
/* C04b_msgQ.c P88 */
/* 头文件 */
#include "vxWorks.h"
#include "msgQLib.h"
#include "stdio.h"
#include "stdlib.h"
#include "String.h"
#include "semLib.h"
#include "taskLib.h"
#include "logLib.h"
#ifdef INCLUDE_LOGGING
logInit (conslefd, MAX_LOG_MSGS);
#endif
/* 宏定义 */
#define MAX_MSGS (30) /* 消息队列长度 */
#define MAX_MSG_LEN (50) /* 消息队列中消息的最大长度 */
#define STACK_SIZE 20000 /* 分配给每个任务的堆栈大小 */
#define DELAY_TICKS 50 /* 发送消息的间隔时间 */
#define MAX_LOG_MSGS (200)
/* --- LED IO addresses (only rGPBDAT is used) --- */
#define rGPBCON (*(volatile unsigned *) 0x56000010)
#define rGPBDAT (*(volatile unsigned *) 0x56000014)
#define rGPBUP (*(volatile unsigned *) 0x56000018)
#ifdef INCLUDE_LOGGING
logInit (ioGlobalStdGet(1), MAX_LOG_MSGS);
/*Initial,set Standard IO Device as logging device*/
#endif
/* 全局变量 */
int tidTask1; /* 任务ID定义 */
int tidTask2;
int tidTask3;
int tidTask4;
int LedFd;
SEM_ID SemId; /* 信号量ID,用于同步 */
MSG_Q_ID MsgQId1; /* 消息队列ID定义 */
MSG_Q_ID MsgQId2;
MSG_Q_ID MsgQId3;
MSG_Q_ID MsgQId4;
/* 函数声明 */
STATUS st(void);
STATUS progStart(void);
STATUS task1(void);
STATUS task2(void);
STATUS task3(void);
STATUS task4(void);
void ps(void);
void progStop(void);
void Led_Display(int data)
{
rGPBDAT = (rGPBDAT & ~(0xf<<5)) | ((~data & 0xf)<<5);
}
/******************************************************************
*
* progStart - 启动实例程序
*
* 负责创建消息队列与任务
*
* RETURNS: OK, ERROR
*/
STATUS progStart(void)
{
/* 创建消息队列 */
MsgQId1 = msgQCreate(MAX_MSGS, MAX_MSG_LEN, MSG_Q_PRIORITY);
MsgQId2 = msgQCreate(MAX_MSGS, MAX_MSG_LEN, MSG_Q_PRIORITY);
MsgQId3 = msgQCreate(MAX_MSGS, MAX_MSG_LEN, MSG_Q_PRIORITY);
MsgQId4 = msgQCreate(MAX_MSGS, MAX_MSG_LEN, MSG_Q_PRIORITY);
/* 创建信号量 */
SemId = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
LedFd = open("/tgtsvr",2,0);
if (MsgQId1 == NULL)
{
return (ERROR);
}
if (MsgQId2 == NULL)
{
return (ERROR);
}
if (MsgQId3 == NULL)
{
return (ERROR);
}
if (MsgQId4 == NULL)
{
return (ERROR);
}
/* 创建任务 */
tidTask1 = taskSpawn("tTask1", 200, 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", 240, 0, STACK_SIZE,
(FUNCPTR)task3,0,0,0,0,0,0,0,0,0,0);
tidTask4 = taskSpawn("tTask4", 230, 0, STACK_SIZE,
(FUNCPTR)task4,0,0,0,0,0,0,0,0,0,0);
printf("Program Initial.\n");
return (OK);
}
/******************************************************************
*
* task1 – 周期性地向消息队列发送消息
*
* 用于周期性地向消息队列发送消息,
* 设置发送优先级为MSG_Q_FIFO,timeout参数为WAIT_FOREVER
*
* RETURNS: OK
*/
STATUS task1(void)
{
char msgBuf[MAX_MSG_LEN];
taskDelay(DELAY_TICKS);
semFlush(SemId); /*Synchronize*/
FOREVER
{
/* 清空消息接收缓冲 */
memset(msgBuf, 0, MAX_MSG_LEN);
/* 从消息队列接收消息,当消息队列空时阻塞(Pend)等待 */
if (msgQReceive(MsgQId1, msgBuf, MAX_MSG_LEN, WAIT_FOREVER)
== ERROR)
{
return (ERROR);
}
if (strncmp(msgBuf, "Shutdown",8) == 0) /*Shutdown*/
{
printf("Shuting down...\n");
progStop();
taskDelete(tidTask1);
return;
}
else if (strncmp(msgBuf, "Error",5) == 0) /*Error Logging*/
{
logMsg(msgBuf,0,0,0,0,0,0);
}
else {
/*Other Error Handling*/
sprintf(msgBuf,"Unkonwn Error : %s",msgBuf);
logMsg(msgBuf,0,0,0,0,0,0);
}
} /*Forever Loop*/
return (OK);
}
/******************************************************************
*
* task2 – 接收消息并显示
*
* console 命令行接收 Task。接收并分析 console发来的命令行及参数。
自行设置5种以上命令, 并根据命令的内容向Task3或/及Task4发送激励消息。
同时实现系统退出命令, 使系统采用适当方式安全退出。 收到非法命令向Task1
告警。
*
* RETURNS: OK
*/
STATUS task2(void)
{
int Flag=-1;
int cmprlt;
char msgBuf[MAX_MSG_LEN];
semTake(SemId, WAIT_FOREVER);
FOREVER
{
taskDelay(10);
memset(msgBuf, 0, MAX_MSG_LEN);
printf("\nInput the command :> ");
scanf("%s",msgBuf);
if (strncmp(msgBuf, "Led",3) == 0)
Flag = 0;
else if (strncmp(msgBuf, "Print",5) == 0)
Flag = 1;
else if (strncmp(msgBuf, "Shutdown",8) == 0)
Flag = 2;
switch(Flag)
{
case 0: /*Turn to Task 3*/
if (msgQSend(MsgQId3, msgBuf, MAX_MSG_LEN,
WAIT_FOREVER, MSG_Q_FIFO) == ERROR)
{
printf("Message Sending Error.\n");
return;
}
break;
case 1:/*Turn to Task 4*/
if (msgQSend(MsgQId4, msgBuf, MAX_MSG_LEN,
WAIT_FOREVER, MSG_Q_FIFO) == ERROR)
{
printf("Message Sending Error.\n");
return;
}
break;
case 2:/*Turn to Task 1*/
if (msgQSend(MsgQId1, msgBuf, MAX_MSG_LEN,
WAIT_FOREVER, MSG_Q_FIFO) == ERROR)
{
printf("Message Sending Error.\n");
return;
}
break;
default:/*Warning*/
sprintf(msgBuf,"Error: Syntax Error: %s \n",msgBuf);
if (msgQSend(MsgQId1, msgBuf, MAX_MSG_LEN,
WAIT_FOREVER, MSG_Q_FIFO) == ERROR)
{
printf("Message Sending Error.\n");
return;
}
break;
}
Flag=-1;
/* 清空消息接收缓冲 */
/* memset(msgBuf, 0, MAX_MSG_LEN); */
} /*Forever Loop*/
return OK;
}
/******************************************************************
*
* task3 – 接收消息并显示
*
* Task3:Led 控制 Task。接收 Led 控制消息(命令) ,自定义 Led 显示方式表
现命令执行情况。本 task应负责led相关 I/O port初始化。收到非法 led控制
命令向 Task1告警。
*
* RETURNS: OK
*/
STATUS task3(void)
{
char msgBuf[MAX_MSG_LEN];
int num;
char numCH;
semTake(SemId, WAIT_FOREVER);
FOREVER
{
/* 清空消息接收缓冲 */
memset(msgBuf, 0, MAX_MSG_LEN);
/* 从消息队列接收消息,当消息队列空时阻塞(Pend)等待 */
if (msgQReceive(MsgQId3, msgBuf, MAX_MSG_LEN, WAIT_FOREVER)
== ERROR)
{
return (ERROR);
}
/* 将接收到的消息显示出来 */
if (strncmp(msgBuf, "Led",3) == 0)
{
numCH = (char )*(msgBuf+3);
num = (int ) numCH - 48;
}
if (num<0||num>9)
{
/*Error to Task 1*/
sprintf(msgBuf,"Error: Argument Error : %s \n",msgBuf);
if (msgQSend(MsgQId1, msgBuf, MAX_MSG_LEN,
WAIT_FOREVER, MSG_Q_FIFO) == ERROR)
{
printf("Message Sending Error.\n");
return;
}
}else{
/*write(LedFd,0,1); /*Write to Led Device*/
printf("Write to Led %d\n",num);
Led_Display(num);
}
} /*Forever Loop*/
}
/******************************************************************
*
* task4 – 接收消息并显示
*
* Task4: console输出 Task。 接收需打印输出的字串消息(命令),输出到 console。
收到长度为0 或超常字串向 Task1告警。
*
* RETURNS: OK
*/
STATUS task4(void)
{
char msgBuf[MAX_MSG_LEN];
semTake(SemId, WAIT_FOREVER);
FOREVER
{
/* 清空消息接收缓冲 */
memset(msgBuf, 0, MAX_MSG_LEN);
/* 从消息队列接收消息,当消息队列空时阻塞(Pend)等待 */
if (msgQReceive(MsgQId4, msgBuf, MAX_MSG_LEN, WAIT_FOREVER)
== ERROR)
{
return (ERROR);
}
/* 将接收到的消息显示出来 */
printf("Echo: %s\n", (char *)(msgBuf+5));
} /*Forever Loop*/
return OK;
}
/******************************************************************
*
* progStop - 停止实例程序
*
* 调用本函数来停止本实例程序,删除创建的任务并释放消息队列资源。
*
* RETURNS: N/A
*/
void progStop(void)
{
taskSuspend(tidTask2);
taskSuspend(tidTask3);
taskSuspend(tidTask4);
/* 删除信号量 */
semDelete(SemId);
/* 删除创建的任务 */
taskDelete(tidTask2);
taskDelete(tidTask3);
taskDelete(tidTask4);
close(LedFd);
/* 释放信号量资源 */
msgQDelete(MsgQId1);
msgQDelete(MsgQId2);
msgQDelete(MsgQId3);
msgQDelete(MsgQId4);
printf("BYE!\n");
taskDelete(tidTask1);
return;
}
void ps(void)
{
progStop();
}
STATUS st(void)
{
progStart();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -