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

📄 k51a1234.asm

📁 同事写的一个内核
💻 ASM
📖 第 1 页 / 共 3 页
字号:
    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 + -