;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * 当一个汇编函数在C文件中调用的时候,如果有两个形参,则执行的时候会将这两个形参分别传入到CPU寄存器r0和r1中
; * r0 --> from
; * r1 --> to
;* yes: 将参数 to 保存到 rt_interrupt_to_thread 变量 -> 触发PendSV异常 -> 结束
; * 线程切换流程:开始 -> rt_thread_switch_interrupt_flag == 1? -<
; * no:将参数 from 保存到 rt_interrupt_from_thread 变量 -> 将参数 to 保存到 rt_interrupt_to_thread 变量 -> 触发PendSV异常 -> 结束
; */
rt_hw_context_switch_interrupt
EXPORT rt_hw_context_switch_interrupt
rt_hw_context_switch PROC
EXPORT rt_hw_context_switch
;检查 rt_thread_switch_interrupt_flag 变量是否为 1
;如果变量为 1 就跳过更新 from 线程的内容
LDR r2, =rt_thread_switch_interrupt_flag ;加载 rt_thread_switch_interrupt_flag 变量的地址到 r2 寄存器
LDR r3, [r2] ;加载 rt_thread_switch_interrupt_flag 变量的值到 r3 寄存器
CMP r3, #1 ; r3 与 1 比较,即判断 rt_thread_switch_interrupt_flag 变量的值是不是为 1,相等则执行 BEQ 指令,否则不执行
BEQ _reswitch
MOV r3, #1 ;设置 r3 的值为 1
STR r3, [r2] ;将 r3 的值存储到 rt_thread_switch_interrupt_flag,即将变量 rt_thread_switch_interrupt_flag 置 1
;保存 rt_interrupt_from_thread 变量的值
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread ;加载 rt_interrupt_from_thread 变量的地址到 r2 寄存器
STR r0, [r2] ;存储 r0 的值到 rt_interrupt_from_thread 变量, 即上一个线程栈指针 sp 的指针
_reswitch
;设置 rt_interrupt_to_thread 的值
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread ;加载 rt_interrupt_to_thread 变量的地址到 r2 寄存器
STR r1, [r2] ;存储 r1 的值到 rt_interrupt_to_thread 变量,即下一个线程栈指针 sp 的指针
;触发PendSV异常,实现上下文切换
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
;子程序返回
BX LR
;子程序结束
ENDP
内核移植(七)--线程切换
最新推荐文章于 2024-12-10 09:46:07 发布