IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> rtt小结 -> 正文阅读

[嵌入式]rtt小结

最近在公司小芯片上移植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; //系统时间+1
 82     -- thread->remaining_tick;   //时间+1
 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                       /* set rt_thread_switch_interrupt_flag to 1 */
 56     LONG_S      t1, t0, 0
 57     la      t0, rt_interrupt_from_thread   /* set rt_interrupt_from_thread */
 58     LONG_S      a0, t0, 0
 59 _reswitch:                          //把B进程的sp存在这里
 60     la      t0, rt_interrupt_to_thread     /* set 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     /* let k0 keep the current context sp */
 76     move    tp, sp
 77     /* switch to kernel stack */
 78     la  sp, _system_stack                                                                                                                                                                                                                                                   
 79 
 80     bl     rt_interrupt_enter
 81     /* Get Old SP from k0 as paremeter in a0 */
 82     move    a0, tp
 83     bl     rt_general_exc_dispatch
 84     bl     rt_interrupt_leave
 85 
 86     /* switch sp back to thread context */
 87     move    sp, tp
 88 #if 1
 89     /*
 90     * if rt_thread_switch_interrupt_flag set, jump to
 91     * rt_hw_context_switch_interrupt_do and do not return
 92     */
 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                     /* clear flag */
 97 
 98     /*
 99     * switch to the new thread
100     */
101     la  t0, rt_interrupt_from_thread//做一个标志位
102     LONG_L  t1, t0, 0
103     nop
104     LONG_S  sp, t1, 0                       /* store sp in preempted task TCB */
105 
106     la  t0, rt_interrupt_to_thread
107     LONG_L  t1, t0, 0
108     nop													//在这里读取B进程sp
109     LONG_L  sp, t1, 0                       /* get new task stack pointer */
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;//把打断处ra放到epc里
 28     SAVE_ALL//现在的sp还是A的,把epc存到sp里
 29 //sp寄存器里存B进程的栈
 30     REG_S      sp, a0, 0       /* store sp in preempted tasks TCB */
 31     REG_L      sp, a1, 0       /* get new task stack pointer */
 32 //当个异常返回了,这样就执行B进程了
 33     RESTORE_ALL_AND_RET

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:27:28  更:2022-04-04 12:30:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:39:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码