内核移植(七)--线程切换

;/*
; * 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

你可能感兴趣的:(RT-Thread,RT-Thread,内核移植,线程切换)