📄 os_sem.s
字号:
; if (tasks_waiting == FALSE) {
tst R14
brne L24
.dbline 190
.dbline 195
; #if OS_EVENT_NAME_SIZE > 1
; pevent->OSEventName[0] = '?'; /* Unknown name */
; pevent->OSEventName[1] = OS_ASCII_NUL;
; #endif
; pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
clr R2
movw R30,R22
std z+0,R2
.dbline 196
; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
lds R2,_OSEventFreeList
lds R3,_OSEventFreeList+1
std z+2,R3
std z+1,R2
.dbline 197
; pevent->OSEventCnt = 0;
clr R2
clr R3
movw R30,R22
std z+4,R3
std z+3,R2
.dbline 198
; OSEventFreeList = pevent; /* Get next free event control block */
sts _OSEventFreeList+1,R23
sts _OSEventFreeList,R22
.dbline 199
; OS_EXIT_CRITICAL();
mov R16,R12
xcall _OS_CPU_SR_Restore
.dbline 200
; *err = OS_NO_ERR;
clr R2
movw R30,R10
std z+0,R2
.dbline 201
; pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */
clr R20
clr R21
.dbline 202
xjmp L21
L24:
.dbline 202
; } else {
.dbline 203
; OS_EXIT_CRITICAL();
mov R16,R12
xcall _OS_CPU_SR_Restore
.dbline 204
; *err = OS_ERR_TASK_WAITING;
ldi R24,8
movw R30,R10
std z+0,R24
.dbline 205
; pevent_return = pevent;
movw R20,R22
.dbline 206
; }
.dbline 207
; break;
xjmp L21
L27:
.dbline 210
.dbline 211
ldi R24,1
std y+0,R24
clr R18
clr R19
movw R16,R22
xcall _OS_EventTaskRdy
.dbline 212
L28:
.dbline 210
;
; case OS_DEL_ALWAYS: /* Always delete the semaphore */
; while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for semaphore */
movw R30,R22
ldd R2,z+5
tst R2
brne L27
.dbline 217
; (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM);
; }
; #if OS_EVENT_NAME_SIZE > 1
; pevent->OSEventName[0] = '?'; /* Unknown name */
; pevent->OSEventName[1] = OS_ASCII_NUL;
; #endif
; pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
clr R2
movw R30,R22
std z+0,R2
.dbline 218
; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
lds R2,_OSEventFreeList
lds R3,_OSEventFreeList+1
std z+2,R3
std z+1,R2
.dbline 219
; pevent->OSEventCnt = 0;
clr R2
clr R3
movw R30,R22
std z+4,R3
std z+3,R2
.dbline 220
; OSEventFreeList = pevent; /* Get next free event control block */
sts _OSEventFreeList+1,R23
sts _OSEventFreeList,R22
.dbline 221
; OS_EXIT_CRITICAL();
mov R16,R12
xcall _OS_CPU_SR_Restore
.dbline 222
; if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiting */
mov R24,R14
cpi R24,1
brne L30
.dbline 222
.dbline 223
; OS_Sched(); /* Find highest priority task ready to run */
xcall _OS_Sched
.dbline 224
; }
L30:
.dbline 225
; *err = OS_NO_ERR;
clr R2
movw R30,R10
std z+0,R2
.dbline 226
; pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */
clr R20
clr R21
.dbline 227
; break;
xjmp L21
L20:
.dbline 230
;
; default:
; OS_EXIT_CRITICAL();
mov R16,R12
xcall _OS_CPU_SR_Restore
.dbline 231
; *err = OS_ERR_INVALID_OPT;
ldi R24,7
movw R30,R10
std z+0,R24
.dbline 232
; pevent_return = pevent;
movw R20,R22
.dbline 233
; break;
L21:
.dbline 235
; }
; return (pevent_return);
movw R16,R20
.dbline -2
L13:
adiw R28,1
xcall pop_gset5
.dbline 0 ; func end
ret
.dbsym r tasks_waiting 14 c
.dbsym r pevent_return 20 pS[os_event]
.dbsym r cpu_sr 12 c
.dbsym r err 10 pc
.dbsym r opt 20 c
.dbsym r pevent 22 pS[os_event]
.dbend
.dbfunc e OSSemPend _OSSemPend fV
; cpu_sr -> R22
; err -> R20,R21
; timeout -> R12,R13
; pevent -> R10,R11
.even
_OSSemPend::
xcall push_gset4
movw R12,R18
movw R10,R16
ldd R20,y+8
ldd R21,y+9
.dbline -1
.dbline 271
; }
; #endif
;
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * PEND ON SEMAPHORE
; *
; * Description: This function waits for a semaphore.
; *
; * Arguments : pevent is a pointer to the event control block associated with the desired
; * semaphore.
; *
; * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
; * wait for the resource up to the amount of time specified by this argument.
; * If you specify 0, however, your task will wait forever at the specified
; * semaphore or, until the resource becomes available (or the event occurs).
; *
; * err is a pointer to where an error message will be deposited. Possible error
; * messages are:
; *
; * OS_NO_ERR The call was successful and your task owns the resource
; * or, the event you are waiting for occurred.
; * OS_TIMEOUT The semaphore was not received within the specified
; * timeout.
; * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore.
; * OS_ERR_PEND_ISR If you called this function from an ISR and the result
; * would lead to a suspension.
; * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
; *
; * Returns : none
; *********************************************************************************************************
; */
;
; void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
; {
.dbline 273
; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; OS_CPU_SR cpu_sr = 0;
clr R22
.dbline 287
; #endif
;
;
;
; #if OS_ARG_CHK_EN > 0
; if (err == (INT8U *)0) { /* Validate 'err' */
; return;
; }
; if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
; *err = OS_ERR_PEVENT_NULL;
; return;
; }
; #endif
; if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
movw R30,R10
ldd R24,z+0
cpi R24,3
breq L33
.dbline 287
.dbline 288
; *err = OS_ERR_EVENT_TYPE;
ldi R24,1
movw R30,R20
std z+0,R24
.dbline 289
; return;
xjmp L32
L33:
.dbline 291
; }
; if (OSIntNesting > 0) { /* See if called from ISR ... */
clr R2
lds R3,_OSIntNesting
cp R2,R3
brsh L35
.dbline 291
.dbline 292
; *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
ldi R24,2
movw R30,R20
std z+0,R24
.dbline 293
; return;
xjmp L32
L35:
.dbline 295
; }
; OS_ENTER_CRITICAL();
xcall _OS_CPU_SR_Save
mov R22,R16
.dbline 296
; if (pevent->OSEventCnt > 0) { /* If sem. is positive, resource available ... */
movw R30,R10
ldd R2,z+3
ldd R3,z+4
tst R2
brne X6
tst R3
breq L37
X6:
.dbline 296
.dbline 297
; pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */
movw R24,R10
adiw R24,3
movw R30,R24
ldd R24,z+0
ldd R25,z+1
sbiw R24,1
std z+1,R25
std z+0,R24
.dbline 298
; OS_EXIT_CRITICAL();
mov R16,R22
xcall _OS_CPU_SR_Restore
.dbline 299
; *err = OS_NO_ERR;
clr R2
movw R30,R20
std z+0,R2
.dbline 300
; return;
xjmp L32
L37:
.dbline 303
; }
; /* Otherwise, must wait until event occurs */
; OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */
lds R24,_OSTCBCur
lds R25,_OSTCBCur+1
adiw R24,10
movw R30,R24
ldd R24,z+0
ori R24,1
std z+0,R24
.dbline 304
; OSTCBCur->OSTCBPendTO = FALSE;
clr R2
lds R30,_OSTCBCur
lds R31,_OSTCBCur+1
std z+11,R2
.dbline 305
; OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */
lds R30,_OSTCBCur
lds R31,_OSTCBCur+1
std z+9,R13
std z+8,R12
.dbline 306
; OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
movw R16,R10
xcall _OS_EventTaskWait
.dbline 307
; OS_EXIT_CRITICAL();
mov R16,R22
xcall _OS_CPU_SR_Restore
.dbline 308
; OS_Sched(); /* Find next highest priority task ready */
xcall _OS_Sched
.dbline 309
; OS_ENTER_CRITICAL();
xcall _OS_CPU_SR_Save
mov R22,R16
.dbline 310
; if (OSTCBCur->OSTCBPendTO == TRUE) { /* See if we timedout */
lds R30,_OSTCBCur
lds R31,_OSTCBCur+1
ldd R24,z+11
cpi R24,1
brne L39
.dbline 310
.dbline 311
; OS_EventTO(pevent);
movw R16,R10
xcall _OS_EventTO
.dbline 312
; OS_EXIT_CRITICAL();
mov R16,R22
xcall _OS_CPU_SR_Restore
.dbline 313
; *err = OS_TIMEOUT; /* Indicate that didn't get event within TO */
ldi R24,10
movw R30,R20
std z+0,R24
.dbline 314
; return;
xjmp L32
L39:
.dbline 316
; }
; OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
clr R2
clr R3
lds R30,_OSTCBCur
lds R31,_OSTCBCur+1
std z+7,R3
std z+6,R2
.dbline 317
; OS_EXIT_CRITICAL();
mov R16,R22
xcall _OS_CPU_SR_Restore
.dbline 318
; *err = OS_NO_ERR;
clr R2
movw R30,R20
std z+0,R2
.dbline -2
L32:
xcall pop_gset4
.dbline 0 ; func end
ret
.dbsym r cpu_sr 22 c
.dbsym r err 20 pc
.dbsym r timeout 12 i
.dbsym r pevent 10 pS[os_event]
.dbend
.dbfunc e OSSemPost _OSSemPost fc
; cpu_sr -> R20
; pevent -> R22,R23
.even
_OSSemPost::
xcall push_gset2
movw R22,R16
sbiw R28,1
.dbline -1
.dbline 340
; }
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * POST TO A SEMAPHORE
; *
; * Description: This function signals a semaphore
; *
; * Arguments : pevent is a pointer to the event control block associated with the desired
; * semaphore.
; *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -