您好、欢迎来到现金彩票网!
当前位置:彩之网 > 中断处理 >

arm linux 下中断流程简要分析中断处理流程

发布时间:2019-06-19 11:14 来源:未知 编辑:admin

  首先在分析源码之前,让我们了解一些原理性的东西,我们都知道在处理中断要保存当前现场状态,然后才能处理中断,处理完之后还要把现场状态恢复过来才能返回到被中断的地方继续执行,这里要说明的是在指令跳转到中断向量的地方开始执行之前,CPU帮我们做了哪些事情:

  R14_irq =要执行的下条指令地址+ 4//这里的下条指令是相对于被中断指令的下条。即返回地址

  SPSR_irq = CPSR//保存的现场状态,r0到r12要由我们软件来保存(如果需要的话)。

  当watchdog超时时将会产生中断,中断号就是IRQ_WDT,当产生中断时,系统将从跳转表中的中断位置开始运行,对于我们这篇文章来说:是从0xffff0000 + 24处开始运行。 这个地址的指令是:

  即直接跳转到vector_irq处去运行。这些都在中断初始化的时候分析过了。

  @ lr保存的是被打断指令处地址+8的值,(看上面的分析,由PC得到), 这里-4则就是中断

  mrslr, spsr@获取spsr的值,该值保存了被中断处执行环境的状态(参考上面的分析)

  movs的目的对象如果是pc的话,则还会把spsr赋值给cpsr,上面我们看到spsr被设成管理模式,因此这条语句过后的代码也就跑在了管理模式下。

  ,pt_regs中对应的就是上面栈上的18个寄存器,ARM_pc是pc寄存器存放在这个数组中的偏移。

  接着看get_thread_info, 它也是个宏,用来获取当前线程的地址。在我的一篇linux启动代码分析里曾写过线程的定义方式:

  由它定义的线K字节对齐的, 并且在这8K的最低地址处存放的就是thread_info对象,即该栈拥有者线程的对象,而get_thread_info就是通过把sp低13位清0(8K边界)来获取当前thread_info对象的地址。

  调用该宏后寄存器tsk里存放的就是当前线程的地址了,tsk是哪个寄存器呢,我们在看:

  movspc, lr@ return & move spsr_svc into cpsr, 返回被中断代码处继续执行,并把spsr赋给cpsp,即恢复被中断处的现场状态。这样CPU又可以从被中断的地方继续执行了,而且这个时候所有的寄存器值(r0到r12),包括状态寄存器值(cpsr)都是源码被中断时的值。

  由该汇编可知,如果在用户模式下产生中断的话,在返回的时候,会根据需要进行进程调度,而从代码可知,如果中断发生在管理等内核模式下的话是不会进行进程调度的。

  *如果该中断正在处理或者该中断被disable掉了的话,就不处理该中断,并清掉pending

  /*如果有IRQ_PENDING状态,则说明又有中断产生过,则继续执行*/

  该函数的大体功能都在函数体内解释出来了,这里我们对调用的每个函数在进行分析。

  由上面这两个函数可以看出来mask_ack_irq的作用是先mask掉该中断,并清除pending位,中断被mask掉后系统就不再响应了, 而pending位被清掉说明系统中该中断没有触发。一般在中断处理完后都要清pending位, 要不然系统会认为该中断又被触发了。

  handle_edge_irq()里调用的unmask函数,其实就是打开相应的中断,让系统响应这个中断,代码就不列出来了。

  该函数主要就是调用了action的handler函数,也就是我们用request_irq注册的中断例程。这里需要注意的是:如果我们注册中断的时候指明可以共享的话,则必须在我们的中断例程里判断当前产生的中断是否就是我们自己的中断,这可以通过传进来的参数来判断(该参数就是我们注册时提供的)。

http://ando2.com/zhongduanchuli/111.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有