⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_mutex.s43

📁 IAR project for MSP430 and uC/OS. All configured to start filling with tasks.
💻 S43
📖 第 1 页 / 共 3 页
字号:
	JEQ	(?0075)	
; 216.	        *err = OS_ERR_DEL_ISR;                             /* ... can't DELETE from an ISR             */
	MOV.B	#140,0(R8)	
; 217.	        return (pevent);
	MOV	R11,R12	
; 218.	    }
	JMP	(?0094)	
?0075:
; 219.	#if OS_ARG_CHK_EN > 0
; 220.	    if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
	CMP	#0,R11	
	JNE	(?0077)	
; 221.	        *err = OS_ERR_PEVENT_NULL;
	MOV.B	#4,0(R8)	
; 222.	        return ((OS_EVENT *)0);
	MOV	#0,R12	
; 223.	    }
	JMP	(?0094)	
?0077:
; 224.	    if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {      /* Validate event block type                */
	MOV.B	#4,R12	
	CMP.B	@R11,R12	
	JEQ	(?0079)	
; 225.	        *err = OS_ERR_EVENT_TYPE;
	MOV.B	#1,0(R8)	
; 226.	        return (pevent);
	MOV	R11,R12	
; 227.	    }
	JMP	(?0094)	
?0079:
; 228.	#endif
; 229.	    OS_ENTER_CRITICAL();
	DINT		
; 230.	    if (pevent->OSEventGrp != 0x00) {                      /* See if any tasks waiting on mutex        */
	CMP.B	#0,1(R11)	
	JEQ	(?0081)	
; 231.	        tasks_waiting = TRUE;                              /* Yes                                      */
	MOV.B	#1,R10	
; 232.	    } else {
	JMP	(?0082)	
?0081:
; 233.	        tasks_waiting = FALSE;                             /* No                                       */
	MOV.B	#0,R10	
?0082:
; 234.	    }
; 235.	    switch (opt) {
	SUB.B	#0,R14	
	JEQ	(?0084)	
	SUB.B	#1,R14	
	JEQ	(?0087)	
	JMP	(?0093)	
?0084:
; 236.	        case OS_DEL_NO_PEND:                               /* Delete mutex only if no task waiting     */
; 237.	             if (tasks_waiting == FALSE) {
	CMP.B	#0,R10	
	JNE	(?0086)	
; 238.	                 pip                 = (INT8U)(pevent->OSEventCnt >> 8);
	MOV	2(R11),R12	
	SWPB	R12	
	AND.B	#-1,R12	
; 239.	                 OSTCBPrioTbl[pip]   = (OS_TCB *)0;        /* Free up the PIP                          */
	ADD	R12,R12	
	MOV	#0,OSTCBPrioTbl(R12)	
; 240.	                 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
	MOV.B	#0,0(R11)	
; 241.	                 pevent->OSEventPtr  = OSEventFreeList;    /* Return Event Control Block to free list  */
	MOV	&OSEventFreeList,4(R11)	
; 242.	                 OSEventFreeList     = pevent;
	MOV	R11,&OSEventFreeList	
; 243.	                 OS_EXIT_CRITICAL();
	EINT		
; 244.	                 *err = OS_NO_ERR;
	MOV.B	#0,0(R8)	
; 245.	                 return ((OS_EVENT *)0);                   /* Mutex has been deleted                   */
	MOV	#0,R12	
; 246.	             } else {
	JMP	(?0094)	
?0086:
; 247.	                 OS_EXIT_CRITICAL();
	EINT		
; 248.	                 *err = OS_ERR_TASK_WAITING;
	MOV.B	#8,0(R8)	
; 249.	                 return (pevent);
	MOV	R11,R12	
; 250.	             }
	JMP	(?0094)	
?0087:
; 251.	
; 252.	        case OS_DEL_ALWAYS:                                /* Always delete the mutex                  */
; 253.	             while (pevent->OSEventGrp != 0x00) {          /* Ready ALL tasks waiting for mutex        */
	CMP.B	#0,1(R11)	
	JEQ	(?0088)	
; 254.	                 OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX);
	PUSH.B	#16	
	MOV	#0,R14	
	MOV	R11,R12	
	CALL	#OS_EventTaskRdy	
	ADD	#2,SP	
	JMP	(?0087)	
?0088:
; 255.	             }
; 256.	             pip                 = (INT8U)(pevent->OSEventCnt >> 8);
	MOV	2(R11),R12	
	SWPB	R12	
	AND.B	#-1,R12	
; 257.	             OSTCBPrioTbl[pip]   = (OS_TCB *)0;            /* Free up the PIP                          */
	ADD	R12,R12	
	MOV	#0,OSTCBPrioTbl(R12)	
; 258.	             pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
	MOV.B	#0,0(R11)	
; 259.	             pevent->OSEventPtr  = OSEventFreeList;        /* Return Event Control Block to free list  */
	MOV	&OSEventFreeList,4(R11)	
; 260.	             OSEventFreeList     = pevent;                 /* Get next free event control block        */
	MOV	R11,&OSEventFreeList	
; 261.	             OS_EXIT_CRITICAL();
	EINT		
; 262.	             if (tasks_waiting == TRUE) {                  /* Reschedule only if task(s) were waiting  */
	CMP.B	#1,R10	
	JNE	(?0092)	
; 263.	                 OS_Sched();                               /* Find highest priority task ready to run  */
	CALL	#OS_Sched	
?0092:
; 264.	             }
; 265.	             *err = OS_NO_ERR;
	MOV.B	#0,0(R8)	
; 266.	             return ((OS_EVENT *)0);                       /* Mutex has been deleted                   */
	MOV	#0,R12	
; 267.	
; 268.	        default:
	JMP	(?0094)	
?0093:
; 269.	             OS_EXIT_CRITICAL();
	EINT		
; 270.	             *err = OS_ERR_INVALID_OPT;
	MOV.B	#7,0(R8)	
; 271.	             return (pevent);
	MOV	R11,R12	
; 272.	    }
?0094:
	POP	R8	
	POP	R11	
	POP	R10	
	RET		
?0083:
; 273.	}
OSMutexPend:
; 274.	#endif
; 275.	
; 276.	/*$PAGE*/
; 277.	/*
; 278.	*********************************************************************************************************
; 279.	*                                  PEND ON MUTUAL EXCLUSION SEMAPHORE
; 280.	*
; 281.	* Description: This function waits for a mutual exclusion semaphore.
; 282.	*
; 283.	* Arguments  : pevent        is a pointer to the event control block associated with the desired
; 284.	*                            mutex.
; 285.	*
; 286.	*              timeout       is an optional timeout period (in clock ticks).  If non-zero, your task will
; 287.	*                            wait for the resource up to the amount of time specified by this argument.
; 288.	*                            If you specify 0, however, your task will wait forever at the specified
; 289.	*                            mutex or, until the resource becomes available.
; 290.	*
; 291.	*              err           is a pointer to where an error message will be deposited.  Possible error
; 292.	*                            messages are:
; 293.	*                               OS_NO_ERR          The call was successful and your task owns the mutex
; 294.	*                               OS_TIMEOUT         The mutex was not available within the specified time.
; 295.	*                               OS_ERR_EVENT_TYPE  If you didn't pass a pointer to a mutex
; 296.	*                               OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
; 297.	*                               OS_ERR_PEND_ISR    If you called this function from an ISR and the result
; 298.	*                                                  would lead to a suspension.
; 299.	*
; 300.	* Returns    : none
; 301.	*
; 302.	* Note(s)    : 1) The task that owns the Mutex MUST NOT pend on any other event while it owns the mutex.
; 303.	*              2) You MUST NOT change the priority of the task that owns the mutex
; 304.	*********************************************************************************************************
; 305.	*/
; 306.	void  OSMutexPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
; 307.	{
	PUSH	R10	
	PUSH	R11	
	PUSH	R8	
	MOV	R12,R10	
	MOV	8(SP),R11	
; 308.	#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
; 309.	    OS_CPU_SR  cpu_sr;
; 310.	#endif    
; 311.	    INT8U      pip;                                        /* Priority Inheritance Priority (PIP)      */
; 312.	    INT8U      mprio;                                      /* Mutex owner priority                     */
; 313.	    BOOLEAN    rdy;                                        /* Flag indicating task was ready           */
; 314.	    OS_TCB    *ptcb;
; 315.	
; 316.	
; 317.	    if (OSIntNesting > 0) {                                /* See if called from ISR ...               */
	CMP.B	#0,&OSIntNesting	
	JEQ	(?0096)	
; 318.	        *err = OS_ERR_PEND_ISR;                            /* ... can't PEND from an ISR               */
	MOV.B	#2,0(R11)	
; 319.	        return;
; 320.	    }
	JMP	(?0116)	
?0096:
; 321.	#if OS_ARG_CHK_EN > 0
; 322.	    if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
	CMP	#0,R10	
	JNE	(?0098)	
; 323.	        *err = OS_ERR_PEVENT_NULL;
	MOV.B	#4,0(R11)	
; 324.	        return;
; 325.	    }
	JMP	(?0116)	
?0098:
; 326.	    if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {      /* Validate event block type                */
	MOV.B	#4,R12	
	CMP.B	@R10,R12	
	JEQ	(?0100)	
; 327.	        *err = OS_ERR_EVENT_TYPE;
	MOV.B	#1,0(R11)	
; 328.	        return;
; 329.	    }
	JMP	(?0116)	
?0100:
; 330.	#endif
; 331.	    OS_ENTER_CRITICAL();                                                                   /* Is Mutex available?                      */
	DINT		
; 332.	    if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) {
	MOV	2(R10),R12	
	AND.B	#255,R12	
	CMP.B	#255,R12	
	JNE	(?0102)	
; 333.	        pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;       /* Yes, Acquire the resource                */
	AND	#65280,2(R10)	
; 334.	        pevent->OSEventCnt |= OSTCBCur->OSTCBPrio;         /*      Save priority of owning task        */
	MOV	&OSTCBCur,R12	
	MOV.B	29(R12),R12	
	BIS	R12,2(R10)	
; 335.	        pevent->OSEventPtr  = (void *)OSTCBCur;            /*      Point to owning task's OS_TCB       */
	MOV	&OSTCBCur,4(R10)	
; 336.	        OS_EXIT_CRITICAL();
	EINT		
; 337.	        *err  = OS_NO_ERR;
	MOV.B	#0,0(R11)	
; 338.	        return;
; 339.	    }
	JMP	(?0116)	
?0102:
; 340.	    pip   = (INT8U)(pevent->OSEventCnt >> 8);                     /* No, Get PIP from mutex            */
	MOV	2(R10),R12	
	SWPB	R12	
	AND.B	#-1,R12	
; 341.	    mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);  /*     Get priority of mutex owner   */
	MOV	2(R10),R15	
	AND.B	#255,R15	
; 342.	    ptcb  = (OS_TCB *)(pevent->OSEventPtr);                       /*     Point to TCB of mutex owner   */
	MOV	4(R10),R13	
; 343.	    if (ptcb->OSTCBPrio != pip && mprio > OSTCBCur->OSTCBPrio) {  /*     Need to promote prio of owner?*/
	CMP.B	29(R13),R12	
	JEQ	(?0104)	
	MOV	&OSTCBCur,R8	
	CMP.B	R15,29(R8)	
	JC	(?0104)	
; 344.	        if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) { /*     See if mutex owner is ready   */
	MOV.B	31(R13),R15	
	BIT.B	OSRdyTbl(R15),32(R13)	
	JEQ	(?0108)	
; 345.	                                                                  /*     Yes, Remove owner from Rdy ...*/
; 346.	                                                                  /*          ... list at current prio */
; 347.	            if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {
	MOV.B	31(R13),R15	
	MOV.B	32(R13),R8	
	XOR.B	#-1,R8	
	AND.B	R8,OSRdyTbl(R15)	
	CMP.B	#0,OSRdyTbl(R15)	
	JNE	(?0110)	
; 348.	                OSRdyGrp &= ~ptcb->OSTCBBitY;
	MOV.B	33(R13),R15	
	XOR.B	#-1,R15	
	AND.B	R15,&OSRdyGrp	
?0110:
; 349.	            }
; 350.	            rdy = TRUE;
	MOV.B	#1,R15	
; 351.	        } else {
	JMP	(?0111)	
?0108:
; 352.	            rdy = FALSE;                                          /* No                                */
	MOV.B	#0,R15	
?0111:
; 353.	        }
; 354.	        ptcb->OSTCBPrio         = pip;                     /* Change owner task prio to PIP            */
	MOV.B	R12,29(R13)	
; 355.	        ptcb->OSTCBY            = ptcb->OSTCBPrio >> 3;
	MOV.B	29(R13),R8	
	CLRC		
	RRC.B	R8	
	RRA.B	R8	
	RRA.B	R8	
	MOV.B	R8,31(R13)	
; 356.	        ptcb->OSTCBBitY         = OSMapTbl[ptcb->OSTCBY];
	MOV.B	31(R13),R8	
	MOV.B	OSMapTbl(R8),33(R13)	
; 357.	        ptcb->OSTCBX            = ptcb->OSTCBPrio & 0x07;
	MOV.B	29(R13),R8	
	AND.B	#7,R8	
	MOV.B	R8,30(R13)	
; 358.	        ptcb->OSTCBBitX         = OSMapTbl[ptcb->OSTCBX];
	MOV.B	30(R13),R8	
	MOV.B	OSMapTbl(R8),32(R13)	
; 359.	        if (rdy == TRUE) {                                 /* If task was ready at owner's priority ...*/
	CMP.B	#1,R15	
	JNE	(?0113)	
; 360.	            OSRdyGrp               |= ptcb->OSTCBBitY;     /* ... make it ready at new priority.       */
	BIS.B	33(R13),&OSRdyGrp	
; 361.	            OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
	MOV.B	31(R13),R15	
	BIS.B	32(R13),OSRdyTbl(R15)	
?0113:
; 362.	        }
; 363.	        OSTCBPrioTbl[pip]       = (OS_TCB *)ptcb;
	ADD	R12,R12	
	MOV	R13,OSTCBPrioTbl(R12)	
?0104:
; 364.	    }
; 365.	    OSTCBCur->OSTCBStat |= OS_STAT_MUTEX;             /* Mutex not available, pend current task        */
	MOV	&OSTCBCur,R12	
	BIS.B	#16,28(R12)	
; 366.	    OSTCBCur->OSTCBDly   = timeout;                   /* Store timeout in current task's TCB           */
	MOV	&OSTCBCur,R12	
	MOV	R14,26(R12)	
; 367.	    OS_EventTaskWait(pevent);                         /* Suspend task until event or timeout occurs    */
	MOV	R10,R12	
	CALL	#OS_EventTaskWait	
; 368.	    OS_EXIT_CRITICAL();
	EINT		
; 369.	    OS_Sched();                                        /* Find next highest priority task ready         */
	CALL	#OS_Sched	
; 370.	    OS_ENTER_CRITICAL();
	DINT		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -