SylixOS ArmV7m 支持

问题分析

Cortex-M系列与Cortex-A系列不同,在中断处理函数中,会产生如下情况:
问题一
Cortex-A系列进入中断后,会切换到IRQ模式,同时硬件上自动关闭IRQ,而Cortex-M系列进入中断后,硬件不会自动关闭中断。即使中断处理中,第一条指令执行CPSID I关闭中断,如果有高优先级中断产生,仍然有可能还没有来的及关中断,就被高优先级中断抢占(晚到中断)。这种情况属于中断嵌套,但是此时系统的CPU_ulInterNesting次数仍然是1,这里需要额外处理

问题二
在任务切换时,Cortex-A可以将LR赋值给PC值时,同时将保存的SPSR的值赋给CPSR,即赋值PC的时候同时打开中断,这里可以理解为原子操作。而Cortex-M系列的开中断操作需要额外的指令,且硬件上无法保证开中断和BX LR的原子性,有可能在执行中断服务程序时,由于此时是关中断的,已经有高优先级中断处于Pending状态,一旦我打开中断,没有来得及执行BX LR,就被高优先级中断抢占,此时仍然属于中断嵌套,但是CPU_ulInterNesting次数仍然是1,所以也需要做特殊处理


解决方法分析

无论是问题一还是问题二,在硬件上都属于中断嵌套,但是由于发生这两种情况时,CPU_ulInterNesting为1,所以系统看来,都不属于中断嵌套,这样会产生问题。

1.针对问题二,当执行BX LR时,如果被抢占,之前考虑的解决方法是对于此时的现场不做保护,因为我们只需要保证返回到任务被中断现场即可,这里涉及到一个问题,即嵌套的两级中断并没有按层次返回,而是直接从嵌套中断返回到任务,这种做法对于Cortex-M系列是不允许的,会产生Usage fault,如下图(图片来源于The definitive guide to the ARM Cortex-M3):

图片内容解释如下,当Task A运行时被外设IRQ打断,在执行IRQ服务程序时,产生更高优先级中断(SysTick),在SysTick中,如果发生了上下文切换,那么CPU会直接切换到Task B去运行,而没有回到IRQ服务程序,这样会产生Usage fault异常。这样设计是合理地,中断服务程序应该优先处理。为了避免产生Usage fault,这里可以手动执行一次BX LR操作,且要保证MSP中内容与中断嵌套时硬件自动压栈内容一致(否则仍然产生Usage fault),这种方法虽然可以解决Usage fault,但是欺骗了处理器,可能存在一定风险,所以不采用这种方法。

2.针对问题一和二,在执行服务程序后,进行API_InterExit时,都不应该进行任务调度,否则如果有高优先级任务产生,会切换到高优先级运行,而此时处于中断嵌套,这样就会产生Usage fault。所以要保证当问题一和二的情况发生时,不能发生调度。对于问题一发生时,即使不进行调度,在其返回后,仍热会执行API_InterExit,进行调度,所以不存在问题。如果在问题二发生时,由于我任务现场已经恢复了,如果调度时发现有高优先级任务产生,会导致pcpuCur->CPU_ptcbTCBCur与当前上下文不对应,如果不调度的话,虽然可以继续正常运行,但是如果此刻已经有高优先级任务就绪,由于这里没有调度会导致调度延迟,最坏情况会导致一个tick,这是不允许的,所以这里使用了PendSV来避免该情况。如果此时情况一和情况二发生,此时虽然不执行调度程序,但是会置位PendSV,由于PendSV优先级最低,当完成任务切换时,会立即执行PendSV服务程序,并执行一次调度,选取最高优先级任务运行。目前的中断处理流程如下图:

目前在问题一和二发生时没有执行调度,而是发送PendSV,最佳的方法是执行调度程序,但是不会修改pcpuCur->CPU_ptcbTCBCur,仅仅判断是否有高优先级任务,如果有高优先级任务需要执行,再发送PendSV,否则不会发送PendSV,这样不会导致pcpuCur->CPU_ptcbTCBCur和任务上下文不一致。目前的方法不是最好的,有可能在发送PendSV时,并不需要调度。对于蓝色的允许抢占的中断服务程序,这里面是不会发送PendSV的,只会在最外层中断执行调度。

SylixOS ArmV7m 支持相关推荐

  1. 【050】SylixOS全面支持C-SKY系列处理器

    SylixOS全面支持C-SKY系列处理器 发布于2018年11月09日 翼辉欢迎新朋友C-SKY 今天是C-SKYCPU架构加入SylixOS生态的日子,有了C-SKY的加入,SylixOS能够支持 ...

  2. 【039】SylixOS支持多核RISC-V处理器

    SylixOS支持多核RISC-V处理器 发布于2018年04月23日 2018年3月31日,SiFive发布全球首款多核全功能RISC-V处理器:FU540,此款处理器也是全球第一颗有能力运行标准L ...

  3. SylixOS电源管理之外设功耗管理

    1.前言 在这个世界中,任何系统的运转都需要能量.如树木依靠光能生长,如马儿依靠食物奔跑,如计算机系统依靠电能运行.而能量的获取是有成本的,因此如果能在保证系统运转的基础上,尽量节省对能量的消耗,就会 ...

  4. SylixOS快问快答

    Q: SylixOS 版权是什么形式, 是否分为<开发版税>和<运行时版税>. A: SylixOS 是开源并免费的操作系统, 支持 BSD/GPL 协议(GPL 版本暂未确定 ...

  5. SylixOS进化简史

    内容来自 SylixOS内核文件<README>,从中我们可以看到SylixOS不断完善的大体阶段. 23:05 2009-4-18 SylixOS 作者 2005 年毕业于西安科技大学测 ...

  6. SylixOS中的中断接口基础实现

    SylixOS中断实现相对简单,主要借助arch接口,bsp接口,cpu对象,调度接口等实现.还通过数组和链表管理中断对象. 基于arch接口实现类 全局中断开关接口的简单封装. #define KN ...

  7. 3.ARMv7-M exception model(1)

    ARMv7-M exception model ARMv7-M和ARMv7在异常处理中的不同为:ARMv7-M在异常进入和退出时使用硬件进行关键信息保存和恢复,并且使用Vector中的table代笔异 ...

  8. SylixOS更新记录

    内容来自 SylixOS内核文件<CHANGELOG>,从中我们可以看到SylixOS不断完善的细节. HISTORY (GIT HEAD) ++ New features: 2020-0 ...

  9. SylixOS 经得起检验的国产操作系统 (四)

    内核服务 SylixOS内核小巧,它提供的操作系统最基础的服务,这些服务包括:        1.        线程管理        2.        协程管理        3.        ...

最新文章

  1. JAVA 线上故障排查完整套路,从 CPU、磁盘、内存、网络、GC 一条龙!
  2. 使用soapUI代替WSDL2JAVA生成cxf HTTPS 客户端调用代码
  3. Linux下使用mail命令发送邮件
  4. SpringMVC的数据响应-回写数据-直接回写json格式字符串(应用)
  5. C++主要操作符重载的定义和总结
  6. reinterpret_cast和static_cast的总结
  7. Eclipse 常用快捷键,实战经典
  8. 7位领域大佬,带你解读三维点云的前沿应用
  9. screen,client,page三种确定鼠标坐标的区别和原生JS事件写法,区别于Jquery的$.on(x,y);和$.click()...
  10. HDU2009 求数列的和【入门】
  11. 图嵌入(一)--综述
  12. 拓端tecdat|R语言代写岭回归ridge regression分析租房价格报告
  13. Wifi文件传输项目总结
  14. 七天引爆社交新零售(助你提高十倍业绩)——前言
  15. 柱状图中xy轴怎么出现_『怎样设置excel图标的x、y轴』excel图表xy轴名称
  16. iOS 保持界面流畅的技巧,满满都是收获。
  17. vue在微信里面的兼容问题_Vue在 iOS 微信浏览器下不能播放
  18. 诊断公司的CRO业务简述
  19. 个人Javascript学习
  20. 【C语言】对输入的若干个数去重并排序的算法

热门文章

  1. 《深度探索C++对象模型》:简单对象模型、表格驱动模型、C++对象模型
  2. Simulink Test自动化(三)-创建TestReport和CoverageReport
  3. JavaScript随手笔记---数组中相同的元素进行分组(数据聚合) groupBy函数
  4. 多项式算法3:多项式除法
  5. 电竞天才Uzi宣布退役!用数据带你回顾他的职业生涯
  6. Linux如何查看内核版本并安装内核头文件linux-headers-generic
  7. java程序员 女装_java程序员面试着装要求
  8. Alian解读SpringBoot 2.6.0 源码(一):SpringApplication对象创建(Spring工厂加载机制)
  9. 动态窗口算法(DWA)
  10. python scatter函数_Matplotlib之scatter()函数