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

📄 os_cpu_a.s

📁 LWIP是一个轻量级的TCP/IP协议栈
💻 S
字号:
@*************************************************************************@		uC/OS-II  for SkyEye simulator @ @ 		Revision:   1.0        		@ 		Bugs Report:  lmcs00@mails.tsinghua.edu.cn@ 		Date:   Dec 18 2002 1:06:30 @@*************************************************************************        .file   "os_cpu_a.S".text        @-------------------------------------------------------------------------        .align  2        .global OSStartHighRdy        .type    OSStartHighRdy,functionOSStartHighRdy:	@ // 1) 调用 用户编写的 hook 函数        BL 	OSTaskSwHook             @ Call user defined task switch hook	@ // 2) 设置 OSRunning 变量为 true , 表示多任务调度开始        LDR 	r4,=OSRunning            @ Indicate that multitasking has started        MOV 	r5, #1        STRB 	r5, [r4]	@ // 3) 获得最高优先级任务的 TCB 块指针,得到该任务的堆栈 sp ,	@ //    从堆栈 sp 中依次恢复出 spsr, cpsr, r0-r12, lr, pc        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, r4        LDMFD 	sp!, {r4}              @ pop new task s psr        MSR 	cpsr, r4        LDMFD 	sp!, {r0-r12,lr,pc}    @ pop new task s r0-r12,lr & pc 	    @-----------------------------------------------------------------------        .align  2        .global OSCtxSw        .type    OSCtxSw,functionOSCtxSw:	@ // 1) PUSH ALL 将当前执行任务的 CPU 现场保存到 该任务的堆栈中	@ //    依次将 pc, lr, r12-r0, cpsr, spsr 推入 堆栈 sp 中        STMFD 	sp!, {lr}              @ push pc (lr should 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:	@ // 2) 设置当前优先级为最高任务的优先级 OSPrioHighRdy        @ OSPrioCur = OSPrioHighRdy        LDR 	r4, =OSPrioCur        LDR 	r5, =OSPrioHighRdy        LDRB 	r6, [r5]        STRB 	r6, [r4]                @ // 3) 获得当前执行任务的 TCB 块指针        @ Get current task TCB address        LDR 	r4, =OSTCBCur        LDR 	r5, [r4]        STR 	sp, [r5]                 @ store sp in preempted tasks s TCB	@ // 4) 调用用户定义的 hook 函数        BL 	OSTaskSwHook             @ call Task Switch Hook	@ // 5) 获得最高优先级任务的 TCB 块指针, 并且将它的堆栈指针复制到 CPU 的 sp 中, 改变当前堆栈        @ Get highest priority task TCB address        LDR 	r6, =OSTCBHighRdy        LDR 	r6, [r6]        LDR 	sp, [r6]                 @ get new task s stack pointer	@ // 6) 将最高优先级任务的 TCB 块指针 复制到 当前任务 TCB 指针中        @ OSTCBCur = OSTCBHighRdy        STR 	r6, [r4]                 @ set new current task TCB address	@ // 7) 将堆栈中保存的最高优先级任务的 CPU 现场恢复出来	@ //    依次从堆栈中弹出 spsr, cpsr, r0-r12, lr, pc        LDMFD 	sp!, {r4}              @ pop new task s spsr        MSR 	spsr, r4        LDMFD 	sp!, {r4}              @ pop new task s psr        MSR 	cpsr, r4        LDMFD 	sp!, {r0-r12,lr,pc}    @ pop new task s r0-r12,lr & pc    @-----------------------------------------------------------------------        .align  2        .global OSIntCtxSw        .type    OSIntCtxSw,functionOSIntCtxSw:		@ // 1) 这个就是会被 OSIntExit() 调用的 OSIntCtxSw() 函数入口	@ //    在这里的处理仅仅是设置了一个标志位 OSIntCtxSwFlag = True        @ OSIntCtxSwFlag = True        LDR 	r0, =OSIntCtxSwFlag        MOV 	r1, #1        STR 	r1, [r0]                @ // 2) 函数返回        MOV 	pc, lr    @-----------------------------------------------------------------------	@ // 用来临时保存 某些 寄存器的值, 这里不能使用 push 和 pop, 因为前后的 sp 可能会不一样.	SAVED_REG:	.long   0x00000000	SAVED_LR:	.long   0x00000000	.align  2        .global  OSTickISR        .type    OSTickISR,functionOSTickISR:	@ // 1) PUSH ALL 将当前执行任务的 CPU 现场保存到 该任务的堆栈中, 注意 pc.return = lr - 4	SUB	lr, lr, #4	STMFD	sp!, {r0-r12, lr} 	@ // 1.1) 同时也将 spsr_irq 压入堆栈, spsr_irq = cpsr_svc        MRS 	r4, spsr        	STMFD 	sp!, {r4}              @ push current spsr	@ // 2) 调用系统中断进入和退出的 hook 函数, do_IRQ 是用于更新仿真硬件中断屏蔽位寄存器的操作	BL	OSIntEnter        @ chy 2003-01-18 the OSTimeTick is called in do_IRQ        @BL OSTimeTick	BL	do_IRQ	BL	OSIntExit		@ // 3) 从 OSIntExit() 中退出时,如果需要进行中断级的上下文切换,则系统会调用 OSIntCtxSw	@ //	其结果就是 此时的标志位 OSIntCtxSwFlag == True	LDR	r0, =OSIntCtxSwFlag	LDR 	r1, [r0]	CMP	r1, #1	BEQ	_IntCtxSw	@ // 如果此时标志位被设置,则跳转到 _IntCtxSw 执行中断级的上下文切换			@ // 4) 将中断前的 CPCS_svc ( 目前保存在 spsr_irq 中 ) 推入堆栈        LDMFD 	sp!, {r4}              	MSR     spsr, r4		@ // 5) 如果此时 标志位 没有被设置, 则不需要进行调度,直接从中断中返回原来的任务	@ //    使用 ^ 的作用是 可以在恢复 pc 的时候, 同时也把 spsr -> cpsr 	LDMFD	sp!, {r0-r12, pc}^_IntCtxSw:	@ // 0) 这里需要首先将那个切换标志 OSIntCtxSwFlag 恢复成 0	LDR 	r0, =OSIntCtxSwFlag        MOV 	r1, #0        STR 	r1, [r0]		@ // 1) 然后也从栈中恢复 出 spsr_irq = cpsr_svc        LDMFD 	sp!, {r4} 	MSR 	spsr, r4 		@ // 2) 先恢复堆栈指针 sp 到初始位置:即 PUSH ALL 以前的值,同时恢复原来任务的上下文	LDMFD	sp!, {r0-r12, lr}	@ // 3) 这里我们先需要保存 r4 作为中间变量, lr_irq 作为将来任务返回的 pc 恢复值	STR	r4, SAVED_REG		@ 这里需要先借用一下 r4, 所以先把它保存一下	STR	lr, SAVED_LR		@ 这里需要记录下返回地址 lr_irq , 所以先把它保存一下 		@ // 4) 此时需要改变处理器的模式, 以便来恢复 svc 状态下下的 sp_svc 值, 也就是当前任务的"当前"堆栈指针	MOV	r4, #0x00000093	MSR	cpsr, r4		@ // 5) 这里获得将来进行任务恢复时的 pc 值, 就是中断态下的 lr_irq 	LDR	r4, SAVED_LR		@ 这里获得恢复时的 pc 值( lr_irq )放入 r4			@ // 6) 把将来的任务返回地址 lr_irq 压入堆栈 sp_svc 中, 这个 sp_svc 也就是被中断的任务的堆栈指针        STMFD 	sp!, {r4}               @ push pc (lr_irq should be pushed in place of PC)		@ // 7) 已经用完了 r4,  这里恢复它的原值	LDR	r4, SAVED_REG		@ ok, here we recover r4 , because r4 has done its job.		@ // 8) 执行保存 CPU 现场的操作, 然后进行跳转任务级的切换代码中        STMFD 	sp!, {r0-r12,lr}       @ push lr & register file        MRS 	r4, spsr        STMFD 	sp!, {r4}              @ push current psr        MRS 	r4, spsr        STMFD 	sp!, {r4}              @ push current spsr	@ // 9) 执行跳转到 任务上下文的切换 代码		B	_OSCtxSw		    @----------------------------------------------------------------------        .align  2        .global ARMDisableInt        .type    ARMDisableInt,functionARMDisableInt:		@ // 1) 保存 cpsr 到当前任务的堆栈 => push cpsr	MRS	r0, cpsr	STMFD	sp!, {r0}			@ push current PSR		@ // 2) 设置 cpsr 的中断屏蔽位 	ORR	r0, r0, #0x80		@ // 3) 屏蔽中断	MSR	cpsr, r0			@ disable IRQ Int s		@ // 4) 返回	MOV	pc, lr    @------------------------------------------------------------------------        .align  2        .global ARMEnableInt        .type    ARMEnableInt,functionARMEnableInt:			@ // 1) 从堆栈中弹出 cpsr => pop cpsr 到 r0	LDMFD	sp!, {r0}			@ pop current PSR		@ // 2) 用 r0 来恢复 cpsr	MSR	cpsr_c, r0			@ restore original cpsr			@ // 3) 返回	MOV	pc, lr    @------------------------------------------------------------------------    	    @-------------------------------------------------------------------------

⌨️ 快捷键说明

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