最近在公司小芯片上移植rtt: 看rtt的一些小感悟: 因为芯片是单核,进程调度发生: 假如A进程-》B进程: 1:在中断中发生, 当clock时钟中断触发,系统tick+1,此时就要检查有没有线程的时间片到了,如果有,要发生调度 2:在已有的进程中手动掉用高优先级进程,要发生调度 3:该进程执行完毕,进程退出的时候,要发生调度
中断中:
12 void rt_hw_timer_handler(void)
113 {
116 write_csr_tintclear(CSR_TINTCLR_TI);
119 rt_tick_increase();
125 }
展开 部分代码已经删除
5 void rt_tick_increase(void)
66 {
76 ++ rt_tick;
82 -- thread->remaining_tick;
83 if (thread->remaining_tick == 0)
84 {
90 rt_schedule();
91 }
99 }
展开调度: 这里就有区分了,调度发生在中断里和不发生在中断里
void rt_schedule(void)
{
....
to_thread = _scheduler_get_highest_priority_thread(&highest_ready_priority);
if (rt_interrupt_nest == 0)
485 {
486 extern void rt_thread_handle_sig(rt_bool_t clean_state);
494 rt_hw_interrupt_enable(level);
495
}
517 else
518 {
519 RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("switch in interrupt\n"));
520
521 rt_hw_context_switch_interrupt((rt_ubase_t)&from_thread->sp,
522 (rt_ubase_t)&to_thread->sp);
523 }
}
发生在中断里: 因为中断进入的时候,保存了A进程的sp到t 寄存器里,sp换成了系统栈,按理来说退出中断的时候要从tp寄存器取回A进程的sp,然后在sp栈中找到epc,重新到中断打断的代码处执行 但是现在有调度,要在退出中断后执行B进程,就不能从tp里取sp了 要去一个其他位置,这个位置存的是B的sp
看rt_hw_context_switch_interrupt实现
51 rt_hw_context_switch_interrupt:
52 la t0, rt_thread_switch_interrupt_flag
53 REG_L t1, t0, 0
54 bnez t1, _reswitch
55 li t1, 0x01
56 LONG_S t1, t0, 0
57 la t0, rt_interrupt_from_thread
58 LONG_S a0, t0, 0
59 _reswitch:
60 la t0, rt_interrupt_to_thread
61 LONG_S a1, t0, 0
62 jr ra
63 nop
64
然后退出中断的时候去那里读取sp
72 mips_irq_handle:
73 SAVE_ALL
74
75
76 move tp, sp
77
78 la sp, _system_stack
79
80 bl rt_interrupt_enter
81
82 move a0, tp
83 bl rt_general_exc_dispatch
84 bl rt_interrupt_leave
85
86
87 move sp, tp
88 #if 1
89
93 la t0, rt_thread_switch_interrupt_flag
94 LONG_L t1, t0, 0
95 beqz t1, spurious_interrupt
96 LONG_S zero, t0, 0
97
98
101 la t0, rt_interrupt_from_thread
102 LONG_L t1, t0, 0
103 nop
104 LONG_S sp, t1, 0
105
106 la t0, rt_interrupt_to_thread
107 LONG_L t1, t0, 0
108 nop
109 LONG_L sp, t1, 0
110 #endif
111 b spurious_interrupt
112 nop
113 spurious_interrupt:
114 RESTORE_ALL_AND_RET
如果进程切换不是发生在中断中,怎么记录呢 mips和la的指令都是risc指令结构,手动调度高优先级的时候要调用bl和jirl指令,就会存储打断代码下调ra,然后把让存到epc里,然后保存上下文到A进程栈sp中,再去调度。
26 rt_hw_context_switch:
27 csrwr ra, LOONGARCH_CSR_EPC;
28 SAVE_ALL
29
30 REG_S sp, a0, 0
31 REG_L sp, a1, 0
32
33 RESTORE_ALL_AND_RET
|