uC/OS-II源码解析(os_cpu_a.asm)
2017-05-19 14:24
471 查看
;********************************************************************************** ;* ;*ver : 2.52 ;* file : os_cpu_a.asm ;* brief : 处理器相关汇编文件 ;* ;*********************************************************************************** ;*********************************************************************************** ; 声明&定义 ;*********************************************************************************** PUBLIC _OSTickISR ;时钟节拍中断服务函数 PUBLIC _OSStartHighRdy ;最高优先级任务就绪函数 PUBLIC _OSCtxSw ;任务级的上下文切换 PUBLIC _OSIntCtxSw ;中断级的上下文切换 EXTRN _OSIntExit:FAR ;声明函数OSIntExit() EXTRN _OSTimeTick:FAR ;声明函数OSTimeTick() EXTRN _OSTaskSwHook:FAR ;声明函数OSTaskSwHook() EXTRN _OSIntNesting:BYTE ;声明变量OSIntNesting EXTRN _OSTickDOSCtr:BYTE ;声明变量OSTickDOSCtr EXTRN _OSPrioHighRdy:BYTE ;声明变量OSPrioHighRdy EXTRN _OSPrioCur:BYTE ;声明变量OSPrioCur EXTRN _OSRunning:BYTE ;声明变量OSRunning EXTRN _OSTCBCur:DWORD ;声明变量OSTCBCur EXTRN _OSTCBHighRdy:DWORD ;声明变量OSTCBHighRdy .MODEL LARGE .CODE .186 PAGE ; /*$PAGE*/ ;************************************************************************************ ; 就绪态最高优先级任务启动函数 ; void OSStartHighRdy(void) ; ; 堆栈结构如下 : ; ; OSTCBHighRdy->OSTCBStkPtr --> DS (低地址) ; ES ; DI ; SI ; BP ; SP ; BX ; DX ; CX ; AX ; OFFSET of task code address ; SEGMENT of task code address ; Flags to load in PSW ; OFFSET of task code address ; SEGMENT of task code address ; OFFSET of 'pdata' ; SEGMENT of 'pdata' (高地址) ; ; Note : OSStartHighRdy() 示意性代码: ; a) 调用OSTaskSwHook(), ; b) OSRunning = TRUE, ; c) 得到将要恢复运行任务的堆栈指针, ; Stack pointer = OSTCBHighRdy->OSTCBStkPtr; ; d) 从新任务的堆栈中恢复处理器的所有寄存器 ; f) 执行中断返回指令 ;************************************************************************************** _OSStartHighRdy PROC FAR MOV AX, SEG _OSTCBHighRdy ; MOV DS, AX ; ; CALL FAR PTR _OSTaskSwHook ; 调用用户自定义函数 OSTaskSwHook() ; MOV AL, 1 ; 置变量 OSRunning 为 TRUE MOV BYTE PTR DS:_OSRunning, AL ; 表明多任务已经启动 ; 得到待运行任务的堆栈指针 LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy->OSTCBStkPtr MOV SS, ES:[BX+2] ; MOV SP, ES:[BX+0] ; ; POP DS ; 弹出寄存器 POP ES ; 必须按照OSTaskStkInit()中相反方向弹出 POPA ; ; IRET ; 中断返回弹出程序指针、状态寄存器 _OSStartHighRdy ENDP PAGE ; /*$PAGE*/ ;**************************************************************************************** ; 任务切换 (任务级) ; void OSCtxSw(void) ; ; Note(s) : 示意性代码如下: ; 1) 保存处理器寄存器 ; 2) 在当前任务的TCB中保存当前任务的堆栈指针 ; OSTCBCur->OSTCBStkPtr = Stack pointer ; 3) OSTaskSwHook() ; 4) OSTCBCur = OSTCBHighRdy ; 5) OSPrioCur = OSPrioHighRdy ; 6) 得到将要开始重新运行的任务的堆栈指针 ; Stack pointer = OSTCBHighRdy->OSTCBStkPtr; ; 7) 从新任务的任务堆栈中恢复处理器所有寄存器的值 ; 8) 执行中断返回指令 ; ;**************************************************************************************** _OSCtxSw PROC FAR ; PUSHA ; 保存处理器寄存器 PUSH ES ; PUSH DS ; ; MOV AX, SEG _OSTCBCur ; Reload DS in case it was altered MOV DS, AX ; ; 将堆栈指针保存在任务控制块中 LES BX, DWORD PTR DS:_OSTCBCur ; OSTCBCur->OSTCBStkPtr = SS:SP MOV ES:[BX+2], SS ; MOV ES:[BX+0], SP ; ; CALL FAR PTR _OSTaskSwHook ; 调用用户自定义函数OSTaskSwHook() ; 新任务控制块赋值给当前任务控制块 MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ; OSTCBCur = OSTCBHighRdy MOV DX, WORD PTR DS:_OSTCBHighRdy ; MOV WORD PTR DS:_OSTCBCur+2, AX ; MOV WORD PTR DS:_OSTCBCur, DX ; ; 新任务优先级赋值给当前任务优先级 MOV AL, BYTE PTR DS:_OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy MOV BYTE PTR DS:_OSPrioCur, AL ; ; 得到新的任务堆栈指针 LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy->OSTCBStkPtr MOV SS, ES:[BX+2] ; MOV SP, ES:[BX] ; ; POP DS ; 从新任务堆栈中恢复cpu寄存器 POP ES ; POPA ; ; IRET ; 中断返回指令,弹出程序指针和状态寄存器 ; _OSCtxSw ENDP PAGE ; /*$PAGE*/ ;**************************************************************************************** ; 任务切换 (中断级) ; void OSIntCtxSw(void) ; ; Note(s): 示意性代码如下: ; 1) 调用用户自定义 OSTaskSwHook() ; 2) OSTCBCur = OSTCBHighRdy ; 3) OSPrioCur = OSPrioHighRdy ; 4) 得到将要重新执行的任务的堆栈指针 ; Stack pointer = OSTCBHighRdy->OSTCBStkPtr ; 5) 从新任务的堆栈中恢复所有处理器寄存器 ; 6) 执行中断返回指令 ;***************************************************************************************** _OSIntCtxSw PROC FAR ; CALL FAR PTR _OSTaskSwHook ; 调用用户自定义函数OSTaskSwHook() ; MOV AX, SEG _OSTCBCur ; MOV DS, AX ; ; 新任务控制块赋值给当前任务控制块 MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ; OSTCBCur = OSTCBHighRdy MOV DX, WORD PTR DS:_OSTCBHighRdy ; MOV WORD PTR DS:_OSTCBCur+2, AX ; MOV WORD PTR DS:_OSTCBCur, DX ; ; 新任务优先级赋值给当前任务优先级 MOV AL, BYTE PTR DS:_OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy MOV BYTE PTR DS:_OSPrioCur, AL ; 得到将要重新运行的任务堆栈指针 LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy->OSTCBStkPtr MOV SS, ES:[BX+2] ; MOV SP, ES:[BX] ; ; POP DS ; 从新任务堆栈中恢复所有处理器寄存器 POP ES ; POPA ; ; IRET ; 执行中断返回指令弹出程序指针和状态寄存器 ; _OSIntCtxSw ENDP PAGE ; /*$PAGE*/ ;***************************************************************************************** ; 时钟节拍中断服务子程序 ; ; brief : _OSTickISR1和_OSTickISR2是和PC DOS相关的操作,无需关注 ; ; Note(s) : 需要关注的示意性代码如下: ; ; 保存处理器寄存器; ; 调用OSIntEnter()或者直接给OSIntNexting加1 ; if (OSIntNesting == 1) { ; OSTCBCur->OSTCBStkPtr = Stack pointer ; } ; 给产生中断的设备清中断 ; 重新允许中断(可选) ; OSTimeTick(); ; OSIntExit(); ; 恢复处理器寄存器 ; 执行中断返回指令 ;****************************************************************************************** ; _OSTickISR PROC FAR ; PUSHA ; 保存处理器寄存器 PUSH ES PUSH DS ; MOV AX, SEG(_OSIntNesting) ; MOV DS, AX INC BYTE PTR DS:_OSIntNesting ; OSIntNesting加1 ; CMP BYTE PTR DS:_OSIntNesting, 1 ; if (OSIntNesting == 1) JNE SHORT _OSTickISR1 MOV AX, SEG(_OSTCBCur) ; MOV DS, AX ; 堆栈指针保存到TCB中 LES BX, DWORD PTR DS:_OSTCBCur ; OSTCBCur->OSTCBStkPtr = SS:SP MOV ES:[BX+2], SS ; MOV ES:[BX+0], SP ; ; _OSTickISR1: MOV AX, SEG(_OSTickDOSCtr) ; Reload DS MOV DS, AX DEC BYTE PTR DS:_OSTickDOSCtr CMP BYTE PTR DS:_OSTickDOSCtr, 0 JNE SHORT _OSTickISR2 ; Every 11 ticks (~199.99 Hz), chain into DOS ; MOV BYTE PTR DS:_OSTickDOSCtr, 11 INT 081H ; Chain into DOS's tick ISR JMP SHORT _OSTickISR3 _OSTickISR2: MOV AL, 20H ; Move EOI code into AL. MOV DX, 20H ; Address of 8259 PIC in DX. OUT DX, AL ; Send EOI to PIC if not processing DOS timer. ; _OSTickISR3: CALL FAR PTR _OSTimeTick ; 调用 OSTimeTick() ; CALL FAR PTR _OSIntExit ; 调用 OSInitExit() ; POP DS ; 恢复处理器寄存器 POP ES POPA ; IRET ; 中断返回弹出程序指针和状态寄存器 _OSTickISR ENDP ; END
相关文章推荐
- uC/OS-II源码解析(os_cpu_c.c)
- uC/OS-II源码解析(os_cpu.h)
- uC/OS-II源码解析(os_q.c)
- uC/OS-II源码解析(os_sem.c)
- uC/OS-II源码解析(includes.h)
- uC/OS-II源码解析(os_cfg.h)
- uC/OS-II源码解析(os_mbox.c)
- uC/OS-II源码解析(os_mutex.c)
- uC/OS-II源码解析(os_mem.c)
- uC/OS-II源码解析(os_time.c)
- uC/OS-II源码解析(os_core.c)
- uC/OS-II源码解析(ucos_ii.c)
- uC/OS-II源码解析(os_task.c)
- uc/os-II 源码剖析笔记(1)——几个OS相关的基本概念(二)
- uC/OS-II源码分析(一)
- 【专题】uC/OS-II内核架构解析(5)---uC/OS-II通信与同步
- uC/OS-II源码分析(总体思路 三)
- uc/os-II 源码剖析笔记(1)——几个RTOS里面的基本概念(一)
- uC/OS-II源码分析(总体思路 二)
- 【专题】uC/OS-II内核架构解析(3)---uC/OS-II系统核心