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

📄 os_cpu_a.asm

📁 做DSP最应该懂得157个问题(回答).
💻 ASM
字号:

	.def	_OSCtxSw, _OSIntCtxSw;
	.def	_OSStartHighRdy;
	.def	_OSTaskStkInit; 

	.mmregs 
;**************** Context save and restore macros ************
;
;  order must be the same as the compiler generated 
;  ISR context save/restores
; 
;**************************************************************
CONTEXT_SAVE .macro
        PSHM      AL;
        PSHM      AH;
        PSHM      AG;
        PSHM      BL;
        PSHM      BH;
        PSHM      BG;
        PSHM      AR0;
        PSHM      AR1;
        PSHM      AR2;
        PSHM      AR3;
        PSHM      AR4;
        PSHM      AR5;
        PSHM      AR6;
        PSHM      AR7;
        PSHM      AR7;	 a bug in C compiler, ended up as AR7
        PSHM      BK;
        PSHM      T;
        PSHM      ST0;
        PSHM      ST1;
        PSHM      BRC;
        PSHM      PMST;
        PSHM      RSA;
        PSHM      REA;
;		PSHM	  IMR;  C compiler dosn't generate this, need to add if the context save is done by C compiler
	.endm
	
CONTEXT_RESTORE .macro
;		POPM	  IMR;  C compiler doesn't generate this.
        POPM      REA;
        POPM      RSA;
        POPM      PMST;
        POPM      BRC;
        POPM      ST1;
        POPM      ST0;
        POPM      T;
        POPM      BK;
        POPM      AR7;	A bug in C compiler, no FP for C54x. ended up as AR7
        POPM      AR7;
        POPM      AR6;
        POPM      AR5;
        POPM      AR4;
        POPM      AR3;
        POPM      AR2;
        POPM      AR1;
        POPM      AR0;
        POPM      BG;
        POPM      BH;
        POPM      BL;
        POPM      AG;
        POPM      AH;
        POPM      AL;
	.endm 
	
	;   NON MODULO MEMORY   
    .ref  _OSTCBHighRdy, _OSTaskSwHook, _OSRunning, _OSTCBCur;
    .ref  _OSPrioCur, _OSPrioHighRdy
	
	.text 
;*********************************************************************************************************
;                                          START MULTITASKING
;                                       void OSStartHighRdy(void)
;
; The stack frame is assumed to look as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> IMR
;								REA
;								RSA
;								PMST
;								BRC
;								ST0
;								ST1
;								T
;								BK
;								AR7
;								AR7
;								AR6
;								AR5
;								AR4
;								AR3
;								AR2
;								AR1
;								AR0
;								BG
;								BH
;								BL
;								AG
;								AH
;								AL   (*pdata, passed in register A)
;								*task (serve as the return address)
;										
;
; Note : OSStartHighRdy() MUST:
;           a) Call OSTaskSwHook() then,
;           b) Set OSRunning to TRUE,
;           c) Switch to the highest priority task.
;*********************************************************************************************************	
_OSStartHighRdy:
	CALL #_OSTaskSwHook		;  call _OSTaskSwHook
	ST #1, *(_OSRunning)	;  set OSRunning try
	LD *(_OSTCBHighRdy), A	;  OSTCBHighRdy points to the TCB ready to run
	NOP				;
	NOP				;
	STLM A, AR0		;          AR0 has the TCB address
	NOP				;
	NOP				;
	LD *AR0(0), A	;          *AR0 has the sp
	NOP				;
	NOP				;
	STLM A, SP		; load the sp for new task
	
	NOP;  need some nops for SP to truely changed
	NOP;
	
	CONTEXT_RESTORE; new task context is restored here, no A has *pdata, sp point to *task
	NOP;
	NOP;
	
	RETE;	   run task
	
; initialize the task stack
; inputs: 
;	A =  *task
;	SP(0) = *pdata
;	SP(1) = *ptos
;   SP(2) = opt (ignored)
; outputs:
;	A = new stack_top ->need to save in TCB	
; 
; After calling this function, the task stack will look like this:
;
; A(new stack_top) ---->	IMR
;							REA
;							RSA
;							PMST
;							BRC
;							ST0
;							ST1
;							T
;							BK
;							AR7
;							AR7
;							AR6
;							AR5
;							AR4
;							AR3
;							AR2
;							AR1
;							AR0
;							BG
;							BH
;							BL
;							AG
;							AH
;							AL   (*pdata, passed in register A)
;							*task (serve as the return address)
;										
_OSTaskStkInit:
    
	LDM SP, B	; temp save SP to BL
	STLM A, T	; temp save *task to T
	LD *SP(1), A; A has *pdata now
	NOP			;
	NOP			;
	SFTL A, 8, A; temp save *pdata to BH
	ADD A, 8, B ;
	LD *SP(2), A; A has *task_stack_top
	NOP			;
	NOP			;
	STLM A, SP	; change SP to the task stack
	LDM T, A	;
	NOP;
	NOP;
	PSHM AL		; task start address
	SFTL B, -16, A; A has the *pdata
	NOP;
	NOP;
	CONTEXT_SAVE; 
	
	LDM SP, A	; the top of the stack
	
	STLM B, SP	; restore the SP
	NOP			;
	NOP			;
	NOP			; need some no ops so SP is truly restored before RET

	RET; 
	    
;*********************************************************************************************************
;                                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 -> PC of task to suspend
;
;          3) The stack frame of the task to resume looks as follows:
; 
;                 OSTCBHighRdy->OSTCBStkPtr --> IMR
;												REA
;												RSA
;												PMST
;												BRC
;												ST0
;												ST1
;												T
;												BK
;												AR7
;												AR7
;												AR6
;												AR5
;												AR4
;												AR3
;												AR2
;												AR1
;												AR0
;												BG
;												BH
;												BL
;												AG
;												AH
;												AL
;												PC of task to resume
;*********************************************************************************************************
_OSCtxSw:

	CONTEXT_SAVE	; save all registers on the current stack
	NOP				;
	NOP				; 
	                   
	LDM SP, B		;
	LD *(_OSTCBCur), A;
	NOP				;
	NOP				;
	
    STLM A, AR0	; store the curr sp to its tcb
    NOP			;
    NOP			;
	STL	B,  *AR0(0); 
	NOP			;
	NOP			;
    
    CALL #_OSTaskSwHook;
    
; OSTCBCur = OSTCBHighRdy
; OSPrioCur = OSPrioHighRdy
	LD *(_OSTCBHighRdy), A;
	LD *(_OSPrioHighRdy), B;
	NOP;
	STL A, *(_OSTCBCur);
	STL B, *(_OSPrioCur);
	            
; restoring the new task
	STLM A, AR0		;
	NOP				;
	NOP				;
	LD *AR0(0), A	;
	NOP				;
	NOP				;
	STLM A, SP		; load the sp for new task
	
	NOP;  need some nops for SP to truely changed
	NOP;
	
	CONTEXT_RESTORE; new task context is restored here
	NOP;
	NOP;
	
	RETE;  
	
;*********************************************************************************************************
;                                PERFORM A CONTEXT SWITCH (From an ISR)
;                                        void OSIntCtxSw(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 --> 	FRAME -1 from OSIntExit
;                                	        return address to OSIntExit()
;                                    	    return address to ISR
;                                         	dummy to make even SP after push old SP
;                                           old SP, -- SP before old even adjustment
;                                           if old SP is odd, this is a dummy, otherwise non-exist                               
;                                           MMRs - but no IMR
;                                           ..
;											..
;											..
;                                           return address of the task code

;          3) The stack frame of the task to resume looks as follows:
; 
;             OSTCBHighRdy->OSTCBStkPtr --> MMRs
;                                           address of the task to resume
;*********************************************************************************************************
	
_OSIntCtxSw:
; When gets here, the SP top looks like this
;  
;	XXXX  <- SP	;FRAME -1 from OSIntExit
;	XXXX  	 	;return address to OSIntExit
;	XXXX  		;return address to ISR
;	XXXX		;dummy to make even SP after push old SP
;	XXXX		;old SP, -- SP before old even adjustment
;	XXXX		;if old SP is odd, this is a dummy, otherwise non-exist
;	XXXX		;MMRs - but no IMR
;	XXXX		
;

	FRAME 4			; adjust the sp, pop up the return address of OSIntExit's caller and OSIntCtxSw's caller and the even word
    POPM SP			; restore the old SP(before even/odd adjust)
    NOP				;
;    PSHM IMR		; IMR is not saved by C compiler, add it to the stack
    NOP				; 
    LDM SP, B		; save sp to B
	LD *(_OSTCBCur), A;
	
    STLM A, AR0		; store the curr sp to its tcb
    NOP				;
    NOP				;
	STL	B,  *AR0(0)	; 
	NOP				;
	NOP				; 
	
	; call user-defined OSTaskSwHook();
	CALL #_OSTaskSwHook;
	
	LD *(_OSTCBHighRdy), A;
	LD *(_OSPrioHighRdy), B;
	NOP;
	STL A, *(_OSTCBCur);
	STL B, *(_OSPrioCur);
	
	; restoring the new task	
	NOP				;
	NOP				;
	STLM A, AR0		;
	NOP				;
	NOP				;
	LD *AR0(0), A	;
	NOP				;
	NOP				;
	STLM A, SP		; load the sp for new task
	
	NOP;  need some nops for SP to truely changed
	NOP;
	
	CONTEXT_RESTORE; new task context is restored here
	NOP;
	NOP;
	
	RETE; 
	
;*********************************************************************************************************
;                                            HANDLE TICK ISR
;
; Description: This function is called 199.99 times per second or, 11 times faster than the normal DOS
;              tick rate of 18.20648 Hz.  Thus every 11th time, the normal DOS tick handler is called.
;              This is called chaining.  10 times out of 11, however, the interrupt controller on the PC
;              must be cleared to allow for the next interrupt.
;
; 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;
;*********************************************************************************************************
;
	   
.end 

		

	

⌨️ 快捷键说明

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