OSMBOX邮箱源码注释.docx
- 文档编号:11832834
- 上传时间:2023-04-05
- 格式:DOCX
- 页数:20
- 大小:24.35KB
OSMBOX邮箱源码注释.docx
《OSMBOX邮箱源码注释.docx》由会员分享,可在线阅读,更多相关《OSMBOX邮箱源码注释.docx(20页珍藏版)》请在冰豆网上搜索。
OSMBOX邮箱源码注释
1/*
2*********************************************************************************************************
3*uC/OS-II实时控制内核
4*消息邮箱管理
5*文件:
OS_MBOX.C消息邮件管理代码
6*作者:
JeanJ.Labrosse
7*中文注解:
钟常慰zhongcw@译注版本:
1.0请尊重原版内容
8*********************************************************************************************************
9*/
10
11#ifndefOS_MASTER_FILE//是否已经定义OS_MASTER_FILE
12#include"includes.h"//包含"includes.h"文件
13#endif//结束定义
14
15#ifOS_MBOX_EN>0//条件编译允许
(1)产生消息邮箱相关代码
16/*
17*********************************************************************************************************
18*查看指定的消息邮箱是否有需要的消息(ACCEPTMESSAGEFROMMAILBOX)
19*
20*描述:
OSMboxAccept()函数查看指定的消息邮箱是否有需要的消息。
不同于OSMboxPend()函数,如果没有需要的消息,
21*OSMboxAccept()函数并不挂起任务。
如果消息已经到达,该消息被传递到用户任务并且从消息邮箱中清除。
通
22*常中断调用该函数,因为中断不允许挂起等待消息。
23*
24*意见:
pevent是指向需要查看的消息邮箱的指针。
当建立消息邮箱时,该指针返回到用户程序。
25*(参考OSMboxCreate()函数)。
26*
27*返回:
如果消息已经到达,返回指向该消息的指针;如果消息邮箱没有消息,返回空指针。
28*
29*注意:
必须先建立消息邮箱,然后使用。
30*********************************************************************************************************
31*/
32
33#ifOS_MBOX_ACCEPT_EN>0//允许
(1)生成OSMboxAccept()代码
34void*OSMboxAccept(OS_EVENT*pevent)//查看消息邮箱(消息邮箱指针)
35{
36#ifOS_CRITICAL_METHOD==3//中断函数被设定为模式3
37OS_CPU_SRcpu_sr;
38#endif
39void*msg;//定义消息邮箱内容的指针
40
41
42#ifOS_ARG_CHK_EN>0//所有参数必须在指定的参数内
43if(pevent==(OS_EVENT*)0){//当消息邮箱指针为NULL时,返回0,空指针
44return((void*)0);
45}
46if(pevent->OSEventType!
=OS_EVENT_TYPE_MBOX){//当事件类型≠消息邮箱类型
47return((void*)0);//返回空指针
48}
49#endif
50OS_ENTER_CRITICAL();//关闭中断
51msg=pevent->OSEventPtr;//取消息邮箱中的内容
52pevent->OSEventPtr=(void*)0;//将消息邮箱的内容清0
53OS_EXIT_CRITICAL();//打开中断
54return(msg);//返回消息,如果为空,说明没有消息;不为空,说明有内容
55}
56#endif
57/*$PAGE*/
58/*
59*********************************************************************************************************
60*建立并初始化一个消息邮箱(CREATEAMESSAGEMAILBOX)
61*
62*描述:
建立并初始化一个消息邮箱。
消息邮箱允许任务或中断向其他一个或几个任务发送消息。
63*
64*参数:
msg参数用来初始化建立的消息邮箱。
如果该指针不为空,建立的消息邮箱将含有消息。
65*
66*返回:
指向分配给所建立的消息邮箱的事件控制块的指针。
如果没有可用的事件控制块,返回空指针。
67*
68*注意:
必须先建立消息邮箱,然后使用。
69*********************************************************************************************************
70*/
71
72OS_EVENT*OSMboxCreate(void*msg)//建立并初始化一个消息邮箱(msg参数不为空含内容)
73{
74#ifOS_CRITICAL_METHOD==3//中断函数被设定为模式3
75OS_CPU_SRcpu_sr;
76#endif__
77OS_EVENT*pevent;//定义一个指向事件控制块的指针
78
79
80if(OSIntNesting>0){//中断嵌套数>0时,表示还有中断任务在运行
81return((OS_EVENT*)0);//返回0
82}
83OS_ENTER_CRITICAL();//关闭中断
84pevent=OSEventFreeList;//pevent=空余事件管理列表
85if(OSEventFreeList!
=(OS_EVENT*)0){//如果有空余事件管理块
86OSEventFreeList=(OS_EVENT*)OSEventFreeList->OSEventPtr;
87}//空余事件控制链表指向下一个空余事件控制块
88OS_EXIT_CRITICAL();//打开中断
89if(pevent!
=(OS_EVENT*)0){//如果有空余的事件控制块可用
90pevent->OSEventType=OS_EVENT_TYPE_MBOX;//则这个类型=消息邮箱类形
91pevent->OSEventPtr=msg;//将初始值存入事件管理块ECB中
92OS_EventWaitListInit(pevent);//初始化一个事件控制块
93}
94return(pevent);//返回该详细邮箱(事件)的指针,即邮箱句柄
95}
96/*$PAGE*/
97/*
98*********************************************************************************************************
99*删除消息邮箱(DELETEAMAIBOX)
100*
101*描述:
删除消息邮箱。
因为多任务可能会试图继续使用已经删除了的邮箱,故调用本函数有风险。
使用本函数
102*须特别小心。
一般的说,删除邮箱之前,应该首先删除与本邮箱有关的任务。
103*
104*描述:
pevent指向邮箱得指针.该指针是在邮箱建立时,返回给用户应用程序的指针.(参考OSMboxCreate())
105*
106*opt该选项定义邮箱的删除条件:
107*opt==OS_DEL_NO_PEND可以选择只能在已经没有任何任务在等待该邮箱的消息时,才能删除邮箱;
108*opt==OS_DEL_ALWAYS不管有没有任务在等待邮箱的消息,立即删除邮箱。
109*-->第2种情况下,所有等待邮箱消息的任务都立即进入就绪态。
110*
111*err指向错误代码的指针,返回出错代码可以是以下几种之一:
112*OS_NO_ERR调用成功,邮箱已经删除;
113*OS_ERR_DEL_ISR试图在中断服务子程序中删除邮箱;
114*OS_ERR_INVALID_OPT无效的opt参数,用户没有将opt定义为上述2种情况之一;
115*OS_ERR_TASK_WAITING一个或更多的任务在等待邮箱的消息;
116*OS_ERR_EVENT_TYPEpevent不是指向邮箱的指针;
117*OS_ERR_PEVENT_NULL已经没有OS_EVENT数据结构可以使用。
118*
119*返回:
pevent返回空指针NULL,表示邮箱已被删除,返回pevent,表示邮箱没有删除,在这种情况下,应该进一步
120*查看出错代码,找到出错原因。
121*
122*注意:
1)使用这个函数调用时,须特别小心。
因为其他任务可能还要用这个邮箱。
123*2)当挂起的任务进入就绪态时,中断是关闭的,这就意味着中断延迟时间与在等待邮箱的消息的任务数有关。
124*3)调用OSMboxAccept()函数也不可能知道邮箱是否已经被删除了。
125*********************************************************************************************************
126*/
127
128#ifOS_MBOX_DEL_EN>0//允许
(1)生成OSMboxDel()代码
129//删除消息邮箱(消息邮箱指针、删除条件、出错代码指针)
130OS_EVENT*OSMboxDel(OS_EVENT*pevent,INT8Uopt,INT8U*err)
131{
132#ifOS_CRITICAL_METHOD==3//中断函数被设定为模式3
133OS_CPU_SRcpu_sr;
134#endif
135BOOLEANtasks_waiting;//定义布尔量,任务等待条件
136
137
138if(OSIntNesting>0){//中断嵌套数>0时,表示还有中断任务在运行
139*err=OS_ERR_DEL_ISR;//错误等于(试图在中断程序中删除一个信号量事件)
140return(pevent);//返回消息邮箱指针
141}
142#ifOS_ARG_CHK_EN>0//所有参数在指定的范围之内
143if(pevent==(OS_EVENT*)0){//当消息邮箱指针为NULL,即0(空)
144*err=OS_ERR_PEVENT_NULL;//错误等于(已经没有可用的OS_EVENT数据结构了)
145return(pevent);//返回消息邮箱指针
146}
147if(pevent->OSEventType!
=OS_EVENT_TYPE_MBOX){//当事件类型不否是消息邮箱类型
148*err=OS_ERR_EVENT_TYPE;//pevent指针不是指向消息邮箱
149return(pevent);//返回消息邮箱指针
150}
151#endif
152OS_ENTER_CRITICAL();//关闭中断
153if(pevent->OSEventGrp!
=0x00){//事件等待标志,索引值≠0,有任务在等待
154tasks_waiting=TRUE;//有任务在等待=1(TRUE真)
155}else{
156tasks_waiting=FALSE;//否则,没有任务在等待=0,(FALSE假)
157}
158switch(opt){//条件选择
159caseOS_DEL_NO_PEND:
//1)没有任务在等待该消息邮箱
160if(tasks_waiting==FALSE){//如果没有事件在等待
161pevent->OSEventType=OS_EVENT_TYPE_UNUSED;//事件类型=空闲
162pevent->OSEventPtr=OSEventFreeList;//信号量对应的指针=空余块链接表
163OSEventFreeList=pevent;//空余块链接表=当前事件指针
164OS_EXIT_CRITICAL();//关闭中断
165*err=OS_NO_ERR;//错误等于(成功删除)
166return((OS_EVENT*)0);//返回0
167}else{//否则,有任务在等待
168OS_EXIT_CRITICAL();//打开中断
169*err=OS_ERR_TASK_WAITING;//错误等于(有一个或一个以上的任务在等待消息邮箱)
170return(pevent);//返回消息邮箱指针
171}
172
173caseOS_DEL_ALWAYS:
//2)多任务等待,尽管有任务在等待,还是要删除
174while(pevent->OSEventGrp!
=0x00){//等待标志≠0,还是要删除
175//OS_EventTaskRdy()函数将最高级优先级任务从等待列表中删除
176OS_EventTaskRdy(pevent,(void*)0,OS_STAT_MBOX);//使一个任务进入就绪态
177}
178pevent->OSEventType=OS_EVENT_TYPE_UNUSED;//事件类型=空闲
179pevent->OSEventPtr=OSEventFreeList;//消息邮箱对应的指针=空余块链接表
180OSEventFreeList=pevent;//空余块链接表=当前事件指针
181OS_EXIT_CRITICAL();//关闭中断
182if(tasks_waiting==TRUE){//当任务等待=1,真
183OS_Sched();//任务调度,最高优先级进入运行状态
184}
185*err=OS_NO_ERR;//错误等于(成功删除)
186return((OS_EVENT*)0);//返回0
187
188default:
//3)当以上两种情况都不是
189OS_EXIT_CRITICAL();//关闭中断
190*err=OS_ERR_INVALID_OPT;//错误等于(没有将opt参数定义为2种合法的参数之一)
191return(pevent);//返回信号量指针
192}
193}
194#endif
195
196/*$PAGE*/
197/*
198*********************************************************************************************************
199*任务等待消息(PENDONMAILBOXFORAMESSAGE)
200*
201*描述:
用于任务等待消息。
消息通过中断或另外的任务发送给需要的任务。
202*
203*参数:
pevent是指向即将接受消息的消息邮箱的指针。
该指针的值在建立该消息邮箱时可以得到。
204*
205*timeout允许一个任务在经过了指定数目的时钟节拍后还没有得到需要的消息时恢复运行。
如果该值为零表
206*示任务将持续的等待消息。
最大的等待时间为65,535个时钟节拍。
这个时间长度并不是非常严格的,
207*可能存在一个时钟节拍的误差,因为只有在一个时钟节拍结束后才会减少定义的等待超时时钟节拍。
208*
209*err是指向包含错误码的变量的指针。
OSMboxPend()函数返回的错误码可能为下述几种:
210*
211*OS_NO_ERR消息被正确的接受;
212*OS_TIMEOUT消息没有在指定的周期数内送到;
213*OS_ERR_EVENT_TYPEpevent不是指向消息邮箱的指针;
214*OS_ERR_PEND_ISR从中断调用该函数。
虽然规定了不允许从中断调用该函数,但uC/OS-ii仍
215*然包含了检测这种情况的功能;
216*OS_ERR_PEVENT_NULL'pevent'是空指针。
217*
218*返回:
返回接受的消息并将*err置为OS_NO_ERR。
如果没有在指定数目的时钟节拍内接受到需要的消息,
219*OSMboxPend()函数返回空指针并且将*err设置为OS_TIMEOUT。
220*
221*注意:
必须先建立消息邮箱,然后使用。
222*不允许从中断调用该函数。
223*********************************************************************************************************
224*/
225//等待一个消息邮箱函数(消息邮箱指针、允许等待的时钟节拍、代码错误指针)
226void*OSMboxPend(OS_EVENT*pevent,INT16Utimeout,INT8U*err)
227{
228#ifOS_CRITICAL_METHOD==3//中断函数被设定为模式3
229OS_CPU_SRcpu_sr;
230#endif
231void*msg;//定义消息邮箱内容的指针
232
233
234if(OSIntNesting>0){//中断嵌套数>0时,表示还有中断任务在运行
235*err=OS_ERR_PEND_ISR;//错误等于(试图在中断程序中等待一个消息邮箱事件)
236return((void*)0);//返回
237}
238#ifOS_ARG_CHK_EN>0//所有参数在指定的范围之内
239if(pevent==(OS_EVENT*)0){//当邮箱指针为NULL,即0(空)
240*err=OS_ERR_PEVENT_NULL;//pevent是空指针
241return((void*)0);//返回
242}
243if(pevent->OSEventType!
=OS_EVENT_TYPE_MBOX){//当事件类型不否是消息邮箱类型
244*err=OS_ERR_EVENT_TYPE;//pevent指针不是指向消息邮箱
245return((void*)0);//返回
246}
247#endif
248OS_ENTER_CRITICAL();//关闭中断
249msg=pevent->OSEventPtr;//保存消息邮箱内容(消息指针)到局部变量
250if(msg!
=(void*)0){//邮箱中如果有消息,则已取走
251pevent->OSEventPtr=(void*)0;//将0存入消息邮箱中
252OS_EXIT_CRITICAL();//打开中断
253*err=OS_NO_ERR;//返回成功调用,取出消息
254return(msg);//返回接收消息
255}
/****************如果消息邮箱为空,则进入等待中*****************/
256OSTCBCur->OSTCBStat|=OS_STAT_MBOX;//将任务状态置1,进入睡眠状态,只能通过消息邮箱唤醒
257OSTCBCur->OSTCBDly=timeout;//最长等待时间=timeout,递减式
258OS_EventTaskWait(pevent);//使任务进入等待时间唤醒状态
259OS_EXIT_CRITICAL();//打开中断
260OS_Sched();//进入调度任务,使就绪态优先级最高任务运行
261OS_ENTER_CRITICAL();//关闭中断
/**************当程序返回后,函数检查程序返回的原因,是因收到消息,还是因等待超时期满*********/
262msg=OSTCBCur->OSTCBMsg;//接收消息=指向任务消息的指针
263if(msg!
=(void*)0){//接收消息邮箱是否为空
264OSTCBCur->OSTCBMsg=(void*)0;//传递给消息的指针=空
265OSTCBCur->OSTCBStat=OS_STAT_RDY;//表示任务处于就绪状态
266OSTCBCur->OSTCBEventPtr=(OS_EVENT*)0;//指向事件控制块的指针=0
267OS_EXIT_CRITICAL();//打开中断
268*err=OS_NO_ERR;//成功等待该消息邮箱
269return(msg);//返回接收消息
270}
271OS_EventTO(pevent);//如果没有获得消息,由于等待超时而返回
272OS_EXIT_CRITICAL();//打开中断
273*err=OS_TIMEOUT;//消息没有在指定的时间送到
274return((void*)0);//返回0
275}
276/*$PAGE*/
277/*
278*********************************************************************************************************
279*通过消息邮箱向任务发送消息(POSTMESSAGETOAMAILBOX)
280*
281*描述:
通过消息邮箱向任务发送消息。
消息是一个指针长度的变量,在不同的程序中消息的使用也可能
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OSMBOX 邮箱 源码 注释