📄 os_cpu.rtf
字号:
;
; Arguments : none
;
; Returns : none
;
; Note(s) : The following C-like pseudo-code describe the operation being performed in the code below.
;
; Save all registers on the current task's stack;
; OSIntNesting++;
; OSTickDOSCtr--;
; if (OSTickDOSCtr == 0) {
; INT 81H; Chain into DOS every 54.925 mS
; (Interrupt will be cleared by DOS)
; } else {
; Send EOI to PIC; Clear tick interrupt by sending an End-Of-Interrupt to the 8259
; PIC (Priority Interrupt Controller)
; }
; OSTimeTick(); Notify uC/OS-II that a tick has occured
; OSIntExit(); Notify uC/OS-II about end of ISR
; Restore all registers that were save on the current task's stack;
; Return from Interrupt;
;*********************************************************************************************************
;
_OSTickISR PROC FAR
;
PUSHA ; Save interrupted task's context
PUSH ES
PUSH DS
;
MOV AX, SEG _OSTickDOSCtr ; Reload DS
MOV DS, AX
;
INC BYTE PTR _OSIntNesting ; Notify uC/OS-II of ISR
;
DEC BYTE PTR DS:_OSTickDOSCtr
CMP BYTE PTR DS:_OSTickDOSCtr, 0
JNE SHORT _OSTickISR1 ; 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 _OSTickISR2
_OSTickISR1:
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.
;
_OSTickISR2:
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
;
END
OS_CPU.H
#ifdef OS_CPU_GLOBALS
#define OS_CPU_EXT
#else
#define OS_CPU_EXT extern
#endif
*********************************************************************************************************
* DATA TYPES
*********************************************************************************************************
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U; /* Unsigned 8 bit quantity */
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
*********************************************************************************************************
* Intel 80x86 (Real-Mode, Large Model)
*Method #1: Disable/Enable interrupts using simple instructions. After critical section, interrupts
* will be enabled even if they were disabled before entering the critical section. You MUST
* change the constant in OS_CPU_A.ASM, function OSIntCtxSw() from 10 to 8.
*Method #2: Disable/Enable interrupts by preserving the state of interrupts. In other words, if
* interrupts were disabled before entering the critical section, they will be disabled when
* leaving the critical section. You MUST change the constant in OS_CPU_A.ASM, function
* OSIntCtxSw() from 8 to 10.
*********************************************************************************************************
#define OS_CRITICAL_METHOD 2
#if OS_CRITICAL_METHOD == 1
#define OS_ENTER_CRITICAL() asm CLI /* Disable interrupts */
#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 */
#define uCOS 0x80 /* Interrupt vector # used for context switch */
#define OS_TASK_SW() asm INT uCOS
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
OS_CPU_EXT INT8U OSTickDOSCtr; /* Counter used to invoke DOS's tick handler every 'n' ticks */
OS_CPU_C.C
#define OS_CPU_GLOBALS
#include "includes.h"
*********************************************************************************************************
* INITIALIZE A TASK'S STACK
* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the
* stack frame of the task being created. This function is highly processor specific.
*Arguments : task is a pointer to the task code
* pdata is a pointer to a user supplied data area that will be passed to the task
* when the task first executes.
* ptos is a pointer to the top of stack. It is assumed that 'ptos' points to
* a 'free' entry on the task stack. If OS_STK_GROWTH is set to 1 then
* 'ptos' will contain the HIGHEST valid address of the stack. Similarly, if
* OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address
* of the stack.
* opt specifies options that can be used to alter the behavior of OSTaskStkInit().
* (see uCOS_II.H for OS_TASK_OPT_???).
* Returns : Always returns the location of the new top-of-stack' once the processor registers have
* been placed on the stack in the proper order.
* Note(s) : Interrupts are enabled when your task starts executing. You can change this by setting the
* PSW to 0x0002 instead. In this case, interrupts would be disabled upon task startup. The
* application code would be responsible for enabling interrupts at the beginning of the task
* code. You will need to modify OSTaskIdle() and OSTaskStat() so that they enable
* interrupts. Failure to do this will make your system crash!
*********************************************************************************************************
void *OSTaskStkInit (void (*task)(void *pd), void *pdata, void *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 ((void *)stk);
}
#if OS_CPU_HOOKS_EN
*********************************************************************************************************
* TASK CREATION HOOK
* Description: This function is called when a task is created.
* Arguments : ptcb is a pointer to the task control block of the task being created.
* Note(s) : 1) Interrupts are disabled during this call.
*********************************************************************************************************
void OSTaskCreateHook (OS_TCB *ptcb)
{
ptcb = ptcb; /* Prevent compiler warning */
}
*********************************************************************************************************
* TASK DELETION HOOK
* Description: This function is called when a task is deleted.
* Arguments : ptcb is a pointer to the task control block of the task being deleted.
* Note(s) : 1) Interrupts are disabled during this call.
*********************************************************************************************************
void OSTaskDelHook (OS_TCB *ptcb)
{
ptcb = ptcb; /* Prevent compiler warning */
}
*********************************************************************************************************
* TASK SWITCH HOOK
* Description: This function is called when a task switch is performed. This allows you to perform other
* operations during a context switch.
* Note(s) : 1) Interrupts are disabled during this call.
* 2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that
* will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the
* task being switched out (i.e. the preempted task).
*********************************************************************************************************
void OSTaskSwHook (void){ }
*********************************************************************************************************
* STATISTIC TASK HOOK*
* Description: This function is called every second by uC/OS-II's statistics task. This allows your
* application to add functionality to the statistics task.
*********************************************************************************************************
void OSTaskStatHook (void){ }
*********************************************************************************************************
* TICK HOOK
*Description: This function is called every tick.*
* Note(s) : 1) Interrupts may or may not be ENABLED during this call.
*********************************************************************************************************
void OSTimeTickHook (void){ }
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -