学习嵌入式实时操作系统ucos的比较好的三本书:嵌入式实时操作系统ucosii原理及应用(任哲)、嵌入式实时操作系统ucosiii(宫辉等译)、ucosiii内核实现与应用开发实战指南(刘火良)。第一本书先看,结合ucosii源码,可以完整理解整个ucosii系统(约三万两千行代码),然后用后面两本书交叉学习ucosiii系统即可(估计五六万行吧,反正比ucosii代码量多了很多,所以推荐先学ucosii,再学ucosiii)。

对于单片机,比如arm(stm32),51等单片机,跑裸机程序,都是有且仅有一个堆栈(就是栈)(当然有些单片机的另外还有个专门的中断堆栈,发生中断了,跳转到中断服务函数运行就是在这个栈里,运行完了自动跳回原来的系统栈继续被打断的函数运行),也叫系统栈(一定是在单片机内部ram里的,这样访问速度才快),c语言程序都是运行在这个栈里。现在单片机跑了操作系统比如ucosiii了,这个系统栈仍然存在,比如一开始的main函数就是在这里运行的,除此之外,每个任务还各自有一个堆栈。arm单片机由于内存ram够多(51单片机内部ram不够,所以一般都是在内部ram利用公共的系统堆栈,其他任务各自的堆栈放外部ram里(读写速度相对慢一些),然后任务切换时候就跟内部ram的公共系统栈复制数据即可,具体可参考上述第一本书的225页,所以51单片机的任务切换函数反而编写更繁琐),所以每一个任务堆栈也是创建在内部ram里。把CPU的堆栈指针sp(指向的是堆栈的栈顶,即入栈出栈的地方,所以这个地址是动态加减的,可以看我这篇文章,C语言函数调用时候内存中栈的动态变化详细分析)指向哪个堆栈栈顶,那么此时CPU运行的函数代码的过程都是在这个堆栈里完成的(比如局部变量,过程临时地址等的存储),这个堆栈加上CPU内部的寄存器就能实现整个程序的运行了。所以CPU实现任务切换的原理就是:当前任务A正在运行,那么CPU的堆栈指针肯定就是指向任务A的任务堆栈的栈顶,且CPU里面的寄存器的暂存值是记录的当前这个任务中运行的函数信息(比如子函数返回值,进位,状态字等),那么想要切换到任务B(即任务A里主动调用了OSCtxSw()函数,也叫任务级任务切换函数),先把任务A的状态给保存入A的堆栈里(CPU中的所有寄存器的值,任务A的堆栈的栈顶地址保存给任务A的任务控制块TCB里的成员StkPtr),然后只需要把CPU的堆栈指针寄存器指向任务B的堆栈的栈顶(是通过把CPU的堆栈寄存器赋值为任务B的控制块的成员StkPtr即可),同时把B的堆栈(上一次被中断时候保存的CPU内左右寄存器的值,包括指令寄存器pc的值)中先前保存的CPU的寄存器的值推入现在CPU中(pc寄存器的值得用汇编RET指令才能推入CPU),这样就完全实现了任务B的继续运行,即无缝切换。

