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

📄 os_cpu_a.asm

📁 uCOS的移植代码,到80xc52系列单片机.
💻 ASM
字号:
; $Id:os_cpu_a.asm,
;
; Description:
;	uC/OS-51 - Assembler functions for 8XC52
;
; Author[s]:
;	Lucas Cruz Martos	<lcm@eresmas.net>
;
; Language:
;	BSO-Tasking ASM51 v5.0r2
;
; Reference:
;	MicroC/OS-II The Real Time Kernel Edit: R&D Books
;	Jean J. Labrosse
; ===========================================================================
$CASE

$INCLUDE(8051\REG52.INC)
NAME    UCOS_II52A

	; Make LINK51 complain if memory models are mixed up
	EXTRN	CODE(%MODEL)	

	; WARNING: the following macros, extern and global var definitions
	; must match with os_cpu_c.h, and ucos_ii.h:
	;
	;
	extrn   data(_OSIntNesting)	; UBYTE   _data OSIntNesting;
	extrn   data(_OSTCBCur)		; OS_TCB  _data *OSTCBCur;
	extrn   data(_OSTCBHighRdy)	; OS_TCB  _data *OSTCBHighRdy;
	extrn	data(_OSRunning)
	extrn	xdata(_OSPrioCur)
	extrn	xdata(_OSPrioHighRdy)
	;
	;;extrn	code(_?OSIntEnter)	; void OSIntEnter(void);
	extrn	code(_?OSIntExit)	; void OSIntExit(void);
	extrn  	code(_?OSTaskSwHook)	; void OSTaskSwHook(void);
	extrn	code(_?OSTimeTick)
	extrn	code(_?OSSerialISR)
	extrn	data(__SP)		; CC51 Virtual Stack Pointer
        extrn   idata(__STKSTART)

UCOS_II52A_DATA_SEG SEGMENT DATA
	RSEG UCOS_II52A_DATA_SEG
	public _OSTick
_OSTick:
	ds 1

; -------------------------------------------------------------------------
; Macros
; -------------------------------------------------------------------------

%*DEFINE (SAVE_ALL)
(
	; Save current task context
	;
	; PCL, PCH have already been pushed by lcall/interrupt
	;
	push psw		
	push acc
	push b
	push dpl
	push dph
	;
	push ar0
	push ar1
	push ar2
	push ar3
	push ar4
	push ar5
	push ar6
	push ar7
	;
	; --------------------------------
	; Save CC51 Virtual Stack Pointer
	;
	push __SP+1	; Stack pointer
	push __SP
	; --------------------------------
	;
	push sp
)
;
; Load a 16-bit variable into DPTR
;
%*DEFINE (LDPTR(value))
(
	mov dph, %value+0		; DPTR = %value
	mov dpl, %value+1
)
;
; Save DPTR into a 16-bit variable
;
%*DEFINE (SDPTR(value))
(
	mov %value+0, dph		; %value = DPTR
	mov %value+1, dpl
)
;
; Copy system stack to TCB stack
;
; Parameters:
;	DPTR:	beginning of TCB stack -1
;	R1:	beginning os system stack -1
;	R5:	number of bytes to copy
;
; Returns:
;	DPTR:	set at top of the TCB stack
;	R1:	set at top of system stack
;
; Modifies:
;	ACC DPTR R4
;
%*DEFINE (COPY_STK_TO_TCBSTK) LOCAL savestk2
(
; we copy the system stack to the TCB stack
	;
	mov	r4, ar5			; R4 = count
%savestk2:
	inc	r1
	inc	dptr
	mov	a, @r1
	movx	@dptr, a
	djnz	r4, %savestk2
)


; Copy TCB stack to system stack, then adjust SP accordingly
;
; Parameters:
;	DPTR:	beginning of TCB stack -1
;	R1:	beginning os system stack -1
;	R5:	number of bytes to copy
;
; Returns:
;	DPTR:	set at top of the TCB stack
;	R1:	set at top of the new system stack
;	SP:	set at top of the new system stack
;
; Modifies:
;	ACC R4
;
%*DEFINE (COPY_TCBSTK_TO_STK) LOCAL copystk1
(
	; We copy TCB stack to system stack, then adjust SP accordingly
	;
	mov r4, ar5			; R4 = count
%copystk1:
	inc dptr
	inc r1
	movx a, @dptr
	mov @r1, a
	djnz r4, %copystk1
	; Now R1 is the new task SP
	mov sp, r1
)

; Copy TCB's stack address
;
; Parameters:
;	DPTR:	TCB address
;
; Returns:
;	DPTR:	set at top of the TCB stack
;	R5:	number of bytes to copy
;
; Modifies:
;	ACC R4
;
%DEFINE (GETTCBSTKINFO)
(
	movx a, @dptr
	mov r0,a
	inc dptr
	movx a, @dptr
	mov r1, a
	mov dpl, r1
	mov dph, r0
; We get the number of bytes to copy from TCB's stack to system stack
	inc dptr
	movx a, @dptr
	mov r5, a	; number of bytes to copy
)

