uCOSii消息邮箱管理

uCOSii消息邮箱管理 (MESSAGE MAILBOX MANAGEMENT)

消息邮箱主要用于中断和任务之间进行邮件传递,或者是在任务与任务之间进行邮件交换。

我个人觉得,了解uCOSii消息邮箱的几个重要函数,还是有必要的。不是所有人都给我们测试案例。

1、重点需要了解下面几个函数

消息邮箱指针=OSMboxCreate(消息邮箱数据块指针) 建立并初始化一个消息邮箱,在初始化时,通常将“消息邮箱数据块指针”设置为0,,如:MailBoxes_Event = OSMboxCreate( (void*)0 );

OSMboxAccept(消息邮箱指针)返回指针不为0,则表示接收到消息邮箱的新数据,同时会清除消息邮箱的数据块指针,允许再次发送邮箱新数据。

OSMboxPend(消息邮箱指针,0,&err);*per=OS_ERR_NONE,且返回指针不为0,则表示接收到消息邮箱的新数据,同时会清除消息邮箱的数据块指针,允许再次发送邮箱新数据。

OSMboxPost(消息邮箱指针pevent, 消息邮箱数据块指针); 返回值OS_ERR_NONE,且pevent->OSEventPtr = pmsg才表示消息邮箱发送成功

OSMboxPostOpt(消息邮箱指针pevent, 消息邮箱数据块指针, opt) 返回值OS_ERR_NONE,且pevent->OSEventPtr = pmsg才表示消息邮箱发送成功

OSMboxDel() 删除消息邮箱(消息邮箱指针、删除条件、出错代码指针)

OSMboxQuery() 查询一个邮箱的当前状态(信号量指针、状态数据结构指针)

2、OSMboxPost (OS_EVENT  *pevent,  void *pmsg) 点对点发送邮件

假定:

ReceiveMailbox1_Task任务优先级为5,该任务采用OSMboxPend()接收邮件

ReceiveMailbox2_Task任务优先级为6,该任务也采用OSMboxPend()接收邮件

Send_an_email_by_point_to_point_Task任务优先级为7

两个任务都在等待新邮件,则在采用点对点发送邮件时,只有优先级级别高的任务可以收到邮件。

//函数功能:返回值OS_ERR_NONE,且pevent->OSEventPtr = pmsg才表示消息邮箱发送成功

由于接收邮件时会清除pevent->OSEventPtrpevent->OSEventPtr = pmsg这个条件通常不作判断

//在使用OSMboxAccept()接收邮件时,可以判断MailBoxEventPointer->OSEventPtr和pMailBoxMessage相等

//注意:若上次发的邮件没有被接收,会取消本次发送,返回OS_ERR_MBOX_FULL​​​​​​​

// pevent为消息邮箱的指针

//pmsg是指向消息邮箱的数据块地址

INT8U  OSMboxPost (OS_EVENT  *pevent,

                   void      *pmsg)

{

#if OS_CRITICAL_METHOD == 3u

    OS_CPU_SR  cpu_sr = 0u;

#endif

#if OS_ARG_CHK_EN > 0u

if (pevent == (OS_EVENT *)0)

{//消息邮箱的指针为0

      return (OS_ERR_PEVENT_NULL);

}

if (pmsg == (void *)0)

{//消息邮箱的数据块地址0

return (OS_ERR_POST_NULL_PTR);

    }

#endif

if (pevent->OSEventType != OS_EVENT_TYPE_MBOX)

 {//该事件类型不是消息邮箱

        return (OS_ERR_EVENT_TYPE);

}

OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

///发现消息邮箱挂起的任务” ///

if (pevent->OSEventGrp != 0u)

{//查询是否有消息邮箱挂起的任务,若有,则立即发送邮件

        (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);

        //pevent所指的消息邮箱发送邮件,发送内容为pmsg指针

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        OS_Sched();//发现有更高优先级的任务在企图运行,执行任务调度

        return (OS_ERR_NONE);

}

///没有发现消息邮箱挂起的任务” ///

if (pevent->OSEventPtr != (void *)0)//查询邮箱中的内容是否被接收

{//上次发送的消息邮箱中的内容没有被读取,取消发送邮件

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        return (OS_ERR_MBOX_FULL);//没有执行发送消息邮箱,就退出了

}

/上次发送的消息邮箱中的内容已经被读取/

pevent->OSEventPtr = pmsg;

//pevent所指的消息邮箱发送邮件,发送内容为pmsg指针

//pmsg是指向消息邮箱的数据块地址

    OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

return (OS_ERR_NONE); //执行发送消息邮箱后,才退出

}

2OSMboxPostOpt (OS_EVENT  *pevent, void *pmsg,INT8U opt)群发邮件

在全部使用OSMboxPend()接收邮件时,群发邮件比较有意义。一般不用OSMboxPend()接收邮件,因为任务挂起,影响任务的工作效率

假定:

ReceiveMailbox1_Task任务优先级为5,该任务采用OSMboxPend()接收邮件

ReceiveMailbox2_Task任务优先级为6,该任务也采用OSMboxPend()接收邮件

MassEmail_Task任务优先级为7

两个任务都在等待新邮件,则在采用群发邮件时,这两个任务都可以收到邮件。

opt = OS_POST_OPT_BROADCAST=0x01,群发邮件

opt! = OS_POST_OPT_BROADCAST=0x01,点对点发送邮件

//函数功能:返回值OS_ERR_NONE,且pevent->OSEventPtr = pmsg才表示消息邮箱发送成功

由于接收邮件时会清除pevent->OSEventPtrpevent->OSEventPtr = pmsg这个条件通常不作判断

//注意:若上次发的邮件没有被接收,会取消本次发送,返回OS_ERR_MBOX_FULL

// pevent为消息邮箱的指针

//pmsg是指向消息邮箱的数据块地址

//opt = OS_POST_OPT_BROADCAST=0x01 群发邮件

// opt! = OS_POST_OPT_BROADCAST=0x01, 点对点发送邮件

//opt &OS_POST_OPT_NO_SCHED==0,需要执行任务调度

INT8U  OSMboxPostOpt (OS_EVENT  *pevent,

                      void      *pmsg,

                      INT8U      opt)

{

#if OS_CRITICAL_METHOD == 3u

    OS_CPU_SR  cpu_sr = 0u;

#endif

#if OS_ARG_CHK_EN > 0u

if (pevent == (OS_EVENT *)0)

{//消息邮箱的指针为0

        return (OS_ERR_PEVENT_NULL);

    }

if (pmsg == (void *)0)

{//消息邮箱的数据块地址为0

        return (OS_ERR_POST_NULL_PTR);

    }

#endif

if (pevent->OSEventType != OS_EVENT_TYPE_MBOX)

{//该事件类型不是消息邮箱

        return (OS_ERR_EVENT_TYPE);

}

OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

///发现消息邮箱挂起的任务” ///

if (pevent->OSEventGrp != 0u)

{//查询是否有消息邮箱挂起的任务

        if ((opt & OS_POST_OPT_BROADCAST) != 0x00u)//群发邮件

{

            while (pevent->OSEventGrp != 0u)

{//循环查询是否有消息邮箱挂起的任务

                (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);

                //pevent所指的消息邮箱发送邮件,发送内容为pmsg指针

            }

        }

        else//点对点发送邮件

        {

            (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);

            //pevent所指的消息邮箱发送邮件,发送内容为pmsg指针

        }

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        if ((opt & OS_POST_OPT_NO_SCHED) == 0u)

        {

            OS_Sched();//发现有更高优先级的任务在企图运行,执行任务调度

        }

        return (OS_ERR_NONE);//邮件发完,返回

  }

///没有发现消息邮箱挂起的任务” ///

if (pevent->OSEventPtr != (void *)0) //查询邮箱中的内容是否被接收

{//上次发送的邮件没有被接收,告诉邮箱满了

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        return (OS_ERR_MBOX_FULL); //没有执行发送消息邮箱,就退出了

}

/上次发送的消息邮箱中的内容已经被读取/

pevent->OSEventPtr = pmsg;

//pevent所指的消息邮箱发送邮件,发送内容为pmsg指针

//pmsg是指向消息邮箱的数据块地址

OS_EXIT_CRITICAL();

    return (OS_ERR_NONE); //执行发送消息邮箱后,才退出

}

3、OSMboxAccept (OS_EVENT *pevent)无等待接收邮件

函数功能:返回指针不为0,则表示接收到消息邮箱的新数据,同时会清除消息邮箱的数据块指针,允许再次发送邮箱新数据。

// pevent为消息邮箱的指针

//返回指针就是消息邮箱的数据块首地址

void  *OSMboxAccept (OS_EVENT *pevent)

{

    void      *pmsg;

#if OS_CRITICAL_METHOD == 3u

    OS_CPU_SR  cpu_sr = 0u;

#endif

#if OS_ARG_CHK_EN > 0u

if (pevent == (OS_EVENT *)0)

{//pevent指针为0

        return ((void *)0);

    }

#endif

if (pevent->OSEventType != OS_EVENT_TYPE_MBOX)

{//事件类型不是消息邮箱

    return ((void *)0);

}

    OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

    pmsg = pevent->OSEventPtr; //接收邮件,读取消息邮箱的数据块首地址

pevent->OSEventPtr = (void *)0;

//新邮箱数据接收到后,则立即清除消息邮箱的数据块指针,便于下次发送邮箱新数据

    OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

    return (pmsg); //返回邮箱数据块首地址 

}

4、*OSMboxPend (OS_EVENT *pevent, INT32U timeout, INT8U *perr)

timeout=0任务会一直挂起,直到收到新邮件

timeout!=0任务在timeout个节拍内,若收到新邮件,则退出,否则,超时退出邮件接收

函数功能:*per= OS_ERR_NONE,且返回指针不为0,则表示接收到消息邮箱的新数据,同时会清除消息邮箱的数据块指针,允许再次发送邮箱新数据。

// pevent为消息邮箱的指针

// timeout为等待时间;timeout=0任务会一直挂起,直到收到新邮件

//返回指针就是消息邮箱的数据块首地址

void  *OSMboxPend (OS_EVENT  *pevent,

                   INT32U     timeout,

                   INT8U     *perr)

{

void      *pmsg;

#if OS_CRITICAL_METHOD == 3u

    OS_CPU_SR  cpu_sr = 0u;

#endif

#ifdef OS_SAFETY_CRITICAL

if (perr == (INT8U *)0)

{// perr指针为0

        OS_SAFETY_CRITICAL_EXCEPTION();//这句看不懂,不要关心

    }

#endif

#if OS_ARG_CHK_EN > 0u

if (pevent == (OS_EVENT *)0)

 {// pevent指针为0

        *perr = OS_ERR_PEVENT_NULL;

        return ((void *)0);

    }

#endif

if (pevent->OSEventType != OS_EVENT_TYPE_MBOX)

{//事件类型不是消息邮箱

        *perr = OS_ERR_EVENT_TYPE;

        return ((void *)0);

}

if (OSIntNesting > 0u)

{//中断嵌套级别大于0

        *perr = OS_ERR_PEND_ISR;

        return ((void *)0);

}

if (OSLockNesting > 0u)

{//多任务锁定嵌套级别大于0

        *perr = OS_ERR_PEND_LOCKED;

        return ((void *)0);

}

    OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

pmsg = pevent->OSEventPtr; //接收邮件,读取消息邮箱的数据块首地址

if (pmsg != (void *)0)

{//”消息邮箱的数据块首地址不为0,表示消息邮箱的新数据被收到

        pevent->OSEventPtr = (void *)0;

//新邮箱数据接收到后,则立即清除消息邮箱的数据块指针,便于下次发送邮箱新数据

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        *perr = OS_ERR_NONE;

        return (pmsg); //返回邮箱数据块首地址

}

///没有收到消息邮箱的新数据”/

OSTCBCur->OSTCBStat     |= OS_STAT_MBOX;

    OSTCBCur->OSTCBStatPend=OS_STAT_PEND_OK; // 消息不可用,设置任务将进入等待

OSTCBCur->OSTCBDly       = timeout;//设置任务延迟的节拍数

    OS_EventTaskWait(pevent);// 暂停当前任务,直到发生事件或超时为止

    OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

    OS_Sched();//发现有更高优先级的任务在企图运行,执行任务调度

   

//其他任务执行完后,回到当前任务//

OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

switch (OSTCBCur->OSTCBStatPend)

{

    case OS_STAT_PEND_OK: //任务已经等到消息邮箱的新数据

             pmsg = OSTCBCur->OSTCBMsg;//读取邮箱数据块首地址

            *perr =  OS_ERR_NONE;

             break;

        case OS_STAT_PEND_ABORT://任务没有等到消息邮箱的新数据

             pmsg = (void *)0;

            *perr =  OS_ERR_PEND_ABORT;

             break;

        case OS_STAT_PEND_TO: //任务因没有等到消息邮箱的新数据导致超时

        default:

             OS_EventTaskRemove(OSTCBCur, pevent);

             pmsg = (void *)0;

            *perr =  OS_ERR_TIMEOUT;

             break;

}

OSTCBCur->OSTCBStat  =  OS_STAT_RDY;//设置当前任务状态为准备状态

OSTCBCur->OSTCBStatPend=OS_STAT_PEND_OK; // 消息不可用,设置任务将进入等待

OSTCBCur->OSTCBEventPtr= (OS_EVENT *)0;//清除消息邮箱的指针

#if (OS_EVENT_MULTI_EN > 0u)

    OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0;

#endif

OSTCBCur->OSTCBMsg= (void *)0;

//新邮箱数据接收到后,则立即清除消息邮箱的数据块指针,便于下次发送邮箱新数据

    OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

return (pmsg); //返回邮箱数据块首地址                                   

}

//延时ticks节拍数

void  OSTimeDly (INT32U ticks)

{

    INT8U      y;

#if OS_CRITICAL_METHOD == 3u

    OS_CPU_SR  cpu_sr = 0u;

#endif

if (OSIntNesting > 0u)

 {

        return;

}

if (OSLockNesting > 0u)

{

        return;

}

if (ticks > 0u)

{

OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

        y  =  OSTCBCur->OSTCBY;

        OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX;

        if (OSRdyTbl[y] == 0u)

{

            OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;

        }

        OSTCBCur->OSTCBDly = ticks;//装载时钟节拍数

        OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        OS_Sched();//发现有更高优先级的任务在企图运行,执行任务调度

    }

}

5、测试代码

#include "ReceiveMailbox1_Task.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "My_Task_Priority.h"

void ReceiveMailbox1_Task(void *pdata);

const char ReceiveMailbox1_Task_rn_REG[]="\r\n";
const char ReceiveMailbox1_Task_REG[]="ReceiveMailbox1_Task:";
//ReceiveMailbox1_Task任务
void ReceiveMailbox1_Task(void *pdata)
{
	void  *pMailBox;
	u8 err;
	u32 timeout;

	while(1)
	{
		timeout=0;
		pMailBox=OSMboxPend(MailBoxEventPointer,timeout,&err);
		//err=OS_ERR_NONE且pMailBox!=0,则表示接收到新邮件,并清除"消息邮箱的数据块"指针,允许再次发送新邮件;
		//MailBoxEventPointer为消息邮箱的指针
    //timeout为等待的系统时间节拍数,当timeout=0任务会一直被挂起,直到收到新邮件
		//err=OS_ERR_NONE表示成功接收邮件的一个条件,其次是返回值pMailBox!=0,即消息邮箱的数据块首地址不能为NULL
		if(pMailBox!=NULL && err==OS_ERR_NONE )
		{
	    printf("%s",ReceiveMailbox1_Task_rn_REG);
	    printf("%s",ReceiveMailbox1_Task_REG);
			printf("%s",(char*)pMailBox);//打印消息邮箱数据
		}
		OSTimeDlyHMSM(0,0,0,100);//100ms闪烁一次
	}
}

#include "ReceiveMailbox2_Task.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "My_Task_Priority.h"

void ReceiveMailbox2_Task(void *pdata);

const char ReceiveMailbox2_Task_rn_REG[]="\r\n";
const char ReceiveMailbox2_Task_REG[]="ReceiveMailbox2_Task:";
//ReceiveMailbox2_Task任务
void ReceiveMailbox2_Task(void *pdata)
{
	void  *pMailBox=0;
	u8 err;
	u32 timeout;

	while(1)
	{
		timeout=0;
		pMailBox=OSMboxPend(MailBoxEventPointer,timeout,&err);
		//err=OS_ERR_NONE且pMailBox!=0,则表示接收到新邮件,并清除"消息邮箱的数据块"指针,允许再次发送新邮件;
		//MailBoxEventPointer为消息邮箱的指针
    //timeout为等待的系统时间节拍数,当timeout=0任务会一直被挂起,直到收到新邮件
		//err=OS_ERR_NONE表示成功接收邮件的一个条件,其次是返回值pMailBox!=0,即消息邮箱的数据块首地址不能为NULL
		if(pMailBox!=NULL && err==OS_ERR_NONE )
		{
	    printf("%s",ReceiveMailbox2_Task_rn_REG);
	    printf("%s",ReceiveMailbox2_Task_REG);
			printf("%s",(char*)pMailBox);//打印消息邮箱数据
		}
		OSTimeDlyHMSM(0,0,0,100);//100ms闪烁一次
	}
}
#include "Send_an_email_by_point_to_point_Task.h"
#include "delay.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "My_Task_Priority.h"

u8 Send_an_email_by_point_to_pointCnt;
char MailBoxBuffer[2][50];

const char Send_an_email_by_point_to_point_Task_rn_REG[]="\r\n";
const char Send_an_email_by_point_to_point_Task_REG[]="Send_an_email_by_point_to_point_Task:";
const char Send_an_email_by_point_to_pointCnt_REG[]="Send_an_email_by_point_to_pointCnt=";
void Send_an_email_by_point_to_point_Task(void *pdata);
	
//Send_an_email_by_point_to_point_Task任务
void Send_an_email_by_point_to_point_Task(void *pdata)
{
	void  *pMailBoxMessage;//邮箱消息指针
	u8 cnt;
	u8 err;

	cnt=0;
	while(1)
	{
		//delay_ms(1000);
		OSTimeDlyHMSM(0,0,0,1000);//延时100ms
		Send_an_email_by_point_to_pointCnt++;

		if(Send_an_email_by_point_to_pointCnt>10)//每10秒,点对点发送一次邮件
		{
			Send_an_email_by_point_to_pointCnt=0;
			if(cnt%2) pMailBoxMessage=MailBoxBuffer[1];
			else pMailBoxMessage=MailBoxBuffer[0];
			sprintf(pMailBoxMessage,"%u",cnt);//装载新邮件
			err=OSMboxPost(MailBoxEventPointer,pMailBoxMessage);
		  //err=OS_ERR_NONE且MailBoxEventPointer->OSEventPtr=pMailBoxMessage,则表示表示点对点发送邮件成功
			//由于接收邮件时会清除MailBoxEventPointer->OSEventPtr=pMailBoxMessage,这个条件通常不作判断
		  //MailBoxEventPointer为消息邮箱的指针
			//pMailBoxMessage为消息邮箱的数据首地址
			if(err==OS_ERR_NONE)
			{
				cnt++;
	      printf("%s",Send_an_email_by_point_to_point_Task_rn_REG);
	      printf("%s",Send_an_email_by_point_to_point_Task_REG);
				printf("%s",(char*)pMailBoxMessage);
			}
		}
		printf("%s",Send_an_email_by_point_to_point_Task_rn_REG);
		printf("%s",Send_an_email_by_point_to_pointCnt_REG);
		printf("%u",Send_an_email_by_point_to_pointCnt);
	}
}
#include "MassEmail_Task.h"
#include "delay.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "My_Task_Priority.h"

u8 MassEmailCnt;
char MailBoxBuffer[50];

const char MassEmail_Task_rn_REG[]="\r\n";
const char MassEmail_Task_REG[]="MassEmail_Task:";
const char MassEmailCnt_REG[]="MassEmailCnt=";
void MassEmail_Task(void *pdata);
	
//MassEmail_Task任务
void MassEmail_Task(void *pdata)
{
	void  *pMailBoxMessage;//邮箱消息指针
	u8 cnt;
	u8 err;

	cnt=0;
	while(1)
	{
		//delay_ms(1000);
		OSTimeDlyHMSM(0,0,0,1000);//延时100ms
		MassEmailCnt++;
		if(MassEmailCnt>10)//每10秒,群发一次邮件
		{
			MassEmailCnt=0;
			pMailBoxMessage=MailBoxBuffer;
			sprintf(pMailBoxMessage,"%u",cnt);//装载新邮件
			err=OSMboxPostOpt(MailBoxEventPointer,pMailBoxMessage,OS_POST_OPT_BROADCAST);
		  //err=OS_ERR_NONE且MailBoxEventPointer->OSEventPtr=pMailBoxMessage,则表示表示群发邮件发送成功
			//由于接收邮件时会清除MailBoxEventPointer->OSEventPtr=pMailBoxMessage,这个条件通常不作判断
		  //MailBoxEventPointer为消息邮箱的指针
			//pMailBoxMessage为消息邮箱的数据首地址
			//OS_POST_OPT_BROADCAST要求群发邮件
			if(err==OS_ERR_NONE)
			{
				cnt++;
	      printf("%s",MassEmail_Task_rn_REG);
	      printf("%s",MassEmail_Task_REG);
				printf("%s",(char*)pMailBoxMessage);
			}
		}
		printf("%s",MassEmail_Task_rn_REG);
		printf("%s",MassEmailCnt_REG);
		printf("%u",MassEmailCnt);
	}
}
#include "Start_Task.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "My_Task_Priority.h"
#include "ReceiveMailbox1_Task.h"
#include "ReceiveMailbox2_Task.h"
#include "Send_an_email_by_point_to_point_Task.h"

void Start_Task(void *pdata);

const char Start_Task_rn_REG[]="\r\n";
const char Start_Task_Initialise_REG[]="Start_Task Initialise";
//Start_Task任务
void Start_Task(void *pdata)
{
	OS_CPU_SR cpu_sr=0;
	pdata = pdata;

	printf("%s",Start_Task_rn_REG);
	printf("%s",Start_Task_Initialise_REG);


	OS_ENTER_CRITICAL();   //进入临界区(无法被中断打断),需要定义cpu_sr变量
	MailBoxEventPointer = OSMboxCreate( (void*)0 );
	//建立并初始化一个消息邮箱(msg参数不为空含内容)
	//将“消息邮箱数据块指针”设置为0

	OSTaskCreate( ReceiveMailbox1_Task,/* 函数指针*/
	              (void *)0,/* 建立任务时,传递的参数*/
								(OS_STK*)&ReceiveMailbox1_TASK_STACK[ReceiveMailbox1_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
								ReceiveMailbox1_TASK_PRIORITY/* 任务优先级*/
							);						   
	OSTaskCreate( ReceiveMailbox2_Task,/* 函数指针*/
	              (void *)0,/* 建立任务时,传递的参数*/
								(OS_STK*)&ReceiveMailbox2_TASK_STACK[ReceiveMailbox2_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
								ReceiveMailbox2_TASK_PRIORITY/* 任务优先级*/
							);
	OSTaskCreate( Send_an_email_by_point_to_point_Task,/* 函数指针*/
								(void *)0,/* 建立任务时,传递的参数*/
								(OS_STK*)&Send_an_email_by_point_to_point_TASK_STACK[Send_an_email_by_point_to_point_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
								Send_an_email_by_point_to_point_TASK_PRIORITY/* 任务优先级*/
							);
	
	//OSTaskSuspend(START_TASK_PRIO);	//挂起起始任务Start_Task(),但不删除
	OSTaskDel(OS_PRIO_SELF); //删除自己
	OS_EXIT_CRITICAL();		//退出临界区(可以被中断打断)
}
#include "Start_Task.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "My_Task_Priority.h"
#include "ReceiveMailbox1_Task.h"
#include "ReceiveMailbox2_Task.h"
#include "MassEmail_Task.h"

void Start_Task(void *pdata);

const char Start_Task_rn_REG[]="\r\n";
const char Start_Task_Initialise_REG[]="Start_Task Initialise";
//Start_Task任务
void Start_Task(void *pdata)
{
	OS_CPU_SR cpu_sr=0;
	pdata = pdata;

	printf("%s",Start_Task_rn_REG);
	printf("%s",Start_Task_Initialise_REG);


	OS_ENTER_CRITICAL();   //进入临界区(无法被中断打断),需要定义cpu_sr变量
	MailBoxEventPointer = OSMboxCreate( (void*)0 );
	//建立并初始化一个消息邮箱(msg参数不为空含内容)
	//将“消息邮箱数据块指针”设置为0

	OSTaskCreate( ReceiveMailbox1_Task,/* 函数指针*/
	              (void *)0,/* 建立任务时,传递的参数*/
								(OS_STK*)&ReceiveMailbox1_TASK_STACK[ReceiveMailbox1_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
								ReceiveMailbox1_TASK_PRIORITY/* 任务优先级*/
							);						   
	OSTaskCreate( ReceiveMailbox2_Task,/* 函数指针*/
	              (void *)0,/* 建立任务时,传递的参数*/
								(OS_STK*)&ReceiveMailbox2_TASK_STACK[ReceiveMailbox2_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
								ReceiveMailbox2_TASK_PRIORITY/* 任务优先级*/
							);
	OSTaskCreate( MassEmail_Task,/* 函数指针*/
								(void *)0,/* 建立任务时,传递的参数*/
								(OS_STK*)&MassEmail_TASK_STACK[MassEmail_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
								MassEmail_TASK_PRIORITY/* 任务优先级*/
							);
	
	//OSTaskSuspend(START_TASK_PRIO);	//挂起起始任务Start_Task(),但不删除
	OSTaskDel(OS_PRIO_SELF); //删除自己
	OS_EXIT_CRITICAL();		//退出临界区(可以被中断打断)
}
#include "My_Task_Priority.h"

OS_STK START_TASK_STACK[START_TASK_STACK_SIZE]; //START_TASK任务堆栈
OS_STK ReceiveMailbox1_TASK_STACK[ReceiveMailbox1_TASK_STACK_SIZE];   //ReceiveMailbox1_TASK任务堆栈
OS_STK ReceiveMailbox2_TASK_STACK[ReceiveMailbox2_TASK_STACK_SIZE];   //ReceiveMailbox2_TASK任务堆栈
__align(8) OS_STK MassEmail_TASK_STACK[MassEmail_TASK_STACK_SIZE];
//MassEmail_TASK任务堆栈
//如果任务中使用printf来打印浮点数据的话一点要8字节对齐

OS_EVENT *MailBoxEventPointer;
u8 MailBoxEvent_Err;
//My_Task_Priority.h
#ifndef __MY_TASK_PRIORITY_H
#define __MY_TASK_PRIORITY_H

#include "includes.h"

//任务的优先级资源由操作系统提供,以μC/OS-II为例,共有64个优先级,优先级的高低按编号从0(最高)到63(最低)排序;

/*
为了保证“启动任务”能够连续运行,必须将“启动任务”的优先级选择为最高。
否则,当“启动任务”创建一个优先级高于自己的任务时,刚刚创建的任务就
会立即进入运行状态,而与这个任务关联的其它任务可能还没有创建,它使
用的通信工具也还没有创建,系统必然出错。
*/

#define START_TASK_PRIORITY      4   //设置START_TASK任务优先级,开始任务的优先级设置为最高
#define START_TASK_STACK_SIZE   192  //设置START_TASK任务堆栈大小,为8的倍数
extern OS_STK START_TASK_STACK[START_TASK_STACK_SIZE]; //START_TASK任务堆栈

#define ReceiveMailbox1_TASK_PRIORITY       5   //设置ReceiveMailbox1_TASK任务优先级为5
#define ReceiveMailbox1_TASK_STACK_SIZE  	 56  //设置ReceiveMailbox1_TASK任务堆栈大小为56,为8的倍数
extern OS_STK ReceiveMailbox1_TASK_STACK[ReceiveMailbox1_TASK_STACK_SIZE];  //ReceiveMailbox1_TASK任务堆栈

#define ReceiveMailbox2_TASK_PRIORITY       6   //设置ReceiveMailbox2_TASK任务优先级为6
#define ReceiveMailbox2_TASK_STACK_SIZE  	 72  //设置ReceiveMailbox2_TASK任务堆栈大小为72,为8的倍数
extern OS_STK ReceiveMailbox2_TASK_STACK[ReceiveMailbox2_TASK_STACK_SIZE];  //ReceiveMailbox2_TASK任务堆栈

#define MassEmail_TASK_PRIORITY        7   //设置MassEmail_TASK任务优先级为7 
#define MassEmail_TASK_STACK_SIZE      56  //设置MassEmail_TASK任务堆栈大小为56,为8的倍数
extern OS_STK MassEmail_TASK_STACK[MassEmail_TASK_STACK_SIZE];    //MassEmail_TASK任务堆栈

extern OS_EVENT *MailBoxEventPointer;
extern u8 MailBoxEvent_Err;

#endif

6、点对点发送邮件: 

7、群发邮件: 

 8、使用OSMboxAccept()查询接收邮件

#include "ReceiveMailbox_Task.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "My_Task_Priority.h"

void ReceiveMailbox_Task(void *pdata);

const char ReceiveMailbox_Task_rn_REG[]="\r\n";
const char ReceiveMailbox_Task_REG[]="ReceiveMailbox_Task:";
//ReceiveMailbox_Task任务
void ReceiveMailbox_Task(void *pdata)
{
	void  *pMailBox;

	while(1)
	{
		pMailBox=OSMboxAccept(MailBoxEventPointer);
		//pMailBox!=0,则表示接收到新邮件,并清除"消息邮箱的数据块"指针,允许再次发送新邮件;
		//MailBoxEventPointer为消息邮箱的指针
		if(pMailBox!=NULL)
		{
	    printf("%s",ReceiveMailbox_Task_rn_REG);
	    printf("%s",ReceiveMailbox_Task_REG);
			printf("%s",(char*)pMailBox);//打印消息邮箱数据
		}
		OSTimeDlyHMSM(0,0,0,100);//延迟100ms
	}
}
#include "Send_email_Task.h"
#include "delay.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "My_Task_Priority.h"

u8 Send_emailCnt;
char MailBoxBuffer[2][50];

const char Send_email_Task_rn_REG[]="\r\n";
const char Send_email_Task_REG[]="Send_email_Task:";
const char Send_emailCnt_REG[]="Send_emailCnt=";
void Send_email_Task(void *pdata);
	
//Send_email_Task任务
void Send_email_Task(void *pdata)
{
	void  *pMailBoxMessage;//邮箱消息指针
	u8 cnt;
	u8 err;

	cnt=0;
	while(1)
	{
		//delay_ms(1000);
		OSTimeDlyHMSM(0,0,0,1000);//延时100ms
		Send_emailCnt++;

		if(Send_emailCnt>10)//每10秒,点对点发送一次邮件
		{
			Send_emailCnt=0;
			if(cnt%2) pMailBoxMessage=MailBoxBuffer[1];
			else pMailBoxMessage=MailBoxBuffer[0];
			sprintf(pMailBoxMessage,"%u",cnt);//装载新邮件
			err=OSMboxPost(MailBoxEventPointer,pMailBoxMessage);
		  //err=OS_ERR_NONE且MailBoxEventPointer->OSEventPtr=pMailBoxMessage,则表示表示点对点发送邮件成功
			//由于接收邮件时会清除MailBoxEventPointer->OSEventPtr=pMailBoxMessage,这个条件通常不作判断
			//在使用OSMboxAccept()接收邮件时,可以判断MailBoxEventPointer->OSEventPtr和pMailBoxMessage相等
		  //MailBoxEventPointer为消息邮箱的指针
			//pMailBoxMessage为消息邮箱的数据首地址
			if(err==OS_ERR_NONE && MailBoxEventPointer->OSEventPtr==pMailBoxMessage)
			{
				cnt++;
	      printf("%s",Send_email_Task_rn_REG);
	      printf("%s",Send_email_Task_REG);
				printf("%s",(char*)pMailBoxMessage);
			}
		}
		printf("%s",Send_email_Task_rn_REG);
		printf("%s",Send_emailCnt_REG);
		printf("%u",Send_emailCnt);
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/25239.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

R语言混合效应(多水平/层次/嵌套)模型及贝叶斯实现技术

回归分析是科学研究中十分重要的数据分析工具。随着现代统计技术发展,回归分析方法得到了极大改进。混合效应模型(Mixed effect model),即多水平模型(Multilevel model)/分层模型(Hierarchical Model)/嵌套…

如何快速运用R语言实现生物群落(生态)数据统计分析与绘图

R 语言作的开源、自由、免费等特点使其广泛应用于生物群落数据统计分析。生物群落数据多样而复杂,涉及众多统计分析方法。本次以生物群落数据分析中的最常用的统计方法回归和混合效应模型、多元统计分析技术及结构方程等数量分析方法为主线,通过多个来自…

Linux:查看进程。

Linux:查看进程。 windows linux TTY如果是?说明是不是终端(控制台)启动的,而是系统内部自己启动的。 TIME是启动Linux后,这个进程一共占用了cpu多少时间00…

QT 设计ROS GUI界面订阅和发布话题

QT 设计ROS GUI界面订阅和发布话题 主要参考下面的博客 ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!) Qt ROS 相关配置请看上一篇博客 首先建立工作空间和功能包&a…

【探索】机器指令翻译成 JavaScript

前言 前些时候研究脚本混淆时,打算先学一些「程序流程」相关的概念。为了不因太枯燥而放弃,决定想一个有趣的案例,可以边探索边学。 于是想了一个话题:尝试将机器指令 1:1 翻译 成 JavaScript,这样就能在浏览器中&am…

Java程序设计入门教程-- if 条件语句

目录 单分支选择语句(if) 双分支选择语句(if…else) 嵌套if语句 单分支选择语句(if) 情形 当判断条件满足时,执行语句体S,而不满足则什么都不做。 格式 if (条件判断表…

【计算机视觉 | 目标检测】术语理解6:ViT 变种( ViT-H、ViT-L ViT-B)、bbox(边界框)、边界框的绘制(含源代码)

文章目录 一、ViT & ViT变种1.1 ViT的介绍1.2 ViT 的变种 二、bbox(边界框)三、边界框的绘制 一、ViT & ViT变种 1.1 ViT的介绍 ViT,全称为Vision Transformer,是一种基于Transformer架构的视觉处理模型。传统的计算机视…

java企业工程项目管理系统平台源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)

工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…

回调函数与钩子函数的区别,另QT中connect函数的实现,lambda的使用

1、钩子函数是回调函数的一种 广泛来说两者都是一样的 严格来说 钩子函数的函数名早已被定义好,只是函数内部需要用户在应用层来定义, 1)可以完全通过宏来实现系统是否调用该函数(底层不封闭,修改宏的参数实现是否编…

【2023 · CANN训练营第一季】MindSpore模型快速调优攻略 第二章——MindSpore调试调优

1.生态迁移 生态迁移工具使用示例 生态迁移工具技术方案 不同框架间模型定义前端表达差别巨大(相同算子的API技术难点 、 算子功能、模型构建方式差别较大); 对于同一框架,不管前端表达差异如何,最终对应的计算 图是相似的。因此提出&#x…

Kubernetes部署+kubesphere管理平台安装

Kubernetes官网;kubesphere官网 不论是Kubernetes官网还是找的其它部署步骤,基本都是推荐搭建集群的方式,是为了实现高可用.....等等,这样一来至少需要两台或三台的服务器来搭建,这样对我们的成本也是非常大的&#xf…

Axure教程——直方图(中继器)

本文将教大家如何用AXURE用中继器制作直方图 一、效果介绍 如图: 预览地址:https://yjkepz.axshare.com 下载地址:https://download.csdn.net/download/weixin_43516258/87842701 二、制作方法 (1)制作刻度表 设计5个刻…

CSDN上海城市开发者社区线下活动纪实

引言 5月27号中午,很高兴能和现CSDN副总裁、前微软 Azure 工程团队首席研发经理、技术畅销书《编程之美》及《构建之法》的作者邹欣邹老师,以及CSDN的 “上海城市开发者社区” 的部分成员齐聚一堂,参加CSDN上海城市开发者社区自5月初成立以来…

Ctfshow基础二刷(1)

前言: 前两天的信安给我整emo了,头一回打正经比赛,结果发现基础太差,代码审计烂得一踏糊涂。 寻思寻思,从头整一遍基础。又买了安恒出的新书。争取7号去吉林打省队选拔不给导儿丢脸吧呜呜 文件包含 web78: 这题一…

curl 命令-接口测试

curl 命令-接口测试 JUST DO IT 温暖春日 在linux/Unix 为代表的os上, 对后端进行测试, 模拟连接请求都会书写脚本 场景: 在Linux 上接口测试工具有ab, restClient, postman等, 最常用的方法是curl进行简单测试 curl是非常方便的Rest 客户端, 可以很方便的完成 Rest API测…

AcWing算法提高课-1.3.11二维费用的背包问题

宣传一下算法提高课整理 <— CSDN个人主页&#xff1a;更好的阅读体验 <— 本题链接&#xff08;AcWing&#xff09; 点这里 题目描述 有 N N N 件物品和一个容量是 V V V 的背包&#xff0c;背包能承受的最大重量是 M M M。 每件物品只能用一次。体积是 v i v_…

vcruntime140.dll丢失怎么办?怎么解决vcruntime140.dll丢失的问题

当您运行一个需要此文件的程序时&#xff0c;如果您的系统中不存在这个文件&#xff0c;会提示出错信息“找不到vcruntime140.dll”或“vcruntime140.dll丢失”。这种情况下&#xff0c;您需要解决这个问题&#xff0c;才能继续运行此应用程序。我们将介绍vcruntime140.dll丢失…

5.27下周黄金行情走势预测及开盘操作策略

近期有哪些消息面影响黄金走势&#xff1f;下周黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;周五(5月26日)黄金大幅下跌&#xff0c;主要受到美国数据影响&#xff0c;美国公布的4月PCE和耐用品订单数据向好&#xff0c;再次强化市场对美联储的鹰派押注。现货…

(四)ArcGIS空间数据的转换与处理——数据结构转换

ArcGIS空间数据的转换与处理——数据转换 空间数据的来源很多&#xff0c;如地图、工程图、规划图、航空与遥感影像等&#xff0c;因此空间数据也有多种格式。根据应用需要&#xff0c;需对数据进行格式转换&#xff0c;不同数据结构间的转换主要包括矢量数据到栅格数据的转换…

戏曲APP软件开发需具备哪些功能呢?

戏曲是我国的国粹&#xff0c;传统戏曲文化源远流长&#xff0c;博大精深&#xff0c;数千年以来一直都是深受大众喜欢的文化生活的重要环节。随着时代的推进&#xff0c;娱乐形式更加多样化&#xff0c;传统的剧场演出形式的戏曲传播方式已经跟不上时代发展以及人们的需求了。…