接着继续说,此时CPU正在运行任务A,如果此时任务A发生了中断,那么进入中断服务函数前,还是把此断点信息压入A的堆栈里(CPU中所有的寄存器自动的全部保存进入A的堆栈里,包括堆栈指针寄存器里的值赋值给了OSTCBCurPtr->StkPtr,注意:这里的堆栈地址在中断函数的内容之前,也就说明下次切换回来直接是从被中断打断的点继续运行的,而不是中断函数内部(即与中断函数没有任何关系了),为什么这里进入中断可以自动保存断点呢呢,因为中断服务程序是得自己用汇编定制写前面的操作部分的,然后才到用户服务C程序部分,参考上述说的第二本书的116页,如下图所示:

可以看到进入中断函数的自动保存部分也是自己由汇编代码自己编写的,然后才到c语言写的中断处理部分,最后调用OSIntExit函数,这个函数里面会进行一次任务切换,使用的是下面说的OSIntCtxSw()函数,即中断级任务切换函数,这不正是在中断里使用的嘛,这就是这个中断级切换名字的由来,很明显它不需要做前面的寄存器保存工作,只需要把任务B的堆栈内容推入CPU即可,后面会继续说。从上面的中断函数编写模板可知,每个中断函数进入的时候都要用OSIntEnter()(就是执行OSIntNestingCtr++)函数和快要退出时候写上OSIntExit()函数,如果在OSIntExit函数里发生的任务调度确实有更高优先级任务运行了,那么就时通过OSIntCtxSw()函数发生的任务切换 ,里面不会进行保存了,而是直接推入待运行任务B的堆栈内容进入CPU即可,当再次切换回任务A的时候,就是直接从A上次被中断打断的点继续执行下去,因为从前面可以知道上次保存的断点信息时进入中断函数那儿的,而不是这个中断函数发生任务切换这儿的,所以中断函数最后那两句推入cpu寄存器和return语句就作废了。如果OSIntExit()函数里面没有发生任务切换(比如里面待切换任务跟原任务一样),那么就马上退出中断函数了,执行后面那句推入cpu寄存器的所有值)(发生中断转入中断函数的过程跟在函数中主动调用了一个子函数过程都是一样的),而不是系统堆栈(系统堆栈就是最开始的main函数跑了一下,后面一直不会跑了),此时中断函数会继续在A的堆栈里运行(就像调用了子函数)(也叫做中断函数的栈帧,而不是另外的一个堆栈,正如上面所说的,大部分单片机都没有另外的中断堆栈),如果是想在这个中断函数里做任务切换(比如系统定时器时间片到了定时器中断函数里进行任务切换),那么很明显跟上面的任务内主动切换不一样,这里不再需要保存任务A的断点信息(比如CPU寄存器因为已经被发生中断自动保存了),正如前面已经解释了,直接推入待运行任务B的信息即可,这样就完成了在中断里的任务切换,这也是任务级任务切换函数和中断级切换函数的不同点和存在的原因。

还有一点,中断函数还可以像裸机时候一样用,但是里面得关闭中断使能(防止更高优先级中断来了发生中断嵌套后在更高优先级里发生任务切换,由上面分析可知,这样就有问题),而且这个中断函数里只执行少量不耗时的动作而已就结束了。这样可以简单快速的响应一些外部不耗时事件,也叫做无需内核参与的中断服务程序。如果需要响应快速的响应外部耗时事件中断,那还是得中断程序任务化(因为中断执行的动作尽量少才不影响整个系统的实时性),即在此中断里发消息给一个最高优先级的任务,然后发生中断级任务切换,然后让耗时事件在那个最高优先级任务里处理即可。

ucosii/iii实时嵌入式操作系统任务切换与中断管理深入解析相关推荐

  1. 系统架构设计笔记(63)—— 实时嵌入式操作系统

    整体上看,一个嵌入式系统的实时性能是由硬件 . 实时操作系统及应用程序共同决定的,其中,嵌入式实时操作系统内核的性能起着关键的作用. 通常,有两种类型的实时嵌入式操作系统:实时内核型的 RTEOS 与 ...

  2. 嵌入式操作系统和RTOS(实时操作系统)介绍。

    目录 嵌入式操作系统 RTOS(实时操作系统) 实时操作系统: 什么是嵌入式操作系统 一μClinux 二μC/OS-II 三eCos 四 FreeRTOS 五 mbed OS 六 RTX 七 VxW ...

  3. 嵌入式操作系统内核原理和开发(总结篇)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 很多朋友都喜欢嵌入式操作系统的内容,但是如何实现和仿真这样一个系统一直是困扰我们的难题.现在郑 ...

  4. 主流嵌入式操作系统介绍(一)

    主流嵌入式操作系统介绍(一) 2010年08月13日 http://www.edu03.com/2010/0610/863.html 嵌入式系统是以应用为中心,软硬件可裁减的,适用于对功能.可靠性.成 ...

  5. 嵌入式操作系统介绍分析

    一,各种嵌入式操作系统介绍 1.uC/OS-II u C / OS 是一种免费公开源代码.结构小巧.具有可剥夺实时内核的实时操作系统. μC/OS-II 的前身是μC/OS,最早出自于1992 年美国 ...

  6. 各种嵌入式操作系统介绍

    一,各种嵌入式操作系统介绍 1.uC/OS-II u C / OS 是一种免费公开源代码.结构小巧.具有可剥夺实时内核的实时操作系统.  μC/OS-II 的前身是μC/OS,最早出自于1992 年美 ...

  7. 嵌入式操作系统内核原理和开发

    嵌入式操作系统内核原理和开发(开篇) 操作系统是很多人每天必须打交道的东西,因为在你打开电脑的一刹那,随着bios自检结束,你的windows系统已经开始运行了.如果问大家操作系统是什么?可能有的人会 ...

  8. 嵌入式学习笔记(一)嵌入式操作系统测试

    嵌入式操作系统产品在学习的过程中,了解产品特性能够有助于学习产品功能,并且能够从用户角度发掘产品需要满足的重要特征,从而提炼产品特点,并且化作产品亮点,转化为产品未来占领市场.提升竞争力的关键切入点. ...

  9. 分析实时嵌入式系统软件调试问题

    设为首页 | 值班电话:18958035226 捷配欢迎您! [登录] 免费注册 | 行业黑名单 | 捷配商城 | 网站导航 全球领先的电子元器件市场 IC电子元器件PDF技术资料电子资讯电子通论坛 ...

最新文章

  1. c语言中程序偏离,C语言中的指针加减偏移量
  2. 清华直博,10年深耕于Al,对话自动驾驶独角兽创始人
  3. IntelliJ IDEA 2020.2.1 发布,Lombok插件可能被官方支持
  4. Oracle 备份与恢复学习笔记(6_1)
  5. 使用CSS设置JavaFX饼图样式
  6. XML反序列化出错,XML 文档(2, 2)中有错误
  7. 在何时该用什么方式编译WinCE
  8. 编译性语言、解释性语言和脚本语言
  9. mysql的程序怎么升级成mysqli_如何将mysql更改为mysqli?-问答-阿里云开发者社区-阿里云...
  10. 51 FI配置-财务会计-固定资产-折旧-维护期间控制方法
  11. JavaScript NaN 属性
  12. 几种方法找到整型阵列中的最大值和最小值
  13. 在竞赛中不断成长--(广油最帅的崽)行走的皮卡丘
  14. oppo计算机找不到,oppo手机文件在电脑上无法读取怎么办
  15. paperwhite3翻页_亚马逊Kindle Paperwhite 3G / Wi-Fi评论
  16. 从零到上亿用户,我是如何一步步优化MySQL数据库的?(建议收藏)
  17. python网络爬虫网易云音乐_怎么使用Python网络爬虫爬取网易云音乐歌词
  18. ffmpeg实现硬件转码(使用FFmpeg调用NVIDIA GPU实现H265转码H264)
  19. mysql进阶教程pdf_Mysql基础到进阶精品视频教程附讲义文档 91课
  20. android百度天气预报接口,用百度天气接口的实现安卓天气预报(json数据)

热门文章

  1. Python 小型课设作业,仅200行代码,使用youtube-dl下载视频,使用OpenCV和ffmpeg处理视频成字符视频
  2. 安卓手机主题软件_安卓主题壁纸app下载-安卓主题壁纸软件下载v9.0.7
  3. Android上基于HSV颜色模型实现取色盘功能
  4. 【计算机组成原理】NRZ1、PM、FM、MFM的写电流波形及特点
  5. PowerPoint也可以速查文稿字数
  6. 开发运营必看,跳出雷区必须知道的微信小程序平台运营规范
  7. java 本质_java final本质解释,_Java_ 少侠科技
  8. 风险提示:“美食流多品牌全托管加盟”涉嫌诈骗
  9. Photoshop CS4 将图像放大,增加像素,提高清晰度
  10. 怎么写短视频标题?爆款短视频写作技巧总结