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

📄 os_cpu_a.s

📁 BK7S64开发板的uC/OS-II移植源代码
💻 S
字号:
;*******************************************************************************************
;OS_CPU_A.s



	PRESERVE8
	AREA	OS_CPU_A, CODE, READONLY
    CODE32
	
; 定义于ucos_ii.h中的外部变量
;OS_EXT  OS_TCB           *OSTCBCur;                        /* Pointer to currently running TCB         */
;OS_EXT  OS_TCB           *OSTCBHighRdy;                    /* Pointer to highest priority TCB R-to-R   */
;OS_EXT  INT8U             OSPrioCur;                       /* Priority of current task                 */
;OS_EXT  INT8U             OSPrioHighRdy;                   /* Priority of highest priority task        */
;OS_EXT  BOOLEAN           OSRunning;                       /* Flag indicating that kernel is running   */

			IMPORT	OSTCBCur
			IMPORT	OSTCBHighRdy

			IMPORT	OSPrioCur
			IMPORT	OSPrioHighRdy
   
            IMPORT  OSRunning

;*******************************************************************************************
	      EXPORT	OSStartHighRdy
       ;功能:	      
       ;1)SP=OSTCBHighRdy->OSTCBStkPtr
       ;2)OSTCBCur->OSTCBHighRdy
       ;3)将当前优先级最高的任务切换到运行态,本任务只在系统开始运行前运行一次!该函数不会返回到
	   ;  调用者OSStart().
	
OSStartHighRdy
    LDR  r4,=OSRunning      ;起始状态时OSRunning显然为0
    MOV  r5,#1
    STRB r5,[r4]            ;直接置1,标志系统进入运行状态
    
    IMPORT OSTaskSwHook
    BL     OSTaskSwHook
    
	LDR	 r4, =OSTCBCur	    ; 当前任务TCB地址
	LDR	 r5, =OSTCBHighRdy	; 最高优先级任务的TCB地址

	LDR  r5, [r5]		    ; TCB的第一个元素就是OSTCBStkPtr,即任务的栈指针
	LDR	 sp, [r5]		    ; 更新当前任务的栈指针为预先设置的值
	                        ; SP=OSTCBHighRdy->OSTCBStkPtr
	STR	 r5, [r4]		    ; 将优先级最高的任务设置为当前任务
	                        ; OSTCBCur=OSTCBHighRdy

	LDMFD	sp!, {r4}		; 从任务堆栈中恢复上下文(context)
	;MSR	SPSR_cxsf, r4	; usr,sys模式无SPSR	
	LDMFD	sp!, {r4}		; 
	MSR	    CPSR_cxsf, r4	; CPSR --- SYS Mode
	LDMFD	sp!, {r0-r12, lr, pc }	
	                        ; 任务运行



;*******************************************************************************************
	      EXPORT	OS_TASK_SW
       ;功能
       ;1)保存当前任务上下文
       ;2)更新系统变量OSPrioCur = OSPrioHighRdy
       ;3)OSTCBCur->OSTCBStkPtr=SP	保存SP到当前任务控制块
       ;4)获得即将进入运行状态的高优先级任务的栈指针SP=OSTCBHighRdy->OSTCBStkPtr
       ;5)更新系统变量OSTCBCur->OSTCBHighRdy
       ;6)切换任务上下文

OS_TASK_SW
	STMFD	sp!, {lr}		; 保存 pc
	STMFD	sp!, {lr}		; 保存 lr
	;OS_TASK_SW这个函数,在系统调用它时是在当前任务最后失去CPU时,当前任务再次
	;获得CPU时,其恰好在OS_TASK_SW调用完毕后的那个位置,因此,lr被放入pc
	;在栈中的位置,即任务继续开始执行的位置;此外,lr放在栈中的位置也是无关
	;紧要的,因为,这个子函数返回时的lr是无意义的
	STMFD	sp!, {r0-r12}	; 保存任务上下文
	MRS	    r4, CPSR
	STMFD	sp!, {r4}		; save current PSR
	;MRS	r4, SPSR		; 任务运行于SYS模式,无SPSR,栈中的CPSR与SPSR相同					        
	STMFD	sp!, {r4}		; 构成一致的堆栈结构

    IMPORT OSTaskSwHook     
    BL     OSTaskSwHook

	LDR	    r4, =OSPrioCur  ; 开始切换任务
	LDR	    r5, =OSPrioHighRdy 
	LDRB	r6, [r5]        ; 更新系统变量
	STRB	r6, [r4]        ; OSPrioCur = OSPrioHighRdy
	                        		                      
	LDR	r4, =OSTCBCur       ; 获取当前任务的栈指针
	LDR	r5, [r4]
	STR	sp, [r5]		    ; 保存当前任务的栈指针
	                        ; OSTCBCur->OSTCBStkPtr=SP	保存SP到当前任务控制块
	                        ; 当前运行任务的上下文保存完毕
							
	LDR	r6, =OSTCBHighRdy   ; 高优先级任务的TCB地址
	LDR	r6, [r6]
	LDR	sp, [r6]		    ; 取得高优先级任务的栈指针
	                        ; SP=OSTCBHighRdy->OSTCBStkPtr 更新SP为即将运行的任务的栈指针
	
	STR	r6, [r4]		    ; 更新系统变量
	                        ; OSTCBCur = OSTCBHighRdy
	
	LDMFD	sp!, {r4}		 
	;MSR	SPSR_cxsf, r4	; 运行在sys模式下,无需SPSR的更新
	LDMFD	sp!, {r4}		
	MSR	    CPSR_cxsf, r4		
	LDMFD	sp!, {r0-r12, lr, pc}	
	                        ; 高优先级任务的上下文恢复完成,切换到高优先级任务运行

