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

📄 os_cpu_a.s

📁 keil mdk 3.22下移植的uCOS II 2.83
💻 S
字号:
	AREA	|subr|, CODE, READONLY
            IMPORT  OSRunning                    ; EXTERNAL references
            IMPORT  OSPrioCur
            IMPORT  OSPrioHighRdy
            IMPORT  OSTCBCur
            IMPORT  OSTCBHighRdy
            IMPORT  OSIntNesting
            IMPORT  OSIntExit
            IMPORT  OSTaskSwHook
            IMPORT  OSIntEnter
            IMPORT  OSTimeTick      
            
            EXPORT  OS_CPU_SR_Save               ; Functions declared in this file
            EXPORT  OS_CPU_SR_Restore
            EXPORT  OSStartHighRdy               
            EXPORT  OSCtxSw
            EXPORT  OSIntCtxSw
            EXPORT  OSTickISR
	        EXPORT  OSIntISR
	    
OSIntCtxSwFlag  DCD  0x00000000 
SAVED_LR_SVC	DCD  0x00000000        ; some variables for temparal use
SAVED_LR_IRQ	DCD  0x00000000
SAVED_SPSR	    DCD  0x00000000

NO_INT      EQU     0xC0                         ; Mask used to disable interrupts (Both FIR and IRQ)
SYS32_MODE  EQU     0x1F
FIQ32_MODE  EQU     0x11
IRQ32_MODE  EQU     0x12

OS_CPU_SR_Save
        MRS     R0,CPSR                     ; Set IRQ and FIQ bits in CPSR to disable all interrupts
        ORR     R1,R0,#NO_INT				;0XC0
        MSR     CPSR_c,R1
        MRS     R1,CPSR                     ; Confirm that CPSR contains the proper interrupt disable flags
        AND     R1,R1,#NO_INT
        CMP     R1,#NO_INT
        BNE     OS_CPU_SR_Save              ; Not properly disabled (try again)
        MOV     PC,LR                       ; Disabled, return the original CPSR contents in R0
OS_CPU_SR_Restore
        MSR     CPSR_c,R0
        MOV     PC,LR
        

OSStartHighRdy
		PRESERVE8 			
        BL 	OSTaskSwHook             ; Call user-defined hook function

        LDR 	r4,=OSRunning            ; Indicate that multitasking has started
        MOV 	r5, #1                   
        STRB 	r5, [r4]                 ; OSRunning = true

        LDR 	r4, =OSTCBHighRdy        ; Get highest priority task TCB address
        LDR 	r4, [r4]                 ; get stack pointer
        LDR 	sp, [r4]                 ; switch to the new stack

        LDMFD 	sp!, {r4}                ; pop new task s spsr
        MSR 	spsr_cxsf, r4
        LDMFD 	sp!, {r4}                ; pop new task s psr
        MSR 	cpsr_cxsf, r4
        LDMFD 	sp!, {r0-r12,lr,pc}      ; pop new task s r0-r12,lr & pc

OSCtxSw 
        STMFD 	sp!, {lr}                ; push pc (lr is actually be pushed in place of PC)
        STMFD 	sp!, {r0-r12,lr}         ; push lr & register file
        MRS 	r4, cpsr
        STMFD 	sp!, {r4}                ; push current psr
        MRS 	r4, spsr
        STMFD 	sp!, {r4}                ; push current spsr

_OSCtxSw 
        LDR 	r4, =OSPrioCur           ; OSPrioCur = OSPrioHighRdy
        LDR 	r5, =OSPrioHighRdy
        LDRB 	r6, [r5]
        STRB 	r6, [r4]
        
        LDR 	r4, =OSTCBCur            ; Get current task TCB address
        LDR 	r5, [r4]
        STR 	sp, [r5]                 ; store sp in preempted tasks s TCB

        BL 	OSTaskSwHook             ; call Task Switch Hook

        LDR 	r6, =OSTCBHighRdy        ; Get highest priority task TCB address
        LDR 	r6, [r6]
        LDR 	sp, [r6]                 ; get new task s stack pointer

        STR 	r6, [r4]                 ; set new current task TCB address

        LDMFD 	sp!, {r4}                ; pop new task spsr
        MSR 	spsr_cxsf, r4
        LDMFD 	sp!, {r4}                ; pop new task cpsr
        MSR 	cpsr_cxsf, r4
        LDMFD 	sp!, {r0-r12,lr,pc}      ; pop new task r0-r12,lr & pc
        
OSIntCtxSw 	
        LDR 	r0, =OSIntCtxSwFlag      ; OSIntCtxSwFlag = true
        MOV 	r1, #1
        STR 	r1, [r0]     
        MOV 	pc, lr                   ; return 


clear_irq   
	   MOV      r0,#0xffffffff;#0x400
       MOV      r1,#0x1e00000
       STR      r0,[r1,#0x24]    
       MOV      pc,r14

OSTickISR
OSISR 
OSIntISR
	SUB	lr, lr, #4            
	STMFD	sp!, {r0-r12, lr}        ; push r0-r12 register file and lr( pc return address )
    MRS 	r4, spsr        
	STMFD 	sp!, {r4}                ; push current spsr_irq ( =cpsr_svc )


	BL	OSIntEnter
	BL 	OSTimeTick 
	                  ; here do_IRQ is used to clear some virtual-hardware flags
					 ;AND RELOAD THE TIMER 
	BL	OSIntExit	
	;bl clear_irq 
	
	;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	;bl clear_irq 
	MOV      r0,#0xffffffff;#0x400    ;clear all irq flags!
    MOV      r1,#0x1e00000
    STR      r0,[r1,#0x24]    
	;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	LDR	r0, =OSIntCtxSwFlag      ; check if OSIntCtxFlag is marked as true
	LDR 	r1, [r0]
	CMP	r1, #1
	
	BEQ	_IntCtxSw	         ; if OSIntCtxFlag = true, then jump to _IntCtxSw
		
    LDMFD 	sp!, {r4}                ; get cpsr_svc from stack
	MSR     spsr_cxsf, r4                 ; prepare spsr to return svc mode	
	LDMFD	sp!, {r0-r12, pc}^       ; recover r0-r12 and pc from stack, cpsr also


_IntCtxSw
		
        MOV 	r1, #0                   ; clear OSIntCtxSwFlag = flase
        STR 	r1, [r0]
	
        LDMFD 	sp!, {r4}                ; restore spsr_irq 
	MSR 	spsr_cxsf, r4 	
	STR	r4, SAVED_SPSR
	LDMFD	sp!, {r0-r12, lr}        ; recover the irq stack pointer

	STR	lr, SAVED_LR_IRQ         ; save lr_irq to SAVED_LR_IRQ 	
	MOV	lr, #0x000000d3          ; change forcely cpsr to svc mode
	MSR	cpsr_cxsf, lr	
	STR     lr, SAVED_LR_SVC         ; save lr_svc to SAVED_LR_SVC
	LDR	lr, SAVED_LR_IRQ         ; get lr_irq value saved in SAVED_LR_IRQ 
	STMFD 	sp!, {lr}                ; push future task pc (lr_irq should be pushed in place of PC)
	LDR	lr, SAVED_LR_SVC         ; get lr_svc value saved in SAVED_LR_SVC 
    STMFD 	sp!, {r0-r12,lr}         ; push lr & r0-r12 register file
	LDR     r4, SAVED_SPSR
        ;MRS 	r4, spsr
    STMFD 	sp!, {r4}                ; push current psr
	
        ;MRS 	r4, spsr
    STMFD 	sp!, {r4}                ; push spsr

	B	_OSCtxSw                 ; jump to _OSCtxSw	


    END

⌨️ 快捷键说明

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