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的更多相关文章

  1. Cortex-M3双堆栈MSP和PSP+函数栈帧

    为了防止几百年以后找不到该文章,特此转载 ------------------------------------------------开始转载--------------------------- ...

  2. 【freertos】002-posix模拟器设计与cortex m3异常处理

    目录 前言 posix 标准接口层设计 模拟器的系统心跳 模拟器的task底层实质 模拟器的任务切换原理 cortex M3/M4异常处理 双堆栈指针 双操作模式 栈帧 EXC_RETURN 前言 如 ...

  3. ARM Cortex M3(V7-M架构)硬件启动程序 一

    Cortex-m3启动代码分析笔记 启动代码文件名是STM32F10X.S,它的作用先总结下,然后再分析. 启动代码作用一般是: 1)堆和栈的初始化: 2)中断向量表定义: 3)地址重映射及中断向量表 ...

  4. stm32和cortex M3学习内核简单总结

    1.stm32综述 2.寄存器组 3.操作模式和特权级别 4.存储器映射 5.中断和异常 6.其他 Stm32综述 这可以说是我第一款认真学习的单片机了,学完这个就要开启我通往arm9的大门了,接下来 ...

  5. ARM Cortex M3系列GPIO口介绍(工作方式探讨)

    一.Cortex M3的GPIO口特性    在介绍GPIO口功能前,有必要先说明一下M3的结构框图,这样能够更好理解总线结构和GPIO所处的位置. Cortex M3结构框图     从图中可以看出 ...

  6. ARM 架构、ARM7、ARM9、STM32、Cortex M3 M4 、51、AVR 之间有什么区别和联系?(转载自知乎)

    ARM架构:  由英国ARM公司设计的一系列32位的RISC微处理器架构总称,现有ARMv1~ARMv8种类. ARM7:       一类采用ARMv3或ARMv4架构的,使用冯诺依曼结构的内核. ...

  7. app和bootloader跳转 MSP与PSP

    1.不要把跳转函数放在中断中,如此导致在跳转后的app或者bootloder都是在中断状态,只要你一开启该中断,就可能出现硬件中断了 2.如果你的APP使用了ucos系统,在跳转函数中还需要增加__s ...

  8. STM32学习之路入门篇之指令集及cortex——m3的存储系统

    STM32学习之路入门篇之指令集及cortex——m3的存储系统 一.汇编语言基础 一).汇编语言:基本语法 1.汇编指令最典型的书写模式: 标号 操作码        操作数1, 操作数2,... ...

  9. 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 ...

随机推荐

  1. thinkphp5自动生成文档/注释代码自动生成api文档

    composer require weiwei/api-doc dev-master 安装之后,readme 有详细的使用说明代码: 部分界面: gitbub:https://github.com/z ...

  2. Linux ls命令参数详解 <转>

    下面是一个与 ls 一起使用的一些常用选项的简短列表.请记住,你可以通过阅读 ls 的说明书页(man ls)来获得选项的完整列表. -a – 全部(all).列举目录中的全部文件,包括隐藏文件(.f ...

  3. Needham-Schroeder协议的形式化描述语言

    1.对TLS1.3协议形式化描述过程 第一步:   Needham-Schroeder 过程的分析 常量和变量的定义: /* * Needham-Schroeder过程的形式化描述 */ // THE ...

  4. 【问题】man命令打开的手册上链接怎么展开?

    参考:How to follow links in linux man pages? 前言 在使用man查看命令帮助的时候,有些文字下面会有下划线.给人的感觉是一个链接,但是又打不开.那么到底是不是链 ...

  5. 数据库中的Schema到底是什么

    参考:http://database.guide/what-is-a-database-schema/ 在数据库中,schema(发音 “skee-muh” 或者“skee-mah”,中文叫模式)是数 ...

  6. Java泛型全解析【接口、类、封装类型】

    目录   1.导读  2.为何需要泛型?   3.泛型的定义格式   3.泛型的好处  4.什么时候使用泛型?   5.泛型的擦除   6.泛型的补偿  7.泛型的应用      7.1[泛型类]   ...

  7. Swaks - SMTP界的瑞士军刀

    0x00 安装: kali中自带,或者从作者网页下载 http://www.jetmore.org/john/code/swaks/ 0x01 基本用法: swaks –to <要测试的邮箱&g ...

  8. 用js刷剑指offer(二叉搜索树的后序遍历序列)

    题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 牛客网链接 js代码 function Verif ...

  9. lombok自定义扩展实践

    lombok是一款能够在java代码编译阶段改变代码的插件.比如生成setter和getter方法,生成log类变量等,能够简化一些特定的模版式代码.本文将以实现一个基于特定注解生成日志代码的方式,简 ...

  10. 40个优化你的php代码的小提示

    1. 若是一个办法可静态化,就对它做静态声明.速度可提拔至4倍. 2. echo 比 print 快. 3. 应用echo的多重参数(译注:指用逗号而不是句点)庖代字符串连接. 4. 在履行for轮回 ...