📄 k51a1234.asm
字号:
clr task4_running
push psw
push acc
push b
push dpl
push dph
mov sp_task4, sp
jb acc.0, sig_send_active1
jb acc.1, sig_send_active2
;-----------------------------------------------------
; task4 can not send signal to itself, then the signal
; is send to task3.
;-----------------------------------------------------
sig_send_active3:
mov sp, sp_task3
setb task3_ready
setb task3_running
ljmp k51_wait_ret_task
;-----------------------------------------------------
sig_send_active1:
mov sp, sp_task1
setb task1_ready
setb task1_running
ljmp k51_wait_ret_task
;-----------------------------------------------------
sig_send_active2:
mov sp, sp_task2
setb task2_ready
setb task2_running
ljmp k51_wait_ret_task
;-----------------------------------------------------
; task1 has highest priority, signaled task is set to
; ready, but do not switch to it.
;-----------------------------------------------------
task1_send_sig:
jb acc.1, sig_send_rdy2
jb acc.2, sig_send_rdy3
sig_send_rdy4:
setb task4_ready
setb ea
ret
sig_send_rdy2:
setb task2_ready
setb ea
ret
sig_send_rdy3:
setb task3_ready
setb ea
ret
;-----------------------------------------------------
task2_send_sig:
jb acc.3, sig_send_rdy4
jb acc.2, sig_send_rdy3
sig_send_sw21:
push psw
push acc
push b
push dpl
push dph
mov sp_task2, sp
clr task2_running
sjmp sig_send_active1
;-----------------------------------------------------
task3_send_sig:
jb acc.3, sig_send_rdy4
push psw
push acc
push b
push dpl
push dph
mov sp_task3, sp
clr task3_running
jb acc.1, sig_send_active1
sjmp sig_send_active2
;-------------------------------------------------------------------------------
; void k51_signal_wait(unsigned char idata* p_obj)
; void k51_mutex_wait (unsigned char idata* p_obj)
; these 2 functions do the same thing.
; bit7 of obj indicates the object is signaled or available,
; bit0-3 indicates waiting tasks(task1-4). If it's a signal, only 1 task could
; be included in the list, if it's a mutex, every task is allowed.
;-------------------------------------------------------------------------------
_k51_mutex_wait:
_k51_signal_wait:
clr ea
mov a, r7
mov r0, a
mov a, @r0
jnb acc.7, k51_sig_wait_100
mov @r0, #0 ; signaled, do not need wait
; the signal is cleared
setb ea
ret
k51_sig_wait_100:
push psw
push acc
push b
push dpl
push dph
jbc task1_running, sig_wait_task1
jbc task2_running, sig_wait_task2
jbc task3_running, sig_wait_task3
;-----------------------------------------------------
; task4 will goto idle state, no task actives
;-----------------------------------------------------
sig_wait_task4:
clr task4_running
clr task4_ready
orl a, #8 ; waiting: task4
mov @r0, a
mov sp_task4, sp
sjmp k51_wait_go_idle ; no task actives
;-----------------------------------------------------
sig_wait_task1:
clr task1_running
clr task1_ready
orl a, #1 ; waiting: task1
mov @r0, a
mov sp_task1, sp
jb task2_ready, sigw_active_task2
jb task3_ready, sigw_active_task3
jb task4_ready, sigw_active_task4
sjmp k51_wait_go_idle ; no task actives
sigw_active_task2:
setb task2_running
mov sp, sp_task2
sjmp k51_wait_ret_task
;-----------------------------------------------------
sigw_active_task3:
setb task3_running
mov sp, sp_task3
sjmp k51_wait_ret_task
;-----------------------------------------------------
sigw_active_task4:
setb task4_running
mov sp, sp_task4
;-----------------------------------------------------
k51_wait_ret_task:
pop dph
pop dpl
pop b
pop acc
pop psw
setb ea
ret
;-----------------------------------------------------
sig_wait_task2:
clr task2_running
clr task2_ready
orl a, #2 ; waiting: task2
mov @r0, a
mov sp_task2, sp
jb task3_ready, sigw_active_task3
jb task4_ready, sigw_active_task4
sjmp k51_wait_go_idle ; no task actives
;-----------------------------------------------------
sig_wait_task3:
clr task3_running
clr task3_ready
orl a, #4 ; waiting: task3
mov @r0, a
mov sp_task3, sp
jb task4_ready, sigw_active_task4
; no task actives
k51_wait_go_idle:
mov sp, sp_task1 ; idle task use task1's stack
setb ea
ljmp k51_idle_task
IF MUTEX_ENABLE <> 0
;-------------------------------------------------------------------------------
; void k51_mutex_init(unsigned char idata* p_mut)
; { *p_mut = 0x80; /* available */ }
;-----------------------------------------------------
; The bit7 of a mutex indicates it's available.
; bit0-bit3 indicates tasks(1-4) are waiting for this mutex.
;-------------------------------------------------------------------------------
_k51_mutex_init:
mov a, r7
mov r0, a
mov @r0, #80h
ret
;-------------------------------------------------------------------------------
; void k51_mutex_release(unsigned char idata* p_mut)
; If any task is waiting for the mutex, the task with highest priority will
; be set to ready and remove to the wait list.
; If no task is waiting for it, the mutex is set to available state.
;-------------------------------------------------------------------------------
_k51_mutex_release:
clr ea
mov a, r7
mov r0, a
mov a, @r0
anl a, #0fh ; check task list
jnz mut_release_100
setb acc.7 ; no task is waiting, make it
mov @r0, a ; available and return.
setb ea
ret
mut_release_100:
jb task1_running, mut_rls_task1
jb task2_running, mut_rls_task2
jb task3_running, mut_rls_task3
;-----------------------------------------------------
; A task wait on the mutex will active, instead of task4.
;-----------------------------------------------------
mut_rls_task4:
clr task4_running ; running cleared. (ready still set)
push psw
push acc
push b
push dpl
push dph
mov sp_task4, sp ; make task's stack
jb acc.0, mut_rls_active1
jb acc.1, mut_rls_active2
;-----------------------------------------------------
; A task can not release a mutex to itself,
; so the waiting task must be task3.
;-----------------------------------------------------
mut_rls_active3:
anl a, #0fbh ; bit2 clear, task3 removed.
mov @r0, a
setb task3_ready
setb task3_running
mov sp, sp_task3
sjmp k51_wait_ret_task
;-----------------------------------------------------
mut_rls_active1:
anl a, #0feh ; bit0 clear, task1 removed.
mov @r0, a
setb task1_ready
setb task1_running
mov sp, sp_task1
sjmp k51_wait_ret_task
;-----------------------------------------------------
mut_rls_active2:
anl a, #0fdh ; bit1 clear, task2 removed.
mov @r0, a
setb task2_ready
setb task2_running
mov sp, sp_task2
ljmp k51_wait_ret_task
;-----------------------------------------------------
; task1 has highest priority, it release a mutex do
; not need to switch to another task.
;-----------------------------------------------------
mut_rls_task1:
jb acc.1, mut_rls_rdy2
jb acc.2, mut_rls_rdy3
mut_rls_rdy4:
anl a, #0f7h ; bit3 clear, task4 removed.
mov @r0, a
setb task4_ready
setb ea
ret
mut_rls_rdy2:
anl a, #0fdh ; bit1 clear, task2 removed.
mov @r0, a
setb task2_ready
setb ea
ret
mut_rls_rdy3:
anl a, #0fbh ; bit2 clear, task3 removed.
mov @r0, a
setb task3_ready
setb ea
ret
;-----------------------------------------------------
mut_rls_task2:
jb acc.0, mut_rls_sw21
jb acc.2, mut_rls_rdy3
sjmp mut_rls_rdy4
mut_rls_sw21:
push psw
push acc
push b
push dpl
push dph
mov sp_task2, sp
clr task2_running
sjmp mut_rls_active1
;-----------------------------------------------------
mut_rls_task3:
jb acc.0, mut_rls_sw31
jb acc.1, mut_rls_sw32
sjmp mut_rls_rdy4
mut_rls_sw31:
push psw
push acc
push b
push dpl
push dph
mov sp_task3, sp
clr task3_running
sjmp mut_rls_active1
mut_rls_sw32:
push psw
push acc
push b
push dpl
push dph
mov sp_task3, sp
clr task3_running
sjmp mut_rls_active2
;-------------------------------------------------------------------------------
ENDIF ; MUTEX_ENABEL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -