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->OSEventPtr,pevent->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); //执行发送消息邮箱后,才退出
}
2、OSMboxPostOpt (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->OSEventPtr,pevent->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);
}
}