精华内容
下载资源
问答
  • 前言笔者在 《程序是如何在 CPU 中运行的(二)》中从 PC 指针寄存器的角度分析了一级函数调用和二级函数调用执行的过程,那么中断服务子程序又是如何被执行的呢?两者的相同点和不同点是什么呢?该篇文章笔者将详细地...

    前言

    笔者在 《程序是如何在 CPU 中运行的(二)》中从 PC 指针寄存器的角度分析了一级函数调用和二级函数调用执行的过程,那么中断服务子程序又是如何被执行的呢?两者的相同点和不同点是什么呢?该篇文章笔者将详细地阐述这个概念。

    中断的概念

    当 CPU 正在处理某件事情的时候,外部发生的某一事件请求 CPU 迅速去处理,于是,CPU 暂时中止当前的工作,转去处理所发生的事件。中断服务处理完该事件以后,再回到原来被中止的地方,继续原来的工作,这样的过程称之为中断,示意图如下:

    195249593_1_20200710015203364

    中断响应及处理过程

    回顾函数调用的过程,子程序由主程序进行调用,从而完成执行。但是中断服务子程序并没有被主程序进行调用,中断服务子程序的执行是通过中断请求完成的,也就是说中断服务子程序可以发生在主程序执行的随意位置,那现在就面临一个问题了,如果当CPU 正在执行函数调用的子程序的内容的时候产生了一个中断请求,那么这个时候 CPU 将暂停执行函数调用的子程序的内容,转而去执行中断服务子程序的内容,如果不进行额外的处理,那么函数调用的子程序的相关数据将丢失,因此在执行中断服务子程序之前,CPU 必须要保存发生中断的那个地方的相关信息,这个操作用专业的术语来讲就是保护现场,保护现场之后,CPU 将执行中断服务子程序的内容,执行完中断服务子程序的内容之后,CPU 要回到刚刚暂停的地方继续执行,另外在返回之前,CPU 还要进行恢复现场,恢复现场之后,就可以返回到暂停的地方继续执行了,下面是整个过程的示意图:

    195249593_2_20200710015203505

    通过上述示意图我们也可以看到在返回地址这个地方,中断服务子程序和函数调用子程序的返回地址所遵循的原理是一样的,函数调用子程序的返回地址是函数调用指令的下一条指令的地址,而在上述示意图中的 N 和 N 1 的含义也是类似的,当 CPU 执行到第 N 条指令的时候,CPU 接收到了一个中断请求,在执行完第 N 条指令之后,转而去执行中断服务子程序的内容,然后中断服务子程序的返回地址对应的是第 N 1 条指令的地址。

    中断的堆栈占用

    在刚刚所述的内容中,说到 CPU 在执行中断服务子程序的内容之前,需要保护现场,那保护现场这个操作具体是怎么实现的呢?这个时候,就要用到我们的堆栈了。在这里拿 ARM Cortex M3 举例,在响应中断时所做的第一个操作就是保护现场,它会依次把 xPSR,PC,LR,R12以及 R3-R0 由硬件自动压入适当的堆栈中,注意,这里是自动压入堆栈,也就是说如果我们看对应的汇编代码是看不到这部分压栈操作的。另外,我们知道对于 ARM Cortex M3 的堆栈来说,它存在两个,一个是主堆栈指针(MSP),一个是线程堆栈指针(PSP),其中主堆栈指针是复位后默认使用的堆栈指针,用于操作系统内核和中断处理程序,线程堆栈指针(PSP)是由用户的应用程序代码所使用。那么在执行现场保护时将相关寄存器的值压入堆栈,应该使用哪个堆栈指针呢?这也是存在一个原则的,如果在响应中断时,当前的代码正在使用线程堆栈指针(PSP),那么将使用线程堆栈指针(PSP)进行压栈,否则将使用主堆栈指针(MSP)。另外在 CPU 进入中断服务子程序之后,所涉及的堆栈操作所使用的堆栈一直是主堆栈指针(MSP)。为了更直观的展示这个过程,下图是发生中断请求后,堆栈的变化示意图:

    195249593_3_20200710015203552

    通过上图我们可以很清楚地看到在响应中断时产生的保护现场操作,堆栈明显增长了,而在执行完中断服务子程序的内容之后,又将执行恢复现场的操作,这个时候堆栈的内容又减少了。

    为了更清楚地展示压入堆栈寄存器的操作,笔者在这里也给出上述图中堆栈粉色部分的详细内容,图片如下:

    195249593_4_20200710015203646

    上述就是保护现场时所压入堆栈的相关寄存器,另外还需注意的一点是当所涉及的中断服务子程序逻辑比较复杂的时候,就需要更多的寄存器了,这个时候就需要用到 R4-R11 了,但是这部分寄存器是不能进行自动压栈的,也就是说如果在中断服务子程序中使用到这部分寄存器的时候就需要进行手动压栈,那么这部分的压栈操作在汇编层面就能看到了。

    中断向量表

    在上述所阐述的内容中,我们知道了中断会在主程序的任意发生中断请求,从而执行中断服务子程序的内容,也阐述了在执行中断服务子程序的内容之前需要进行保护现场的操作,以及执行完中断服务子程序的内容之后需要进行恢复现场。现在我们再来思考,在 CPU 中,中断源不止一种,可以是按键按下所触发的一个外部中断,也可能是在使用串行通信时,收到数据所触发的一个中断,亦或者在 CPU 中定义的一个定时中断由于设置的时间到了而触发的定时中断,这个时候,就浮现一个问题了,要如何将这一个一个的中断源与其各自的中断服务子程序所一一对应起来呢?换句更为通俗的话来讲就是当 CPU 接收到一个中断信号时,CPU 将如何找到对应的中断服务子程序进行执行呢?这个时候,就需要中断向量表了,下面是中断向量表的特点:

    中断向量表在 CPU 中是一段连续的存储空间

    中断向量表在 CPU 复位后有默认的起始地址

    每一个中断在中断向量表中都有对应的表项,该表项的值为该中断源对应的中断服务程序的地址

    由程序代码确定中断向量表中的每个表项

    上述特点说中断向量表都存在默认的起始地址,在这里依旧拿 ARM Cortex M3 内核来看,它的中断向量表默认的起始地址是从地址 0x0000 0000 开始的,如下图所示:

    195249593_5_20200710015203724

    当然这只是一部分,并不是全部的表项。有了中断向量表之后,那么当 CPU 接收到中断请求的时候,就会根据这个中断请求的信号去查这个表,从而查找到其所对应的中断服务子程序的地址,然后将这个地址赋值给 PC 指针寄存器就,那么 CPU 就可以完成中断服务子程序的执行了,对于 PC 指针寄存器不是太清楚地朋友可以看笔者的这篇文章 《程序是如何在 CPU 中运行的(二)》。

    中断服务函数的写法

    中断服务函数的写法不同的 CPU 有各自不同的写法,对于 ARM Cortex M3 的 CPU 来说,因为其内核的特点,在执行完中断服务函数后的返回指令与普通函数调用的返回指令是一样的,因此中断服务函数的写法与 C 语言中普通函数的定义没有区别,比如下面是 STM32F103 的一个外部中断的服务函数

    void EXTI0_IRQHandler(void)

    {

    /* 确保是否产生了中断 */

    if(EXTI_GetITStatus(EXTI_Line0) != RESET)

    {

    /*用户代码*/

    /*清除中断标志位*/

    EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);

    }

    }1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    通过上述的代码我们可以看到中断服务函数的另一个特点,就是它的返回值和形参都为 void ,这也是由原因的,因为中断服务函数本来就不是由主程序进行调用的,既然中断服务函数不会被其他函数所调用,那么其返回值和形参自然是 void 了。

    上述说到是因为 ARM Cortex M3 的 CPU 在处理中断服务函数的返回地址时用的指令和普通函数调用时的返回地址的指令一致,所以才能够使中断服务函数的写法与普通 C 语言函数没有差异,下面举一个 51 单片机的定时器中断服务函数的例子:

    void InterruptTimer0() interrupt 1

    {

    /*省略*/

    }1

    2

    3

    4

    上述的这个中断服务函数, InterruptTimer0可以任意起,但是括号后面的是有严格规定的,为了 51 单片机能够进行中断处理,C51 编译器对函数进行了扩展,增加了一个扩展关键字interrupt,从而让 CPU 知道这个是一个中断服务函数。

    中断的嵌套

    C 语言函数能够进行嵌套调用,同样的中断服务函数也能够进行嵌套,同样的用一张图来表明中断的嵌套:

    195249593_6_20200710015203880

    可以看到中断的嵌套也是在消耗堆栈的,和使用函数嵌套调用一个道理,这里需要注意的是中断是存在优先级的,如果发生了一个比当前执行的中断优先级低的中断请求,那么新产生的中断请求会等待正在执行的中断执行完成之后才开始响应新的中断,如果产生的中断的优先级比当前的优先级要高,那么也就会像上图所示一样进行执行。另外需要注意的是,中断的优先级是有限的,也就是说中断嵌套的层数是有限的,如果再考虑堆栈溢出的话,那么中断嵌套的层数还和堆栈的大小有关。

    总结

    上述就是关于中断的相关内容,简单地叙述了中断是如何响应的,如何执行保护现场和恢复现场的操作,CPU 如何根据中断向量表找到对应的中断服务函数,以及中断的嵌套,这就是这次分享的全部内容啦~

    展开全文
  • 目录 中断执行的四种方式 continue 代码 执行效果 ...代码 ...有关中断执行的注意点 ...相同语句但是中断执行的方式一样,会出现不同的效果。 continue 代码 using System; namespace ConsoleA.

    目录

    中断执行的四种方式

    continue

    代码

     执行效果

    break

    代码

    效果

    有关中断执行的注意点


    中断执行的四种方式

    • continue :立即终止当前的循环(继续执行下一次循环)
    • break :立即终止循环,继续执行循环后面的第一行代码
    • goto :可以跳出循环,到已标记好的位置上
    • return:跳出包含其的函数

    相同语句但是中断执行的方式不一样,会出现不同的效果。

    continue

    代码

    using System;
    
    namespace ConsoleApptest
    {
        class Program
        {
            static void Main(string[] args)
            {
                for (int i = 0; i < 10; i++)
                {
                    if (i % 2 == 1)
                    {
                        continue;
                    }
                    Console.WriteLine(i);
                }
            }
        }
    }
    

     执行效果

    break

    代码

    using System;
    
    namespace ConsoleApptest
    {
        class Program
        {
            static void Main(string[] args)
            {
                for (int i = 0; i < 10; i++)
                {
                    if (i % 2 == 1)
                    {
                        break;
                    }
                    Console.WriteLine(i);
                }
            }
    
        }
    }
    

    效果

    有关中断执行的注意点

    • goto可以跳出循环,但不能跳入
    • 注意continue和break的区别
    • 使用continue应该谨慎 
    展开全文
  • 最近一个小项目需要调用系统的外部命令去调用其他工具 执行操作,但是发现 使用Runtime.getRuntime().exec() 并执行成功。实例说明Runtime.getRuntime().exec(“nohup python /usr/local/datax/bin/datax.py /...

    最近一个小项目需要调用到系统的外部命令去调用其他工具 执行操作,

    但是发现 使用 Runtime.getRuntime().exec() 并不能执行成功。

    实例说明

    Runtime.getRuntime().exec(“nohup python /usr/local/datax/bin/datax.py /usr/local/datax/job/task6_job7.json >/data/app/logs/datax-exec.log  2>&1 & ”);

    发现 datax 并没有执行起来, 程序也没有阻塞执行,反正很快就执行完了。

    如果 加上 waitFor 呢?

    Runtime.getRuntime().exec(“nohup python /usr/local/datax/bin/datax.py /usr/local/datax/job/task6_job7.json >/data/app/logs/datax-exec.log  2>&1 & ”).waitFor();

    发现还是和之前的一样。

    如果明确等待时间看看

    Runtime.getRuntime().exec(“nohup python /usr/local/datax/bin/datax.py /usr/local/datax/job/task6_job7.json >/data/app/logs/datax-exec.log  2>&1 & ”).waitFor(1,, TimeUnit.MINUTES);

    发现 任务可以执行,但是

    1. 如果 本来执行 完 这个 命令耗时2分钟,那么如果配置等待1分钟,那么到了1分钟就会强制中断这个命令的执行!

    2. 会导致java 线程一直等待 ,执行 1分钟之后才会继续执行下去。

    貌似 这样并不好用啊。

    换种调用shell 的姿势

    同事说 他之前都是用这个 方法来调用 shell 命令的,并没有这个问题。试着将改为调用shell 脚本的方式呢

    以下是 脚本内容

    #!/bin/bash

    nohup python /usr/local/datax/bin/datax.py /usr/local/datax/job/task6_job7.json >/data/app/logs/datax-exec.log 2>&1 &

    echo "执行作业完成....."

    exit 0

    执行

    Runtime.getRuntime().exec(new String[]{"sh","/data/script/run-job.sh"}).waitFor();

    成功执行了 命令, 并且没有阻塞java的线程执行

    总结

    大概的意思就是 如果不用 sh 调用 shell 的方式,那么 其他方式在 java的 Runtime.getRuntime().exec 调用 之后就会 中断 执行。

    而 sh 的方式 就可以在 Runtime.getRuntime().exec 调用之后 在 系统 后台自动继续执行。

    展开全文
  • 刚写好的代码打算上传到git当中,结果不留神不知道哪出问题了导致push更新代码不成功,反而把自己写好几天的代码都弄丢了,回收站和360恢复文件什么的都找不到,搞了好久终于找到解决方法了,下面给大家附上解决的...

    直接步入正题
    刚写好的代码打算上传到git当中,结果不留神不知道哪出问题了导致push更新代码不成功,反而把自己写好几天的代码都弄丢了,回收站和360恢复文件什么的都找不到,搞了好久终于找到解决方法了,下面给大家附上解决的思路

    1.执行命令:
    git reflog

    在这里插入图片描述
    发现是 【 4214952 (购物车+收藏+订单) HEAD@{3}: 】这里操作时把代码搞丢了

    2. 执行命令:
    git reset --hard HEAD@{3}

    在这里插入图片描述
    出现 HEAD is now at 4de5b02 购物车+收藏+订单 这类型字样就说明你丢失的代码找回来了,成功找回代码不禁倒吸一口冷气,不然要撞墙了

    展开全文
  • 一起来学习LiteOS中断模块的源代码

    千次阅读 2021-03-12 10:07:10
    摘要:本文带领大家一起剖析了LiteOS中断模块的源代码。 本文我们来一起学习下LiteOS中断模块的源代码,文中所涉及的源代码,均可以在LiteOS开源站点https://gitee.com/LiteOS/LiteOS获取。中断代码、开发文档,...
  • python循环定时中断执行某一段程序...这样子每隔一段时间执行一次中断当然能用sleep,这样子整个进程就停在这了,而不是接着爬数据解决方法用到threading的Timer,也类似单片机那样子,在中断程序中再重置定时器,...
  • 关于如何中断线程的执行,又学一项新技能!!
  • 2018-03-28 00:56:39中断正在执行代码无论是%run执行的脚本还是长时间运行的命令ctrl + cIn [1]:KeyboardInterrupt执行剪切板中的代码ctrl-shift-VIn [1]: def f(x,y,z):...: return (x + y) / z...: a = 5...: b ...
  • 一、线程的状态线程可以阻塞于四种状态:1、当线程执行Thread.sleep()时,它一直阻塞指定的毫秒时间之后,或者阻塞被另一个线程打断;2、当线程碰到一条wait()语句时,它会一直阻塞接到通知notify()、被中断、...
  • FreeRTOS学习笔记--临界段代码处关闭中断一、临界段代码二、Cortex-M4中断管理三、中断屏蔽实验四、结语 一、临界段代码 大家在学习FreeRTOS时对...所以我们在执行这类代码时,需要将不必要的中断进行屏蔽,这就涉及
  • Java中断机制

    2021-02-25 18:32:12
    1. 引言当我们点击某个杀毒软件的取消按钮来停止查杀病毒时,当我们在控制台敲入quit命令以结束某个后台服务时……都需要通过一个线程去取消另一个线程正在执行的任务。...捕获或检测到中断后,是抛出Interrup...
  • 执行不到编辑器会报错Unreachable code(永远达不到的代码) public static void main(String[] args) { for(;;) { } System.out.println();//此处报错:Unreachable code(永远达不到的代码) } 2....
  • STM32串口接收中断执行了一次?

    千次阅读 2021-06-01 17:55:38
    插入代码 中断服务函数中去掉读取Res = UART_ReceiveData(UART2); 后 数据只能执行一次,估计是缓冲区被占位,必须读取出来才能继续接收 日后有时间再研究一下 解决方法 加上Res = UART_ReceiveData(UART2); ...
  • javascript中非常坑的一点是,所以的代码几乎都为异步执行做了准备,虽然在很多时候这样做确实很方便,但是有的时候却坑了开发者。在javascript中有一个很疼的问题,就是没有办法退出程序,也就是其他很多语言中都有...
  • 1、简介 2、中断处理 3、软中断
  • 在基本上,我正在创建一个登录系统作为我的课程作业的一个概念,但我在任何地方都找不到答案。在我的代码分为两个文件,一个logger,它用一个日志文件处理输入和输出,以及主要类,如数据库连接、登录代码本身等下面...
  • 中断中断处理流程

    千次阅读 2020-12-20 04:41:20
    1. 中断概念中断是指由于接收来自外围硬件(相对于中央处理器和内存)的异步信号或来自软件的同步信号,而进行相应的硬件/软件处理。发出这样的信号称为进行中断请求(interrupt request,IRQ)。硬件中断导致处理器...
  • 使用中断时,哪些处理在中断服务程序中执行,哪些处理在应用程序中执行中断服务程序怎样与应用程序通信? 软件与外设的交互,基本有两种模式:轮询和中断。轮询是由软件定时地查询外设的各种寄存器,检查该外设...
  • 定时器中断函数的使用

    千次阅读 2021-05-19 18:41:36
    1.定时器与延时的区别大家可能会觉得我们用延时函数照样可以实现上一讲代码的实验现象,但是定时器与延时的概念不同,延时函数需要占用CPU的使用权,正在延时的时候其他任务没有CPU的使用权就会拖慢执行效率。...
  • · 执行Promise里面的同步代码console.log('promise1') · 运行promise().then,发现是promise对象,推微任务队列中 · 执行console.log('end async') · test1外面的同步代码执行结束后,回到test1中,...
  • 从事嵌入式开发的伙伴可能会思考过一个问题,我们一般都是使用芯片厂商提供的驱动库和初始化文件,直接从main函数开始写程序,那么系统上电之后,程序怎么引导进main函数执行的呢?还有,系统上电之后RAM的数据是...
  • 它往往只是简单的读取寄存器中的中断状态并清除中断标志后就进行“登记中断”(也就是将底半部处理程序挂在设备的底半部执行队列中的工作)特点:响应速度快下半部:中断处理的大部分工作都在底半部,它几乎做中断...
  • 中断指令INT 理解

    2021-05-06 21:33:30
    前言 我们在学习操作系统时,在引导部分代码中,会看到 int 指令,比如: int 10h 书上会解释说,通过10h中断能够实现显示屏...功能:转相应的中断处理程序执行。 举例 mov ah, 1 ; 设置入参 int 21h ; 调用2
  • 单片机外部中断详解及程序

    千次阅读 2021-04-23 11:34:03
    单片机在自主运行的时候一般是在执行一个死循环程序,在没有外界干扰(输入信号)的时候它基本处于一个封闭状态。比如一个电子时钟,它会按时、分、秒的规律来自主运行并通过输出设备(如液晶显示屏)把时间显示出来...
  • 但是要注意,这两种程序同时有主从关系,主要体现在前者对后者的管理上。而主要的原因是内核程序能够执行某些特权指令而用户程序是没有使用权限的。因此,如果用户想要使用这些特权指令,而用户又能直接使用这些...
  • 内容摘要:这是之前有一个朋友项目中实际遇到的问题:在一个窗口中,希望点击某个按钮后(或者同类操作),播放一个警告的声音,很显然,...问题分析:播放音频本身难,而且在WPF中,音频播放默认就是异步的,根本...
  • 嵌入式中断:统计各中断关键信息 ,中断执行/挂起/被打断次数,中断优先级异常等 先上图 实现方法: 实现代码: 数据结构 初始化 获取中断寄存器数据:ICSR 获取中断寄存器数据:IABR 换算中断抢占数据 打印/存储...
  • 关注+星标公众号,错过精彩内容转自 | C语言与CPP编程1 前言 最近在公司维护的项目中碰到一个解决了定位很久的 bug , bug 找到的时候发现犯了很低级的错误——在中断处理函数...
  • 我希望能够在应用程序运行时执行其他代码(保存图片),以便保存所有图片,并在浏览器上打开页面时显示localhost。在我该怎么做才能同时完成这些任务?在烧瓶应用:app = Flask(__name__)@app.route(...
  • 中断的意思(学习过微机原理与接口技术的同学,没学过单片机,也应该知道),我们在这里就讲了,首先来回忆下中断系统涉及哪些问题。(1)中断源:中断请求信号的来源。(8051有3个内部中断源T0,T1,串行口,2个外部...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 396,037
精华内容 158,414
关键字:

中断部分代码执行不到