📄 os_sem.lst
字号:
C51 COMPILER V7.50 OS_SEM 12/14/2007 08:25:43 PAGE 1
C51 COMPILER V7.50, COMPILATION OF MODULE OS_SEM
OBJECT MODULE PLACED IN OS_SEM.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE OS_SEM.C LARGE BROWSE DEBUG OBJECTEXTEND
line level source
1 /*
2 *********************************************************************************************************
3 * uC/OS-II
4 * The Real-Time Kernel
5 * SEMAPHORE MANAGEMENT
6 *
7 * (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL
8 * All Rights Reserved
9 *
10 * File : OS_SEM.C
11 * By : Jean J. Labrosse
12 * Version : V2.85
13 *
14 * LICENSING TERMS:
15 * ---------------
16 * uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
-
17 * If you plan on using uC/OS-II in a commercial product you need to contact Micri祄 to properly license
18 * its use in your product. We provide ALL the source code for your convenience and to help you experience
19 * uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
20 * licensing fee.
21 *********************************************************************************************************
22 */
23
24 #ifndef OS_MASTER_FILE
25 #include <ucos_ii.h>
26 #endif
27
28 #if OS_SEM_EN > 0
29 /*$PAGE*/
30 /*
31 *********************************************************************************************************
32 * ACCEPT SEMAPHORE
33 *
34 * Description: This function checks the semaphore to see if a resource is available or, if an event
35 * occurred. Unlike OSSemPend(), OSSemAccept() does not suspend the calling task if the
36 * resource is not available or the event did not occur.
37 *
38 * Arguments : pevent is a pointer to the event control block
39 *
40 * Returns : > 0 if the resource is available or the event did not occur the semaphore is
41 * decremented to obtain the resource.
42 * == 0 if the resource is not available or the event did not occur or,
43 * if 'pevent' is a NULL pointer or,
44 * if you didn't pass a pointer to a semaphore
45 *********************************************************************************************************
46 */
47
48 #if OS_SEM_ACCEPT_EN > 0
49 INT16U OSSemAccept (OS_EVENT *pevent) reentrant
50 {
51 1 INT16U cnt;
52 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
C51 COMPILER V7.50 OS_SEM 12/14/2007 08:25:43 PAGE 2
55 1
56 1
57 1
58 1 #if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
return (0);
}
#endif
63 1 if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
64 2 return (0);
65 2 }
66 1 OS_ENTER_CRITICAL();
67 1 cnt = pevent->OSEventCnt;
68 1 if (cnt > 0) { /* See if resource is available */
69 2 pevent->OSEventCnt--; /* Yes, decrement semaphore and notify caller */
70 2 }
71 1 OS_EXIT_CRITICAL();
72 1 return (cnt); /* Return semaphore count */
73 1 }
74 #endif
75
76 /*$PAGE*/
77 /*
78 *********************************************************************************************************
79 * CREATE A SEMAPHORE
80 *
81 * Description: This function creates a semaphore.
82 *
83 * Arguments : cnt is the initial value for the semaphore. If the value is 0, no resource is
84 * available (or no event has occurred). You initialize the semaphore to a
85 * non-zero value to specify how many resources are available (e.g. if you have
86 * 10 resources, you would initialize the semaphore to 10).
87 *
88 * Returns : != (void *)0 is a pointer to the event control block (OS_EVENT) associated with the
89 * created semaphore
90 * == (void *)0 if no event control blocks were available
91 *********************************************************************************************************
92 */
93
94 OS_EVENT *OSSemCreate (INT16U cnt) reentrant
95 {
96 1 OS_EVENT *pevent;
97 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
100 1
101 1
102 1
103 1 if (OSIntNesting > 0) { /* See if called from ISR ... */
104 2 return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */
105 2 }
106 1 OS_ENTER_CRITICAL();
107 1 pevent = OSEventFreeList; /* Get next free event control block */
108 1 if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */
109 2 OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
110 2 }
111 1 OS_EXIT_CRITICAL();
112 1 if (pevent != (OS_EVENT *)0) { /* Get an event control block */
113 2 pevent->OSEventType = OS_EVENT_TYPE_SEM;
114 2 pevent->OSEventCnt = cnt; /* Set semaphore value */
115 2 pevent->OSEventPtr = (void *)0; /* Unlink from ECB free list */
116 2 #if OS_EVENT_NAME_SIZE > 1
C51 COMPILER V7.50 OS_SEM 12/14/2007 08:25:43 PAGE 3
117 2 pevent->OSEventName[0] = '?'; /* Unknown name */
118 2 pevent->OSEventName[1] = OS_ASCII_NUL;
119 2 #endif
120 2 OS_EventWaitListInit(pevent); /* Initialize to 'nobody waiting' on sem. */
121 2 }
122 1 return (pevent);
123 1 }
124
125 /*$PAGE*/
126 /*
127 *********************************************************************************************************
128 * DELETE A SEMAPHORE
129 *
130 * Description: This function deletes a semaphore and readies all tasks pending on the semaphore.
131 *
132 * Arguments : pevent is a pointer to the event control block associated with the desired
133 * semaphore.
134 *
135 * opt determines delete options as follows:
136 * opt == OS_DEL_NO_PEND Delete semaphore ONLY if no task pending
137 * opt == OS_DEL_ALWAYS Deletes the semaphore even if tasks are waiting.
138 * In this case, all the tasks pending will be readied.
139 *
140 * perr is a pointer to an error code that can contain one of the following values:
141 * OS_ERR_NONE The call was successful and the semaphore was deleted
142 * OS_ERR_DEL_ISR If you attempted to delete the semaphore from an ISR
143 * OS_ERR_INVALID_OPT An invalid option was specified
144 * OS_ERR_TASK_WAITING One or more tasks were waiting on the semaphore
145 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore
146 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
147 *
148 * Returns : pevent upon error
149 * (OS_EVENT *)0 if the semaphore was successfully deleted.
150 *
151 * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
152 * the semaphore MUST check the return code of OSSemPend().
153 * 2) OSSemAccept() callers will not know that the intended semaphore has been deleted unless
154 * they check 'pevent' to see that it's a NULL pointer.
155 * 3) This call can potentially disable interrupts for a long time. The interrupt disable
156 * time is directly proportional to the number of tasks waiting on the semaphore.
157 * 4) Because ALL tasks pending on the semaphore will be readied, you MUST be careful in
158 * applications where the semaphore is used for mutual exclusion because the resource(s)
159 * will no longer be guarded by the semaphore.
160 *********************************************************************************************************
161 */
162
163 #if OS_SEM_DEL_EN > 0
164 OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) reentrant
165 {
166 1 BOOLEAN tasks_waiting;
167 1 OS_EVENT *pevent_return;
168 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
171 1
172 1
173 1
174 1 #if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return (pevent);
}
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
C51 COMPILER V7.50 OS_SEM 12/14/2007 08:25:43 PAGE 4
*perr = OS_ERR_PEVENT_NULL;
return (pevent);
}
#endif
183 1 if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
184 2 *perr = OS_ERR_EVENT_TYPE;
185 2 return (pevent);
186 2 }
187 1 if (OSIntNesting > 0) { /* See if called from ISR ... */
188 2 *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
189 2 return (pevent);
190 2 }
191 1 OS_ENTER_CRITICAL();
192 1 if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on semaphore */
193 2 tasks_waiting = OS_TRUE; /* Yes */
194 2 } else {
195 2 tasks_waiting = OS_FALSE; /* No */
196 2 }
197 1 switch (opt) {
198 2 case OS_DEL_NO_PEND: /* Delete semaphore only if no task waiting */
199 2 if (tasks_waiting == OS_FALSE) {
200 3 #if OS_EVENT_NAME_SIZE > 1
201 3 pevent->OSEventName[0] = '?'; /* Unknown name */
202 3 pevent->OSEventName[1] = OS_ASCII_NUL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -