📄 os_mutex.lst
字号:
534 *
535 * Returns : OS_ERR_NONE The call was successful and the mutex was signaled.
536 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex
537 * OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
538 * OS_ERR_POST_ISR Attempted to post from an ISR (not valid for MUTEXes)
539 * OS_ERR_NOT_MUTEX_OWNER The task that did the post is NOT the owner of the MUTEX.
540 * OS_ERR_PIP_LOWER If the priority of the new task that owns the Mutex is
541 * HIGHER (i.e. a lower number) than the PIP. This error
542 * indicates that you did not set the PIP higher (lower
543 * number) than ALL the tasks that compete for the Mutex.
544 * Unfortunately, this is something that could not be
545 * detected when the Mutex is created because we don't know
546 * what tasks will be using the Mutex.
547 *********************************************************************************************************
548 */
549
550 INT8U OSMutexPost (OS_EVENT *pevent)
551 {
552 INT8U pip; /* Priority inheritance priority */
553 INT8U prio;
554 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
555 OS_CPU_SR cpu_sr = 0;
556 #endif
557
558
559
560 if (OSIntNesting > 0) { /* See if called from ISR ... */
561 return (OS_ERR_POST_ISR); /* ... can't POST mutex from an ISR */
562 }
563 #if OS_ARG_CHK_EN > 0
564 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
565 return (OS_ERR_PEVENT_NULL);
566 }
567 #endif
568 if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
569 return (OS_ERR_EVENT_TYPE);
570 }
571 OS_ENTER_CRITICAL();
572 pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get priority inheritance priority of mutex */
573 prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get owner's original priority */
574 if (OSTCBCur != (OS_TCB *)pevent->OSEventPtr) { /* See if posting task owns the MUTEX */
575 OS_EXIT_CRITICAL();
576 return (OS_ERR_NOT_MUTEX_OWNER);
577 }
578 if (OSTCBCur->OSTCBPrio == pip) { /* Did we have to raise current task's priority? */
579 OSMutex_RdyAtPrio(OSTCBCur, prio); /* Restore the task's original priority */
580 }
581 OSTCBPrioTbl[pip] = OS_TCB_RESERVED; /* Reserve table entry */
582 if (pevent->OSEventGrp != 0) { /* Any task waiting for the mutex? */
583 /* Yes, Make HPT waiting for mutex ready */
584 prio = OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX, OS_STAT_PEND_OK);
585 pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Save priority of mutex's new owner */
586 pevent->OSEventCnt |= prio;
587 pevent->OSEventPtr = OSTCBPrioTbl[prio]; /* Link to new mutex owner's OS_TCB */
588 if (prio <= pip) { /* PIP 'must' have a SMALLER prio ... */
589 OS_EXIT_CRITICAL(); /* ... than current task! */
590 OS_Sched(); /* Find highest priority task ready to run */
591 return (OS_ERR_PIP_LOWER);
592 } else {
593 OS_EXIT_CRITICAL();
594 OS_Sched(); /* Find highest priority task ready to run */
595 return (OS_ERR_NONE);
596 }
597 }
598 pevent->OSEventCnt |= OS_MUTEX_AVAILABLE; /* No, Mutex is now available */
599 pevent->OSEventPtr = (void *)0;
600 OS_EXIT_CRITICAL();
601 return (OS_ERR_NONE);
602 }
603 /*$PAGE*/
604 /*
605 *********************************************************************************************************
606 * QUERY A MUTUAL EXCLUSION SEMAPHORE
607 *
608 * Description: This function obtains information about a mutex
609 *
610 * Arguments : pevent is a pointer to the event control block associated with the desired mutex
611 *
612 * p_mutex_data is a pointer to a structure that will contain information about the mutex
613 *
614 * Returns : OS_ERR_NONE The call was successful and the message was sent
615 * OS_ERR_QUERY_ISR If you called this function from an ISR
616 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
617 * OS_ERR_PDATA_NULL If 'p_mutex_data' is a NULL pointer
618 * OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mutex.
619 *********************************************************************************************************
620 */
621
622 #if OS_MUTEX_QUERY_EN > 0
623 INT8U OSMutexQuery (OS_EVENT *pevent, OS_MUTEX_DATA *p_mutex_data)
624 {
625 INT8U i;
626 #if OS_LOWEST_PRIO <= 63
627 INT8U *psrc;
628 INT8U *pdest;
629 #else
630 INT16U *psrc;
631 INT16U *pdest;
632 #endif
633 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
634 OS_CPU_SR cpu_sr = 0;
635 #endif
636
637
638
639 if (OSIntNesting > 0) { /* See if called from ISR ... */
640 return (OS_ERR_QUERY_ISR); /* ... can't QUERY mutex from an ISR */
641 }
642 #if OS_ARG_CHK_EN > 0
643 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
644 return (OS_ERR_PEVENT_NULL);
645 }
646 if (p_mutex_data == (OS_MUTEX_DATA *)0) { /* Validate 'p_mutex_data' */
647 return (OS_ERR_PDATA_NULL);
648 }
649 #endif
650 if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
651 return (OS_ERR_EVENT_TYPE);
652 }
653 OS_ENTER_CRITICAL();
654 p_mutex_data->OSMutexPIP = (INT8U)(pevent->OSEventCnt >> 8);
655 p_mutex_data->OSOwnerPrio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);
656 if (p_mutex_data->OSOwnerPrio == 0xFF) {
657 p_mutex_data->OSValue = OS_TRUE;
658 } else {
659 p_mutex_data->OSValue = OS_FALSE;
660 }
661 p_mutex_data->OSEventGrp = pevent->OSEventGrp; /* Copy wait list */
662 psrc = &pevent->OSEventTbl[0];
663 pdest = &p_mutex_data->OSEventTbl[0];
664 for (i = 0; i < OS_EVENT_TBL_SIZE; i++) {
665 *pdest++ = *psrc++;
666 }
667 OS_EXIT_CRITICAL();
668 return (OS_ERR_NONE);
669 }
670 #endif /* OS_MUTEX_QUERY_EN */
671
672 /*$PAGE*/
673 /*
674 *********************************************************************************************************
675 * RESTORE A TASK BACK TO ITS ORIGINAL PRIORITY
676 *
677 * Description: This function makes a task ready at the specified priority
678 *
679 * Arguments : ptcb is a pointer to OS_TCB of the task to make ready
680 *
681 * prio is the desired priority
682 *
683 * Returns : none
684 *********************************************************************************************************
685 */
686
687 static void OSMutex_RdyAtPrio (OS_TCB *ptcb, INT8U prio)
688 {
689 INT8U y;
690
691
692 y = ptcb->OSTCBY; /* Remove owner from ready list at 'pip' */
693 OSRdyTbl[y] &= ~ptcb->OSTCBBitX;
694 if (OSRdyTbl[y] == 0) {
695 OSRdyGrp &= ~ptcb->OSTCBBitY;
696 }
697 ptcb->OSTCBPrio = prio;
698 #if OS_LOWEST_PRIO <= 63
699 ptcb->OSTCBY = (INT8U)((prio >> (INT8U)3) & (INT8U)0x07);
700 ptcb->OSTCBX = (INT8U) (prio & (INT8U)0x07);
701 ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY);
702 ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX);
703 #else
704 ptcb->OSTCBY = (INT8U)((prio >> (INT8U)4) & (INT8U)0x0F);
705 ptcb->OSTCBX = (INT8U) (prio & (INT8U)0x0F);
706 ptcb->OSTCBBitY = (INT16U)(1 << ptcb->OSTCBY);
707 ptcb->OSTCBBitX = (INT16U)(1 << ptcb->OSTCBX);
708 #endif
709 OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready at original priority */
710 OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
711 OSTCBPrioTbl[prio] = ptcb;
712 }
713
714
715 #endif /* OS_MUTEX_EN */
Segment part sizes:
Function/Label Bytes
-------------- -----
0 bytes of memory
Errors: none
Warnings: none
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -