os_sem.lst
来自「在51上运行的小的OS系统」· LST 代码 · 共 578 行 · 第 1/3 页
LST
578 行
123 * Arguments : pevent is a pointer to the event control block associated with the desired
124 * semaphore.
125 *
126 * opt determines delete options as follows:
127 * opt == OS_DEL_NO_PEND Delete semaphore ONLY if no task pending
128 * opt == OS_DEL_ALWAYS Deletes the semaphore even if tasks are waiting.
129 * In this case, all the tasks pending will be readied.
130 *
131 * err is a pointer to an error code that can contain one of the following values:
132 * OS_NO_ERR The call was successful and the semaphore was deleted
133 * OS_ERR_DEL_ISR If you attempted to delete the semaphore from an ISR
134 * OS_ERR_INVALID_OPT An invalid option was specified
135 * OS_ERR_TASK_WAITING One or more tasks were waiting on the semaphore
136 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore
137 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
138 *
139 * Returns : pevent upon error
140 * (OS_EVENT *)0 if the semaphore was successfully deleted.
141 *
142 * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
143 * the semaphore MUST check the return code of OSSemPend().
144 * 2) OSSemAccept() callers will not know that the intended semaphore has been deleted unless
145 * they check 'pevent' to see that it's a NULL pointer.
146 * 3) This call can potentially disable interrupts for a long time. The interrupt disable
147 * time is directly proportional to the number of tasks waiting on the semaphore.
148 * 4) Because ALL tasks pending on the semaphore will be readied, you MUST be careful in
149 * applications where the semaphore is used for mutual exclusion because the resource(s)
150 * will no longer be guarded by the semaphore.
151 *********************************************************************************************************
152 */
153
154 #if OS_SEM_DEL_EN > 0
155 OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *err)
156 {
157 BOOLEAN tasks_waiting;
158 OS_EVENT *pevent_return;
159 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
162
163
164
165 #if OS_ARG_CHK_EN > 0
166 if (err == (INT8U *)0) { /* Validate 'err' */
167 return (pevent);
168 }
169 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
170 *err = OS_ERR_PEVENT_NULL;
171 return (pevent);
172 }
173 #endif
174 if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
175 *err = OS_ERR_EVENT_TYPE;
176 return (pevent);
177 }
178 if (OSIntNesting > 0) { /* See if called from ISR ... */
179 *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
180 return (pevent);
181 }
182 OS_ENTER_CRITICAL();
183 if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on semaphore */
184 tasks_waiting = TRUE; /* Yes */
C51 COMPILER V8.08 OS_SEM 08/04/2008 21:49:52 PAGE 5
185 } else {
186 tasks_waiting = FALSE; /* No */
187 }
188 switch (opt) {
189 case OS_DEL_NO_PEND: /* Delete semaphore only if no task waiting */
190 if (tasks_waiting == FALSE) {
191 #if OS_EVENT_NAME_SIZE > 1
192 pevent->OSEventName[0] = '?'; /* Unknown name */
193 pevent->OSEventName[1] = OS_ASCII_NUL;
194 #endif
195 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
196 pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
197 pevent->OSEventCnt = 0;
198 OSEventFreeList = pevent; /* Get next free event control block */
199 OS_EXIT_CRITICAL();
200 *err = OS_NO_ERR;
201 pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */
202 } else {
203 OS_EXIT_CRITICAL();
204 *err = OS_ERR_TASK_WAITING;
205 pevent_return = pevent;
206 }
207 break;
208
209 case OS_DEL_ALWAYS: /* Always delete the semaphore */
210 while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for semaphore */
211 (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM);
212 }
213 #if OS_EVENT_NAME_SIZE > 1
214 pevent->OSEventName[0] = '?'; /* Unknown name */
215 pevent->OSEventName[1] = OS_ASCII_NUL;
216 #endif
217 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
218 pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
219 pevent->OSEventCnt = 0;
220 OSEventFreeList = pevent; /* Get next free event control block */
221 OS_EXIT_CRITICAL();
222 if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiting */
223 OS_Sched(); /* Find highest priority task ready to run */
224 }
225 *err = OS_NO_ERR;
226 pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */
227 break;
228
229 default:
230 OS_EXIT_CRITICAL();
231 *err = OS_ERR_INVALID_OPT;
232 pevent_return = pevent;
233 break;
234 }
235 return (pevent_return);
236 }
237 #endif
238
239 /*$PAGE*/
240 /*
241 *********************************************************************************************************
242 * PEND ON SEMAPHORE
243 *
244 * Description: This function waits for a semaphore.
245 *
246 * Arguments : pevent is a pointer to the event control block associated with the desired
C51 COMPILER V8.08 OS_SEM 08/04/2008 21:49:52 PAGE 6
247 * semaphore.
248 *
249 * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
250 * wait for the resource up to the amount of time specified by this argument.
251 * If you specify 0, however, your task will wait forever at the specified
252 * semaphore or, until the resource becomes available (or the event occurs).
253 *
254 * err is a pointer to where an error message will be deposited. Possible error
255 * messages are:
256 *
257 * OS_NO_ERR The call was successful and your task owns the resource
258 * or, the event you are waiting for occurred.
259 * OS_TIMEOUT The semaphore was not received within the specified
260 * timeout.
261 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore.
262 * OS_ERR_PEND_ISR If you called this function from an ISR and the result
263 * would lead to a suspension.
264 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
265 *
266 * Returns : none
267 *********************************************************************************************************
268 */
269
270 void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
271 {
272 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
275
276
277
278 #if OS_ARG_CHK_EN > 0
279 if (err == (INT8U *)0) { /* Validate 'err' */
280 return;
281 }
282 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
283 *err = OS_ERR_PEVENT_NULL;
284 return;
285 }
286 #endif
287 if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
288 *err = OS_ERR_EVENT_TYPE;
289 return;
290 }
291 if (OSIntNesting > 0) { /* See if called from ISR ... */
292 *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
293 return;
294 }
295 OS_ENTER_CRITICAL();
296 if (pevent->OSEventCnt > 0) { /* If sem. is positive, resource available ... */
297 pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */
298 OS_EXIT_CRITICAL();
299 *err = OS_NO_ERR;
300 return;
301 }
302 /* Otherwise, must wait until event occurs */
303 OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */
304 OSTCBCur->OSTCBPendTO = FALSE;
305 OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */
306 OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
307 OS_EXIT_CRITICAL();
308 OS_Sched(); /* Find next highest priority task ready */
C51 COMPILER V8.08 OS_SEM 08/04/2008 21:49:52 PAGE 7
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?