欢迎转载,转载时需保留作者信息,谢谢。

邮箱:tangzhongp@163.com

博客园地址:http://www.cnblogs.com/embedded-tzp

Csdn博客地址:http://blog.csdn.net/xiayulewa

 

环境: http://www.cnblogs.com/embedded-tzp/p/4443876.html

 

 

1. arm硬件中断

从头介绍中断原理太麻烦,一般来说看这篇文章的人对中断必然已经有了一定的认识。不管哪款处理器,中断的基本概念是一样的:

中断向量表。

中断优先级。

中断现场保护与恢复。

 

1.1. 中断向量表

 

中断向量表,程序发生中断后会跳转到该表执行,一般在里面放置mov pc, addr_of_isr_func形式的指令,以中断向量表为跳板,跳转到中断服务程序中。

一般处理器中断向量表地址是固定的,arm920t固定在0x00000000,或者0xFFFF0000处,其地址是通过配置CP15的Register 1实现的。详细可阅读ARM920T_TRM1_S.pdf

默认中断向量表是在0x00000000处,arm920t的中断向量表如下:

        

上图为arm中断处理的流程,在程序正常运行时, 发生定时器中断,跳转到中断向量表处执行对应指令,而irq中断向量地址指令为goto irq_isr, 跳转到中断irq中断服务程序,此时首先保存现场,执行完中断逻辑后,再恢复现场,后中断返回,从之前被中断处的下一条指令继续运行。

 

 

 

1.2. Linux内核中的中断向量表

在entry-armv.S (src\arch\arm\kernel)中定义中断向量表。

    .section .vectors, "ax", %progbits

__vectors_start:

    W(b)    vector_rst

    W(b)    vector_und

    W(ldr)  pc, __vectors_start + 0x1000

    W(b)    vector_pabt

    W(b)    vector_dabt

    W(b)    vector_addrexcptn

    W(b)    vector_irq

W(b)    vector_fiq

 

 

1.3. linux中断初始化配置

 

硬件:有主中断SRCPND,子中断SUBSRCPND。主中断也可称为父中断。

 

处理器中断初始化: MACHINE_START:s3c2440_init_irq中初始化, 同时初始化static struct s3c_irq_intc *s3c_intc[3];变量

 

中断(irq,abt,und)的堆栈初始化setup_arch→setup_processor→cpu_init→struct stack *stk = &stacks[cpu] (irq,abt,und)

 

映射中断向量表:setup_arch→paging_init→devicemaps_init

 

定义中断向量表:src\arch\arm\kernel\entry-armv.S(其大部分定义在entry-header.S (src\arch\arm\kernel)):__vectors_start

 

中断方式初始化:如上升沿等,在init_s3c2440base里面定义

 

 

1.4. Linux中断执行流程

1.4.1. 中断入口与现场保护

假定程序运行在用户态,中断类型为irq,则:

 

   中断发生→W(b)   vector_irq( vector_irq 由vector_stub irq, IRQ_MODE, 4定义)→执行宏vector_stub定义的vector_irq中断服务程序, 定义见下:

    vector_stub irq, IRQ_MODE, 4

 

    .long   __irq_usr           @  0  (USR_26 / USR_32)

    .long   __irq_invalid           @  1  (FIQ_26 / FIQ_32)

    .long   __irq_invalid           @  2  (IRQ_26 / IRQ_32)

    .long   __irq_svc           @  3  (SVC_26 / SVC_32)

.long   __irq_invalid           @  4

 

vector_stub的作用是保存中断现场,获取中断前处理器状态,然后将状态设置为SVC mode,后跳转到相应的中断才处理程序。 前面假定中断前为用户态,所以中断发生后,会最终跳转到__irq_usr处执行。

1.4.2.    中断服务程序

__irq_usr→irq_handler→handle_arch_irq(是个函数指针,全局变量=s3c24xx_handle_irq, 在s3c24xx_init_intc中被赋值)→s3c24xx_handle_intc→handle_IRQ→generic_handle_irq→desc->handle_irq→如果是父中断,则执行s3c_irq_demux(在s3c24xx_irq_map中设置,执行chained_irq_enter→irq_ack清除主中断)→generic_handle_irq→desc->handle_irq即handle_edge_irq(chip->irq_ack清除次级中断相关位,在s3c24xx_irq_map中设置)→handle_irq_event→ handle_irq_event_percpu→action->handler(由request_irq申请,循环处理action = action->next)

 

1.4.3.    中断返回与现场恢复

以__irq_usr为例:b ret_to_user_from_irq(entry-common.S (src\arch\arm\kernel)定义)→ work_pending (在entry-common.S (src\arch\arm\kernel)定义)→ do_work_pending→ schedule

 

 

handle_arch_irq赋值流程:MACHINE_START的init_irq(s3c2440_init_irq)→s3c24xx_init_intc→set_handle_irq

 

desc->handle_irq注册流程:MACHINE_START::s3c2440_init_irq→s3c24xx_init_intc→irq_domain_add_legacy(传入 

s3c24xx_irq_ops)→ops->map(即s3c24xx_irq_ops->map),即s3c24xx_irq_map→根据中断类型如果是边沿触发,则 

desc->handle_irq=handle_edge_irq

 

 

 

    用到的变量与文件对应关系: 

src\arch\arm\include\asm\Unified.h: #define PSR_ISETSTATE 0

src\arch\arm\include\asm\linkage.h: #define ENDPROC(name) \

  .type name, %function; \

  END(name)

src\include\linux\linkage.h:#define END(name) \

  .size name, .-name

#endif

 

Asm-offsets.c (src\arch\arm\kernel):  DEFINE(S_FRAME_SIZE,    sizeof(struct pt_regs))

entry-header.S (src\arch\arm\kernel)): why .req   r8     @ Linux syscall (!= 0)

Unified.h (src\arch\arm\include\asm):#define BSYM(sym) sym

src\arch\arm\kernel\Asm-offsets.c: DEFINE(SYS_ERROR0,     0x9f0000);

 

1.5. linux中断注册

request_irq→request_threaded_irq→__setup_irq→new->irq = irq;   *old_ptr = new;(old_ptr指向action链表的最后一项)

 

 

1.6. linux中断地址映射

 

linux中断地址分配:MACHINE_START中mini2440_map_io→s3c24xx_init_io →iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); // 该函数分析详细见gpio章节。

由上述可见,#define S3C_VA_IRQ  S3C_ADDR(0x00000000), 知irq虚拟地址为0xF6000000,且因为串口物理地址和虚拟地址对应关系确定了,irq物理地址和虚拟地址也确定了,因为PA1-PA2 = VA1-VA2

 

1.7. linux中断数据结构

 

 

由上图可见,中断号可以索引所有的中断对象。

中断概貌:最重要的结构是全局变量struct irq_desc irq_desc[NR_IRQS]; 每一个中断号对应一个struct irq_desc, 在MACHINE_START中的s3c2440_init_irq主要是初始化该结构体。每个中断号和具体的irq_desc[i]对应,根据中断号就能知道该中断的所有信息,如该中断是父中断还是子中断,该中断的处理函数。父中断读取子中断源,通过desc->handle_irq = s3c_irq_demux(不一定是这个函数,为了描述方便举例的,后同)执行具体的子中断函数,子中断再执行desc->handle_irq = handle_edge_irq,最终都会

执行desc->action->handler。 总结起来 desc->handle_irq是执行函数分配,desc->action->handler执行具体的中断函数,

 

 1.4.  函数集合

request_irq

free_irq

 

 

 

【linux kernel】 中断处理-中断上半部的更多相关文章

  1. Linux kernel的中断子系统之(六):ARM中断处理过程

    返回目录:<ARM-Linux中断系统>. 总结:二中断处理经过两种模式:IRQ模式和SVC模式,这两种模式都有自己的stack,同时涉及到异常向量表中的中断向量. 三ARM处理器在感知到 ...

  2. Linux kernel的中断子系统之(一):综述

    返回目录:<ARM-Linux中断系统>. 总结: 一从作为一名驱动工程师角度看,用好中断需要正确认识request_threaded_irq/request_irq关系.中断临界区保护. ...

  3. Linux kernel的中断子系统之(八):softirq

    返回目录:<ARM-Linux中断系统>. 总结:中断分为上半部和下半部,上半部关中断:下半部开中断,处理可以延迟的事情.下半部有workqueue/softirq/tasklet三种方式 ...

  4. Linux kernel的中断子系统之(三):IRQ number和中断描述符

    返回目录:<ARM-Linux中断系统>. 总结: 二描述了中断处理示意图,以及关中断.开中断,和IRQ number重要概念. 三介绍了三个重要的结构体,irq_desc.irq_dat ...

  5. Linux kernel的中断子系统之(二):IRQ Domain介绍

    返回目录:<ARM-Linux中断系统>. 总结:一.二概述了软硬件不同角度的IRQ Number和HW Interrupt ID,这就需要他们之间架个桥梁. 三介绍了架设这种桥梁的几种方 ...

  6. Linux kernel的中断子系统之(四):High level irq event handler

    返回目录:<ARM-Linux中断系统>. 总结:从架构相关的汇编处理跳转到Machine/控制器相关的handle_arch_irq,generic_handle_irq作为High l ...

  7. Linux kernel的中断子系统之(九):tasklet

    返回目录:<ARM-Linux中断系统>. 总结: 二介绍了tasklet存在的意义. 三介绍了通过tasklet_struct来抽想一个tasklet,每个CPU维护一个tasklet链 ...

  8. Linux kernel的中断子系统之(七):GIC代码分析

    返回目录:<ARM-Linux中断系统>. 总结: 原文地址:<linux kernel的中断子系统之(七):GIC代码分析> 参考代码:http://elixir.free- ...

  9. linux kernel的中断子系统之(三):IRQ number和中断描述符【转】

    转自:http://www.wowotech.net/linux_kenrel/interrupt_descriptor.html 一.前言 本文主要围绕IRQ number和中断描述符(interr ...

  10. linux kernel的中断子系统 softirq

    linux kernel的中断子系统之(八):softirq http://www.wowotech.net/irq_subsystem/soft-irq.html http://www.ibm.co ...

随机推荐

  1. 用composer安装 Laravel | Laravel需要的环境配置

    一:安装 参考网站 http://v4.golaravel.com/docs/4.2/installation 1.先确保安装好了PHP,和服务器环境 2.然后下载composer可执行文件到当前目录 ...

  2. linux-2.6.33移植到FL2440

    宿主机:ubuntu10.04 目标机:fl2440 交叉编译器:arm-linux-gcc-3.4.1 交叉编译器路径:/usr/local/arm/3.4.1 要移植的内核版本:linux-2.6 ...

  3. FluentConsole是一个托管在github的C#开源组件

    FluentConsole是一个托管在github的C#开源组件 阅读目录 1.控制台能有啥滑头? 2.FluentConsole基本介绍 3.使用介绍 4.资源 从该系列的第一篇文章 .NET平台开 ...

  4. 条码的种类(types of barcode)

    条码基本上分为两大类:一维条码(1D Barcode)及二维条码(2D Barcode). 一维条码(1D Barcode) 所谓一维条码,简单的说就是条码只能横向水平方向列印,其缺点是储存的资料量较 ...

  5. 在Windows环境下使用MinGW编译Qt 4.8.6

    1.修改环境变量工具推荐:Rapid Environment Editor.官网:http://www.rapidee.com/ 修改前请先备份当前的环境变量.然后: (1)检查系统变量path,删除 ...

  6. [WPF疑难]如何禁用WPF窗口的系统菜单(SystemMenu)

    原文 [WPF疑难]如何禁用WPF窗口的系统菜单(SystemMenu) [WPF疑难]如何禁用WPF窗口的系统菜单(SystemMenu) 周银辉 点击窗口左上角图标时弹出来的菜单也就是这里所说的系 ...

  7. IT第四天 - 运算符、随机数、Math类

    IT第四天 上午 运算符 1.%运算符的应用 2.运算符优先级:小括号 ! 算数运算符 关系运算符 && ||   赋值运算符 3.三元运算符:?表示条件为true的结果,:表示条件为 ...

  8. BZOJ 1618: [Usaco2008 Nov]Buying Hay 购买干草

    题目 1618: [Usaco2008 Nov]Buying Hay 购买干草 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 679  Solved:  ...

  9. Apple Swift 中文教程 高速參考 基本的语法

    总的来说.语法有java的味道,也有python的味道,还有swift自己的味道. 有些语法还是挺不伦不类的,不太好理解,即使你有几年的java或python经验,也不见得有些语法你能非常轻松的看明确 ...

  10. C++赋值函数详解

    赋值函数        每个类只有一个赋值函数         由于并非所有的对象都会使用拷贝构造函数和赋值函数,程序员可能对这两个函数有些轻视.  1,如果不主动编写拷贝构造函数和赋值函数,编译器将 ...