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

📄 os_cpu_a.s

📁 网上一个朋对UCGUI整作的一个简单分析, 大家看看,虽然不是很详细, 但比较有整体性.
💻 S
字号:
        .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 块指针,得到该任务的堆栈,	@ //    从堆栈中依次恢复出 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 		@ End of OSStartHighRdy    @-----------------------------------------------------------------------        .align  2        .global OSCtxSw        .type    OSCtxSw,functionOSCtxSw:/*	Perform a context switch.	On entry, OSTCBCur and OSPrioCur hold the current TCB and priority	and OSTCBHighRdy and OSPrioHighRdy contain the same for the task	to be switched to.	The following code assumes that the virtual memory is directly	mapped into  physical memory. If this is not true, the cache must 	be flushed at context switch to avoid address aliasing.*/	@ // 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	@ // 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	 .align  2        .global  OSTickISR        .type    OSTickISR,functionOSTickISR:	@ // 1) PUSH ALL 将当前执行任务的 CPU 现场保存到 该任务的堆栈中	STMDB	sp!, {r0-r11, lr}		@ // 2) 调用系统中断进入和退出的 hook 函数	@BL	OSIntEnter	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) 如果此时 标志位 没有被设置, 则不需要进行调度,直接从中断中返回原来的任务	LDMFD	sp!, {r0-r11, lr}	SUBS	pc, lr, #4	_IntCtxSw:	@ // 3.0) 改变处理器模式, 	MRS	lr, SPSR	AND	lr, lr, #0xFFFFFFE0	ORR	lr, lr, #0x13	MSR	CPSR, lr		@ // 3.1) 先恢复堆栈指针 sp 到初始位置:即 1) PUSH ALL 以前的值,同时恢复原来任务的上下文	LDMFD	sp!, {r0-r11, lr}	SUB	lr, lr, #4	@ // 3.2) 执行跳转到 任务上下文的切换 代码		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, #0xC0		@ mask IRQ Int s	ORR	r0, r0, #0x80		@ mask IRQ Int s		@ // 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, r0			@ restore original CPSR		@ // 3) 返回	MOV	pc, lr    @------------------------------------------------------------------------    @-------------------------------------------------------------------------

⌨️ 快捷键说明

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