Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 14 80x86, Large Model Port Porting to real mode and for the large model –Real mode: 1Mb memory space (pointers in this model require 32 bits) –In.

Similar presentations


Presentation on theme: "Chapter 14 80x86, Large Model Port Porting to real mode and for the large model –Real mode: 1Mb memory space (pointers in this model require 32 bits) –In."— Presentation transcript:

1 Chapter 14 80x86, Large Model Port Porting to real mode and for the large model –Real mode: 1Mb memory space (pointers in this model require 32 bits) –In real mode, all registers are 16 bits wide, and they all need to be saved during a context switch

2 80x86 real-mode register map

3 How to use 16-bit registers to access up to 1Mb memory

4 uC/OS-II Hardware/Software Architecture u u u Setting the value of 1 #define constants (OS_CPU.H) Declaring 10 data types (OS_CPU.H) Declaring 3 #define macros (OS_CPU.H) Writing 10 simple functions in C (OS_CPU_C.C) Writing 4 assembly language functions (OS_CPU_A.ASM)

5 OS_CPU.H #ifdef OS_CPU_GLOBALS #define OS_CPU_EXT #else #define OS_CPU_EXT extern #endif /* *************************************************************************** * DATA TYPES * (Compiler Specific) *************************************************************************** */ typedef unsigned char BOOLEAN; typedef unsigned char INT8U; /* Unsigned 8 bit quantity */ (1) typedef signed char INT8S; /* Signed 8 bit quantity */ typedef unsigned int INT16U; /* Unsigned 16 bit quantity */ typedef signed int INT16S; /* Signed 16 bit quantity */ typedef unsigned long INT32U; /* Unsigned 32 bit quantity */ typedef signed long INT32S; /* Signed 32 bit quantity */ typedef float FP32; /* Single precision floating point */ typedef double FP64; /* Double precision floating point */ typedef unsigned int OS_STK; /* Each stack entry is 16-bit wide */ #define BYTE INT8S /* Define data types for backward compatibility... */ #define UBYTE INT8U /*... to uC/OS V1.xx. Not actually needed for... */ #define WORD INT16S /*... uC/OS-II. */ #define UWORD INT16U #define LONG INT32S #define ULONG INT32U

6 #define OS_CRITICAL_METHOD 2 #if OS_CRITICAL_METHOD == 1 #define OS_ENTER_CRITICAL() asm CLI /* Disable interrupts */ (2) #define OS_EXIT_CRITICAL() asm STI /* Enable interrupts */ #endif #if OS_CRITICAL_METHOD == 2 #define OS_ENTER_CRITICAL() asm {PUSHF; CLI} /* Disable interrupts */ #define OS_EXIT_CRITICAL() asm POPF /* Enable interrupts */ #endif /* ***************************************************** * Intel 80x86 (Real-Mode, Large Model) Miscellaneous ***************************************************** */ #define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on 80x86 */ (3) #define uCOS 0x80 /* Interrupt vector # used for context switch */ (4) #define OS_TASK_SW() asm INT uCOS //vector to the assembly language function OSCtxSw() (5) /* *********************************************************** * GLOBAL VARIABLES ********************************************************** */ OS_CPU_EXT INT8U OSTickDOSCtr; /* Counter used to invoke DOS's tick handler every 'n' ticks */ (6) // the defualt tick rate is 18.2Hz. if we set the clock tick to 200Hz, this allow you to chain into DOS once every 11 ticks.

7 Context Switch In uC/OS-II, the stack frame for a ready task always looks as if an interrupt has just occurred and all processor registers were saved onto to it OS_TASk_SW() is always called from task-level code OSIntExit() is used to perform a context switch when an ISR makes a higher priority task ready for execution OS_CPU_A.ASM –OSStartHighRdy() –OSCtxSw() –OSIntCtxSw() –OSTickISR()

8 OSStartHighRdy(): called by OSStart() Void OSStartHighRdy(void) { call user definable OSTaskSwHook() Get the stack pointer of the task to resume: stack pointer = OSTCBHighRdy->OSTCBStkPtr; OSRunning = True; Restore all processor registers from the new task’s stack; Execute a return from interrupt instruction: } _OSStartHighRdy PROC FAR MOV AX, SEG _OSTCBHighRdy ; Reload DS MOV DS, AX ; LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy->OSTCBStkPtr (1) MOV SS, ES:[BX+2] ; //TCB data segment MOV SP, ES:[BX+0] ; //TCB address ; POP DS ; Load task's context (2) POP ES ; (3) POPA ; (4) ; IRET ; Run task (5) _OSStartHighRdy ENDP typedef struct os_tcb { OS_STK *OSTCBStkPtr;

9 80x86 stack frame when task is created

10 OSTaskStkInit() OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt) { INT16U *stk; opt = opt; /* 'opt' is not used, prevent warning */ stk = (INT16U *)ptos; /* Load stack pointer */ *stk-- = (INT16U)FP_SEG(pdata); /* Simulate call to function with argument */ *stk-- = (INT16U)FP_OFF(pdata); *stk-- = (INT16U)FP_SEG(task); *stk-- = (INT16U)FP_OFF(task); *stk-- = (INT16U)0x0202; /* SW = Interrupts enabled */ *stk-- = (INT16U)FP_SEG(task); /* Put pointer to task on top of stack */ *stk-- = (INT16U)FP_OFF(task); *stk-- = (INT16U)0xAAAA; /* AX = 0xAAAA */ *stk-- = (INT16U)0xCCCC; /* CX = 0xCCCC */ *stk-- = (INT16U)0xDDDD; /* DX = 0xDDDD */ *stk-- = (INT16U)0xBBBB; /* BX = 0xBBBB */ *stk-- = (INT16U)0x0000; /* SP = 0x0000 */ *stk-- = (INT16U)0x1111; /* BP = 0x1111 */ *stk-- = (INT16U)0x2222; /* SI = 0x2222 */ *stk-- = (INT16U)0x3333; /* DI = 0x3333 */ *stk-- = (INT16U)0x4444; /* ES = 0x4444 */ *stk = _DS; /* DS = Current value of DS */ return ((OS_STK *)stk); }

11 OSCtxSw(): a task call an OS kernel call =>OSSched() => select a highest priority => INT 80H => OSCtxSw() void OSCtxSw(void) { Save processor registers; Save the current task’s stack pointer into the current task’s OS_TCB: OSTCBCur->OSTCBStkPtr = Stack pointer; Call user definable OSTaskSwHook(); OSTCBCur = OSTCBHighRdy; OSPrioCur = OSPrioHighRdy; Get the stack pointer of the task to resume: Stack pointer = OSTCBHighRdy->OSTCBStkPtr; Restore all processor registers from the new task’s stack; Execute a return from interrupt instruction; }

12 80x86 stack frames during a task-level context switch

13 Listing 9.4 OSCtxSw() _OSCtxSw PROC FAR ; (1) ; PUSHA ; Save current task's context (2) PUSH ES ; (3) PUSH DS ; (4) ; MOV AX, SEG _OSTCBCur ; Reload DS in case it was altered MOV DS, AX ; ; LES BX, DWORD PTR DS:_OSTCBCur ; OSTCBCur->OSTCBStkPtr = SS:SP (5) MOV ES:[BX+2], SS ; MOV ES:[BX+0], SP ; store the suspended task’s SS and SP to OSTCBCur->OSTCBStkPtr ; CALL FAR PTR _OSTaskSwHook (6) ; MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ; OSTCBCur = OSTCBHighRdy (7) 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 (8) MOV BYTE PTR DS:_OSPrioCur, AL ; LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy->OSTCBStkPtr (9) MOV SS, ES:[BX+2] ; MOV SP, ES:[BX] ; ; POP DS ; Load new task's context (10) POP ES ; (11) POPA ; (12) ; IRET ; Return to new task (13) ; _OSCtxSw ENDP

14 OSIntCtxSw(): called by OSIntExit() 80x86 stack frames during an interrupt-level context switch

15 Pseudocode for OSIntCtxSw() void OSIntCtxSw(void) { Adjust the stack pointer to remove calls to: OSIntExit(), OSIntCtxSw() and possibly the push of the processor status word; Save the current task’s stack pointer into the current task’s OS_TCB: OSTCBCur->OSTCBStkPtr = Stack pointer; Call user definable OSTaskSwHook(); OSTCBCur = OSTCBHighRdy; OSPrioCur = OSPrioHighRdy; Get the stack pointer of the task to resume: Stack pointer = OSTCBHighRdy->OSTCBStkPtr; Restore all processor registers from the new task’s stack; Execute a return from interrupt instruction; }

16 OSIntCtxSw() _OSIntCtxSw PROC FAR ; ; Ignore calls to OSIntExit and OSIntCtxSw ; ADD SP,8 ; (Uncomment if OS_CRITICAL_METHOD is 1, see OS_CPU.H) (1) ADD SP,10 ; (Uncomment if OS_CRITICAL_METHOD is 2, see OS_CPU.H) ; MOV AX, SEG _OSTCBCur ; Reload DS in case it was altered MOV DS, AX ; ; LES BX, DWORD PTR DS:_OSTCBCur ; OSTCBCur->OSTCBStkPtr = SS:SP (2) MOV ES:[BX+2], SS ; MOV ES:[BX+0], SP ; ; CALL FAR PTR _OSTaskSwHook (3) ; MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ; OSTCBCur = OSTCBHighRdy (4) 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 (5) MOV BYTE PTR DS:_OSPrioCur, AL ; LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy->OSTCBStkPtr (6) MOV SS, ES:[BX+2] ; MOV SP, ES:[BX] ; ; POP DS ; Load new task's context (7) POP ES ; (8) POPA ; (9) ; IRET ; Return to new task (10) ; _OSIntCtxSw ENDP

17 OSTickISR() Figure 9.6 The PC interrupt vector table (IVT)

18 Pseudocode for tick ISR void OSTickISR (void) { Save processor registers; (1) OSIntNesting++; (2) if (OSIntNesting == 1) { OSTCBCur->OSTCBStkPtr = SS:SP; } OSTickDOSCtr—-; (3) if (OSTickDOSCtr == 0) { OSTickDOSCTR = 11; INT 81H; (4) } else { Send EOI command to PIC (Priority Interrupt Controller); (5) } OSTimeTick(); (6) OSIntExit(); (7) Restore processor registers; (8) Execute a return from interrupt instruction (IRET); (9) }

19 Listing 9.7 OSTickISR() _OSTickISR PROC FAR PUSHA ; Save interrupted task's context PUSH ES PUSH DS ; MOV AX, SEG(_OSIntNesting) ; Reload DS MOV DS, AX INC BYTE PTR DS:_OSIntNesting ; Notify uC/OS-II of ISR ; CMP BYTE PTR DS:_OSIntNesting, 1 ; if (OSIntNesting == 1) JNE SHORT _OSTickISR1 MOV AX, SEG(_OSTCBCur) ; Reload DS MOV DS, AX 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 ; Process system tick CALL FAR PTR _OSIntExit ; Notify uC/OS-II of end of ISR POP DS ; Restore interrupted task's context POP ES POPA IRET ; Return to interrupted task ; _OSTickISR ENDP


Download ppt "Chapter 14 80x86, Large Model Port Porting to real mode and for the large model –Real mode: 1Mb memory space (pointers in this model require 32 bits) –In."

Similar presentations


Ads by Google