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 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> uCOS-II 的任务上下文切换流程 -> 正文阅读

[嵌入式]uCOS-II 的任务上下文切换流程

前言

  • 最近在研究RTOS内核的实现,于是就翻阅一本较 uCOS-II 的书,【嵌入式实时操作系统 uC/OS-II 第二版】,这本书买的比较早了,之前没有细细的看,最近对照着uCOS-II的代码,看了起来,学到了很多
  • uCOS-II 的代码实现比较的经典,对深入学习内核实现原理与掌握内核设计的开发技术有很大的参考价值

任务切换流程

  • 任务切换本质上就是CPU 寄存器的切换,CPU工作需要一套寄存器,改变这套寄存器,就改变了CPU的处理环境(场景),也就实现了任务切换。
  • 为了保证任务被切走,还能切回来继续(接着)执行,需要保存老的,恢复新的。
  • uCOS-II 中称之为 上下文(Context),uCOS-II 在 ARM Cortex-M3 系列MCU上,上下文切换在 PendSV 中断中执行的

OS_CPU_PendSVHandler

  • 这个是 uCOS-II 的 PendSV 中断处理函数,实现了任务上下文的切换,通过长长的注释,很经典的说明了任务切换的流程,这里做个随笔记录一下
  • 原文注释如下:
;********************************************************************************************************
;                                       HANDLE PendSV EXCEPTION
;                                   void OS_CPU_PendSVHandler(void)
;
; Note(s) : 1) PendSV is used to cause a context switch.  This is a recommended method for performing
;              context switches with Cortex-M.  This is because the Cortex-M auto-saves half of the
;              processor context on any exception, and restores same on return from exception.  So only
;              saving of R4-R11 & R14 is required and fixing up the stack pointers. Using the PendSV exception
;              this way means that context saving and restoring is identical whether it is initiated from
;              a thread or occurs due to an interrupt or exception.
;
;           2) Pseudo-code is:
;              a) Get the process SP
;              b) Save remaining regs r4-r11 & r14 on process stack;
;              c) Save the process SP in its TCB, OSTCBCur->OSTCBStkPtr = SP;
;              d) Call OSTaskSwHook();
;              e) Get current high priority, OSPrioCur = OSPrioHighRdy;
;              f) Get current ready thread TCB, OSTCBCur = OSTCBHighRdy;
;              g) Get new process SP from TCB, SP = OSTCBHighRdy->OSTCBStkPtr;
;              h) Restore R4-R11 and R14 from new process stack;
;              i) Perform exception return which will restore remaining context.
;
;           3) On entry into PendSV handler:
;              a) The following have been saved on the process stack (by processor):
;                 xPSR, PC, LR, R12, R0-R3
;              b) Processor mode is switched to Handler mode (from Thread mode)
;              c) Stack is Main stack (switched from Process stack)
;              d) OSTCBCur      points to the OS_TCB of the task to suspend
;                 OSTCBHighRdy  points to the OS_TCB of the task to resume
;
;           4) Since PendSV is set to lowest priority in the system (by OSStartHighRdy() above), we
;              know that it will only be run when no other exception or interrupt is active, and
;              therefore safe to assume that context being switched out was using the process stack (PSP).
;
;           5) Increasing priority using a write to BASEPRI does not take effect immediately.
;              (a) IMPLICATION  This erratum means that the instruction after an MSR to boost BASEPRI
;                  might incorrectly be preempted by an insufficient high priority exception.
;
;              (b) WORKAROUND  The MSR to boost BASEPRI can be replaced by the following code sequence:
;
;                  CPSID i
;                  MSR to BASEPRI
;                  DSB
;                  ISB
;                  CPSIE i
;********************************************************************************************************

PendSV

  • PendSV 被用于触发(引起)一个任务切换(上下文切换)
  • 在Cortex-M 系列中,这是一种【推荐】的方式
  • Cortex-M 在异常(中断)情况下,会【自动保存】一半处理器的上下文(寄存器),退出异常(中断)后会自动恢复。这就解释了为什么我们不手动保存r0~r3、r12、r15、xPSR等寄存器了,注意r14 (LR)这个特殊寄存器,以及 r13 (SP)栈指针寄存器的处理
  • 所以只需要手动保存 R4~R11 以及 R14 寄存器即可(压栈方式)
  • 使用PendSV 异常 来做任务切换,保存与恢复(上下文),不管是在中断还是异常中触发的任务切换,都是同样处理

切换流程

  1. 获取 PSP(Process SP,可以称之为:进程堆栈指针)
  2. 保存【剩余的】r4~r11 r14 寄存器 到 进程栈 (process stack),因为其他的寄存器在进入中断异常时,由MCU 自动保存了
  3. 保存线程栈 SP 到 自己的 TCB任务控制块中,OSTCBCur->OSTCBStkPtr = SP;
  4. 调用 钩子函数 OSTaskSwHook,注意这个钩子函数必须定义,函数执行可以为空,否则会跳转到【空指针】
  5. 获取当前最高的优先级,这个已经获取到,保存在了 OSPrioHighRdy,OSPrioCur = OSPrioHighRdy;
  6. 获取【即将切换任务】的TCB 任务控制块,OSTCBCur = OSTCBHighRdy;
  7. 从【即将切换任务】的TCB 中,获取新的进程堆栈指针(Process SP), SP = OSTCBHighRdy->OSTCBStkPtr;
  8. 新的PSP中恢复 r4-r11 和 r14 (到CPU),这样CPU 的这几个寄存器被更新,
  9. 处理异常返回,这样完成【整个任务上下文】的切换,注意其他自动保存(压栈)的寄存器,如r0~r3,r12、 r13、 r15等,会自动的恢复,不需要手动处理

说明

  • ARM Cortex-M 系列的CPU,进入异常(中断)时寄存器 xPSR, PC, LR, R12, R0-R3 会自动的保存,其中 PC 为 r15, LR 为 r14
  • SP r13 寄存器,保存在任务控制块中 OSTCBStkPtr
  • 处理器进入中断,处理器本身的模式由 Thread mode 切换为 Handler mode
  • 栈 由 Process stack 切换为 Main stack
  • OSTCBCur 指向即将被切换的线程(suspend),被保存挂起
  • OSTCBHighRdy 指向即将切换线程(resume),被恢复
  • PendSV 的优先级最低,注意切换PSP时,需要保证不被其他的异常或中断打断,需要屏蔽全局中断等处理保证安全的切换

小结

  • 操作系统内核的设计博大精深,值得细细研读
  • 了解基于ARM Cortex-M 系列CPU的PendSV,了解任务切换的流程,会对RTOS内核有更进一步的认识
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:58:46  更:2022-04-18 17:58:55 
 
开发: 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:24:37-

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