OSSEM信号量源码注释Word格式文档下载.docx
- 文档编号:22658060
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:21
- 大小:21.97KB
OSSEM信号量源码注释Word格式文档下载.docx
《OSSEM信号量源码注释Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《OSSEM信号量源码注释Word格式文档下载.docx(21页珍藏版)》请在冰豆网上搜索。
28共享资源信号量的值>
0,则说明共享资源可以使用,这个值被返回调用者,信号量的值减1;
29共享资源信号量的值=0,则说明资源不能使用,返回0。
30*************************************************************************************
31*/
32
33#ifOS_SEM_ACCEPT_EN>
0//允许生成OSSemAccept()函数
34INT16UOSSemAccept(OS_EVENT*pevent)//无条件地等待请求一个信号量函数
35{
36#ifOS_CRITICAL_METHOD==3//中断函数被设定为模式3
37OS_CPU_SRcpu_sr;
38#endif
39INT16Ucnt;
//信号量的内容暂时存储变量
40
41
42#ifOS_ARG_CHK_EN>
0//所有参数必须在指定的参数内
43if(pevent==(OS_EVENT*)0){//当信号量指针为NULL时,返回0,空指针
44return(0);
45}
46if(pevent->
OSEventType!
=OS_EVENT_TYPE_SEM){//当事件类型≠信号量类型
47return(0);
//返回0
48}
49#endif
50OS_ENTER_CRITICAL();
//关闭中断
51cnt=pevent->
OSEventCnt;
//取信号值
52if(cnt>
0){//当信号值>
0时,该值有效
53pevent->
OSEventCnt--;
//信号量减1
54}
55OS_EXIT_CRITICAL();
//打开中断
56return(cnt);
//返回信号值
57}
58#endif
59
60/*$PAGE*/
61/*
62*******************************************************************************************
建立一个信号量
63*
64*描述:
建立并初始化一个信号量。
信号量的作用为:
65*1、允许一个任务与其它任务或中断同步;
66*2、取得共享资源的使用权;
67*3、标志事件的发生
68*
69*参数:
cnt建立信号量的初始值,可以为0~65535的任何值
70*
71*注意:
必须先建立信号量,然后才能使用
72*
73*返回:
!
=(void*)0返回指向分配给所建立的消息邮箱的事件控制块指针;
74*==(void*)0如果没有可用的事件控制块,返回空指针
75********************************************************************************************
76*/
77
78OS_EVENT*OSSemCreate(INT16Ucnt)//建立并初始化一个信号量(输入一个信号量值)
79{
80#ifOS_CRITICAL_METHOD==3//中断函数被设定为模式3
81OS_CPU_SRcpu_sr;
82#endif
83OS_EVENT*pevent;
//建立信号量的初始值,可以在0至65535之间
84
85
86if(OSIntNesting>
0){//中断嵌套数>0时,表示还有中断任务在运行
87return((OS_EVENT*)0);
//返回0;
88}
89OS_ENTER_CRITICAL();
90pevent=OSEventFreeList;
//pevent=空余事件管理列表
91if(OSEventFreeList!
=(OS_EVENT*)0){//如果有空余事件管理块
92OSEventFreeList=(OS_EVENT*)OSEventFreeList->
OSEventPtr;
93}//空余事件控制链表指向下一个空余事件控制块
94OS_EXIT_CRITICAL();
95if(pevent!
=(OS_EVENT*)0){//如果有事件控制块ECB可用
96pevent->
OSEventType=OS_EVENT_TYPE_SEM;
//事件类型=信号类型
97pevent->
OSEventCnt=cnt;
//将信号量值存入事件管理块中(信号量的计数器)
98OS_EventWaitListInit(pevent);
//初始化一个事件控制块
99}
100return(pevent);
//返回指针
101}
102
103/*$PAGE*/
104/*
105***********************************************************************************************
106*删除一个信号量
107*描述:
用于删除一个信号量。
108*使用本函数有风险,因为多任务中的其它任务可能还想使用这个信号量,必须特别小心。
109*一般而言,在删除信号量之前,应该先删除所有可能会用到的这个信号量的任务。
110*
111*参数:
pevent指向信号量指针。
该指针的值在建立该信号量时得到。
(参见OSSemCreate()函数)
112*
113*opt该选项定义信号量的删除条件。
可以选择只能在已经没有任何任务在等待该信号量时,才
114*能删除该信号量(OS_DEL_NO_PEND);
或者,不管有没有任务在等待该信号量,立即删除该
115*信号量(OS_DEL_ALWAYS),在这种情况下,所有等待该信号量的任务都立即进入就绪态
116*
117*err指向包含错误码的变量的指针。
返回的错误码可能为以下几种:
118*OS_NO_ERR调用成功,信号量已被删除;
119*OS_ERR_DEL_ISR试图在中断服务子程序中删除信号量;
120*OS_ERR_INVALID_OPT没有将opt参数定义为2种合法的参数之一;
121*OS_ERR_TASK_WAITING有一个或一个以上的任务在等待信号量;
122*OS_ERR_EVENT_TYPEpevent不是指向信号量的指针;
123*OS_ERR_PEVENT_NULL已经没有可用的OS_EVENT数据结构了。
124*
125*返回:
pevent如果信号量已被删除,返回空指针;
126*若信号量没有删除,则返回pevent(信号量指针),可查看出错代码。
127*
128*注意:
1)使用此函数必须特别小心,因为多任务中的其它任务可能还想使用这个信号量;
1292)当挂起的任务进入就绪态时,中断是关闭的,这意味着中断延迟时间与等待信号量的任务数有关。
130************************************************************************************************
131*/
132
133#ifOS_SEM_DEL_EN>
0//允许生成OSSemDel()代码
134OS_EVENT*OSSemDel(OS_EVENT*pevent,INT8Uopt,INT8U*err)
135{//删除一个信号量(信号指针、删除条件、错误指针)
136#ifOS_CRITICAL_METHOD==3//中断函数被设定为模式3
137OS_CPU_SRcpu_sr;
138#endif
139BOOLEANtasks_waiting;
//定义布尔量,任务等待条件
140
141
142if(OSIntNesting>
143*err=OS_ERR_DEL_ISR;
//错误等于(试图在中断程序中删除一个信号量事件)
144return(pevent);
//返回信号量指针
145}
146#ifOS_ARG_CHK_EN>
0//所有参数在指定的范围之内
147if(pevent==(OS_EVENT*)0){//当信号量指针为NULL,即0(空)
148*err=OS_ERR_PEVENT_NULL;
//错误等于(已经没有可用的OS_EVENT数据结构了)
149return(pevent);
150}
151if(pevent->
=OS_EVENT_TYPE_SEM){//当事件类型不否是信号量类型
152*err=OS_ERR_EVENT_TYPE;
//pevent指针不是指向信号量
153return(pevent);
154}
155#endif
156OS_ENTER_CRITICAL();
157if(pevent->
OSEventGrp!
=0x00){//事件等待标志,索引值≠0,有任务在等待
158tasks_waiting=TRUE;
//有任务在等待=1(TRUE真)
159}else{
160tasks_waiting=FALSE;
//否则,没有任务在等待=0,(FALSE假)
161}
162switch(opt){//条件选择
163caseOS_DEL_NO_PEND:
//1)没有任务在等待该信号量
164if(tasks_waiting==FALSE){//如果没有事件在等待
165pevent->
OSEventType=OS_EVENT_TYPE_UNUSED;
//事件类型=空闲
166pevent->
OSEventPtr=OSEventFreeList;
//信号量对应的指针=空余块链接表
167OSEventFreeList=pevent;
//空余块链接表=当前事件指针
168OS_EXIT_CRITICAL();
169*err=OS_NO_ERR;
//错误等于(成功删除)
170return((OS_EVENT*)0);
171}else{//否则,有任务在等待
172OS_EXIT_CRITICAL();
173*err=OS_ERR_TASK_WAITING;
//错误等于(有一个或一个以上的任务在等待信号量)
174return(pevent);
175}
176
177caseOS_DEL_ALWAYS:
//2)多任务等待,尽管有任务在等待,还是要删除
178while(pevent->
=0x00){//等待标志≠0,还是要删除
179OS_EventTaskRdy(pevent,(void*)0,OS_STAT_SEM);
180}//使一个任务进入就绪态
181pevent->
182pevent->
183OSEventFreeList=pevent;
184OS_EXIT_CRITICAL();
185if(tasks_waiting==TRUE){//当任务等待=1,真
186OS_Sched();
//任务调度,最高优先级进入运行状态
187}
188*err=OS_NO_ERR;
189return((OS_EVENT*)0);
190
191default:
//3)当以上两种情况都不是
192OS_EXIT_CRITICAL();
193*err=OS_ERR_INVALID_OPT;
//错误等于(没有将opt参数定义为2种合法的参数之一)
194return(pevent);
195}
196}
197#endif
198
199/*$PAGE*/
200/*
201************************************************************************************************
202*等待一个信号量
203*描述:
等待一个信号量。
204*任务试图取得共享资源使用权、任务需要与其它任务或中断同步及任务需要等待特定事件的发生的场合。
205*若任务调用该函数,且信号量的值>
0,那么OSSemPend()递减该值并返回该值;
206*若任务调用该函数,且信号量的值=0,那么OSSemPend()函数将任务加入该信号量的等待列表中。
207*
208*参数:
209*
210*timeout允许任务在经过指定数目的时钟节拍后还没有得到需要的信号量时;
恢复运行状态。
如果
211*该值为0。
则表示任务将持续地等待信号量。
最长等待时间为65535个时钟节拍。
这个时
212*间长度并不是严格的,可能存在一个时间节拍的误差,因为自由一个时钟节拍结束后,才
213*会给定义的等待超时时钟节拍减1。
214*err指向包含错误码的变量的指针。
返回的错误码可能为以下几种;
215*
216*OS_NO_ERR成功,信号量是可用的;
217*OS_TIMEOUT信号量没有在指定的周期数内置位;
218*OS_ERR_EVENT_TYPEpevent不是指向信号量的指针;
219*OS_ERR_PEND_ISR在中断中调用该函数。
虽然规定了不允许在中断中调用该函数,但
220*ucos仍然包含了检测这种情况的功能;
221*OS_ERR_PEVENT_NULLpevent是空指针。
222*返回:
无
223*注意:
必须先建立信号量,然后才能使用。
224************************************************************************************************
225*/
226//等待一个信号量函数(信号量指针、允许等待的时钟节拍、代码错误指针)
227voidOSSemPend(OS_EVENT*pevent,INT16Utimeout,INT8U*err)__
228{
229#ifOS_CRITICAL_METHOD==3//中断函数被设定为模式3
230OS_CPU_SRcpu_sr;
231#endif
232
233
234if(OSIntNesting>
0){//中断嵌套数>
0时,表示还有中断任务在运行
235*err=OS_ERR_PEND_ISR;
//错误等于(试图在中断程序中等待一个信号量事件)
236return;
//返回
237}
238#ifOS_ARG_CHK_EN>
239if(pevent==(OS_EVENT*)0){//当信号量指针为NULL,即0(空)
240*err=OS_ERR_PEVENT_NULL;
//pevent是空指针
241return;
242}
243if(pevent->
244*err=OS_ERR_EVENT_TYPE;
245return;
246}
247#endif
248OS_ENTER_CRITICAL();
249if(pevent->
OSEventCnt>
0){//当信号量计数器>
0时,
250pevent->
//信号量计数器减1
251OS_EXIT_CRITICAL();
252*err=OS_NO_ERR;
//错误等于(成功,信号量是可用的)
253return;
254}
255
/*******如果信号量计数器为0,则需要等待信号量事件发生*****************************/
256OSTCBCur->
OSTCBStat|=OS_STAT_SEM;
//将任务状态置1,进入睡眠状态,只能通过信号量唤醒
257OSTCBCur->
OSTCBDly=timeout;
//最长等待时间=timeout,递减式
258OS_EventTaskWait(pevent);
//使任务进入等待时间唤醒状态
259OS_EXIT_CRITICAL();
260OS_Sched();
//进入调度任务,使就绪态优先级最高任务运行
/*****程序在两种情况下再次返回:
1.延时期满;
2.收到一个信号量(值)******************/
261OS_ENTER_CRITICAL();
262if(OSTCBCur->
OSTCBStat&
OS_STAT_SEM){//检查任务状态是否还是在睡眠状态,即不是由被等待信号量唤醒,即时钟节拍计数超时唤醒
263OS_EventTO(pevent);
//如果没有等到信号量并超时,由等待事件返回
264OS_EXIT_CRITICAL();
265*err=OS_TIMEOUT;
//错误等于(信号量没有在指定的周期数内置位)
266return;
267}
268OSTCBCur->
OSTCBEventPtr=(OS_EVENT*)0;
//将信号量ECB的指针从该任务控制块中删除
269OS_EXIT_CRITICAL();
270*err=OS_NO_ERR;
271}
272/*$PAGE*/
273/*
274*************************************************************************************************
275*发出一个信号量
276*
277*描述:
置位指定的信号量。
如果指定的信号量是0或大于0,该函数则递增该信号量并返回;
278如果有任何任务在等待信号量,那么最高优先级任务将得到该信号量并进入就绪态;
279如果被唤醒的任务就是最高优先级的就绪态任务,则任务调度函数将进入任务调度。
280*
281*参数:
282*
283*返回:
OS_NO_ERR信号量成功的置位;
284*OS_SEM_OVF信号量的值溢出;
285*OS_ERR_EVENT_TYPEpevent不是指向信号量的指针;
286*OS_ERR_PEVENT_NULLpevent是空指针。
287*************************************************************************************************
288*/
289
290INT8UOSSemPost(OS_EVENT*pevent)//发出一个信号量函数(信号量指针)
291{
292#ifOS_CRITICAL_METHOD==3//中断函数被设定为模式3
293OS_CPU_SRcpu_sr;
294#endif
295
296
297#ifOS_ARG_CHK_EN>
298if(pevent==(OS_EVENT*)0){//当信号量指针为NULL,即0(空)
299return(O
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OSSEM 信号量 源码 注释