;*******************************************************************************************

	    EXPORT  OSIntCtxSw
OSIntCtxSw
	;新的代码,实现了中断的嵌套(其实现依赖于底层向量的处理代码)
	;该函数运行依赖于调用IrqHandler之前的模式转换和栈构造
	;运行于SYS模式,其首先调整SP_sys指针到下图中SPSR处
	;后半部分与OSCtxSw相同
 	;该函数是不返回的,进入时堆栈结构是已知的,除了原来构造的
 	;标准栈,还压入了一些多余的内容(可以参看编译后的汇编代码)
    ;而且这些"多余的内容"和编译器、编译器的设置都有关

;irq的栈结构,进入IrqHandler前,sp指向的恰好是构造的标准栈顶,但是,
;由于函数中又调用了别的函数于是进入OSIntCtxSw后还得调整SP
;**********************************************************************
;低 r4 r14 spsr cpsr r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 lr PC 高
;**********************************************************************
    ADD sp,sp,#16   	;调整SP_sys指向标准栈结构
                        ;在汇编中找到压入堆栈的多余数据,通过调整SP来去掉
	                    ;这是很关键的步骤,具体请参考uC/OS-II的手册
	;后面的内容和OSCtxSw的后半部分相同,依次为
    ;1)OSPrioCur = OSPrioHighRdy
    ;2)OSTCBCur->OSTCBStkPtr=SP	保存SP到当前任务控制块
    ;3)SP=OSTCBHighRdy->OSTCBStkPtr
    ;4)OSTCBCur=OSTCBHighRdy
    ;5)切换上下文
	;6)高优先级任务运行
	
	IMPORT OSTaskSwHook
    BL     OSTaskSwHook
		
	LDR	r4, =OSPrioCur
	LDR	r5, =OSPrioHighRdy
	LDRB	r6, [r5]
	STRB	r6, [r4]       ; OSPrioCur = OSPrioHighRdy
	
	LDR	r4, =OSTCBCur      ; 获得当前任务的TCB地址
	LDR	r5, [r4]
	STR	sp, [r5]		   ; 
	                       ; OSTCBCur->OSTCBStkPtr=SP	保存SP到当前任务控制块
	                      
	LDR	r6, =OSTCBHighRdy  ; 获得高优先级任务的TCB地址
	LDR	r6, [r6]
	LDR	sp, [r6]		   ; 获得高优先级任务的栈指针
	                       ; SP=OSTCBHighRdy->OSTCBStkPtr	更新SP为即将运行的任务
	
	STR	r6, [r4]		   ; 更新系统变量OCTCBCur
	                       ; OSTCBCur = OSTCBHighRdy
	
	LDMFD	sp!, {r4}		
	;MSR	SPSR_cxsf, r4  ; 运行在sys模式下,无需SPSR的更新
	LDMFD	sp!, {r4}		 
	MSR	CPSR_cxsf, r4		 
	LDMFD	sp!, {r0-r12, lr, pc}	
	                       ; 上下文切换完成,切换到高优先级任务运行
;*******************************************************************************************
; 定义于ucos_ii.h中的外部变量
;OS_EXT  INT8U             OSIntNesting;             /* Interrupt nesting level */

    IMPORT  OSIntNesting
	

;*******************************************************************************************	
	END
;*******************************************************************************************

⌨️ 快捷键说明

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