📄 os_mutex.lst
字号:
188 * err is a pointer to an error code that can contain one of the following values:
189 * OS_NO_ERR The call was successful and the mutex was deleted
190 * OS_ERR_DEL_ISR If you attempted to delete the MUTEX from an ISR
191 * OS_ERR_INVALID_OPT An invalid option was specified
192 * OS_ERR_TASK_WAITING One or more tasks were waiting on the mutex
193 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex
194 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
195 *
196 * Returns : pevent upon error
197 * (OS_EVENT *)0 if the mutex was successfully deleted.
198 *
199 * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
200 * the mutex MUST check the return code of OSMutexPend().
201 * 2) This call can potentially disable interrupts for a long time. The interrupt disable
202 * time is directly proportional to the number of tasks waiting on the mutex.
203 * 3) Because ALL tasks pending on the mutex will be readied, you MUST be careful because the
204 * resource(s) will no longer be guarded by the mutex.
205 *********************************************************************************************************
206 */
207
208 #if OS_MUTEX_DEL_EN
209 OS_EVENT *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *err) reentrant //using 0
210 {
211 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
212 1 OS_CPU_SR cpu_sr;
213 1 #endif
214 1 BOOLEAN tasks_waiting;
215 1 INT8U pip;
216 1
217 1
218 1 if (OSIntNesting > 0) { /* See if called from ISR ... */
219 2 *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
220 2 return (pevent);
221 2 }
222 1 #if OS_ARG_CHK_EN > 0
223 1 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
224 2 *err = OS_ERR_PEVENT_NULL;
225 2 return ((OS_EVENT *)0);
226 2 }
227 1 #endif
228 1 if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
229 2 *err = OS_ERR_EVENT_TYPE;
230 2 return (pevent);
231 2 }
232 1 OS_ENTER_CRITICAL();
233 1 if (pevent->OSEventGrp != 0x00) { /* See if any tasks waiting on mutex */
234 2 tasks_waiting = TRUE; /* Yes */
235 2 } else {
236 2 tasks_waiting = FALSE; /* No */
237 2 }
238 1 switch (opt) {
239 2 case OS_DEL_NO_PEND: /* Delete mutex only if no task waiting */
240 2 if (tasks_waiting == FALSE) {
C51 COMPILER V7.06 OS_MUTEX 07/18/2003 11:06:01 PAGE 5
241 3 #if OS_EVENT_NAME_SIZE > 0
242 3 (void)strcpy(pevent->OSEventName, "?"); /* Unknown name */
243 3 #endif
244 3 pip = (INT8U)(pevent->OSEventCnt >> 8);
245 3 OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */
246 3 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
247 3 pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
248 3 pevent->OSEventCnt = 0;
249 3 OSEventFreeList = pevent;
250 3 OS_EXIT_CRITICAL();
251 3 *err = OS_NO_ERR;
252 3 return ((OS_EVENT *)0); /* Mutex has been deleted */
253 3 } else {
254 3 OS_EXIT_CRITICAL();
255 3 *err = OS_ERR_TASK_WAITING;
256 3 return (pevent);
257 3 }
258 2
259 2 case OS_DEL_ALWAYS: /* Always delete the mutex */
260 2 while (pevent->OSEventGrp != 0x00) { /* Ready ALL tasks waiting for mutex */
261 3 OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX);
262 3 }
263 2 #if OS_EVENT_NAME_SIZE > 0
264 2 (void)strcpy(pevent->OSEventName, "?"); /* Unknown name */
265 2 #endif
266 2 pip = (INT8U)(pevent->OSEventCnt >> 8);
267 2 OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */
268 2 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
269 2 pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
270 2 pevent->OSEventCnt = 0;
271 2 OSEventFreeList = pevent; /* Get next free event control block */
272 2 OS_EXIT_CRITICAL();
273 2 if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiting */
274 3 OS_Sched(); /* Find highest priority task ready to run */
275 3 }
276 2 *err = OS_NO_ERR;
277 2 return ((OS_EVENT *)0); /* Mutex has been deleted */
278 2
279 2 default:
280 2 OS_EXIT_CRITICAL();
281 2 *err = OS_ERR_INVALID_OPT;
282 2 return (pevent);
283 2 }
284 1 }
285 #endif
286
287 /*$PAGE*/
288 /*
289 *********************************************************************************************************
290 * PEND ON MUTUAL EXCLUSION SEMAPHORE
291 *
292 * Description: This function waits for a mutual exclusion semaphore.
293 *
294 * Arguments : pevent is a pointer to the event control block associated with the desired
295 * mutex.
296 *
297 * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
298 * wait for the resource up to the amount of time specified by this argument.
299 * If you specify 0, however, your task will wait forever at the specified
300 * mutex or, until the resource becomes available.
301 *
302 * err is a pointer to where an error message will be deposited. Possible error
C51 COMPILER V7.06 OS_MUTEX 07/18/2003 11:06:01 PAGE 6
303 * messages are:
304 * OS_NO_ERR The call was successful and your task owns the mutex
305 * OS_TIMEOUT The mutex was not available within the specified time.
306 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex
307 * OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
308 * OS_ERR_PEND_ISR If you called this function from an ISR and the result
309 * would lead to a suspension.
310 *
311 * Returns : none
312 *
313 * Note(s) : 1) The task that owns the Mutex MUST NOT pend on any other event while it owns the mutex.
314 * 2) You MUST NOT change the priority of the task that owns the mutex
315 *********************************************************************************************************
316 */
317 void OSMutexPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) reentrant //using 0
318 {
319 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
320 1 OS_CPU_SR cpu_sr;
321 1 #endif
322 1 INT8U pip; /* Priority Inheritance Priority (PIP) */
323 1 INT8U mprio; /* Mutex owner priority */
324 1 BOOLEAN rdy; /* Flag indicating task was ready */
325 1 OS_TCB *ptcb;
326 1 OS_EVENT *pevent2;
327 1
328 1
329 1 if (OSIntNesting > 0) { /* See if called from ISR ... */
330 2 *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
331 2 return;
332 2 }
333 1 #if OS_ARG_CHK_EN > 0
334 1 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
335 2 *err = OS_ERR_PEVENT_NULL;
336 2 return;
337 2 }
338 1 #endif
339 1 if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
340 2 *err = OS_ERR_EVENT_TYPE;
341 2 return;
342 2 }
343 1 OS_ENTER_CRITICAL(); /* Is Mutex available? */
344 1 if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) {
345 2 pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Yes, Acquire the resource */
346 2 pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save priority of owning task */
347 2 pevent->OSEventPtr = (void *)OSTCBCur; /* Point to owning task's OS_TCB */
348 2 OS_EXIT_CRITICAL();
349 2 *err = OS_NO_ERR;
350 2 return;
351 2 }
352 1 pip = (INT8U)(pevent->OSEventCnt >> 8); /* No, Get PIP from mutex */
353 1 mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get priority of mutex owner */
354 1 ptcb = (OS_TCB *)(pevent->OSEventPtr); /* Point to TCB of mutex owner */
355 1 if (ptcb->OSTCBPrio != pip && mprio > OSTCBCur->OSTCBPrio) { /* Need to promote prio of owner?*/
356 2 if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) { /* See if mutex owner is ready */
357 3 /* Yes, Remove owner from Rdy ...*/
358 3 /* ... list at current prio */
359 3 if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {
360 4 OSRdyGrp &= ~ptcb->OSTCBBitY;
361 4 }
362 3 rdy = TRUE;
363 3 } else {
364 3 pevent2 = ptcb->OSTCBEventPtr;
C51 COMPILER V7.06 OS_MUTEX 07/18/2003 11:06:01 PAGE 7
365 3 if (pevent2 != (OS_EVENT *)0) { /* Remove from event wait list */
366 4 if ((pevent2->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) {
367 5 pevent2->OSEventGrp &= ~ptcb->OSTCBBitY;
368 5 }
369 4 }
370 3 rdy = FALSE; /* No */
371 3 }
372 2 ptcb->OSTCBPrio = pip; /* Change owner task prio to PIP */
373 2 ptcb->OSTCBY = ptcb->OSTCBPrio >> 3;
374 2 ptcb->OSTCBBitY = OSMapTbl[ptcb->OSTCBY];
375 2 ptcb->OSTCBX = ptcb->OSTCBPrio & 0x07;
376 2 ptcb->OSTCBBitX = OSMapTbl[ptcb->OSTCBX];
377 2 if (rdy == TRUE) { /* If task was ready at owner's priority ...*/
378 3 OSRdyGrp |= ptcb->OSTCBBitY; /* ... make it ready at new priority. */
379 3 OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
380 3 } else {
381 3 pevent2 = ptcb->OSTCBEventPtr;
382 3 if (pevent2 != (OS_EVENT *)0) { /* Remove from event wait list */
383 4 pevent2->OSEventGrp |= ptcb->OSTCBBitY;
384 4 pevent2->OSEventTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -