📄 os_flag.s
字号:
; *
; * Returns : A pointer to an event flag group or a NULL pointer if no more groups are available.
; *
; * Called from: Task ONLY
; *********************************************************************************************************
; */
;
; OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags, INT8U *err)
; {
.dbline 201
; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; OS_CPU_SR cpu_sr;
; #endif
; OS_FLAG_GRP *pgrp;
;
;
; if (OSIntNesting > 0) { /* See if called from ISR ... */
clr R2
lds R3,_OSIntNesting
cp R2,R3
brsh L34
.dbline 201
.dbline 202
; *err = OS_ERR_CREATE_ISR; /* ... can't CREATE from an ISR */
ldi R24,141
movw R30,R18
std z+0,R24
.dbline 203
; return ((OS_FLAG_GRP *)0);
clr R16
clr R17
xjmp L33
L34:
.dbline 205
; }
; OS_ENTER_CRITICAL();
st -y,r16
in r16,0x3F
cli
push r16
ld r16,y+
.dbline 205
.dbline 206
; pgrp = OSFlagFreeList; /* Get next free event flag */
lds R20,_OSFlagFreeList
lds R21,_OSFlagFreeList+1
.dbline 207
; if (pgrp != (OS_FLAG_GRP *)0) { /* See if we have event flag groups available */
cpi R20,0
cpc R20,R21
breq L36
X5:
.dbline 207
.dbline 209
; /* Adjust free list */
; OSFlagFreeList = (OS_FLAG_GRP *)OSFlagFreeList->OSFlagWaitList;
lds R30,_OSFlagFreeList
lds R31,_OSFlagFreeList+1
ldd R2,z+1
ldd R3,z+2
sts _OSFlagFreeList+1,R3
sts _OSFlagFreeList,R2
.dbline 210
; pgrp->OSFlagType = OS_EVENT_TYPE_FLAG; /* Set to event flag group type */
ldi R24,5
movw R30,R20
std z+0,R24
.dbline 211
; pgrp->OSFlagFlags = flags; /* Set to desired initial value */
std z+3,R16
.dbline 212
; pgrp->OSFlagWaitList = (void *)0; /* Clear list of tasks waiting on flags */
clr R2
clr R3
movw R30,R20
std z+2,R3
std z+1,R2
.dbline 213
; OS_EXIT_CRITICAL();
st -y,r16
pop r16
out 0x3F,r16
ld r16,y+
.dbline 213
.dbline 214
; *err = OS_NO_ERR;
movw R30,R18
std z+0,R2
.dbline 215
xjmp L37
L36:
.dbline 215
; } else {
.dbline 216
; OS_EXIT_CRITICAL();
st -y,r16
pop r16
out 0x3F,r16
ld r16,y+
.dbline 216
.dbline 217
; *err = OS_FLAG_GRP_DEPLETED;
ldi R24,154
movw R30,R18
std z+0,R24
.dbline 218
; }
L37:
.dbline 219
; return (pgrp); /* Return pointer to event flag group */
movw R16,R20
.dbline -2
L33:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r pgrp 20 pS[.1]
.dbsym r err 18 pc
.dbsym r flags 16 c
.dbend
.dbfunc e OSFlagDel _OSFlagDel fpS[.1]
.dbstruct 0 10 .2
.dbfield 0 OSFlagNodeNext pV
.dbfield 2 OSFlagNodePrev pV
.dbfield 4 OSFlagNodeTCB pV
.dbfield 6 OSFlagNodeFlagGrp pV
.dbfield 8 OSFlagNodeFlags c
.dbfield 9 OSFlagNodeWaitType c
.dbend
; tasks_waiting -> R10
; pnode -> R12,R13
; err -> R22,R23
; opt -> R12
; pgrp -> R20,R21
.even
_OSFlagDel::
xcall push_gset4
mov R12,R18
movw R20,R16
ldd R22,y+8
ldd R23,y+9
.dbline -1
.dbline 261
; }
;
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * DELETE AN EVENT FLAG GROUP
; *
; * Description: This function deletes an event flag group and readies all tasks pending on the event flag
; * group.
; *
; * Arguments : pgrp is a pointer to the desired event flag group.
; *
; * opt determines delete options as follows:
; * opt == OS_DEL_NO_PEND Deletes the event flag group ONLY if no task pending
; * opt == OS_DEL_ALWAYS Deletes the event flag group even if tasks are
; * waiting. In this case, all the tasks pending will be
; * readied.
; *
; * err is a pointer to an error code that can contain one of the following values:
; * OS_NO_ERR The call was successful and the event flag group was
; * deleted
; * OS_ERR_DEL_ISR If you attempted to delete the event flag group from
; * an ISR
; * OS_FLAG_INVALID_PGRP If 'pgrp' is a NULL pointer.
; * OS_ERR_EVENT_TYPE If you didn't pass a pointer to an event flag group
; * OS_ERR_INVALID_OPT An invalid option was specified
; * OS_ERR_TASK_WAITING One or more tasks were waiting on the event flag
; * group.
; *
; * Returns : pevent upon error
; * (OS_EVENT *)0 if the semaphore was successfully deleted.
; *
; * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
; * the event flag group MUST check the return code of OSFlagAccept() and OSFlagPend().
; * 2) This call can potentially disable interrupts for a long time. The interrupt disable
; * time is directly proportional to the number of tasks waiting on the event flag group.
; *********************************************************************************************************
; */
;
; #if OS_FLAG_DEL_EN > 0
; OS_FLAG_GRP *OSFlagDel (OS_FLAG_GRP *pgrp, INT8U opt, INT8U *err)
; {
.dbline 269
; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; OS_CPU_SR cpu_sr;
; #endif
; BOOLEAN tasks_waiting;
; OS_FLAG_NODE *pnode;
;
;
; if (OSIntNesting > 0) { /* See if called from ISR ... */
clr R2
lds R3,_OSIntNesting
cp R2,R3
brsh L39
.dbline 269
.dbline 270
; *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
ldi R24,140
movw R30,R22
std z+0,R24
.dbline 271
; return (pgrp);
movw R16,R20
xjmp L38
L39:
.dbline 274
; }
; #if OS_ARG_CHK_EN > 0
; if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */
cpi R20,0
cpc R20,R21
brne L41
X6:
.dbline 274
.dbline 275
; *err = OS_FLAG_INVALID_PGRP;
ldi R24,150
movw R30,R22
std z+0,R24
.dbline 276
; return (pgrp);
movw R16,R20
xjmp L38
L41:
.dbline 278
; }
; if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event group type */
movw R30,R20
ldd R24,z+0
cpi R24,5
breq L43
.dbline 278
.dbline 279
; *err = OS_ERR_EVENT_TYPE;
ldi R24,1
movw R30,R22
std z+0,R24
.dbline 280
; return (pgrp);
movw R16,R20
xjmp L38
L43:
.dbline 283
; }
; #endif
; OS_ENTER_CRITICAL();
st -y,r16
in r16,0x3F
cli
push r16
ld r16,y+
.dbline 283
.dbline 284
; if (pgrp->OSFlagWaitList != (void *)0) { /* See if any tasks waiting on event flags */
movw R30,R20
ldd R2,z+1
ldd R3,z+2
tst R2
brne X7
tst R3
breq L45
X7:
.dbline 284
.dbline 285
; tasks_waiting = TRUE; /* Yes */
clr R10
inc R10
.dbline 286
xjmp L46
L45:
.dbline 286
; } else {
.dbline 287
; tasks_waiting = FALSE; /* No */
clr R10
.dbline 288
; }
L46:
.dbline 289
clr R13
tst R12
brne X8
tst R13
breq L50
X8:
movw R24,R12
cpi R24,1
ldi R30,0
cpc R25,R30
breq L53
xjmp L47
X9:
.dbline 289
; switch (opt) {
L50:
.dbline 291
; case OS_DEL_NO_PEND: /* Delete group if no task waiting */
; if (tasks_waiting == FALSE) {
tst R10
brne L51
.dbline 291
.dbline 292
; pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED;
clr R2
movw R30,R20
std z+0,R2
.dbline 293
; pgrp->OSFlagWaitList = (void *)OSFlagFreeList; /* Return group to free list */
lds R2,_OSFlagFreeList
lds R3,_OSFlagFreeList+1
std z+2,R3
std z+1,R2
.dbline 294
; OSFlagFreeList = pgrp;
sts _OSFlagFreeList+1,R21
sts _OSFlagFreeList,R20
.dbline 295
; OS_EXIT_CRITICAL();
st -y,r16
pop r16
out 0x3F,r16
ld r16,y+
.dbline 295
.dbline 296
; *err = OS_NO_ERR;
clr R2
movw R30,R22
std z+0,R2
.dbline 297
; return ((OS_FLAG_GRP *)0); /* Event Flag Group has been deleted */
clr R16
clr R17
xjmp L38
L51:
.dbline 298
; } else {
.dbline 299
; OS_EXIT_CRITICAL();
st -y,r16
pop r16
out 0x3F,r16
ld r16,y+
.dbline 299
.dbline 300
; *err = OS_ERR_TASK_WAITING;
ldi R24,8
movw R30,R22
std z+0,R24
.dbline 301
; return (pgrp);
movw R16,R20
xjmp L38
L53:
.dbline 305
; }
;
; case OS_DEL_ALWAYS: /* Always delete the event flag group */
; pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;
movw R30,R20
ldd R12,z+1
ldd R13,z+2
xjmp L55
L54:
.dbline 306
.dbline 307
clr R18
movw R16,R12
xcall _OS_FlagTaskRdy
.dbline 308
movw R30,R12
ldd R12,z+0
ldd R13,z+1
.dbline 309
L55:
.dbline 306
; while (pnode != (OS_FLAG_NODE *)0) { /* Ready ALL tasks waiting for flags */
tst R12
brne L54
tst R13
brne L54
X10:
.dbline 310
; OS_FlagTaskRdy(pnode, (OS_FLAGS)0);
; pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;
; }
; pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED;
clr R2
movw R30,R20
std z+0,R2
.dbline 311
; pgrp->OSFlagWaitList = (void *)OSFlagFreeList;/* Return group to free list */
lds R2,_OSFlagFreeList
lds R3,_OSFlagFreeList+1
std z+2,R3
std z+1,R2
.dbline 312
; OSFlagFreeList = pgrp;
sts _OSFlagFreeList+1,R21
sts _OSFlagFreeList,R20
.dbline 313
; OS_EXIT_CRITICAL();
st -y,r16
pop r16
out 0x3F,r16
ld r16,y+
.dbline 313
.dbline 314
; if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiting */
mov R24,R10
cpi R24,1
brne L57
.dbline 314
.dbline 315
; OS_Sched(); /* Find highest priority task ready to run */
xcall _OS_Sched
.dbline 316
; }
L57:
.dbline 317
; *err = OS_NO_ERR;
clr R2
movw R30,R22
std z+0,R2
.dbline 318
; return ((OS_FLAG_GRP *)0); /* Event Flag Group has been deleted */
clr R16
clr R17
xjmp L38
L47:
.dbline 321
;
; default:
; OS_EXIT_CRITICAL();
st -y,r16
pop r16
out 0x3F,r16
ld r16,y+
.dbline 321
.dbline 322
; *err = OS_ERR_INVALID_OPT;
ldi R24,7
movw R30,R22
std z+0,R24
.dbline 323
; return (pgrp);
movw R16,R20
.dbline -2
L38:
xcall pop_gset4
.dbline 0 ; func end
ret
.dbsym r tasks_waiting 10 c
.dbsym r pnode 12 pS[.2]
.dbsym r err 22 pc
.dbsym r opt 12 c
.dbsym r pgrp 20 pS[.1]
.dbend
.dbfunc e OSFlagPend _OSFlagPend fc
; node -> y+6
; flags_rdy -> R10
; consume -> R14
; flags_cur -> R20
; err -> R22,R23
; timeout -> y+30
; wait_type -> R12
; flags -> y+26
; pgrp -> R6,R7
.even
_OSFlagPend::
st -y,r19
st -y,r18
xcall push_gset5
movw R6,R16
sbiw R28,16
ldd R12,y+28
ldd R22,y+32
ldd R23,y+33
.dbline -1
.dbline 378
; }
; }
; #endif
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * WAIT ON AN EVENT FLAG GROUP
; *
; * Description: This function is called to wait for a combination of bits to be set in an event flag
; * group. Your application can wait for ANY bit to be set or ALL bits to be set.
; *
; * Arguments : pgrp is a pointer to the desired event flag group.
; *
; * flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to wait for.
; * The bits you want are specified by setting the corresponding bits in
; * 'flags'. e.g. if your application wants to wait for bits 0 and 1 then
; * 'flags' would contain 0x03.
; *
; * wait_type specifies whether you want ALL bits to be set or ANY of the bits to be set.
; * You can specify the following argument:
; *
; * OS_FLAG_WAIT_CLR_ALL You will wait for ALL bits in 'mask' to be clear (0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -