• IM6ULL学习第18章Linux 系统对中断的处理


    什么是栈

    栈是一段内存空间。
    
    • 1

    ARM处理器程序的运行过程

    ARM芯片属于精简指令集(RISC:Reduced Instruction Set Computing)
    特点:
    1、对内存只有读和写两种指令,
    2、所有的数据运算都是在CPU内部完成的。
    
    • 1
    • 2
    • 3
    • 4

    举例实现a=a+b;
    在这里插入图片描述

    CPU 先在内存中读取a,b的值放入到CPU的寄存器(这里的寄存器不是指的内存中分配的)中,再进行运算,然后把计算值返回到内存中。
    1把内存 a 的值读入 CPU 寄存器 R0,
    2 把内存 b 的值读入 CPU 寄存器 R1,
    3 把 R0、R1 累加,存入 R0,
    4 把 R0 的值写入内存 a。
    这个过程中R0 R1寄存器的值会被刷新,那这时如果有B函数打断这个函数,或者响应中断打断这个函数,他们也会使用到CPU中R0,R1寄存器,那么原有的寄存器中的值会被刷新,该如何解决?这时便引入了现场保存和恢复问题。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    程序被中断时,怎么保存现场

    当正在运行的程序被打断时,这时会将CPU寄存器的值保存到相应的栈中。等恢复现场时,再将这些值取出给CPU寄存器。
    
    • 1

    举例1函数A中调用函数B流程如下图所示。
    在这里插入图片描述
    1、函数调用
    在函数 A 里调用函数 B,实际就是中断函数 A 的执行,那么需要把函数 A 调用 B 之前瞬间的 CPU 寄存器的值,保存到栈里;再去执行函数 B;B函数可能之前被调用过,会现将B函数的栈中的值回传给CPU中的寄存器中,运行B函数的代码;B函数调用完成以后,恢复现场,现将B函数中的值存进B对应的栈中将A函数的栈中的值取出给CPU,再继续运行A函数的代码
    2、中断处理
    a) 进程 A 正在执行,这时候发生了中断。
    b) CPU 强制跳到中断异常向量地址去执行,
    c) 这时就需要保存进程 A 被中断瞬间的 CPU 寄存器值
    d) 可以保存在进程 A 的内核态栈,也可以保存在进程 A 的内核结构体中。(这个是不是和后面的两种方法有关我这还不清楚
    e) 中断处理完毕,要继续运行进程 A 之前,恢复这些值。
    3、进程切换
    a) 在所谓的多任务操作系统中,我们以为多个程序是同时运行的。
    b) 如果我们能感知微秒、纳秒级的事件,可以发现操作系统时让这些程序
    依次执行一小段时间,进程 A 的时间用完了,就切换到进程 B。
    c) 怎么切换?
    d) 切换过程是发生在内核态里的,跟中断的处理类似。
    e) 进程 A 的被切换瞬间的 CPU 寄存器值保存在某个地方;
    f) 恢复进程 B 之前保存的 CPU 寄存器值,这样就可以运行进程 B 了。
    可通过下图理解下。
    在这里插入图片描述

    进程和线程的概念

    在 Linux 中:资源分配的单位是进程,调度的单位是线程。

    用线程来处理下半部中断原理

    内核会提供一个worker线程,这个线程里有个work queue 队列;在这个work queue中放一个work struct 结构体,这个结构体提供一个.fun成员就是要执行的函数。
    也就是说,在一个进程里,可能有多个线程,这些线程共用打开的文件句柄、全局变量等等。
    
    • 1
    • 2

    这里我理解线程就是任务,他们可以访问这个进程(相当于单片机中的工程)的定义的一些全局变量
    而这些线程,之间是互相独立的,“同时运行”,也就是说:每一个线程,都有自己的栈。
    在这里插入图片描述

    Linux中系统对中断处理方法

    Linux系统对中断处理的两个原则

    1不能进行中断嵌套,也就是说当前中断响应时,即使优先级更高的中断发生也不能打断当前中断去响应
    2中断的处理越快越好。
    
    • 1
    • 2

    Linux中的中断的扩展

    硬件中断
    硬件中断:每个硬件产生的中断比如按键产生的中断,这类中断称为硬件中断。先可以认为硬件中断是由数组实现的。
    数组中存放的是函数指针。
    
    • 1
    • 2

    在这里插入图片描述
    当A中断发生时,相应的A函数将会被调用。

    软件中断:

    在这里插入图片描述

    软件中断和硬件中断相比,软件中断是认为制造的中断,也有相应的中断号和对应的中断函数,此外还有一个flage用于标记是否产生了中断。那么存在以下两个问题。
    1软件中断何时生产?
    由软件决定,对于 X 号软件中断,只需要把它的 flag 设置为 1 就表示发生了该中断。
    2软件中断何时处理?
    在处理完硬件中断后,再去处理软件中断。软件中断相当于有硬件中断响应后会遍历一下这个数组,检查是否有flage为1,为1响应响应的软件中断
    
    • 1
    • 2
    • 3
    • 4
    • 5

    用上下两部分(硬件中断、软件中断分开)的方式处理中断

    这里注意硬件中断不能够被打断,软件中断可以被实时发生的硬件中断打断
    
    • 1

    在这里插入图片描述

     硬件中断发生时,开始处理,preempt_count(这里简称pct)++为,然后执行中断上半部(硬件中断),硬件中断执行完毕pct--为0,这时判断pct?(pct为0故4为假)执行N,pct++为1然后开启中断(开启中断的意思是可以响应其他硬件中断),处理下半部中断(软件中断),这里分两种情况1、处理软件中断过程中如果没有其他硬件中断打断,则继续处理软件中断,执行完毕后关中断(这时不能响应硬件中断了),然后关中断(硬件中断不能响应),pct-- 为0。2、处理软件中断过程中如果有其他硬件中断(中断B)打断,这时跳到B中断的开始处理处pct++为2 硬件中断B处理,然后pct--为1判断pct,pct为真完成处理,回到硬件中断A的软件中断处,继续处理A和B的软件中断。
    
    • 1

    实现用线程来处理下半部中断的方法

    1先构造一个worker结构体里面提供.func(要执行的函数)
    2中断上半部执行时将worker放入work queue中。
    
    • 1
    • 2

    线程化的中断进行处理 threaded irq

    	对每一个中断都提供一个中断线程。应对于多核cpu。因为一个中断线程只能在一个核上运行,多创建几个可以在多个核的cpu上运行。
    
    • 1
    	内核提供了一个函数 request_threaded_irq,这个函数中的参数irq为中断号查询哪个中断,handler 为上半部中断,上半部中断可以为空这样上半部中断都可以在线程中运行。你可以thread_fn,系统会为这个函数创建一个内核线程,发生中断时,内核线程就会执行这个函数。
    
    • 1

    新技术 threaded irq,为每一个中断都创建一个内核线程;多个中断的内核线程可以分配到多个 CPU 上执行,这提高了效率。
    
    • 1

    这里只是学习时的个人理解仅供个人学习和参考,感谢韦东山老师资料提供的文档,如有侵权即刻删除

  • 相关阅读:
    Fiddler的安装及配置2-2
    尚医通(一)
    【Linux】项目部署CPU彪高如何定位
    java读取指定文件夹下的全部文件,并输出文件名,文件大小,文件创建时间
    制作全志V3s开发板
    java---类加载器
    Spring 篇
    10.java项目-尚医通(10)
    我发现了,提升销售业绩的秘密武器!
    Spring事务传播特性
  • 原文地址:https://blog.csdn.net/Pretender_1205/article/details/133097875