📄 os_mutex.s43
字号:
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 + -