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

📄 final.c

📁 定时中断程序
💻 C
字号:
#include "vxworks.h"
#include "stdio.h"
#include "stdlib.h"
#include "semlib.h"
#include "tasklib.h"
#include "msgQLib.h"
#include"string.h"
#include"wdLib.h"


#define DELAY_TICKS 300/*间隔时间*/
#define STACK_SIZE 20000/*分配给每个任务的堆栈大小*/
#define MAX_MSGS (1000)/*消息队列长度(最大消息个数)*/
#define MAX_MSG_LEN (50)/*消息队列中消息的最大长度*/
#define t1_Wdog_INTV 100
#define t2_Wdog_INTV 200
#define NO_PARAMETER 0
int delay=DELAY_TICKS;/*task2需用的延时时间*/
LOCAL WDOG_ID t1_Wdog=NULL;/*声明看门狗*/
LOCAL WDOG_ID t2_Wdog=NULL;
LOCAL WDOG_ID t3_Wdog=NULL;

int tidtask_mem1;/*任务ID定义*/
int tidtask_memdd2;
MSG_Q_ID mem_16;/*定义各个task的消息队列*/
MSG_Q_ID mem_256;
MSG_Q_ID mem_16_DD;
MSG_Q_ID mem_256_DD;/*mem_16和mem_16_DD的区别是,mem_16是用来
分配内存用的,而mem_16_DD是释放内存用的*/
SEM_ID mem_Rc_ID;/*声明信号量*/
SEM_ID mem_DD_ID;
SEM_ID mem_In_ID;
SEM_ID syncSemID;


int tidtask1;/*任务ID定义*/
int tidtask2;
int tidtask3;
MSG_Q_ID task1MsgQID;/*定义各个task的消息队列*/
MSG_Q_ID task2MsgQID;
MSG_Q_ID task3MsgQID;

STATUS progStart(void);

STATUS task_mem1(void);/*定义初始化内存池的任务*/
STATUS task_memdd2(void); /*定义删除内存池的任务*/
/**/
void mem_Cr(void);/*task_mem1将用到的初始化内存池的函数*/
void mem_DD(void);/*task_memdd2将用到的删除内存池的函数*/
void look(void);/*查看内存池状况的函数*/
void taskmemdd(void);/*任务task_memdd2的函数*/
PART_ID mem_In(int);/*用来申请内存的函数*/
PART_ID p;/*定义的初始化内存池时需要用到的全局变量*/
PART_ID pi;
PART_ID Buf;

STATUS task1(void);/*对应的任务的函数声明*/
STATUS task2(void);
STATUS task3(void);
void progStop(void);
void t1_wdog_timeout(void);/*看门狗的中断后执行的函数*/
void t2_wdog_timeout(void);


typedef struct message/*定义的结构体,在次程序中,所有的消息都是这个结构*/
{int tp;/*tp就是消息的头,从它可以判断出不同的消息*/
char* mes;/*消息主体*/
}mg;
/**/
mg wd_aa1;/*声明中断程序中要用的消息为全局变量*/
mg wd_aa2;
mg wd_aa3;


STATUS progStart(void)
{/**/
 tidtask1= taskSpawn ("ttask1", 250, 0, STACK_SIZE,
        (FUNCPTR) task1,0,0,0,0,0,0,0,0,0,0);
tidtask2= taskSpawn ("ttask2", 205, 0, STACK_SIZE,
        (FUNCPTR) task2,0,0,0,0,0,0,0,0,0,0);
tidtask3= taskSpawn ("ttask3", 200, 0, STACK_SIZE,
        (FUNCPTR) task3,0,0,0,0,0,0,0,0,0,0);
  syncSemID=semBCreate(SEM_Q_FIFO, SEM_EMPTY);

mem_16=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_PRIORITY);
 
if(mem_16==NULL)
{
return(ERROR);
}
mem_256=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_PRIORITY);
if(mem_256==NULL)
{
return(ERROR);
}

mem_16_DD=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_PRIORITY);
 
if(mem_16==NULL)
{
return(ERROR);
}
mem_256_DD=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_PRIORITY);
if(mem_256==NULL)
{
return(ERROR);
}
mem_Rc_ID=semBCreate(SEM_Q_FIFO,1);
mem_In_ID=semBCreate(SEM_Q_FIFO,1);
mem_DD_ID=semBCreate(SEM_Q_FIFO,0);
 tidtask_mem1= taskSpawn ("ttask_mem1", 100, 0, STACK_SIZE,
        (FUNCPTR) task_mem1,0,0,0,0,0,0,0,0,0,0);

 tidtask_memdd2= taskSpawn ("ttask_memdd2", 101, 0, STACK_SIZE,
        (FUNCPTR) task_memdd2,0,0,0,0,0,0,0,0,0,0);



}
/*///////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////*/
/*从这里开始,都是在初始化内存池*/
/*用来初始化内存池和释放内存池的任务不具有所谓的
有相同的结构,因为他们不是真正的程序主体*/
/*////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////*/
STATUS task_mem1(void)
        {
       FOREVER
         {  
semTake (mem_Rc_ID, WAIT_FOREVER);/*因为只想在有需要的时候
建立内存池,所以用一个信号量来限制,信号量mem_Rc_ID
在定义时是可用的,所以在这里用过一次以后就没有
了,实在有需要的时候可以在shell中give mem_Rc_ID信号*/
mem_Cr();/*调用初始化内存池函数*/

semFlush (syncSemID);/*flush所有因得不到syncSemID这个资源
而被pend的任务*/
}
 return(OK);
         }

/**/
STATUS task_memdd2(void)
        {semTake (syncSemID, WAIT_FOREVER);
       FOREVER
         { int a;
semTake(mem_DD_ID, WAIT_FOREVER);/*在程序结束时调用taskmemdd
函数,可以得到mem_DD_ID资源,则允许执行下面命令*/
mem_DD();/*调用内存池删除函数*/
msgQDelete(mem_16);/*释放全局变量*/
msgQDelete(mem_256);
msgQDelete(mem_16_DD);
msgQDelete(mem_256_DD);
logMsg("pi have been deleted!\n");
/*scanf("%d",&a);*/
free(pi);
free(p);
semDelete (mem_DD_ID);
taskDelete (tidtask_memdd2);
}
 return(OK);
         }


void mem_Cr(void)/**/
{
int n,m;
int a;
int i;
PART_ID n_16;
PART_ID m_256;
logMsg("How much number do you want about 16 ?\n");
scanf("%d",&n);
logMsg("How much number do you want about 256 ?\n");
scanf("%d",&m);
a=(16+8)*n+(256+8)*m+256;/*由于16和256字节的,需要额外开销
都是8字节,所以是16+8和256+8、后面多加德256是
为了安全,加上去的*/
p=(PART_ID)malloc(a);
pi=memPartCreate(p,a);/*在p为首地址的a那么大的空间中
创建内存分区*/

i=1;
for(;i<=n;i++)/*循环n次,申请n个16字节的空间*/
{
n_16=memPartAlloc(pi,16);/*在pi指向的内存分区中分配16个字节的内存,
并把首地址赋给n_16*/
/*把首地址传给消息队列mem_16和mem_16_DD*/
if(msgQSend(mem_16,&n_16,sizeof(PART_ID),WAIT_FOREVER,MSG_PRI_NORMAL)==ERROR)
{
return(ERROR);
}
if(msgQSend(mem_16_DD,&n_16,sizeof(PART_ID),WAIT_FOREVER,MSG_PRI_NORMAL)==ERROR)
{
return(ERROR);
}
}
logMsg("16 have been created (%d)\n", msgQNumMsgs(mem_16));
i=1;
for(;i<=m;i++)/*循环m次,申请m个256字节的空间*/
{
m_256=memPartAlloc(pi,256);
if(msgQSend(mem_256,&m_256,sizeof(PART_ID),WAIT_FOREVER,MSG_PRI_NORMAL)==ERROR)
{
return(ERROR);
}
if(msgQSend(mem_256_DD,&m_256,sizeof(PART_ID),WAIT_FOREVER,MSG_PRI_NORMAL)==ERROR)
{
return(ERROR);
}

}
logMsg("256 have been created (%d)\n", msgQNumMsgs(mem_256));
}

void look(void)
{
/*查看16字节内存池状况*/
logMsg("the mem of 16 leave %d\n",msgQNumMsgs(mem_16));
/*查看256字节内存池状况*/
logMsg("the mem of 256 leave %d\n",msgQNumMsgs(mem_256));

}

void mem_DD(void)/**/
{
int a;
int t5cs;
int t5Num;
int aaa;
t5Num=msgQNumMsgs(mem_16_DD);
if(t5Num!=0)/*先判断消息队列中有没有消息
	,也就是首地址,若有,则循环的从
	消息队列中取出来,释放掉*/
{
logMsg("(16) will be delete!\n");
/*scanf("%d",&a);*/
}
t5cs=1;
aaa=msgQNumMsgs(mem_16_DD);
for(;t5cs<=t5Num;t5cs++)
{if(msgQReceive(mem_16_DD,&Buf,sizeof(PART_ID),WAIT_FOREVER)==ERROR)
               {
return(ERROR);
}
memPartFree(pi,Buf);
logMsg("DDDDDDDDDDDDDDDDDD16!!! This is %d\n",aaa-msgQNumMsgs(mem_16_DD));
}




t5Num=msgQNumMsgs(mem_256_DD);
if(t5Num!=0)/*先判断消息队列中有没有消息
	,也就是首地址,若有,则循环的从
	消息队列中取出来,释放掉*/
{
logMsg("(256) will be delete!\n");
/*scanf("%d",&a);*/
}
t5cs=1;
aaa=msgQNumMsgs(mem_256_DD);
for(;t5cs<=t5Num;t5cs++)
{if(msgQReceive(mem_256_DD,&Buf,sizeof(PART_ID),WAIT_FOREVER)==ERROR)
               {
return(ERROR);
}
memPartFree(pi,Buf);
logMsg("DDDDDDDDDDDDDDDDDD256!!! This is %d\n",aaa-msgQNumMsgs(mem_256_DD));
}

}


PART_ID mem_In(n)/*申请内存函数*//**/
{
PART_ID ip;
int In_from_sys=0;
semTake(mem_In_ID, WAIT_FOREVER);
/*当n小于等于16时,则从mem_16消息队列中取一个地址
赋给ip*/
if(n<=16)
{if(msgQNumMsgs(mem_16)<=3)/*如果只剩不到3个含3个地址,则
告警*/
logMsg("only %d be left (16)\n",msgQNumMsgs(mem_16));
if(msgQNumMsgs(mem_16)>0)/*但只要有剩的地址就取出,赋给ip*/
{if(msgQReceive(mem_16,&ip,sizeof(PART_ID),0)==ERROR)
               {
return(ERROR);
}}
else
{logMsg("there is nothing (16)\n");
In_from_sys=1;}
}
else
{/*当n小于等于256时,则从mem_256消息队列中取一个地址
赋给ip*/
if(n<=256)
{if(msgQNumMsgs(mem_256)<=3)/*如果只剩不到3个含3个地址,则
告警*/
logMsg("only %d be left (256)\n",msgQNumMsgs(mem_256));
if(msgQNumMsgs(mem_256)>0)/*但只要有剩的地址就取出,赋给ip*/
{if(msgQReceive(mem_256,&ip,sizeof(PART_ID),0)==ERROR)
               {
return(ERROR);
}}
else
{logMsg("there is nothing (256)\n");
In_from_sys=1;}
}
else/*如果要申请的空间比256还要大,或者消息队列中
	已经没有地址可以用了,则用malloc向内存申请*/
{
In_from_sys=1;
}
}

if(In_from_sys==1)
ip=malloc(n);
semGive (mem_In_ID);
look();
return ip;/*返回地址值*/

}/**/
/*//////////////////以上都是对内存池的设置//////////////
////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
*/
/*从这里开始,才是真正程序的实体,所有任务都有统一的结构*/
STATUS task1(void)
        {
int a_t1;
mg aa_t1;
mg aa_to_t3;
int buf_t1;
mg* msgBuf_t1;
buf_t1=&aa_t1;
aa_t1.tp=1;/*定义task1的头为1*/
aa_t1.mes="I'm task1";/*对task1的消息的主体进行初始化*/
aa_to_t3.tp=1;
aa_to_t3.mes="I'm task1(to task3 and this is long Msg)";
task1MsgQID=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_PRIORITY);
if(task1MsgQID==NULL)
{
return(ERROR);
}/*创建task1的私有消息队列*/
if((t1_Wdog=wdCreate())==NULL)/*创建task1的看门狗*/
{
logMsg("FFFFFFFFFF\n");
return;
}
logMsg("t1_Wdog ID=%x\n",(int)t1_Wdog);
if(msgQSend(task2MsgQID,&buf_t1,4,WAIT_FOREVER,MSG_PRI_NORMAL)==ERROR)
{
return(ERROR);
} 
semTake (syncSemID, WAIT_FOREVER);/*要syncSemID资源,用来保证使得
任务在内存池建好后才能申请内存*/
msgBuf_t1=(mg*)mem_In(sizeof(mg));
       FOREVER
         {  
       /*从自己的消息队列中取消息*/    
if(msgQReceive(task1MsgQID,&msgBuf_t1,4,WAIT_FOREVER)==ERROR)
               {
          return(ERROR);
               }
/*通过switch机制来验证消息头就能判断是
谁发给自己的消息*/
switch(msgBuf_t1->tp)
{/*因为task2的消息的消息头是2*/
case 2:logMsg("%d   %s\n",(*msgBuf_t1).tp,(*msgBuf_t1).mes);
/*收到task2的回复后再向task2发消息*/
if(msgQSend(task2MsgQID,&buf_t1,4,WAIT_FOREVER,MSG_PRI_NORMAL)==ERROR)
{
return(ERROR);
}
/*启动t1_Wdog,为了保证t1_Wdog通知自己在给task2发消息后的一定时间
后再向task3发消息*/
if(wdStart(t1_Wdog,t1_Wdog_INTV,(FUNCPTR)t1_wdog_timeout,NO_PARAMETER)==ERROR)
{
logMsg("FFFFFFFFFF\n");  
wdDelete(t1_Wdog);
return;
}break;
/*因为t1_Wdog的消息头是10*/
case 10:
	/*输出t1_Wdog发给自己的消息*/
		logMsg("%d   %s\n",(*msgBuf_t1).tp,(*msgBuf_t1).mes);
	/*向task3发消息,发给task3的是长消息(即,把整个定义的结构体传过去了)
	而不是传的指针(除传给task3的消息,task3接受task1的消息是长消息
	其他所有在本程序中传的消息均为短消息,即,只传的指针)*/
		if(msgQSend(task3MsgQID,&aa_to_t3,sizeof(mg),WAIT_FOREVER,MSG_PRI_NORMAL)==ERROR)
{
return(ERROR);
}
		logMsg("I(task1) have send a Msg to task3!!\n");break;
}


          }
 return(OK);
         }
/**/
/*因为task的结构都是相同的,所以下面的我就不详细说明
了,只说明功能上的不同之处*/
STATUS task2(void)
        {
int a_t2;
mg aa_t2;
int buf_t2;
mg* msgBuf_t2;
buf_t2=&aa_t2;
aa_t2.tp=2;
aa_t2.mes="I'm task2";
task2MsgQID=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_PRIORITY);
if(task2MsgQID==NULL)
{
return(ERROR);
}
if((t2_Wdog=wdCreate())==NULL)
{
logMsg("FFFFFFFFFFt2_Wdog\n");
return;
}
logMsg("t2_Wdog ID=%x\n",(int)t2_Wdog);
semTake (syncSemID, WAIT_FOREVER);
msgBuf_t2=(mg*)mem_In(sizeof(mg));
       FOREVER
         {
if(msgQReceive(task2MsgQID,&msgBuf_t2,4,WAIT_FOREVER)==ERROR)
               {
          return(ERROR);
               }
switch(msgBuf_t2->tp)
{/*因为task1的消息的消息头是1*/
case 1:
	/*收到task1的消息后就开启t2_Wdog,用来保证在"安全"

⌨️ 快捷键说明

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