📄 os_mutex.ls1
字号:
337 ; }
338 ; }
339 ; #endif
340 ;
341 ; /*$PAGE*/
342 ; /*
343 ; *****************************************************************************************
****************
344 ; * PEND ON MUTUAL EXCLUSION SEMAPHORE
345 ; *
346 ; * Description: This function waits for a mutual exclusion semaphore.
347 ; *
348 ; * Arguments : pevent is a pointer to the event control block associated with the
desired
349 ; * mutex.
350 ; *
351 ; * timeout is an optional timeout period (in clock ticks). If non-zero
, your task will
352 ; * wait for the resource up to the amount of time specified by
this argument.
353 ; * If you specify 0, however, your task will wait forever at th
e specified
354 ; * mutex or, until the resource becomes available.
355 ; *
356 ; * err is a pointer to where an error message will be deposited. P
ossible error
357 ; * messages are:
358 ; * OS_NO_ERR The call was successful and your task
owns the mutex
359 ; * OS_TIMEOUT The mutex was not available within the
specified time.
360 ; * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mute
x
361 ; * OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
362 ; * OS_ERR_PEND_ISR If you called this function from an IS
A51 MACRO ASSEMBLER OS_MUTEX 08/08/2005 11:36:49 PAGE 8
R and the result
363 ; * would lead to a suspension.
364 ; *
365 ; * Returns : none
366 ; *
367 ; * Note(s) : 1) The task that owns the Mutex MUST NOT pend on any other event while it
owns the mutex.
368 ; * 2) You MUST NOT change the priority of the task that owns the mutex
369 ; *****************************************************************************************
****************
370 ; */
371 ; void OSMutexPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
372 ; {
373 ;
374 ; INT8U pip; /* Priority Inheritance Priori
ty (PIP) */
375 ; INT8U mprio; /* Mutex owner priority
*/
376 ; BOOLEAN rdy; /* Flag indicating task was re
ady */
377 ; OS_TCB *ptcb;
378 ;
379 ;
380 ; if (OSIntNesting > 0) { /* See if called from ISR ...
*/
381 ; *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR
*/
382 ; return;
383 ; }
384 ; #if OS_ARG_CHK_EN > 0
385 ; if (pevent == (OS_EVENT *)0) { /* Validate 'pevent'
*/
386 ; *err = OS_ERR_PEVENT_NULL;
387 ; return;
388 ; }
389 ; if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type
*/
390 ; *err = OS_ERR_EVENT_TYPE;
391 ; return;
392 ; }
393 ; #endif
394 ; OS_ENTER_CRITICAL();
/* Is Mutex available? */
395 ; if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) {
396 ; pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Yes, Acquire the resource
*/
397 ; pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save priority of ownin
g task */
398 ; pevent->OSEventPtr = (void *)OSTCBCur; /* Point to owning task's
OS_TCB */
399 ; OS_EXIT_CRITICAL();
400 ; *err = OS_NO_ERR;
401 ; return;
402 ; }
403 ; pip = (INT8U)(pevent->OSEventCnt >> 8); /* No, Get PIP from mut
ex */
404 ; mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get priority of
mutex owner */
405 ; ptcb = (OS_TCB *)(pevent->OSEventPtr); /* Point to TCB of
mutex owner */
406 ; if (ptcb->OSTCBPrio != pip && mprio > OSTCBCur->OSTCBPrio) { /* Need to promote
prio of owner?*/
407 ; if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) { /* See if mutex own
er is ready */
408 ; /* Yes, Remove owne
r from Rdy ...*/
A51 MACRO ASSEMBLER OS_MUTEX 08/08/2005 11:36:49 PAGE 9
409 ; /* ... list at
current prio */
410 ; if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {
411 ; OSRdyGrp &= ~ptcb->OSTCBBitY;
412 ; }
413 ; rdy = TRUE;
414 ; } else {
415 ; rdy = FALSE; /* No
*/
416 ; }
417 ; ptcb->OSTCBPrio = pip; /* Change owner task prio to P
IP */
418 ; ptcb->OSTCBY = ptcb->OSTCBPrio >> 3;
419 ; ptcb->OSTCBBitY = OSMapTbl[ptcb->OSTCBY];
420 ; ptcb->OSTCBX = ptcb->OSTCBPrio & 0x07;
421 ; ptcb->OSTCBBitX = OSMapTbl[ptcb->OSTCBX];
422 ; if (rdy == TRUE) { /* If task was ready at owner'
s priority ...*/
423 ; OSRdyGrp |= ptcb->OSTCBBitY; /* ... make it ready at new pr
iority. */
424 ; OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
425 ; }
426 ; OSTCBPrioTbl[pip] = (OS_TCB *)ptcb;
427 ; }
428 ; OSTCBCur->OSTCBStat |= OS_STAT_MUTEX; /* Mutex not available, pend curren
t task */
429 ; OSTCBCur->OSTCBDly = timeout; /* Store timeout in current task's
TCB */
430 ; OS_EventTaskWait(pevent); /* Suspend task until event or time
out occurs */
431 ; OS_EXIT_CRITICAL();
432 ; OS_Sched(); /* Find next highest priority task
ready */
433 ; OS_ENTER_CRITICAL();
434 ; if (OSTCBCur->OSTCBStat & OS_STAT_MUTEX) { /* Must have timed out if still wai
ting for event*/
435 ; OS_EventTO(pevent);
436 ; OS_EXIT_CRITICAL();
437 ; *err = OS_TIMEOUT; /* Indicate that we didn't get mute
x within TO */
438 ; return;
439 ; }
440 ; OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
441 ; OS_EXIT_CRITICAL();
442 ; *err = OS_NO_ERR;
443 ; }
444 ; /*$PAGE*/
445 ; /*
446 ; *****************************************************************************************
****************
447 ; * POST TO A MUTUAL EXCLUSION SEMAPHORE
448 ; *
449 ; * Description: This function signals a mutual exclusion semaphore
450 ; *
451 ; * Arguments : pevent is a pointer to the event control block associated wit
h the desired
452 ; * mutex.
453 ; *
454 ; * Returns : OS_NO_ERR The call was successful and the mutex was signaled
.
455 ; * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex
456 ; * OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
457 ; * OS_ERR_POST_ISR Attempted to post from an ISR (not valid for MUTEX
es)
458 ; * OS_ERR_NOT_MUTEX_OWNER The task that did the post is NOT the owner of the
MUTEX.
A51 MACRO ASSEMBLER OS_MUTEX 08/08/2005 11:36:49 PAGE 10
459 ; *****************************************************************************************
****************
460 ; */
461 ;
462 ; INT8U OSMutexPost (OS_EVENT *pevent)
463 ; {
464 ;
465 ; INT8U pip; /* Priority inheritance priority
*/
466 ; INT8U prio;
467 ;
468 ;
469 ; if (OSIntNesting > 0) { /* See if called from ISR ...
*/
470 ; return (OS_ERR_POST_ISR); /* ... can't POST mutex from an ISR
*/
471 ; }
472 ; #if OS_ARG_CHK_EN > 0
473 ; if (pevent == (OS_EVENT *)0) { /* Validate 'pevent'
*/
474 ; return (OS_ERR_PEVENT_NULL);
475 ; }
476 ; if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type
*/
477 ; return (OS_ERR_EVENT_TYPE);
478 ; }
479 ; #endif
480 ; OS_ENTER_CRITICAL();
481 ; pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get priority inheritance priorit
y of mutex */
482 ; prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get owner's original
priority */
483 ; if (OSTCBCur->OSTCBPrio != pip &&
484 ; OSTCBCur->OSTCBPrio != prio) { /* See if posting task owns the MUT
EX */
485 ; OS_EXIT_CRITICAL();
486 ; return (OS_ERR_NOT_MUTEX_OWNER);
487 ; }
488 ; if (OSTCBCur->OSTCBPrio == pip) { /* Did we have to raise current tas
k's priority? */
489 ; /* Yes, Return to original priority
*/
490 ; /* Remove owner from ready lis
t at 'pip' */
491 ; if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) {
492 ; OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
493 ; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -