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

📄 ucos-ii的移植代码 for 8051.txt

📁 uCOS-II的移植代码 for 8051
💻 TXT
📖 第 1 页 / 共 3 页
字号:
    ;?STACK:
    Stack:
    DS  40  

      EXTRN BIT   (OSRunning)
      EXTRN XDATA (OSIntNesting)
;      EXTRN XDATA (OSTickDOSCtr)
      EXTRN XDATA (OSPrioHighRdy)
      EXTRN XDATA (OSPrioCur)
    EXTRN XDATA (OSTCBCur)    
      EXTRN XDATA (OSTCBHighRdy)

;*******************************************************************************
*************************
;                        MACRO DEFINE
;*******************************************************************************
*************************
PUSHALL  MACRO
  ;PUSH  PC  
  PUSH  ACC
  PUSH  B
  PUSH  DPH
  PUSH  DPL
  PUSH  PSW
  IRP  REG,  <R7, R6, R5, R4, R3, R2, R1, R0>
  MOV  A,  REG
  PUSH  ACC
  ENDM
  ENDM

POPALL   MACRO
  IRP  REG,  <R0, R1, R2, R3, R4, R5, R6, R7>
  POP  ACC
  MOV  REG,  A
  ENDM
  POP  PSW
  POP  DPL
  POP  DPH
  POP  B
  POP  ACC
  ;RET/RETI
  ENDM

OS_ENTER_CRITICAL  MACRO
  MOV  B,IE        ;因为所有程序没有使用
B寄存器,所以使用了B寄存器作为IE暂存
  CLR  EA
  ENDM
OS_EXIT_CRITICAL  MACRO
  MOV  IE,B        ;因为所有程序没有使用
B寄存器,所以使用了B寄存器作为IE暂存
  ENDM
;*******************************************************************************
*************************
;                      供外部使用的函数
;*******************************************************************************
*************************
       PUBLIC  _?OSTickISR
       PUBLIC   _?OSStartHighRdy
       PUBLIC   _?OSCtxSw
       PUBLIC   _?OSIntCtxSw
/*$PAGE*/
;*******************************************************************************
*************************
;                  函数体段
;*******************************************************************************
*************************
;*******************************************************************************
**************************
;            用户中断程序区    之  定时器中断
1 OSISR_T1()
;*******************************************************************************
**************************
IF OS_ISR_T1_EN <> 0
    CSEG  AT   001BH    ;设置T0中断向量
    LJMP  _OSISR_T1

  ?PR?_OSISR_T1?OS_CPU_A       SEGMENT CODE
  RSEG  ?PR?_OSISR_T1?OS_CPU_A
_OSISR_T1:
  OS_ENTER_CRITICAL
  ;(1)保存处理器寄存器 先PUSH到SP在COPY到?C_XBP
  PUSHALL
  LCALL  _CopySPtoC_XBP      ;COPY SP 的内容到?
C_XBP

  ;(2)记忆中断的嵌套层OSIntNesting++  进入中断
  ;(3) if (OSIntNesting == 1)
  ;  OSTCBCur->OSTCBStkPtr <= ?C_XBP
  LCALL  _Enter_INT
  OS_EXIT_CRITICAL  

  ;(4)调用中断服务外挂
  LCALL  _?OSISR_T1HOOK      ;在这里进行中断服务

  OS_ENTER_CRITICAL
  ;(5) Call OSTimeTick();
  LCALL  _?OSTimeTick

  ;(6) Call OSIntExit();
  LCALL  _?OSIntExit

  ;(7) 恢复处理器寄存器      ;没有高优先级任务在就
绪队列中
  ;LCALL  _ComCtxSw2
  LCALL  _CopyC_XBPtoSP
  POPALL
  
  OS_EXIT_CRITICAL
  RETI
ENDIF
;*******************************************************************************
**************************
;            用户中断程序区    之  外部中断0 
OSISR_INT0()
;*******************************************************************************
**************************
IF OS_ISR_INT0_EN <> 0
    CSEG  AT   0003H    ;设置T0中断向量
    LJMP  _OSISR_INT0

  ?PR?_OSISR_INT0?OS_CPU_A       SEGMENT CODE
  RSEG  ?PR?_OSISR_INT0?OS_CPU_A
_OSISR_INT0:
  OS_ENTER_CRITICAL
  ;(1)保存处理器寄存器 先PUSH到SP在COPY到?C_XBP
  PUSHALL
  LCALL  _CopySPtoC_XBP      ;COPY SP 的内容到?
C_XBP

  ;(2)记忆中断的嵌套层OSIntNesting++  进入中断
  ;(3) if (OSIntNesting == 1)
  ;  OSTCBCur->OSTCBStkPtr <= ?C_XBP
  LCALL  _Enter_INT  
  OS_EXIT_CRITICAL
  
  ;(4)调用中断服务外挂
  LCALL  _?OSISR_INT0HOOK      ;在这里进行中断服务

  OS_ENTER_CRITICAL
  ;(5) Call OSTimeTick();
  LCALL  _?OSTimeTick

  ;(6) Call OSIntExit();
  LCALL  _?OSIntExit

  ;(7) 恢复处理器寄存器    ;没有高优先级任务在就绪队列中
  ;LCALL  _ComCtxSw2
  LCALL  _CopyC_XBPtoSP
  POPALL
  OS_EXIT_CRITICAL
  RETI
ENDIF
;*******************************************************************************
**************************
;            用户中断程序区    之  外部中断1 
OSISR_INT1()
;*******************************************************************************
**************************
IF OS_ISR_INT1_EN <> 0
    CSEG  AT   0013H    ;设置T0中断向量
    LJMP  _OSISR_INT1

  ?PR?_OSISR_INT1?OS_CPU_A       SEGMENT CODE
  RSEG  ?PR?_OSISR_INT1?OS_CPU_A
_OSISR_INT1:
  OS_ENTER_CRITICAL
  ;(1)保存处理器寄存器 先PUSH到SP在COPY到?C_XBP
  PUSHALL
  LCALL  _CopySPtoC_XBP      ;COPY SP 的内容到?
C_XBP

  ;(2)记忆中断的嵌套层OSIntNesting++  进入中断
  ;(3) if (OSIntNesting == 1)
  ;  OSTCBCur->OSTCBStkPtr <= ?C_XBP
  LCALL  _Enter_INT
  OS_EXIT_CRITICAL
  
  ;(4)调用中断服务外挂
  LCALL  _?OSISR_INT1HOOK      ;在这里进行中断服务

  OS_ENTER_CRITICAL
  ;(5) Call OSTimeTick();
  LCALL  _?OSTimeTick

  ;(6) Call OSIntExit();
  LCALL  _?OSIntExit

  ;(7) 恢复处理器寄存器    ;没有高优先级任务在就绪队列中
  ;LCALL  _ComCtxSw2
  LCALL  _CopyC_XBPtoSP
  POPALL
  OS_EXIT_CRITICAL
  RETI
ENDIF
;*******************************************************************************
**************************
;            用户中断程序区    之  串口中断0 
OSISR_S0()
;*******************************************************************************
**************************
IF OS_ISR_S0_EN <> 0
    CSEG  AT   0023H    ;设置T0中断向量
    LJMP  _OSISR_S0

  ?PR?_OSISR_S0?OS_CPU_A       SEGMENT CODE
  RSEG  ?PR?_OSISR_S0?OS_CPU_A
_OSISR_S0:
  OS_ENTER_CRITICAL
  ;(1)保存处理器寄存器 先PUSH到SP在COPY到?C_XBP
  PUSHALL
  LCALL  _CopySPtoC_XBP      ;COPY SP 的内容到?
C_XBP

  ;(2)记忆中断的嵌套层OSIntNesting++  进入中断
  ;(3) if (OSIntNesting == 1)
  ;  OSTCBCur->OSTCBStkPtr <= ?C_XBP
  LCALL  _Enter_INT
  OS_EXIT_CRITICAL
  
  ;(4)调用中断服务外挂
  LCALL  _?OSISR_S0HOOK      ;在这里进行中断服务

  OS_ENTER_CRITICAL
  ;(5) Call OSTimeTick();
  LCALL  _?OSTimeTick

  ;(6) Call OSIntExit();
  LCALL  _?OSIntExit

  ;(7) 恢复处理器寄存器    ;没有高优先级任务在就绪队列中
  ;LCALL  _ComCtxSw2
  LCALL  _CopyC_XBPtoSP
  POPALL

  OS_EXIT_CRITICAL
  RETI
ENDIF


[dvnews_page=OS_CPU_A.ASM之的内核代码部分1]


;*******************************************************************************
**************************
;                     START MULTITASKING
;                    void OSStartHighRdy(void) LG_REENTRANT
;出栈后就意味着启动了第一个任务
; The stack frame is assumed to look as follows:
;
;      出  /\      出栈:task
底\高     (高内存)
;      栈  ||      出栈:ACC
;      顺  ||      出栈:B
;      序  ||      出栈:DPH  
  //暂时忽略第二指针
;       |  ||  |    出栈:DPL
;       |     |    出栈:PSW
;       |______________|    出栈:R7-R4
;              出栈:
os_pdata(R3,R2,R1)用寄存器传递os_pdata
;      OSTCBHighRdy->OSTCBStkPtr -->  出栈:R0  
  (底内存)
;
; Note : OSStartHighRdy() MUST:
;      a) Call OSTaskSwHook() then,
;      b) Set OSRunning to TRUE,
;      c) Switch to the highest priority task.
;*******************************************************************************
**************************
  ?PR?_?OSStartHighRdy?OS_CPU_A   SEGMENT CODE   
            ;第3个问号表示重入函
  RSEG  ?PR?_?OSStartHighRdy?OS_CPU_A  ;函数体段

_?OSStartHighRdy:
  USING  0
  ;OS_ENTER_CRITICAL
  LCALL   _?OSTaskSwHook      ;调用OSTaskSwHook();
  SETB   OSRunning      ;OSRunning= TRUE;
  ;切换到最高优先级的任务
  JMP  CtxSw        ;MOV   ?C_XBP,0

;*******************************************************************************
**************************
;                PERFORM A CONTEXT SWITCH (From task level)
;                      void OSCtxSw(void)
;
; Note(s): 1) Upon entry,
;       OSTCBCur   points to the OS_TCB of the task to suspend
;       OSTCBHighRdy points to the OS_TCB of the task to resume
;
;     2) The stack frame of the task to suspend looks as follows:
;
;         SP -> OFFSET of task to suspend  (Low memory)
;            SEGMENT of task to suspend
;            PSW   of task to suspend  (High memory)
;
;     3) The stack frame of the task to resume looks as follows:
;
;    出  /\  用RET    出栈:task底\高地址   (高内存)
;    栈  ||      出栈:ACC
;    顺  ||      出栈:B
;    序  ||      出栈:DPH  
  //暂时忽略第二指针
;     |  ||  |    出栈:DPL
;     |     |    出栈:PSW
;     |______________|    出栈:R0
;            出栈:os_pdata
(R1,R2,R3)用寄存器传递os_pdata
;    OSTCBHighRdy->OSTCBStkPtr -->  出栈:R4-R7  
  (底内存)
;                        Flags to load in 
PSW       (High memory)
;任务级切换:
;1:PUSHALL
;2:?C_BXP<=(SP)
;3:OSTCBCur->OSTCBStkPtr<=?C_BXP
;4:  ...
;5:?C_BXP<=OSTCBHighRdy->OSTCBStkPtr
;6:(SP)<=?C_BXP
;7:POPALL
;8:RET
;*******************************************************************************
**************************
  ?PR?_?OSCtxSw?OS_CPU_A       SEGMENT CODE
  RSEG  ?PR?_?OSCtxSw?OS_CPU_A
_?OSCtxSw:
  USING  0
  ;OS_ENTER_CRITICAL
  ;(1)保存处理器的寄存器
  PUSHALL

  ;(2)拷贝SP(系统)堆栈中的内容到?C_XBP,    SP  满向上
    ;然后清空它(即MOV SP,#?STACK-1)      ?C_XBP  满向下
  LCALL  _CopySPtoC_XBP      ;COPY SP 的内容到?
C_XBP

  ;(3)在当前任务的任务控制块中保存当前任务(旧任务)的堆栈指针
    ;OSTCBCur->OSTCBStkPtr=?C_XBP
  MOV   DPH,#HIGH(OSTCBCur)
  MOV   DPL, #LOW(OSTCBCur)

  INC  DPTR        ;指针是3字节的
把我害死了
  MOVX  A,@DPTR
  MOV  R1,A
  INC  DPTR
  MOVX  A,@DPTR
  MOV  DPH,R1
  MOV  DPL,A

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -