IRQ line number vs Interrupt vector number

本文详细介绍了计算机系统中中断控制器的工作原理,包括IRQ分配、中断向量表的使用及共享IRQ的实现方式。同时探讨了操作系统如何管理和配置IRQ,以及硬件层面如何与设备驱动进行交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

On the mainbord we have an interrupt controller (IRC) which acts as a multiplexer between the devices which can raise an interrupt and the CPU:

                             |--------|
          |-----------|      |        |
-(0)------| IRC  _____|______| CPU    |
-(...)----| ____/     |      |        |
-(15)-----|/          |      |--------|
          |-----------|

Every device is associated with an IRQ (the number on the left). After every execution the CPU senses the interrupt-request line. If a signal is detected a state save will be performed and the CPU loads an Interrupt Handler Routine which can be found in the Interrupt Vector which is located on a fixed address in memory. As far as I can see the Number of the IRQ and the Vector number in the Interrupt Vector are not the same because I have for example my network card registered to IRQ 8. On an Intel Pentium processor this would point to a routine which is used to signal one error condition so there must be a mapping somewhere which points to the correct handler.


Q&A

Answers with respect to linux kernel. Should work for most other OS's also.

1) If I write an device driver and register an IRQ X for it. From where does the system know which device should be handled? I can for example use request_irq() with IRQ number 10 but how does the system know that the handler should be used for the mouse or keyboard or for whatever i write the driver?

There is no 1 answer to it. For example if this is a custom embedded system, the hardware designer will tell the driver writer "I am going to route device x to irq y". For more flexibility, for example for a network card which generally uses PCI protocol. There are hardware/firmware level arbitration to assign an irq number to a new device when it is detected. This will then be written to one of the PCI configuration register. The driver first reads this device register and then registers its interrupt handler for that particular irq. There will be similar mechanisms for other protocols.

What you can do is look up calls to request_irq in kernel code and how the driver obtained the irq value. It will be different for each kind of driver.

The answer to this question is thus, the system doesn't know. The hardware designer or the hardware protocols provide this information to driver writer. And then the driver writer registers the handler for that particular irq, telling the system what to do in case you see that irq.

2) How is the Interrupt Vector looking then? I mean if I use the IRQ 10 for my device this would overwrite an standard handler which is for error handling in the table (the first usable one is 32 according to Silberschatz (Operating System Concepts)).

Good question. There are two parts to it.

a) When you request_irq (irq,handler). The system really doesn't program entry 0 in the IVT or IDT. But entry N + irq. Where N is the number of error handlers or general purpose exceptions supported on that CPU. Details vary from system to system.

b) What happens if you erroneously request an irq which is used by another driver. You get an error and IDT is not programmed with your handler.

Note: IDT is interrupt descriptor table.

3) Who initialy sets the IRQs? The Bios? The OS?

Bios first and then OS. But there are certain OS's for example, MS-DOS which doesn't reprogram the IVT set up by BIOS. More sophisticated modern OS's like Windows or Linux do not want to rely on particular bios functions, and they re-program the IDT. But bios has to do it initially only then OS comes into picture.

4) Who is responsible for the matching of the IRQ and the offset in the Interrupt Vector?

I am really not clear what you mean. The flow is like this. First your device is assigned an irq number, and then you register an handler for it with that irq number. If you use wrong irq number, and then enable interrupt on your device, system will crash. Because the handler is registered fro wrong irq number.

5) It is possible to share IRQS. How is that possible? There are hardware lanes on the Mainboard which connect devices to the Interrupt Controller. How can to lanes be configured to the same Interrupt? There must be a table which says lane 2 and 3 handle IRQ15 e.g. Where does this table reside and how is it called?

This is a very good question. Extra table is not how it is solved in kernel. Rather for each shared irq, the handlers are kept in a linked list of function pointers. Kernel loops through all the handlers and invokes them one after another until one of the handler claims the interrupt as its own.

The code looks like this:

driver1:

d1_int_handler:
       if (device_interrupted()) <------------- This reads the hardware
       {
           do_interrupt_handling();
           return MY_INTERRUPT;
       }else {
           return NOT_MY_INTERRUPT;
       }

driver2:
       Similar to driver 1


kernel:
      do_irq(irq n)
      {
           if (shared_irq(n))
           {
                irq_chain = get_chain(n);
                while(irq_chain)
                {
                    if ((ret = irq_chain->handler()) == MY_INTERRUPT) 
                        break;
                    irq_chain = irq_chain->next;
                }
                if (ret != MY_INTERRUPT)
                     error "None of the drivers accepted the interrupt";
           }
      }

<think>好的,我现在需要帮助用户查找关于模块中断号与中断向量表的相关信息,特别是在嵌入式系统编程中的内容。首先,我需要明确这两个概念的定义和它们在嵌入式系统中的角色。 用户提到的“模块中断号”应该是指特定硬件模块(如定时器、UART、GPIO等)所对应的中断编号。每个硬件设备在系统中通常会有一个唯一的中断号,用来标识其中断请求。而“中断向量表”是一个存储中断处理程序(ISR)入口地址的数组或表格,中断号对应向量表中的索引,系统通过这个索引找到相应的处理程序。 接下来,我需要回忆嵌入式系统中中断处理的基本流程。当硬件触发中断时,处理器会根据中断号查找中断向量表,跳转到对应的ISR执行。这个过程涉及到硬件和操作系统的协作,比如中断控制器的配置和向量表的初始化。 然后,我需要考虑如何将这些信息结构化地呈现给用户。可能需要分点解释中断号的作用、向量表的结构,以及它们在嵌入式编程中的实际应用。同时,结合用户提供的引用内容,比如引用[1]提到的中断/异常机制是计算机系统的核心,说明硬件和软件如何协同工作,这里可以强调中断号作为硬件与软件交互的桥梁。 用户提供的引用[2]提到了调度程序切换上下文和用户模式,这可能与中断处理后的上下文切换有关。虽然主要讨论进程调度,但可以指出中断处理完毕后,如何通过调度器恢复程序执行,这也涉及到中断处理的全流程。 另外,引用[3]提到状态机实现工具,虽然不直接相关,但可能在复杂的中断处理逻辑中有应用,比如使用状态机管理多个中断源的情况,但暂时可以不深入这部分,除非用户进一步询问。 还需要注意用户提到的LaTeX格式要求,确保技术术语和公式正确使用,例如中断号与向量表索引的关系可以用数学表达式表示,比如用$vector\_table[IRQ\_number]$来说明访问方式。 用户可能还需要具体的代码示例,比如在STM32或AVR微控制器中如何配置中断向量表,或者如何注册中断处理函数。需要确保代码示例正确,并符合常见的嵌入式编程实践。 最后,生成的相关问题需要围绕用户查询的核心,可能涉及配置步骤、常见问题、优化方法等,帮助用户深入理解中断处理的各个方面。</think>### 模块中断号与中断向量表详解 在嵌入式系统编程中,**模块中断号**与**中断向量表**是中断处理机制的核心组成部分,其协作流程如下: 1. **模块中断号 (Interrupt Number)** - 定义:硬件模块(如定时器、UART、GPIO等)的唯一中断标识符,通常由芯片手册规定。 - 作用:标识中断源,例如STM32中定时器TIM2的中断号可能为$IRQ\_TIM2=28$。 - 配置:通过寄存器设置中断优先级和使能状态[^1]。 2. **中断向量表 (Interrupt Vector Table)** - 结构:存储中断服务程序(ISR)入口地址的数组,索引由中断号决定。数学表示为: $$vector\_table[IRQ\_number] = ISR\_address$$ - 初始化:系统启动时加载到固定内存地址(如ARM Cortex-M的0x00000000)[^1]。 3. **中断处理流程** - 硬件触发中断后,CPU根据中断号索引向量表,跳转至对应ISR。 - ISR执行完毕后,通过上下文切换恢复原程序流程[^2]。 ### 嵌入式编程中的实现示例 ```c // STM32中断向量表定义(简化版) void (*const vector_table[])(void) = { [IRQ_TIM2] = TIM2_IRQHandler, // 定时器2中断服务程序 [IRQ_USART1] = USART1_IRQHandler // 串口1中断服务程序 }; // 中断服务函数示例 void TIM2_IRQHandler(void) { // 清除中断标志 TIM2->SR &= ~TIM_SR_UIF; // 处理定时器溢出事件 } ``` ### 关键问题与优化 - **向量表重定位**:可通过修改$VTOR$寄存器实现动态加载,适用于RTOS多任务环境。 - **中断嵌套**:需配置优先级分组(如ARM的NVIC),数学优先级计算为: $$priority = (group\_priority << sub\_priority\_bits) | sub\_priority$$ - **性能影响**:过长ISR会阻塞低优先级中断,可通过"中断下半部"(Bottom Half)拆分处理[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值