从Cortex-M3的MSP 和PSP谈Linux能否在中断中使用Sleep
1、Cortex-M3 的PSP和MSP
曾经在STM32上使用过RT thread和uC/OS,对于任务切换代码一直是一知半解,没有自己手动写出来过,对于任务切换后的ORR LR, LR, #0x04; Ensure exception return uses process stack也不是很理解,一次偶然的机会,遇到网上有人问这个问题,才去深入研究一下。Cortex‐M3 拥有两个堆栈指针,然而它们是banked,因此任一时刻只能使用其中的一个:
主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程)。
进程堆栈指针(PSP):由用户的应用程序代码使用。堆栈指针的最低两位永远是0,这意味着堆栈总是4 字节对齐的。
由此可以看出,在一个系统里有两大部分,一是操作系统和中断,一是用户用户程序,他们使用的资源是不一样的,在任务调度的时候,中断(任务调度的中断)返回到用户程序所以要使用PSP。
2、Linux系统中断中能否使用Sleep
这个是我一个同学的面试题,说给我的时候我第一反应是可以,在中断中使用Sleep不会使得中断挂起,在任务中使用Sleep会将当前的任务挂起,Sleep的原理是根据Sleep的参数N暂停当前的任务,N个周期(也可能是MS)后将该任务置为就绪态,换言之,Sleep实际上就是一次任务调度,那为什么不可以的,我还进一步解释,在uC/OS中,在中断的结尾都会调用OS_INT_EXIT()函数来进行任务的调度,Sleep与OS_INT_EXIT只是函数名不同,最终都是会调用调度器的。
哈哈,对于正确答案我想大家都猜到了,那就是当然不可以的啦,但是我的解释貌似天衣无缝哦,那是因为我是使用uC/OS来解释的,Linux系统当然和uC/OS不同,回头看看,在Cortex-M3的硬件中有MSP和PSP,那么他的设计初衷是什么,那就是操作系统(包括中断)和用户程序分(隔)离,或者说是保护操作系统,防止遭到破坏,在这种思想下,Linux系统中,对于涉及到系统核心的东西使用保护的,不是所有的地方都是可见的,uC/OS是系统和应用程序一起编译,只要是全局变量都是可以见的,而Linux不同,在中断上下为中,current宏是无效的,所以此时是无法进行任务调度的。
以上是我结合Cortex-M3内核的硬件,从隔离和保护的思想去解释为什么Linux下,中断中不能使用Sleep。下面给出我查阅资料的官方解释,主要是《linux内核设计与实现》上的内容。
1、进程上下文
可执行代码是进程的重要组成部分,这些代码从一个可执行文件载入到进程的地址空间执行。一般的程序在用户空间执行,当一个程序执行了系统调用或者触发了某个异常,它就陷入了内核空间,此时,我们称内核代表进程执行并处于进程上下文中。在此上下文中current宏是有效的。(系统调用和异常处理程序是对内核明确定义的接口,进程只有通过这些接口才能陷入内核执行—对内核的所有访问都必须通过这些接口。
2、中断上下文
当执行一个中断处理程序时,内核处于中断上下文中,中断上下文和进程并没有任何瓜葛。与current宏也是不相干的(尽管它会指向被被中断的进程)。因为没有后备进程,所以中断上下文不可以睡眠,否则又怎能再对它重新调度呢?因此,不能从中断上下文中调用某些函数(就是被中断处理程序限制的函数,Sleep就是其中一个)。
事实上,除了MSP和PSP之外,处理器很多的寄存器都是banked,用户程序和中断程序使用的寄存器是不同的,所以进程上下文和中断上下文环境是不同的,如果在中断上下文中进行任务调度,是没有办法保存进程上下文信息的,所以如果这个时候调度就是有问题的,软件上阻止了该调度——即current宏此时是不可见的,从而无法进行调度。
从Cortex-M3的MSP 和PSP谈Linux能否在中断中使用Sleep的更多相关文章
- Cortex-M3双堆栈MSP和PSP+函数栈帧
为了防止几百年以后找不到该文章,特此转载 ------------------------------------------------开始转载--------------------------- ...
- 【freertos】002-posix模拟器设计与cortex m3异常处理
目录 前言 posix 标准接口层设计 模拟器的系统心跳 模拟器的task底层实质 模拟器的任务切换原理 cortex M3/M4异常处理 双堆栈指针 双操作模式 栈帧 EXC_RETURN 前言 如 ...
- ARM Cortex M3(V7-M架构)硬件启动程序 一
Cortex-m3启动代码分析笔记 启动代码文件名是STM32F10X.S,它的作用先总结下,然后再分析. 启动代码作用一般是: 1)堆和栈的初始化: 2)中断向量表定义: 3)地址重映射及中断向量表 ...
- stm32和cortex M3学习内核简单总结
1.stm32综述 2.寄存器组 3.操作模式和特权级别 4.存储器映射 5.中断和异常 6.其他 Stm32综述 这可以说是我第一款认真学习的单片机了,学完这个就要开启我通往arm9的大门了,接下来 ...
- ARM Cortex M3系列GPIO口介绍(工作方式探讨)
一.Cortex M3的GPIO口特性 在介绍GPIO口功能前,有必要先说明一下M3的结构框图,这样能够更好理解总线结构和GPIO所处的位置. Cortex M3结构框图 从图中可以看出 ...
- ARM 架构、ARM7、ARM9、STM32、Cortex M3 M4 、51、AVR 之间有什么区别和联系?(转载自知乎)
ARM架构: 由英国ARM公司设计的一系列32位的RISC微处理器架构总称,现有ARMv1~ARMv8种类. ARM7: 一类采用ARMv3或ARMv4架构的,使用冯诺依曼结构的内核. ...
- app和bootloader跳转 MSP与PSP
1.不要把跳转函数放在中断中,如此导致在跳转后的app或者bootloder都是在中断状态,只要你一开启该中断,就可能出现硬件中断了 2.如果你的APP使用了ucos系统,在跳转函数中还需要增加__s ...
- STM32学习之路入门篇之指令集及cortex——m3的存储系统
STM32学习之路入门篇之指令集及cortex——m3的存储系统 一.汇编语言基础 一).汇编语言:基本语法 1.汇编指令最典型的书写模式: 标号 操作码 操作数1, 操作数2,... ...
- Implementation of Serial Wire JTAG flash programming in ARM Cortex M3 Processors
Implementation of Serial Wire JTAG flash programming in ARM Cortex M3 Processors The goal of the pro ...
随机推荐
- Android笔记(三十) Android中线程之间的通信(二)Handler消息传递机制
什么是Handler 之前说过了,Android不允许主线程(MainThread)外的线程(WorkerThread)去修改UI组件,但是又不能把所有的更新UI的操作都放在主线程中去(会造成ANR) ...
- Scala 中 call by name & call by value 的区别
call by value:会先计算参数的值,然后再传递给被调用的函数 call by name:参数会到实际使用的时候才计算 定义方法 def return1():Int = { println(& ...
- 使用Arduino开发板控制步进电机
目前为止,我还没有真正深入了解过电机,特别是步进电机. 最近我在计划一个项目,需要相对精确的电机控制,所以可能会使用到步进电机,但很快就意识到我首先应该更多地了解这些. 本篇文章主要介绍我到目前为止学 ...
- XSLT格式
XSL 指扩展样式表语言(EXtensible Stylesheet Language). XSL - 不仅仅是样式表语言,包括三部分: XSLT :一种用于转换 XML 文档的语言. XPath : ...
- element ui框架把el-select选中的value设置为对象
- 获取历史K线数据的几个方法
1.通过已有的股票交易软件下载数据,如果他们是开源结构的,就可以解析他们的K线数据. 2.在互联网上抓取数据 int iStockCode;CString strUrl; 通过OpenUrl.Read ...
- 使用 IDEA 打包spring cloud 成 jar在ubuntu 中运行
1. 打开终端 termial , 使用 mvn install . 如果提示 mvn 不是xx 命令 ; 2 则需要配置环境变量 : path : C:\Program F ...
- LeetCode 273. Integer to English Words
原题链接在这里:https://leetcode.com/problems/integer-to-english-words/description/ 题目: Convert a non-negati ...
- 【安卓进阶】Product Flavor基础玩法
在安卓项目开发中,大多时候总是有测试环境.生产环境之类的区别,在不使用Product Flavor时,我们一般都是通过手工改动代码来实现测试环境.生产环境的切换. 这样就造成了项目管理上的不便,频繁的 ...
- sql server in和exists 的区别
如图,现在有两个数据集,左边表示#tempTable1,右边表示#tempTable2.现在有以下问题: 1.求两个集的交集? 2.求tempTable1中不属于集#tempTable2的集? 先 ...