; Fixup field OSTCBCur->OSTCBStkPtr
;
; Modifies:
;	ACC R0 R1 DPTR
;
%*DEFINE (FIX_CUR_STKPTR)
(
	%LDPTR(__SP)
	; Fixup field OSTCBCur->OSTCBStkPtr
	;
	mov a, dpl
	clr c
	subb a, #01
	mov dpl, a
	mov a, dph
	subb a, #00
	mov dph, a

	mov	r0, dph			; R0,R1 = stk - 1
	mov	r1, dpl
	;
	%LDPTR(_OSTCBCur)
	;
	mov	a, r0
	movx	@dptr, a
	inc	dptr
	mov	a, r1
	movx	@dptr, a		; OSTCBCur->OSTCBStkPtr = stk
)

; -------------------------------------------------------------------------
; Start Multitasking
;
; 	void OSStartHighRdy(void)

UCOS_II52A_OSSTARTHIGHRDY_PR   SEGMENT CODE
	RSEG    UCOS_II52A_OSSTARTHIGHRDY_PR
	public  _?OSStartHighRdy

_?OSStartHighRdy:

	lcall _?OSTaskSwHook

_OSStartHighRdyGet:
; We get the stack pointer of the task to resume.
	%LDPTR(_OSTCBHighRdy)
	%GETTCBSTKINFO
	mov r1, #__STKSTART
	%COPY_TCBSTK_TO_STK

	mov a, _OSRunning
	clr c
	subb a, #01
	jz _resume
; OSTunning = TRUE
	inc _OSRunning

_resume:
; We restore all processor registers from the new task's stack.
_restore_context:
	; Restore task context
	;
	pop acc		; SP: discard it

	POP __SP			;Start restoring the context
	POP __SP+1	
	POP ar7
	POP ar6
	POP ar5
	POP ar4
	POP ar3
	POP ar2
	POP ar1
	POP ar0
	POP DPL
	POP DPH
	POP B
	POP ACC
	POP PSW

	setb ea			; Enable interrupts again

	RETI

; -------------------------------------------------------------------------
; Perform a context switch (from task level)
;
;	void OSCtxSw(void)

UCOS_II52A_OSCTXSW_PR   SEGMENT CODE
	RSEG    UCOS_II52A_OSCTXSW_PR
	public  _?OSCtxSw

_?OSCtxSw:
; We save processor registers
	%SAVE_ALL

_OSCtxSw2:
; We save the currest task's stack pointer into current task's OS_TCB
	mov a, sp
	clr c
	subb a, #__STKSTART
	mov r5, a	; number of bytes to copy
	mov r1, #__STKSTART 

	mov a, r5
	add a, #01
	mov r5, a
; Get the current xstack pointer
	%LDPTR(__SP)	
	
	mov a, dpl	; Adjust the xstack pointer
	clr c
	subb a, r5
	mov dpl, a
	mov a, dph
	subb a, #00
	mov dph, a

	mov a, r5
	clr c
	subb a, #01
	mov r5, a

; Save the current xstack pointer to __SP
	%SDPTR(__SP)

;;	mov a, r5	; Save the number of bytes saved
	movx @dptr, a
; We copy the system stack to task's stack
	%COPY_STK_TO_TCBSTK
; OSTCBCur->OSTCBStkPtr = Stack Pointer
	%FIX_CUR_STKPTR

	lcall _?OSTaskSwHook

; OSTCBCur = OSTCBHighRdy
	%LDPTR(_OSTCBHighRdy)
	%SDPTR(_OSTCBCur)
; OSPrioCur = OSPrioHighRdy
	mov dptr, #(_OSPrioHighRdy)
	movx a, @dptr
	mov dptr, #(_OSPrioCur)
	movx @dptr, a

; Get the stack pointer to resume
	ljmp _OSStartHighRdyGet


; -------------------------------------------------------------------------
; Perform a context switch (from an ISR)
;
; We assume that a SAVE_ALL macro
; has already been made by UCOS52_ISR.
;
;	void OSIntCtxSw(void)

UCOS_II52A_OSINTCTXSW_PR   SEGMENT CODE
	RSEG    UCOS_II52A_OSINTCTXSW_PR
	public  _?OSIntCtxSw

_?OSIntCtxSw:
	; Adjust the stack pointer to remove call to:
	;   - call to OSIntExit  (2 bytes)
	;   - call to OSIntCtxSw (2 bytes)
	;   - locals		 (0 bytes)
	;
	mov	a, sp
	clr	c
	subb	a, #4
	mov	sp, a

	ljmp _OSCtxSw2

;
;
; Ref.: uC/OS-II The Real Time Kernel. (Page 98)
;
UCOS_II52A_OSTICKISR_PR   SEGMENT CODE
	RSEG    UCOS_II52A_OSTICKISR_PR
	public  _?OSTickISR

_?OSTickISR:
;		  JNB     P3.5,OSTick2		;si el flag de break est

⌨️ 快捷键说明

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