Chinaunix首页 | 论坛 | 博客
  • 博客访问: 311551
  • 博文数量: 101
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 774
  • 用 户 组: 普通用户
  • 注册时间: 2018-10-15 14:13
个人简介

搭建一个和linux开发者知识共享和学习的平台

文章分类

全部博文(101)

文章存档

2024年(15)

2023年(24)

2022年(27)

2019年(8)

2018年(27)

分类: LINUX

2022-09-05 15:11:49

    可编程中断控制器PIC (Programable Interrupt Controller)是为了解决处理器中断引脚少,而管理的外设多的矛盾的。外设的中断线连接到PIC的pin引脚上,PIC的输出中断信号线连接到处理器的INT引脚上。在实际的硬件平台上,PIC有的在CPU外部,有的被封装在CPU内部。
    在处理器处理外部设备的中断之前,需要对PIC进行配置,作为操作系统初始化任务的一部分。配置工作主要有:
        1.设定外部设备中断触发电信号的类型,如水平触发,边沿触发。
        2.将外设的中断引脚编号映射到处理器可见的软件中断号irq。
        3.屏蔽掉某些外部设备的中断触发。

    软中断号irq,它是发生设备中断时处理器从PIC中读到的中断号码,在linux的中断处理框架中,会使用这个irq来标识一个外设的中断并调用对应的中断处理例程。
    处理流程:
        外设触发一个中断电信号,PIC收到该信号,判断是否被屏蔽,如果没有,PIC在处理器INT引脚上产生一个中断信号,处理器收到INT信号后从PIC里读取一个对应的irq标识号码,把该号码告诉中断处理框架,然后中断处理框架会调用对应的中断处理例程。

    中断向量表,是处理器内部的一个概念,因为处理器除了会被外部设备中断,其内部也可能会产生异常等事件。当这些事件发生时,CPU必须暂停当前的工作,转而去处理中断或异常,因此处理器需要知道到哪里去获得这些中断或异常的处理函数的目标地址。中断向量表就用来解决这个问题,其中每一项都是一个中断或异常处理函数的入口地址。
    外设的中断对应向量表中某一项,这是个通用的外部中断处理函数入口。
    汇编代码调用通用的中断处理函数asm_do_IRQ,参数1位软件中断号irq
    /*
     * Interrupt handling.  Preserves r7, r8, r9
     */
    .macro arch_irq_handler_default
    get_irqnr_preamble r6, lr
    1: get_irqnr_and_base r0, r2, r6, lr
    movne r1, sp
    @
    @ routine called with r0 = irq number, r1 = struct pt_regs *
    @
    adrne lr, BSYM(1b)
    bne asm_do_IRQ

    中断处理的绝大部分处理流程都在asm_do_IRQ中,当这个函数返回时,通用中断处理函数余下部分代码完成中断现场恢复的工作。
    linux内核为驱动提供的中断处理机制分成两个部分:HARDIRQ和SOFTIRQ。前者是在关中断情况下执行,操作尽可能短,后者在开中断情况下执行。在asm_do_IRQ函数中,对irq_enter的调用可以认为是HARDIRQ部分的开始,而SOFTIRQ则在irq_exit中完成。
    struct pt_regs *old_regs = set_irq_regs(regs);
    unsigned int irq = hwirq;
    int ret = 0;

     irq_enter();
    #ifdef CONFIG_IRQ_DOMAIN
    if (lookup)
         irq = irq_find_mapping(domain, hwirq);
    #endif
    /*
    * Some hardware gives randomly wrong interrupts.  Rather
    * than crashing, do something sensible.
    */
    if (unlikely(!irq || irq >= nr_irqs)) {
         ack_bad_irq(irq);
         ret = -EINVAL;
    } else {
         generic_handle_irq(irq);
    }
    irq_exit();
    set_irq_regs(old_regs);
    return ret;




阅读(315) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~